NDDEM
json.hpp
Go to the documentation of this file.
1 // __ _____ _____ _____
2 // __| | __| | | | JSON for Modern C++
3 // | | |__ | | | | | | version 3.12.0
4 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5 //
6 // SPDX-FileCopyrightText: 2013 - 2025 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.12.0
38 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
39 //
40 // SPDX-FileCopyrightText: 2013 - 2025 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.12.0
51 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
52 //
53 // SPDX-FileCopyrightText: 2013 - 2025 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 != 12 || NLOHMANN_JSON_VERSION_PATCH != 0
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 12 // NOLINT(modernize-macro-to-enum)
70 #define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum)
71 
72 #ifndef JSON_DIAGNOSTICS
73  #define JSON_DIAGNOSTICS 0
74 #endif
75 
76 #ifndef JSON_DIAGNOSTIC_POSITIONS
77  #define JSON_DIAGNOSTIC_POSITIONS 0
78 #endif
79 
80 #ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
81  #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
82 #endif
83 
84 #if JSON_DIAGNOSTICS
85  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
86 #else
87  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
88 #endif
89 
90 #if JSON_DIAGNOSTIC_POSITIONS
91  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp
92 #else
93  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS
94 #endif
95 
96 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
97  #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
98 #else
99  #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
100 #endif
101 
102 #ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
103  #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
104 #endif
105 
106 // Construct the namespace ABI tags component
107 #define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) json_abi ## a ## b ## c
108 #define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c) \
109  NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c)
110 
111 #define NLOHMANN_JSON_ABI_TAGS \
112  NLOHMANN_JSON_ABI_TAGS_CONCAT( \
113  NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
114  NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \
115  NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS)
116 
117 // Construct the namespace version component
118 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
119  _v ## major ## _ ## minor ## _ ## patch
120 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
121  NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
122 
123 #if NLOHMANN_JSON_NAMESPACE_NO_VERSION
124 #define NLOHMANN_JSON_NAMESPACE_VERSION
125 #else
126 #define NLOHMANN_JSON_NAMESPACE_VERSION \
127  NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
128  NLOHMANN_JSON_VERSION_MINOR, \
129  NLOHMANN_JSON_VERSION_PATCH)
130 #endif
131 
132 // Combine namespace components
133 #define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
134 #define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
135  NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
136 
137 #ifndef NLOHMANN_JSON_NAMESPACE
138 #define NLOHMANN_JSON_NAMESPACE \
139  nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
140  NLOHMANN_JSON_ABI_TAGS, \
141  NLOHMANN_JSON_NAMESPACE_VERSION)
142 #endif
143 
144 #ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
145 #define NLOHMANN_JSON_NAMESPACE_BEGIN \
146  namespace nlohmann \
147  { \
148  inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
149  NLOHMANN_JSON_ABI_TAGS, \
150  NLOHMANN_JSON_NAMESPACE_VERSION) \
151  {
152 #endif
153 
154 #ifndef NLOHMANN_JSON_NAMESPACE_END
155 #define NLOHMANN_JSON_NAMESPACE_END \
156  } /* namespace (inline namespace) NOLINT(readability/namespace) */ \
157  } // namespace nlohmann
158 #endif
159 
160 // #include <nlohmann/detail/conversions/from_json.hpp>
161 // __ _____ _____ _____
162 // __| | __| | | | JSON for Modern C++
163 // | | |__ | | | | | | version 3.12.0
164 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
165 //
166 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
167 // SPDX-License-Identifier: MIT
168 
169 
170 
171 #include <algorithm> // transform
172 #include <array> // array
173 #include <forward_list> // forward_list
174 #include <iterator> // inserter, front_inserter, end
175 #include <map> // map
176 #include <string> // string
177 #include <tuple> // tuple, make_tuple
178 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
179 #include <unordered_map> // unordered_map
180 #include <utility> // pair, declval
181 #include <valarray> // valarray
182 
183 // #include <nlohmann/detail/exceptions.hpp>
184 // __ _____ _____ _____
185 // __| | __| | | | JSON for Modern C++
186 // | | |__ | | | | | | version 3.12.0
187 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
188 //
189 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
190 // SPDX-License-Identifier: MIT
191 
192 
193 
194 #include <cstddef> // nullptr_t
195 #include <exception> // exception
196 #if JSON_DIAGNOSTICS
197  #include <numeric> // accumulate
198 #endif
199 #include <stdexcept> // runtime_error
200 #include <string> // to_string
201 #include <vector> // vector
202 
203 // #include <nlohmann/detail/value_t.hpp>
204 // __ _____ _____ _____
205 // __| | __| | | | JSON for Modern C++
206 // | | |__ | | | | | | version 3.12.0
207 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
208 //
209 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
210 // SPDX-License-Identifier: MIT
211 
212 
213 
214 #include <array> // array
215 #include <cstddef> // size_t
216 #include <cstdint> // uint8_t
217 #include <string> // string
218 
219 // #include <nlohmann/detail/macro_scope.hpp>
220 // __ _____ _____ _____
221 // __| | __| | | | JSON for Modern C++
222 // | | |__ | | | | | | version 3.12.0
223 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
224 //
225 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
226 // SPDX-License-Identifier: MIT
227 
228 
229 
230 #include <utility> // declval, pair
231 // #include <nlohmann/detail/meta/detected.hpp>
232 // __ _____ _____ _____
233 // __| | __| | | | JSON for Modern C++
234 // | | |__ | | | | | | version 3.12.0
235 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
236 //
237 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
238 // SPDX-License-Identifier: MIT
239 
240 
241 
242 #include <type_traits>
243 
244 // #include <nlohmann/detail/meta/void_t.hpp>
245 // __ _____ _____ _____
246 // __| | __| | | | JSON for Modern C++
247 // | | |__ | | | | | | version 3.12.0
248 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
249 //
250 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
251 // SPDX-License-Identifier: MIT
252 
253 
254 
255 // #include <nlohmann/detail/abi_macros.hpp>
256 
257 
259 namespace detail
260 {
261 
262 template<typename ...Ts> struct make_void
263 {
264  using type = void;
265 };
266 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
267 
268 } // namespace detail
270 
271 
273 namespace detail
274 {
275 
276 // https://en.cppreference.com/w/cpp/experimental/is_detected
277 struct nonesuch
278 {
279  nonesuch() = delete;
280  ~nonesuch() = delete;
281  nonesuch(nonesuch const&) = delete;
282  nonesuch(nonesuch const&&) = delete;
283  void operator=(nonesuch const&) = delete;
284  void operator=(nonesuch&&) = delete;
285 };
286 
287 template<class Default,
288  class AlwaysVoid,
289  template<class...> class Op,
290  class... Args>
291 struct detector
292 {
293  using value_t = std::false_type;
294  using type = Default;
295 };
296 
297 template<class Default, template<class...> class Op, class... Args>
298 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
299 {
300  using value_t = std::true_type;
301  using type = Op<Args...>;
302 };
303 
304 template<template<class...> class Op, class... Args>
305 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
306 
307 template<template<class...> class Op, class... Args>
308 struct is_detected_lazy : is_detected<Op, Args...> { };
309 
310 template<template<class...> class Op, class... Args>
311 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
312 
313 template<class Default, template<class...> class Op, class... Args>
314 using detected_or = detector<Default, void, Op, Args...>;
315 
316 template<class Default, template<class...> class Op, class... Args>
317 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
318 
319 template<class Expected, template<class...> class Op, class... Args>
320 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
321 
322 template<class To, template<class...> class Op, class... Args>
324  std::is_convertible<detected_t<Op, Args...>, To>;
325 
326 } // namespace detail
328 
329 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
330 
331 
332 // __ _____ _____ _____
333 // __| | __| | | | JSON for Modern C++
334 // | | |__ | | | | | | version 3.12.0
335 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
336 //
337 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
338 // SPDX-FileCopyrightText: 2016 - 2021 Evan Nemerson <evan@nemerson.com>
339 // SPDX-License-Identifier: MIT
340 
341 /* Hedley - https://nemequ.github.io/hedley
342  * Created by Evan Nemerson <evan@nemerson.com>
343  */
344 
345 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
346 #if defined(JSON_HEDLEY_VERSION)
347  #undef JSON_HEDLEY_VERSION
348 #endif
349 #define JSON_HEDLEY_VERSION 15
350 
351 #if defined(JSON_HEDLEY_STRINGIFY_EX)
352  #undef JSON_HEDLEY_STRINGIFY_EX
353 #endif
354 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
355 
356 #if defined(JSON_HEDLEY_STRINGIFY)
357  #undef JSON_HEDLEY_STRINGIFY
358 #endif
359 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
360 
361 #if defined(JSON_HEDLEY_CONCAT_EX)
362  #undef JSON_HEDLEY_CONCAT_EX
363 #endif
364 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
365 
366 #if defined(JSON_HEDLEY_CONCAT)
367  #undef JSON_HEDLEY_CONCAT
368 #endif
369 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
370 
371 #if defined(JSON_HEDLEY_CONCAT3_EX)
372  #undef JSON_HEDLEY_CONCAT3_EX
373 #endif
374 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
375 
376 #if defined(JSON_HEDLEY_CONCAT3)
377  #undef JSON_HEDLEY_CONCAT3
378 #endif
379 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
380 
381 #if defined(JSON_HEDLEY_VERSION_ENCODE)
382  #undef JSON_HEDLEY_VERSION_ENCODE
383 #endif
384 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
385 
386 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
387  #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
388 #endif
389 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
390 
391 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
392  #undef JSON_HEDLEY_VERSION_DECODE_MINOR
393 #endif
394 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
395 
396 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
397  #undef JSON_HEDLEY_VERSION_DECODE_REVISION
398 #endif
399 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
400 
401 #if defined(JSON_HEDLEY_GNUC_VERSION)
402  #undef JSON_HEDLEY_GNUC_VERSION
403 #endif
404 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
405  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
406 #elif defined(__GNUC__)
407  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
408 #endif
409 
410 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
411  #undef JSON_HEDLEY_GNUC_VERSION_CHECK
412 #endif
413 #if defined(JSON_HEDLEY_GNUC_VERSION)
414  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
415 #else
416  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
417 #endif
418 
419 #if defined(JSON_HEDLEY_MSVC_VERSION)
420  #undef JSON_HEDLEY_MSVC_VERSION
421 #endif
422 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
423  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
424 #elif defined(_MSC_FULL_VER) && !defined(__ICL)
425  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
426 #elif defined(_MSC_VER) && !defined(__ICL)
427  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
428 #endif
429 
430 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
431  #undef JSON_HEDLEY_MSVC_VERSION_CHECK
432 #endif
433 #if !defined(JSON_HEDLEY_MSVC_VERSION)
434  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
435 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
436  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
437 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
438  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
439 #else
440  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
441 #endif
442 
443 #if defined(JSON_HEDLEY_INTEL_VERSION)
444  #undef JSON_HEDLEY_INTEL_VERSION
445 #endif
446 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
447  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
448 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
449  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
450 #endif
451 
452 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
453  #undef JSON_HEDLEY_INTEL_VERSION_CHECK
454 #endif
455 #if defined(JSON_HEDLEY_INTEL_VERSION)
456  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
457 #else
458  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
459 #endif
460 
461 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
462  #undef JSON_HEDLEY_INTEL_CL_VERSION
463 #endif
464 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
465  #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
466 #endif
467 
468 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
469  #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
470 #endif
471 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
472  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
473 #else
474  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
475 #endif
476 
477 #if defined(JSON_HEDLEY_PGI_VERSION)
478  #undef JSON_HEDLEY_PGI_VERSION
479 #endif
480 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
481  #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
482 #endif
483 
484 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
485  #undef JSON_HEDLEY_PGI_VERSION_CHECK
486 #endif
487 #if defined(JSON_HEDLEY_PGI_VERSION)
488  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
489 #else
490  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
491 #endif
492 
493 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
494  #undef JSON_HEDLEY_SUNPRO_VERSION
495 #endif
496 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
497  #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)
498 #elif defined(__SUNPRO_C)
499  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
500 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
501  #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)
502 #elif defined(__SUNPRO_CC)
503  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
504 #endif
505 
506 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
507  #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
508 #endif
509 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
510  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
511 #else
512  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
513 #endif
514 
515 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
516  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
517 #endif
518 #if defined(__EMSCRIPTEN__)
519  #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
520 #endif
521 
522 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
523  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
524 #endif
525 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
526  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
527 #else
528  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
529 #endif
530 
531 #if defined(JSON_HEDLEY_ARM_VERSION)
532  #undef JSON_HEDLEY_ARM_VERSION
533 #endif
534 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
535  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
536 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
537  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
538 #endif
539 
540 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
541  #undef JSON_HEDLEY_ARM_VERSION_CHECK
542 #endif
543 #if defined(JSON_HEDLEY_ARM_VERSION)
544  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
545 #else
546  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
547 #endif
548 
549 #if defined(JSON_HEDLEY_IBM_VERSION)
550  #undef JSON_HEDLEY_IBM_VERSION
551 #endif
552 #if defined(__ibmxl__)
553  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
554 #elif defined(__xlC__) && defined(__xlC_ver__)
555  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
556 #elif defined(__xlC__)
557  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
558 #endif
559 
560 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
561  #undef JSON_HEDLEY_IBM_VERSION_CHECK
562 #endif
563 #if defined(JSON_HEDLEY_IBM_VERSION)
564  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
565 #else
566  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
567 #endif
568 
569 #if defined(JSON_HEDLEY_TI_VERSION)
570  #undef JSON_HEDLEY_TI_VERSION
571 #endif
572 #if \
573  defined(__TI_COMPILER_VERSION__) && \
574  ( \
575  defined(__TMS470__) || defined(__TI_ARM__) || \
576  defined(__MSP430__) || \
577  defined(__TMS320C2000__) \
578  )
579 #if (__TI_COMPILER_VERSION__ >= 16000000)
580  #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
581 #endif
582 #endif
583 
584 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
585  #undef JSON_HEDLEY_TI_VERSION_CHECK
586 #endif
587 #if defined(JSON_HEDLEY_TI_VERSION)
588  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
589 #else
590  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
591 #endif
592 
593 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
594  #undef JSON_HEDLEY_TI_CL2000_VERSION
595 #endif
596 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
597  #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
598 #endif
599 
600 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
601  #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
602 #endif
603 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
604  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
605 #else
606  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
607 #endif
608 
609 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
610  #undef JSON_HEDLEY_TI_CL430_VERSION
611 #endif
612 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
613  #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
614 #endif
615 
616 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
617  #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
618 #endif
619 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
620  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
621 #else
622  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
623 #endif
624 
625 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
626  #undef JSON_HEDLEY_TI_ARMCL_VERSION
627 #endif
628 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
629  #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
630 #endif
631 
632 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
633  #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
634 #endif
635 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
636  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
637 #else
638  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
639 #endif
640 
641 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
642  #undef JSON_HEDLEY_TI_CL6X_VERSION
643 #endif
644 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
645  #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
646 #endif
647 
648 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
649  #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
650 #endif
651 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
652  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
653 #else
654  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
655 #endif
656 
657 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
658  #undef JSON_HEDLEY_TI_CL7X_VERSION
659 #endif
660 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
661  #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
662 #endif
663 
664 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
665  #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
666 #endif
667 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
668  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
669 #else
670  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
671 #endif
672 
673 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
674  #undef JSON_HEDLEY_TI_CLPRU_VERSION
675 #endif
676 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
677  #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
678 #endif
679 
680 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
681  #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
682 #endif
683 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
684  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
685 #else
686  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
687 #endif
688 
689 #if defined(JSON_HEDLEY_CRAY_VERSION)
690  #undef JSON_HEDLEY_CRAY_VERSION
691 #endif
692 #if defined(_CRAYC)
693  #if defined(_RELEASE_PATCHLEVEL)
694  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
695  #else
696  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
697  #endif
698 #endif
699 
700 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
701  #undef JSON_HEDLEY_CRAY_VERSION_CHECK
702 #endif
703 #if defined(JSON_HEDLEY_CRAY_VERSION)
704  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
705 #else
706  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
707 #endif
708 
709 #if defined(JSON_HEDLEY_IAR_VERSION)
710  #undef JSON_HEDLEY_IAR_VERSION
711 #endif
712 #if defined(__IAR_SYSTEMS_ICC__)
713  #if __VER__ > 1000
714  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
715  #else
716  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
717  #endif
718 #endif
719 
720 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
721  #undef JSON_HEDLEY_IAR_VERSION_CHECK
722 #endif
723 #if defined(JSON_HEDLEY_IAR_VERSION)
724  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
725 #else
726  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
727 #endif
728 
729 #if defined(JSON_HEDLEY_TINYC_VERSION)
730  #undef JSON_HEDLEY_TINYC_VERSION
731 #endif
732 #if defined(__TINYC__)
733  #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
734 #endif
735 
736 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
737  #undef JSON_HEDLEY_TINYC_VERSION_CHECK
738 #endif
739 #if defined(JSON_HEDLEY_TINYC_VERSION)
740  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
741 #else
742  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
743 #endif
744 
745 #if defined(JSON_HEDLEY_DMC_VERSION)
746  #undef JSON_HEDLEY_DMC_VERSION
747 #endif
748 #if defined(__DMC__)
749  #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
750 #endif
751 
752 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
753  #undef JSON_HEDLEY_DMC_VERSION_CHECK
754 #endif
755 #if defined(JSON_HEDLEY_DMC_VERSION)
756  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
757 #else
758  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
759 #endif
760 
761 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
762  #undef JSON_HEDLEY_COMPCERT_VERSION
763 #endif
764 #if defined(__COMPCERT_VERSION__)
765  #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
766 #endif
767 
768 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
769  #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
770 #endif
771 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
772  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
773 #else
774  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
775 #endif
776 
777 #if defined(JSON_HEDLEY_PELLES_VERSION)
778  #undef JSON_HEDLEY_PELLES_VERSION
779 #endif
780 #if defined(__POCC__)
781  #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
782 #endif
783 
784 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
785  #undef JSON_HEDLEY_PELLES_VERSION_CHECK
786 #endif
787 #if defined(JSON_HEDLEY_PELLES_VERSION)
788  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
789 #else
790  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
791 #endif
792 
793 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
794  #undef JSON_HEDLEY_MCST_LCC_VERSION
795 #endif
796 #if defined(__LCC__) && defined(__LCC_MINOR__)
797  #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
798 #endif
799 
800 #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
801  #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
802 #endif
803 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
804  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
805 #else
806  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
807 #endif
808 
809 #if defined(JSON_HEDLEY_GCC_VERSION)
810  #undef JSON_HEDLEY_GCC_VERSION
811 #endif
812 #if \
813  defined(JSON_HEDLEY_GNUC_VERSION) && \
814  !defined(__clang__) && \
815  !defined(JSON_HEDLEY_INTEL_VERSION) && \
816  !defined(JSON_HEDLEY_PGI_VERSION) && \
817  !defined(JSON_HEDLEY_ARM_VERSION) && \
818  !defined(JSON_HEDLEY_CRAY_VERSION) && \
819  !defined(JSON_HEDLEY_TI_VERSION) && \
820  !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
821  !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
822  !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
823  !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
824  !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
825  !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
826  !defined(__COMPCERT__) && \
827  !defined(JSON_HEDLEY_MCST_LCC_VERSION)
828  #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
829 #endif
830 
831 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
832  #undef JSON_HEDLEY_GCC_VERSION_CHECK
833 #endif
834 #if defined(JSON_HEDLEY_GCC_VERSION)
835  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
836 #else
837  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
838 #endif
839 
840 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
841  #undef JSON_HEDLEY_HAS_ATTRIBUTE
842 #endif
843 #if \
844  defined(__has_attribute) && \
845  ( \
846  (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
847  )
848 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
849 #else
850 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
851 #endif
852 
853 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
854  #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
855 #endif
856 #if defined(__has_attribute)
857  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
858 #else
859  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
860 #endif
861 
862 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
863  #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
864 #endif
865 #if defined(__has_attribute)
866  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
867 #else
868  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
869 #endif
870 
871 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
872  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
873 #endif
874 #if \
875  defined(__has_cpp_attribute) && \
876  defined(__cplusplus) && \
877  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
878  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
879 #else
880  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
881 #endif
882 
883 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
884  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
885 #endif
886 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
887  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
888 #elif \
889  !defined(JSON_HEDLEY_PGI_VERSION) && \
890  !defined(JSON_HEDLEY_IAR_VERSION) && \
891  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
892  (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
893  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
894 #else
895  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
896 #endif
897 
898 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
899  #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
900 #endif
901 #if defined(__has_cpp_attribute) && defined(__cplusplus)
902  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
903 #else
904  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
905 #endif
906 
907 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
908  #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
909 #endif
910 #if defined(__has_cpp_attribute) && defined(__cplusplus)
911  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
912 #else
913  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
914 #endif
915 
916 #if defined(JSON_HEDLEY_HAS_BUILTIN)
917  #undef JSON_HEDLEY_HAS_BUILTIN
918 #endif
919 #if defined(__has_builtin)
920  #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
921 #else
922  #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
923 #endif
924 
925 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
926  #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
927 #endif
928 #if defined(__has_builtin)
929  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
930 #else
931  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
932 #endif
933 
934 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
935  #undef JSON_HEDLEY_GCC_HAS_BUILTIN
936 #endif
937 #if defined(__has_builtin)
938  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
939 #else
940  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
941 #endif
942 
943 #if defined(JSON_HEDLEY_HAS_FEATURE)
944  #undef JSON_HEDLEY_HAS_FEATURE
945 #endif
946 #if defined(__has_feature)
947  #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
948 #else
949  #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
950 #endif
951 
952 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
953  #undef JSON_HEDLEY_GNUC_HAS_FEATURE
954 #endif
955 #if defined(__has_feature)
956  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
957 #else
958  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
959 #endif
960 
961 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
962  #undef JSON_HEDLEY_GCC_HAS_FEATURE
963 #endif
964 #if defined(__has_feature)
965  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
966 #else
967  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
968 #endif
969 
970 #if defined(JSON_HEDLEY_HAS_EXTENSION)
971  #undef JSON_HEDLEY_HAS_EXTENSION
972 #endif
973 #if defined(__has_extension)
974  #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
975 #else
976  #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
977 #endif
978 
979 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
980  #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
981 #endif
982 #if defined(__has_extension)
983  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
984 #else
985  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
986 #endif
987 
988 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
989  #undef JSON_HEDLEY_GCC_HAS_EXTENSION
990 #endif
991 #if defined(__has_extension)
992  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
993 #else
994  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
995 #endif
996 
997 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
998  #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
999 #endif
1000 #if defined(__has_declspec_attribute)
1001  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
1002 #else
1003  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
1004 #endif
1005 
1006 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
1007  #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
1008 #endif
1009 #if defined(__has_declspec_attribute)
1010  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1011 #else
1012  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1013 #endif
1014 
1015 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
1016  #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
1017 #endif
1018 #if defined(__has_declspec_attribute)
1019  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1020 #else
1021  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1022 #endif
1023 
1024 #if defined(JSON_HEDLEY_HAS_WARNING)
1025  #undef JSON_HEDLEY_HAS_WARNING
1026 #endif
1027 #if defined(__has_warning)
1028  #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
1029 #else
1030  #define JSON_HEDLEY_HAS_WARNING(warning) (0)
1031 #endif
1032 
1033 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
1034  #undef JSON_HEDLEY_GNUC_HAS_WARNING
1035 #endif
1036 #if defined(__has_warning)
1037  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1038 #else
1039  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1040 #endif
1041 
1042 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
1043  #undef JSON_HEDLEY_GCC_HAS_WARNING
1044 #endif
1045 #if defined(__has_warning)
1046  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1047 #else
1048  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1049 #endif
1050 
1051 #if \
1052  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1053  defined(__clang__) || \
1054  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1055  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1056  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1057  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1058  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1059  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1060  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1061  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1062  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1063  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
1064  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1065  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1066  JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
1067  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
1068  JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
1069  (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
1070  #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
1071 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1072  #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
1073 #else
1074  #define JSON_HEDLEY_PRAGMA(value)
1075 #endif
1076 
1077 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
1078  #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
1079 #endif
1080 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
1081  #undef JSON_HEDLEY_DIAGNOSTIC_POP
1082 #endif
1083 #if defined(__clang__)
1084  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
1085  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
1086 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1087  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1088  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1089 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1090  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
1091  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
1092 #elif \
1093  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1094  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1095  #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
1096  #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
1097 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
1098  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
1099  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
1100 #elif \
1101  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1102  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1103  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
1104  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1105  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1106  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1107  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
1108  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
1109 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1110  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1111  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1112 #else
1113  #define JSON_HEDLEY_DIAGNOSTIC_PUSH
1114  #define JSON_HEDLEY_DIAGNOSTIC_POP
1115 #endif
1116 
1117 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
1118  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1119 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1120  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
1121 #endif
1122 #if defined(__cplusplus)
1123 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
1124 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
1125 # if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
1126 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1127  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1128  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1129  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1130  _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
1131  xpr \
1132  JSON_HEDLEY_DIAGNOSTIC_POP
1133 # else
1134 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1135  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1136  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1137  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1138  xpr \
1139  JSON_HEDLEY_DIAGNOSTIC_POP
1140 # endif
1141 # else
1142 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1143  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1144  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1145  xpr \
1146  JSON_HEDLEY_DIAGNOSTIC_POP
1147 # endif
1148 # endif
1149 #endif
1150 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1151  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1152 #endif
1153 
1154 #if defined(JSON_HEDLEY_CONST_CAST)
1155  #undef JSON_HEDLEY_CONST_CAST
1156 #endif
1157 #if defined(__cplusplus)
1158 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1159 #elif \
1160  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1161  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1162  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1163 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1164  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1165  JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1166  ((T) (expr)); \
1167  JSON_HEDLEY_DIAGNOSTIC_POP \
1168  }))
1169 #else
1170 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1171 #endif
1172 
1173 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
1174  #undef JSON_HEDLEY_REINTERPRET_CAST
1175 #endif
1176 #if defined(__cplusplus)
1177  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1178 #else
1179  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1180 #endif
1181 
1182 #if defined(JSON_HEDLEY_STATIC_CAST)
1183  #undef JSON_HEDLEY_STATIC_CAST
1184 #endif
1185 #if defined(__cplusplus)
1186  #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1187 #else
1188  #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1189 #endif
1190 
1191 #if defined(JSON_HEDLEY_CPP_CAST)
1192  #undef JSON_HEDLEY_CPP_CAST
1193 #endif
1194 #if defined(__cplusplus)
1195 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1196 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1197  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1198  _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1199  ((T) (expr)) \
1200  JSON_HEDLEY_DIAGNOSTIC_POP
1201 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1202 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1203  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1204  _Pragma("diag_suppress=Pe137") \
1205  JSON_HEDLEY_DIAGNOSTIC_POP
1206 # else
1207 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1208 # endif
1209 #else
1210 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1211 #endif
1212 
1213 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1214  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1215 #endif
1216 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1217  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1218 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1219  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1220 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1221  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1222 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1223  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1224 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1225  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1226 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1227  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1228 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1229  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1230 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1231  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1232 #elif \
1233  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1234  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1235  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1236  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1237  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1238  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1239  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1240  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1241  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1242  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1243  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1244  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1245 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1246  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1247 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1248  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1249 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1250  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1251 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1252  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1253 #else
1254  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1255 #endif
1256 
1257 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1258  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1259 #endif
1260 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1261  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1262 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1263  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1264 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1265  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1266 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1267  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1268 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1269  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1270 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1271  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1272 #elif \
1273  JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1274  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1275  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1276  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1277  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1278 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1279  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1280 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1281  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1282 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1283  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1284 #else
1285  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1286 #endif
1287 
1288 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1289  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1290 #endif
1291 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1292  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1293 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1294  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1295 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1296  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1297 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1298  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1299 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1300  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1301 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1302  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1303 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1304  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1305 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1306  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1307 #elif \
1308  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1309  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1310  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1311  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1312 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1313  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1314 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1315  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1316 #else
1317  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1318 #endif
1319 
1320 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1321  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1322 #endif
1323 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1324  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1325 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1326  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1327 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1328  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1329 #else
1330  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1331 #endif
1332 
1333 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1334  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1335 #endif
1336 #if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1337  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1338 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1339  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1340 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1341  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1342 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1343  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1344 #else
1345  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1346 #endif
1347 
1348 #if defined(JSON_HEDLEY_DEPRECATED)
1349  #undef JSON_HEDLEY_DEPRECATED
1350 #endif
1351 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1352  #undef JSON_HEDLEY_DEPRECATED_FOR
1353 #endif
1354 #if \
1355  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1356  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1357  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1358  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1359 #elif \
1360  (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1361  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1362  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1363  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1364  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1365  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1366  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1367  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1368  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1369  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1370  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1371  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1372  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1373  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1374 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1375  #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1376  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1377 #elif \
1378  JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1379  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1380  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1381  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1382  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1383  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1384  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1385  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1386  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1387  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1388  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1389  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1390  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1391  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1392  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1393  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1394  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1395  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1396 #elif \
1397  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1398  JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1399  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1400  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1401  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1402 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1403  #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1404  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1405 #else
1406  #define JSON_HEDLEY_DEPRECATED(since)
1407  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1408 #endif
1409 
1410 #if defined(JSON_HEDLEY_UNAVAILABLE)
1411  #undef JSON_HEDLEY_UNAVAILABLE
1412 #endif
1413 #if \
1414  JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1415  JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1416  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1417  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1418  #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1419 #else
1420  #define JSON_HEDLEY_UNAVAILABLE(available_since)
1421 #endif
1422 
1423 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1424  #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1425 #endif
1426 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1427  #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1428 #endif
1429 #if \
1430  JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1431  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1432  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1433  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1434  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1435  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1436  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1437  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1438  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1439  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1440  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1441  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1442  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1443  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1444  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1445  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1446  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1447  #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1448  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1449 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1450  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1451  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1452 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1453  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1454  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1455 #elif defined(_Check_return_) /* SAL */
1456  #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1457  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1458 #else
1459  #define JSON_HEDLEY_WARN_UNUSED_RESULT
1460  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1461 #endif
1462 
1463 #if defined(JSON_HEDLEY_SENTINEL)
1464  #undef JSON_HEDLEY_SENTINEL
1465 #endif
1466 #if \
1467  JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1468  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1469  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1470  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1471  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1472  #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1473 #else
1474  #define JSON_HEDLEY_SENTINEL(position)
1475 #endif
1476 
1477 #if defined(JSON_HEDLEY_NO_RETURN)
1478  #undef JSON_HEDLEY_NO_RETURN
1479 #endif
1480 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1481  #define JSON_HEDLEY_NO_RETURN __noreturn
1482 #elif \
1483  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1484  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1485  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1486 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1487  #define JSON_HEDLEY_NO_RETURN _Noreturn
1488 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1489  #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1490 #elif \
1491  JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1492  JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1493  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1494  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1495  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1496  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1497  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1498  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1499  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1500  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1501  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1502  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1503  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1504  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1505  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1506  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1507  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1508  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1509 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1510  #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1511 #elif \
1512  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1513  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1514  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1515 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1516  #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1517 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1518  #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1519 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1520  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1521 #else
1522  #define JSON_HEDLEY_NO_RETURN
1523 #endif
1524 
1525 #if defined(JSON_HEDLEY_NO_ESCAPE)
1526  #undef JSON_HEDLEY_NO_ESCAPE
1527 #endif
1528 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1529  #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1530 #else
1531  #define JSON_HEDLEY_NO_ESCAPE
1532 #endif
1533 
1534 #if defined(JSON_HEDLEY_UNREACHABLE)
1535  #undef JSON_HEDLEY_UNREACHABLE
1536 #endif
1537 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1538  #undef JSON_HEDLEY_UNREACHABLE_RETURN
1539 #endif
1540 #if defined(JSON_HEDLEY_ASSUME)
1541  #undef JSON_HEDLEY_ASSUME
1542 #endif
1543 #if \
1544  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1545  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1546  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1547  #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1548 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1549  #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1550 #elif \
1551  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1552  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1553  #if defined(__cplusplus)
1554  #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1555  #else
1556  #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1557  #endif
1558 #endif
1559 #if \
1560  (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1561  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1562  JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1563  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1564  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1565  JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1566  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1567  #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1568 #elif defined(JSON_HEDLEY_ASSUME)
1569  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1570 #endif
1571 #if !defined(JSON_HEDLEY_ASSUME)
1572  #if defined(JSON_HEDLEY_UNREACHABLE)
1573  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1574  #else
1575  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1576  #endif
1577 #endif
1578 #if defined(JSON_HEDLEY_UNREACHABLE)
1579  #if \
1580  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1581  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1582  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1583  #else
1584  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1585  #endif
1586 #else
1587  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1588 #endif
1589 #if !defined(JSON_HEDLEY_UNREACHABLE)
1590  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1591 #endif
1592 
1594 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1595  #pragma clang diagnostic ignored "-Wpedantic"
1596 #endif
1597 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1598  #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1599 #endif
1600 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1601  #if defined(__clang__)
1602  #pragma clang diagnostic ignored "-Wvariadic-macros"
1603  #elif defined(JSON_HEDLEY_GCC_VERSION)
1604  #pragma GCC diagnostic ignored "-Wvariadic-macros"
1605  #endif
1606 #endif
1607 #if defined(JSON_HEDLEY_NON_NULL)
1608  #undef JSON_HEDLEY_NON_NULL
1609 #endif
1610 #if \
1611  JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1612  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1613  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1614  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1615  #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1616 #else
1617  #define JSON_HEDLEY_NON_NULL(...)
1618 #endif
1620 
1621 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1622  #undef JSON_HEDLEY_PRINTF_FORMAT
1623 #endif
1624 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1625  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1626 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1627  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1628 #elif \
1629  JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1630  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1631  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1632  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1633  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1634  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1635  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1636  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1637  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1638  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1639  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1640  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1641  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1642  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1643  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1644  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1645  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1646  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1647 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1648  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1649 #else
1650  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1651 #endif
1652 
1653 #if defined(JSON_HEDLEY_CONSTEXPR)
1654  #undef JSON_HEDLEY_CONSTEXPR
1655 #endif
1656 #if defined(__cplusplus)
1657  #if __cplusplus >= 201103L
1658  #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1659  #endif
1660 #endif
1661 #if !defined(JSON_HEDLEY_CONSTEXPR)
1662  #define JSON_HEDLEY_CONSTEXPR
1663 #endif
1664 
1665 #if defined(JSON_HEDLEY_PREDICT)
1666  #undef JSON_HEDLEY_PREDICT
1667 #endif
1668 #if defined(JSON_HEDLEY_LIKELY)
1669  #undef JSON_HEDLEY_LIKELY
1670 #endif
1671 #if defined(JSON_HEDLEY_UNLIKELY)
1672  #undef JSON_HEDLEY_UNLIKELY
1673 #endif
1674 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1675  #undef JSON_HEDLEY_UNPREDICTABLE
1676 #endif
1677 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1678  #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1679 #endif
1680 #if \
1681  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1682  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1683  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1684 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1685 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1686 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1687 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1688 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1689 #elif \
1690  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1691  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1692  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1693  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1694  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1695  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1696  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1697  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1698  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1699  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1700  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1701  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1702  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1703  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1704  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1705  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1706 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1707  (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1708 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1709  (__extension__ ({ \
1710  double hedley_probability_ = (probability); \
1711  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1712  }))
1713 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1714  (__extension__ ({ \
1715  double hedley_probability_ = (probability); \
1716  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1717  }))
1718 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1719 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1720 #else
1721 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1722 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1723 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1724 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1725 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1726 #endif
1727 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1728  #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1729 #endif
1730 
1731 #if defined(JSON_HEDLEY_MALLOC)
1732  #undef JSON_HEDLEY_MALLOC
1733 #endif
1734 #if \
1735  JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1736  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1737  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1738  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1739  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1740  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1741  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1742  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1743  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1744  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1745  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1746  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1747  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1748  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1749  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1750  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1751  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1752  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1753  #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1754 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1755  #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1756 #elif \
1757  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1758  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1759  #define JSON_HEDLEY_MALLOC __declspec(restrict)
1760 #else
1761  #define JSON_HEDLEY_MALLOC
1762 #endif
1763 
1764 #if defined(JSON_HEDLEY_PURE)
1765  #undef JSON_HEDLEY_PURE
1766 #endif
1767 #if \
1768  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1769  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1770  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1771  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1772  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1773  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1774  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1775  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1776  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1777  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1778  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1779  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1780  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1781  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1782  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1783  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1784  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1785  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1786  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1787 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1788 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1789 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1790 #elif defined(__cplusplus) && \
1791  ( \
1792  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1793  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1794  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1795  )
1796 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1797 #else
1798 # define JSON_HEDLEY_PURE
1799 #endif
1800 
1801 #if defined(JSON_HEDLEY_CONST)
1802  #undef JSON_HEDLEY_CONST
1803 #endif
1804 #if \
1805  JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1806  JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1807  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1808  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1809  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1810  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1811  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1812  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1813  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1814  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1815  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1816  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1817  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1818  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1819  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1820  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1821  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1822  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1823  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1824  #define JSON_HEDLEY_CONST __attribute__((__const__))
1825 #elif \
1826  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1827  #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1828 #else
1829  #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1830 #endif
1831 
1832 #if defined(JSON_HEDLEY_RESTRICT)
1833  #undef JSON_HEDLEY_RESTRICT
1834 #endif
1835 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1836  #define JSON_HEDLEY_RESTRICT restrict
1837 #elif \
1838  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1839  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1840  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1841  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1842  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1843  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1844  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1845  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1846  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1847  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1848  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1849  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1850  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1851  defined(__clang__) || \
1852  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1853  #define JSON_HEDLEY_RESTRICT __restrict
1854 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1855  #define JSON_HEDLEY_RESTRICT _Restrict
1856 #else
1857  #define JSON_HEDLEY_RESTRICT
1858 #endif
1859 
1860 #if defined(JSON_HEDLEY_INLINE)
1861  #undef JSON_HEDLEY_INLINE
1862 #endif
1863 #if \
1864  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1865  (defined(__cplusplus) && (__cplusplus >= 199711L))
1866  #define JSON_HEDLEY_INLINE inline
1867 #elif \
1868  defined(JSON_HEDLEY_GCC_VERSION) || \
1869  JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1870  #define JSON_HEDLEY_INLINE __inline__
1871 #elif \
1872  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1873  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1874  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1875  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1876  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1877  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1878  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1879  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1880  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1881  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1882  #define JSON_HEDLEY_INLINE __inline
1883 #else
1884  #define JSON_HEDLEY_INLINE
1885 #endif
1886 
1887 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1888  #undef JSON_HEDLEY_ALWAYS_INLINE
1889 #endif
1890 #if \
1891  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1892  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1893  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1894  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1895  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1896  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1897  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1898  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1899  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1900  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1901  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1902  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1903  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1904  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1905  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1906  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1907  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1908  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1909  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1910 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1911 #elif \
1912  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1913  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1914 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1915 #elif defined(__cplusplus) && \
1916  ( \
1917  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1918  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1919  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1920  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1921  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1922  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1923  )
1924 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1925 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1926 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1927 #else
1928 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1929 #endif
1930 
1931 #if defined(JSON_HEDLEY_NEVER_INLINE)
1932  #undef JSON_HEDLEY_NEVER_INLINE
1933 #endif
1934 #if \
1935  JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1936  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1937  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1938  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1939  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1940  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1941  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1942  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1943  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1944  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1945  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1946  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1947  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1948  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1949  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1950  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1951  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1952  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1953  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1954  #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1955 #elif \
1956  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1957  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1958  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1959 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1960  #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1961 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1962  #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1963 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1964  #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1965 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1966  #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1967 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1968  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1969 #else
1970  #define JSON_HEDLEY_NEVER_INLINE
1971 #endif
1972 
1973 #if defined(JSON_HEDLEY_PRIVATE)
1974  #undef JSON_HEDLEY_PRIVATE
1975 #endif
1976 #if defined(JSON_HEDLEY_PUBLIC)
1977  #undef JSON_HEDLEY_PUBLIC
1978 #endif
1979 #if defined(JSON_HEDLEY_IMPORT)
1980  #undef JSON_HEDLEY_IMPORT
1981 #endif
1982 #if defined(_WIN32) || defined(__CYGWIN__)
1983 # define JSON_HEDLEY_PRIVATE
1984 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1985 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1986 #else
1987 # if \
1988  JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1989  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1990  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1991  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1992  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1993  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1994  ( \
1995  defined(__TI_EABI__) && \
1996  ( \
1997  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1998  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1999  ) \
2000  ) || \
2001  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2002 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
2003 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
2004 # else
2005 # define JSON_HEDLEY_PRIVATE
2006 # define JSON_HEDLEY_PUBLIC
2007 # endif
2008 # define JSON_HEDLEY_IMPORT extern
2009 #endif
2010 
2011 #if defined(JSON_HEDLEY_NO_THROW)
2012  #undef JSON_HEDLEY_NO_THROW
2013 #endif
2014 #if \
2015  JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
2016  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
2017  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2018  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2019  #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
2020 #elif \
2021  JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
2022  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
2023  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
2024  #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
2025 #else
2026  #define JSON_HEDLEY_NO_THROW
2027 #endif
2028 
2029 #if defined(JSON_HEDLEY_FALL_THROUGH)
2030  #undef JSON_HEDLEY_FALL_THROUGH
2031 #endif
2032 #if \
2033  JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
2034  JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
2035  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2036  #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
2037 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
2038  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
2039 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
2040  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
2041 #elif defined(__fallthrough) /* SAL */
2042  #define JSON_HEDLEY_FALL_THROUGH __fallthrough
2043 #else
2044  #define JSON_HEDLEY_FALL_THROUGH
2045 #endif
2046 
2047 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
2048  #undef JSON_HEDLEY_RETURNS_NON_NULL
2049 #endif
2050 #if \
2051  JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
2052  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2053  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2054  #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
2055 #elif defined(_Ret_notnull_) /* SAL */
2056  #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
2057 #else
2058  #define JSON_HEDLEY_RETURNS_NON_NULL
2059 #endif
2060 
2061 #if defined(JSON_HEDLEY_ARRAY_PARAM)
2062  #undef JSON_HEDLEY_ARRAY_PARAM
2063 #endif
2064 #if \
2065  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
2066  !defined(__STDC_NO_VLA__) && \
2067  !defined(__cplusplus) && \
2068  !defined(JSON_HEDLEY_PGI_VERSION) && \
2069  !defined(JSON_HEDLEY_TINYC_VERSION)
2070  #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
2071 #else
2072  #define JSON_HEDLEY_ARRAY_PARAM(name)
2073 #endif
2074 
2075 #if defined(JSON_HEDLEY_IS_CONSTANT)
2076  #undef JSON_HEDLEY_IS_CONSTANT
2077 #endif
2078 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
2079  #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
2080 #endif
2081 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
2082  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
2083 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2084  #undef JSON_HEDLEY_IS_CONSTEXPR_
2085 #endif
2086 #if \
2087  JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
2088  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2089  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2090  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
2091  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2092  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2093  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
2094  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
2095  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2096  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2097  #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
2098 #endif
2099 #if !defined(__cplusplus)
2100 # if \
2101  JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
2102  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2103  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2104  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2105  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2106  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
2107  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
2108 #if defined(__INTPTR_TYPE__)
2109  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
2110 #else
2111  #include <stdint.h>
2112  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
2113 #endif
2114 # elif \
2115  ( \
2116  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
2117  !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
2118  !defined(JSON_HEDLEY_PGI_VERSION) && \
2119  !defined(JSON_HEDLEY_IAR_VERSION)) || \
2120  (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
2121  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2122  JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
2123  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
2124  JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
2125 #if defined(__INTPTR_TYPE__)
2126  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
2127 #else
2128  #include <stdint.h>
2129  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
2130 #endif
2131 # elif \
2132  defined(JSON_HEDLEY_GCC_VERSION) || \
2133  defined(JSON_HEDLEY_INTEL_VERSION) || \
2134  defined(JSON_HEDLEY_TINYC_VERSION) || \
2135  defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
2136  JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
2137  defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
2138  defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
2139  defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
2140  defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
2141  defined(__clang__)
2142 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2143  sizeof(void) != \
2144  sizeof(*( \
2145  1 ? \
2146  ((void*) ((expr) * 0L) ) : \
2147 ((struct { char v[sizeof(void) * 2]; } *) 1) \
2148  ) \
2149  ) \
2150  )
2151 # endif
2152 #endif
2153 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2154  #if !defined(JSON_HEDLEY_IS_CONSTANT)
2155  #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2156  #endif
2157  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2158 #else
2159  #if !defined(JSON_HEDLEY_IS_CONSTANT)
2160  #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2161  #endif
2162  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2163 #endif
2164 
2165 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2166  #undef JSON_HEDLEY_BEGIN_C_DECLS
2167 #endif
2168 #if defined(JSON_HEDLEY_END_C_DECLS)
2169  #undef JSON_HEDLEY_END_C_DECLS
2170 #endif
2171 #if defined(JSON_HEDLEY_C_DECL)
2172  #undef JSON_HEDLEY_C_DECL
2173 #endif
2174 #if defined(__cplusplus)
2175  #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2176  #define JSON_HEDLEY_END_C_DECLS }
2177  #define JSON_HEDLEY_C_DECL extern "C"
2178 #else
2179  #define JSON_HEDLEY_BEGIN_C_DECLS
2180  #define JSON_HEDLEY_END_C_DECLS
2181  #define JSON_HEDLEY_C_DECL
2182 #endif
2183 
2184 #if defined(JSON_HEDLEY_STATIC_ASSERT)
2185  #undef JSON_HEDLEY_STATIC_ASSERT
2186 #endif
2187 #if \
2188  !defined(__cplusplus) && ( \
2189  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2190  (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2191  JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2192  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2193  defined(_Static_assert) \
2194  )
2195 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2196 #elif \
2197  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2198  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2199  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2200 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2201 #else
2202 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2203 #endif
2204 
2205 #if defined(JSON_HEDLEY_NULL)
2206  #undef JSON_HEDLEY_NULL
2207 #endif
2208 #if defined(__cplusplus)
2209  #if __cplusplus >= 201103L
2210  #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2211  #elif defined(NULL)
2212  #define JSON_HEDLEY_NULL NULL
2213  #else
2214  #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2215  #endif
2216 #elif defined(NULL)
2217  #define JSON_HEDLEY_NULL NULL
2218 #else
2219  #define JSON_HEDLEY_NULL ((void*) 0)
2220 #endif
2221 
2222 #if defined(JSON_HEDLEY_MESSAGE)
2223  #undef JSON_HEDLEY_MESSAGE
2224 #endif
2225 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2226 # define JSON_HEDLEY_MESSAGE(msg) \
2227  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2228  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2229  JSON_HEDLEY_PRAGMA(message msg) \
2230  JSON_HEDLEY_DIAGNOSTIC_POP
2231 #elif \
2232  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2233  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2234 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2235 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2236 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2237 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2238 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2239 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2240 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2241 #else
2242 # define JSON_HEDLEY_MESSAGE(msg)
2243 #endif
2244 
2245 #if defined(JSON_HEDLEY_WARNING)
2246  #undef JSON_HEDLEY_WARNING
2247 #endif
2248 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2249 # define JSON_HEDLEY_WARNING(msg) \
2250  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2251  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2252  JSON_HEDLEY_PRAGMA(clang warning msg) \
2253  JSON_HEDLEY_DIAGNOSTIC_POP
2254 #elif \
2255  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2256  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2257  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2258 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2259 #elif \
2260  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2261  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2262 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2263 #else
2264 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2265 #endif
2266 
2267 #if defined(JSON_HEDLEY_REQUIRE)
2268  #undef JSON_HEDLEY_REQUIRE
2269 #endif
2270 #if defined(JSON_HEDLEY_REQUIRE_MSG)
2271  #undef JSON_HEDLEY_REQUIRE_MSG
2272 #endif
2273 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2274 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2275 # define JSON_HEDLEY_REQUIRE(expr) \
2276  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2277  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2278  __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2279  JSON_HEDLEY_DIAGNOSTIC_POP
2280 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2281  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2282  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2283  __attribute__((diagnose_if(!(expr), msg, "error"))) \
2284  JSON_HEDLEY_DIAGNOSTIC_POP
2285 # else
2286 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2287 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2288 # endif
2289 #else
2290 # define JSON_HEDLEY_REQUIRE(expr)
2291 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2292 #endif
2293 
2294 #if defined(JSON_HEDLEY_FLAGS)
2295  #undef JSON_HEDLEY_FLAGS
2296 #endif
2297 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2298  #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2299 #else
2300  #define JSON_HEDLEY_FLAGS
2301 #endif
2302 
2303 #if defined(JSON_HEDLEY_FLAGS_CAST)
2304  #undef JSON_HEDLEY_FLAGS_CAST
2305 #endif
2306 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2307 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2308  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2309  _Pragma("warning(disable:188)") \
2310  ((T) (expr)); \
2311  JSON_HEDLEY_DIAGNOSTIC_POP \
2312  }))
2313 #else
2314 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2315 #endif
2316 
2317 #if defined(JSON_HEDLEY_EMPTY_BASES)
2318  #undef JSON_HEDLEY_EMPTY_BASES
2319 #endif
2320 #if \
2321  (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2322  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2323  #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2324 #else
2325  #define JSON_HEDLEY_EMPTY_BASES
2326 #endif
2327 
2328 /* Remaining macros are deprecated. */
2329 
2330 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2331  #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2332 #endif
2333 #if defined(__clang__)
2334  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2335 #else
2336  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2337 #endif
2338 
2339 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2340  #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2341 #endif
2342 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2343 
2344 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2345  #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2346 #endif
2347 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2348 
2349 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2350  #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2351 #endif
2352 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2353 
2354 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2355  #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2356 #endif
2357 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2358 
2359 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2360  #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2361 #endif
2362 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2363 
2364 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2365  #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2366 #endif
2367 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2368 
2369 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2370  #undef JSON_HEDLEY_CLANG_HAS_WARNING
2371 #endif
2372 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2373 
2374 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2375 
2376 
2377 // This file contains all internal macro definitions (except those affecting ABI)
2378 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2379 
2380 // #include <nlohmann/detail/abi_macros.hpp>
2381 
2382 
2383 // exclude unsupported compilers
2384 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2385  #if defined(__clang__)
2386  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2387  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2388  #endif
2389  #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2390  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2391  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2392  #endif
2393  #endif
2394 #endif
2395 
2396 // C++ language standard detection
2397 // if the user manually specified the used C++ version, this is skipped
2398 #if !defined(JSON_HAS_CPP_26) && !defined(JSON_HAS_CPP_23) && !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2399  #if (defined(__cplusplus) && __cplusplus > 202302L) || (defined(_MSVC_LANG) && _MSVC_LANG > 202302L)
2400  #define JSON_HAS_CPP_26
2401  #define JSON_HAS_CPP_23
2402  #define JSON_HAS_CPP_20
2403  #define JSON_HAS_CPP_17
2404  #define JSON_HAS_CPP_14
2405  #elif (defined(__cplusplus) && __cplusplus > 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG > 202002L)
2406  #define JSON_HAS_CPP_23
2407  #define JSON_HAS_CPP_20
2408  #define JSON_HAS_CPP_17
2409  #define JSON_HAS_CPP_14
2410  #elif (defined(__cplusplus) && __cplusplus > 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG > 201703L)
2411  #define JSON_HAS_CPP_20
2412  #define JSON_HAS_CPP_17
2413  #define JSON_HAS_CPP_14
2414  #elif (defined(__cplusplus) && __cplusplus > 201402L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2415  #define JSON_HAS_CPP_17
2416  #define JSON_HAS_CPP_14
2417  #elif (defined(__cplusplus) && __cplusplus > 201103L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2418  #define JSON_HAS_CPP_14
2419  #endif
2420  // the cpp 11 flag is always specified because it is the minimal required version
2421  #define JSON_HAS_CPP_11
2422 #endif
2423 
2424 #ifdef __has_include
2425  #if __has_include(<version>)
2426  #include <version>
2427  #endif
2428 #endif
2429 
2430 #if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2431  #ifdef JSON_HAS_CPP_17
2432  #if defined(__cpp_lib_filesystem)
2433  #define JSON_HAS_FILESYSTEM 1
2434  #elif defined(__cpp_lib_experimental_filesystem)
2435  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2436  #elif !defined(__has_include)
2437  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2438  #elif __has_include(<filesystem>)
2439  #define JSON_HAS_FILESYSTEM 1
2440  #elif __has_include(<experimental/filesystem>)
2441  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2442  #endif
2443 
2444  // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2445  #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2446  #undef JSON_HAS_FILESYSTEM
2447  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2448  #endif
2449 
2450  // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2451  #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2452  #undef JSON_HAS_FILESYSTEM
2453  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2454  #endif
2455 
2456  // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2457  #if defined(__clang_major__) && __clang_major__ < 7
2458  #undef JSON_HAS_FILESYSTEM
2459  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2460  #endif
2461 
2462  // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2463  #if defined(_MSC_VER) && _MSC_VER < 1914
2464  #undef JSON_HAS_FILESYSTEM
2465  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2466  #endif
2467 
2468  // no filesystem support before iOS 13
2469  #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2470  #undef JSON_HAS_FILESYSTEM
2471  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2472  #endif
2473 
2474  // no filesystem support before macOS Catalina
2475  #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2476  #undef JSON_HAS_FILESYSTEM
2477  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2478  #endif
2479  #endif
2480 #endif
2481 
2482 #ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2483  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2484 #endif
2485 
2486 #ifndef JSON_HAS_FILESYSTEM
2487  #define JSON_HAS_FILESYSTEM 0
2488 #endif
2489 
2490 #ifndef JSON_HAS_THREE_WAY_COMPARISON
2491  #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
2492  && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
2493  #define JSON_HAS_THREE_WAY_COMPARISON 1
2494  #else
2495  #define JSON_HAS_THREE_WAY_COMPARISON 0
2496  #endif
2497 #endif
2498 
2499 #ifndef JSON_HAS_RANGES
2500  // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has a syntax error
2501  #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427
2502  #define JSON_HAS_RANGES 0
2503  #elif defined(__cpp_lib_ranges)
2504  #define JSON_HAS_RANGES 1
2505  #else
2506  #define JSON_HAS_RANGES 0
2507  #endif
2508 #endif
2509 
2510 #ifndef JSON_HAS_STATIC_RTTI
2511  #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0
2512  #define JSON_HAS_STATIC_RTTI 1
2513  #else
2514  #define JSON_HAS_STATIC_RTTI 0
2515  #endif
2516 #endif
2517 
2518 #ifdef JSON_HAS_CPP_17
2519  #define JSON_INLINE_VARIABLE inline
2520 #else
2521  #define JSON_INLINE_VARIABLE
2522 #endif
2523 
2524 #if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2525  #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2526 #else
2527  #define JSON_NO_UNIQUE_ADDRESS
2528 #endif
2529 
2530 // disable documentation warnings on clang
2531 #if defined(__clang__)
2532  #pragma clang diagnostic push
2533  #pragma clang diagnostic ignored "-Wdocumentation"
2534  #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2535 #endif
2536 
2537 // allow disabling exceptions
2538 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2539  #define JSON_THROW(exception) throw exception
2540  #define JSON_TRY try
2541  #define JSON_CATCH(exception) catch(exception)
2542  #define JSON_INTERNAL_CATCH(exception) catch(exception)
2543 #else
2544  #include <cstdlib>
2545  #define JSON_THROW(exception) std::abort()
2546  #define JSON_TRY if(true)
2547  #define JSON_CATCH(exception) if(false)
2548  #define JSON_INTERNAL_CATCH(exception) if(false)
2549 #endif
2550 
2551 // override exception macros
2552 #if defined(JSON_THROW_USER)
2553  #undef JSON_THROW
2554  #define JSON_THROW JSON_THROW_USER
2555 #endif
2556 #if defined(JSON_TRY_USER)
2557  #undef JSON_TRY
2558  #define JSON_TRY JSON_TRY_USER
2559 #endif
2560 #if defined(JSON_CATCH_USER)
2561  #undef JSON_CATCH
2562  #define JSON_CATCH JSON_CATCH_USER
2563  #undef JSON_INTERNAL_CATCH
2564  #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2565 #endif
2566 #if defined(JSON_INTERNAL_CATCH_USER)
2567  #undef JSON_INTERNAL_CATCH
2568  #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2569 #endif
2570 
2571 // allow overriding assert
2572 #if !defined(JSON_ASSERT)
2573  #include <cassert> // assert
2574  #define JSON_ASSERT(x) assert(x)
2575 #endif
2576 
2577 // allow accessing some private functions (needed by the test suite)
2578 #if defined(JSON_TESTS_PRIVATE)
2579  #define JSON_PRIVATE_UNLESS_TESTED public
2580 #else
2581  #define JSON_PRIVATE_UNLESS_TESTED private
2582 #endif
2583 
2589 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2590  template<typename BasicJsonType> \
2591  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2592  { \
2593  /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
2594  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2595  /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
2596  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2597  auto it = std::find_if(std::begin(m), std::end(m), \
2598  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2599  { \
2600  return ej_pair.first == e; \
2601  }); \
2602  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2603  } \
2604  template<typename BasicJsonType> \
2605  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2606  { \
2607  /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
2608  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2609  /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
2610  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2611  auto it = std::find_if(std::begin(m), std::end(m), \
2612  [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2613  { \
2614  return ej_pair.second == j; \
2615  }); \
2616  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2617  }
2618 
2619 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2620 // may be removed in the future once the class is split.
2621 
2622 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2623  template<template<typename, typename, typename...> class ObjectType, \
2624  template<typename, typename...> class ArrayType, \
2625  class StringType, class BooleanType, class NumberIntegerType, \
2626  class NumberUnsignedType, class NumberFloatType, \
2627  template<typename> class AllocatorType, \
2628  template<typename, typename = void> class JSONSerializer, \
2629  class BinaryType, \
2630  class CustomBaseClass>
2631 
2632 #define NLOHMANN_BASIC_JSON_TPL \
2633  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2634  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2635  AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>
2636 
2637 // Macros to simplify conversion from/to types
2638 
2639 #define NLOHMANN_JSON_EXPAND( x ) x
2640 #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
2641 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2642  NLOHMANN_JSON_PASTE64, \
2643  NLOHMANN_JSON_PASTE63, \
2644  NLOHMANN_JSON_PASTE62, \
2645  NLOHMANN_JSON_PASTE61, \
2646  NLOHMANN_JSON_PASTE60, \
2647  NLOHMANN_JSON_PASTE59, \
2648  NLOHMANN_JSON_PASTE58, \
2649  NLOHMANN_JSON_PASTE57, \
2650  NLOHMANN_JSON_PASTE56, \
2651  NLOHMANN_JSON_PASTE55, \
2652  NLOHMANN_JSON_PASTE54, \
2653  NLOHMANN_JSON_PASTE53, \
2654  NLOHMANN_JSON_PASTE52, \
2655  NLOHMANN_JSON_PASTE51, \
2656  NLOHMANN_JSON_PASTE50, \
2657  NLOHMANN_JSON_PASTE49, \
2658  NLOHMANN_JSON_PASTE48, \
2659  NLOHMANN_JSON_PASTE47, \
2660  NLOHMANN_JSON_PASTE46, \
2661  NLOHMANN_JSON_PASTE45, \
2662  NLOHMANN_JSON_PASTE44, \
2663  NLOHMANN_JSON_PASTE43, \
2664  NLOHMANN_JSON_PASTE42, \
2665  NLOHMANN_JSON_PASTE41, \
2666  NLOHMANN_JSON_PASTE40, \
2667  NLOHMANN_JSON_PASTE39, \
2668  NLOHMANN_JSON_PASTE38, \
2669  NLOHMANN_JSON_PASTE37, \
2670  NLOHMANN_JSON_PASTE36, \
2671  NLOHMANN_JSON_PASTE35, \
2672  NLOHMANN_JSON_PASTE34, \
2673  NLOHMANN_JSON_PASTE33, \
2674  NLOHMANN_JSON_PASTE32, \
2675  NLOHMANN_JSON_PASTE31, \
2676  NLOHMANN_JSON_PASTE30, \
2677  NLOHMANN_JSON_PASTE29, \
2678  NLOHMANN_JSON_PASTE28, \
2679  NLOHMANN_JSON_PASTE27, \
2680  NLOHMANN_JSON_PASTE26, \
2681  NLOHMANN_JSON_PASTE25, \
2682  NLOHMANN_JSON_PASTE24, \
2683  NLOHMANN_JSON_PASTE23, \
2684  NLOHMANN_JSON_PASTE22, \
2685  NLOHMANN_JSON_PASTE21, \
2686  NLOHMANN_JSON_PASTE20, \
2687  NLOHMANN_JSON_PASTE19, \
2688  NLOHMANN_JSON_PASTE18, \
2689  NLOHMANN_JSON_PASTE17, \
2690  NLOHMANN_JSON_PASTE16, \
2691  NLOHMANN_JSON_PASTE15, \
2692  NLOHMANN_JSON_PASTE14, \
2693  NLOHMANN_JSON_PASTE13, \
2694  NLOHMANN_JSON_PASTE12, \
2695  NLOHMANN_JSON_PASTE11, \
2696  NLOHMANN_JSON_PASTE10, \
2697  NLOHMANN_JSON_PASTE9, \
2698  NLOHMANN_JSON_PASTE8, \
2699  NLOHMANN_JSON_PASTE7, \
2700  NLOHMANN_JSON_PASTE6, \
2701  NLOHMANN_JSON_PASTE5, \
2702  NLOHMANN_JSON_PASTE4, \
2703  NLOHMANN_JSON_PASTE3, \
2704  NLOHMANN_JSON_PASTE2, \
2705  NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2706 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2707 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2708 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2709 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2710 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2711 #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)
2712 #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)
2713 #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)
2714 #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)
2715 #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)
2716 #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)
2717 #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)
2718 #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)
2719 #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)
2720 #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)
2721 #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)
2722 #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)
2723 #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)
2724 #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)
2725 #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)
2726 #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)
2727 #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)
2728 #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)
2729 #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)
2730 #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)
2731 #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)
2732 #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)
2733 #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)
2734 #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)
2735 #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)
2736 #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)
2737 #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)
2738 #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)
2739 #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)
2740 #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)
2741 #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)
2742 #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)
2743 #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)
2744 #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)
2745 #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)
2746 #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)
2747 #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)
2748 #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)
2749 #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)
2750 #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)
2751 #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)
2752 #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)
2753 #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)
2754 #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)
2755 #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)
2756 #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)
2757 #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)
2758 #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)
2759 #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)
2760 #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)
2761 #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)
2762 #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)
2763 #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)
2764 #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)
2765 #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)
2766 #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)
2767 #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)
2768 #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)
2769 
2770 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2771 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2772 #define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1) : nlohmann_json_default_obj.v1;
2773 
2780 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2781  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2782  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2783  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2784  friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2785 
2792 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2793  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2794  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2795  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2796  friend void from_json(const BasicJsonType& 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__)) }
2797 
2804 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
2805  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2806  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2807 
2814 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2815  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2816  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2817  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2818  void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2819 
2826 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2827  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2828  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2829  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2830  void from_json(const BasicJsonType& 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__)) }
2831 
2838 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
2839  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2840  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2841 
2848 #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \
2849  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2850  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2851  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2852  friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2853 
2860 #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \
2861  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2862  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2863  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2864  friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2865 
2872 #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \
2873  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2874  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2875 
2882 #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \
2883  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2884  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2885  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2886  void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2887 
2894 #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \
2895  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2896  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2897  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2898  void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2899 
2906 #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \
2907  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2908  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2909 
2910 // inspired from https://stackoverflow.com/a/26745591
2911 // allows calling any std function as if (e.g., with begin):
2912 // using std::begin; begin(x);
2913 //
2914 // it allows using the detected idiom to retrieve the return type
2915 // of such an expression
2916 #define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2917  namespace detail { \
2918  using std::std_name; \
2919  \
2920  template<typename... T> \
2921  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2922  } \
2923  \
2924  namespace detail2 { \
2925  struct std_name##_tag \
2926  { \
2927  }; \
2928  \
2929  template<typename... T> \
2930  std_name##_tag std_name(T&&...); \
2931  \
2932  template<typename... T> \
2933  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2934  \
2935  template<typename... T> \
2936  struct would_call_std_##std_name \
2937  { \
2938  static constexpr auto const value = ::nlohmann::detail:: \
2939  is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2940  }; \
2941  } /* namespace detail2 */ \
2942  \
2943  template<typename... T> \
2944  struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2945  { \
2946  }
2947 
2948 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2949  #define JSON_USE_IMPLICIT_CONVERSIONS 1
2950 #endif
2951 
2952 #if JSON_USE_IMPLICIT_CONVERSIONS
2953  #define JSON_EXPLICIT
2954 #else
2955  #define JSON_EXPLICIT explicit
2956 #endif
2957 
2958 #ifndef JSON_DISABLE_ENUM_SERIALIZATION
2959  #define JSON_DISABLE_ENUM_SERIALIZATION 0
2960 #endif
2961 
2962 #ifndef JSON_USE_GLOBAL_UDLS
2963  #define JSON_USE_GLOBAL_UDLS 1
2964 #endif
2965 
2966 #if JSON_HAS_THREE_WAY_COMPARISON
2967  #include <compare> // partial_ordering
2968 #endif
2969 
2971 namespace detail
2972 {
2973 
2975 // JSON type enumeration //
2977 
3002 enum class value_t : std::uint8_t
3003 {
3004  null,
3005  object,
3006  array,
3007  string,
3008  boolean,
3009  number_integer,
3010  number_unsigned,
3011  number_float,
3012  binary,
3013  discarded
3014 };
3015 
3029 #if JSON_HAS_THREE_WAY_COMPARISON
3030  inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
3031 #else
3032  inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3033 #endif
3034 {
3035  static constexpr std::array<std::uint8_t, 9> order = {{
3036  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
3037  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
3038  6 /* binary */
3039  }
3040  };
3041 
3042  const auto l_index = static_cast<std::size_t>(lhs);
3043  const auto r_index = static_cast<std::size_t>(rhs);
3044 #if JSON_HAS_THREE_WAY_COMPARISON
3045  if (l_index < order.size() && r_index < order.size())
3046  {
3047  return order[l_index] <=> order[r_index]; // *NOPAD*
3048  }
3049  return std::partial_ordering::unordered;
3050 #else
3051  return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
3052 #endif
3053 }
3054 
3055 // GCC selects the built-in operator< over an operator rewritten from
3056 // a user-defined spaceship operator
3057 // Clang, MSVC, and ICC select the rewritten candidate
3058 // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
3059 #if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
3060 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3061 {
3062  return std::is_lt(lhs <=> rhs); // *NOPAD*
3063 }
3064 #endif
3065 
3066 } // namespace detail
3068 
3069 // #include <nlohmann/detail/string_escape.hpp>
3070 // __ _____ _____ _____
3071 // __| | __| | | | JSON for Modern C++
3072 // | | |__ | | | | | | version 3.12.0
3073 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3074 //
3075 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3076 // SPDX-License-Identifier: MIT
3077 
3078 
3079 
3080 // #include <nlohmann/detail/abi_macros.hpp>
3081 
3082 
3084 namespace detail
3085 {
3086 
3100 template<typename StringType>
3101 inline void replace_substring(StringType& s, const StringType& f,
3102  const StringType& t)
3103 {
3104  JSON_ASSERT(!f.empty());
3105  for (auto pos = s.find(f); // find the first occurrence of f
3106  pos != StringType::npos; // make sure f was found
3107  s.replace(pos, f.size(), t), // replace with t, and
3108  pos = s.find(f, pos + t.size())) // find the next occurrence of f
3109  {}
3110 }
3111 
3119 template<typename StringType>
3120 inline StringType escape(StringType s)
3121 {
3122  replace_substring(s, StringType{"~"}, StringType{"~0"});
3123  replace_substring(s, StringType{"/"}, StringType{"~1"});
3124  return s;
3125 }
3126 
3134 template<typename StringType>
3135 inline void unescape(StringType& s)
3136 {
3137  replace_substring(s, StringType{"~1"}, StringType{"/"});
3138  replace_substring(s, StringType{"~0"}, StringType{"~"});
3139 }
3140 
3141 } // namespace detail
3143 
3144 // #include <nlohmann/detail/input/position_t.hpp>
3145 // __ _____ _____ _____
3146 // __| | __| | | | JSON for Modern C++
3147 // | | |__ | | | | | | version 3.12.0
3148 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3149 //
3150 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3151 // SPDX-License-Identifier: MIT
3152 
3153 
3154 
3155 #include <cstddef> // size_t
3156 
3157 // #include <nlohmann/detail/abi_macros.hpp>
3158 
3159 
3161 namespace detail
3162 {
3163 
3166 {
3168  std::size_t chars_read_total = 0;
3170  std::size_t chars_read_current_line = 0;
3172  std::size_t lines_read = 0;
3173 
3175  constexpr operator size_t() const
3176  {
3177  return chars_read_total;
3178  }
3179 };
3180 
3181 } // namespace detail
3183 
3184 // #include <nlohmann/detail/macro_scope.hpp>
3185 
3186 // #include <nlohmann/detail/meta/cpp_future.hpp>
3187 // __ _____ _____ _____
3188 // __| | __| | | | JSON for Modern C++
3189 // | | |__ | | | | | | version 3.12.0
3190 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3191 //
3192 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3193 // SPDX-FileCopyrightText: 2018 The Abseil Authors
3194 // SPDX-License-Identifier: MIT
3195 
3196 
3197 
3198 #include <array> // array
3199 #include <cstddef> // size_t
3200 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3201 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3202 
3203 // #include <nlohmann/detail/macro_scope.hpp>
3204 
3205 
3207 namespace detail
3208 {
3209 
3210 template<typename T>
3212 
3213 #ifdef JSON_HAS_CPP_14
3214 
3215 // the following utilities are natively available in C++14
3216 using std::enable_if_t;
3217 using std::index_sequence;
3220 
3221 #else
3222 
3223 // alias templates to reduce boilerplate
3224 template<bool B, typename T = void>
3226 
3227 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3228 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3229 
3231 
3232 // integer_sequence
3233 //
3234 // Class template representing a compile-time integer sequence. An instantiation
3235 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3236 // type through its template arguments (which is a common need when
3237 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3238 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3239 //
3240 // Example:
3241 //
3242 // template< class T, T... Ints >
3243 // void user_function(integer_sequence<T, Ints...>);
3244 //
3245 // int main()
3246 // {
3247 // // user_function's `T` will be deduced to `int` and `Ints...`
3248 // // will be deduced to `0, 1, 2, 3, 4`.
3249 // user_function(make_integer_sequence<int, 5>());
3250 // }
3251 template <typename T, T... Ints>
3253 {
3254  using value_type = T;
3255  static constexpr std::size_t size() noexcept
3256  {
3257  return sizeof...(Ints);
3258  }
3259 };
3260 
3261 // index_sequence
3262 //
3263 // A helper template for an `integer_sequence` of `size_t`,
3264 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3265 // `std::index_sequence`.
3266 template <size_t... Ints>
3267 using index_sequence = integer_sequence<size_t, Ints...>;
3268 
3269 namespace utility_internal
3270 {
3271 
3272 template <typename Seq, size_t SeqSize, size_t Rem>
3273 struct Extend;
3274 
3275 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3276 template <typename T, T... Ints, size_t SeqSize>
3277 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3278 {
3279  using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3280 };
3281 
3282 template <typename T, T... Ints, size_t SeqSize>
3283 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3284 {
3285  using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3286 };
3287 
3288 // Recursion helper for 'make_integer_sequence<T, N>'.
3289 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3290 template <typename T, size_t N>
3291 struct Gen
3292 {
3293  using type =
3294  typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3295 };
3296 
3297 template <typename T>
3298 struct Gen<T, 0>
3299 {
3301 };
3302 
3303 } // namespace utility_internal
3304 
3305 // Compile-time sequences of integers
3306 
3307 // make_integer_sequence
3308 //
3309 // This template alias is equivalent to
3310 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3311 // replacement for C++14's `std::make_integer_sequence`.
3312 template <typename T, T N>
3314 
3315 // make_index_sequence
3316 //
3317 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3318 // and is designed to be a drop-in replacement for C++14's
3319 // `std::make_index_sequence`.
3320 template <size_t N>
3322 
3323 // index_sequence_for
3324 //
3325 // Converts a typename pack into an index sequence of the same length, and
3326 // is designed to be a drop-in replacement for C++14's
3327 // `std::index_sequence_for()`
3328 template <typename... Ts>
3330 
3332 
3333 #endif
3334 
3335 // dispatch utility (taken from ranges-v3)
3336 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3337 template<> struct priority_tag<0> {};
3338 
3339 // taken from ranges-v3
3340 template<typename T>
3342 {
3343  static JSON_INLINE_VARIABLE constexpr T value{};
3344 };
3345 
3346 #ifndef JSON_HAS_CPP_17
3347  template<typename T>
3348  constexpr T static_const<T>::value;
3349 #endif
3350 
3351 template<typename T, typename... Args>
3352 constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args)
3353 {
3354  return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}};
3355 }
3356 
3357 } // namespace detail
3359 
3360 // #include <nlohmann/detail/meta/type_traits.hpp>
3361 // __ _____ _____ _____
3362 // __| | __| | | | JSON for Modern C++
3363 // | | |__ | | | | | | version 3.12.0
3364 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3365 //
3366 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3367 // SPDX-License-Identifier: MIT
3368 
3369 
3370 
3371 #include <limits> // numeric_limits
3372 #include <string> // char_traits
3373 #include <tuple> // tuple
3374 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3375 #include <utility> // declval
3376 #if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
3377  #include <cstddef> // byte
3378 #endif
3379 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3380 // __ _____ _____ _____
3381 // __| | __| | | | JSON for Modern C++
3382 // | | |__ | | | | | | version 3.12.0
3383 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3384 //
3385 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3386 // SPDX-License-Identifier: MIT
3387 
3388 
3389 
3390 #include <iterator> // random_access_iterator_tag
3391 
3392 // #include <nlohmann/detail/abi_macros.hpp>
3393 
3394 // #include <nlohmann/detail/meta/void_t.hpp>
3395 
3396 // #include <nlohmann/detail/meta/cpp_future.hpp>
3397 
3398 
3400 namespace detail
3401 {
3402 
3403 template<typename It, typename = void>
3404 struct iterator_types {};
3405 
3406 template<typename It>
3408  It,
3409  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3410  typename It::reference, typename It::iterator_category >>
3411 {
3412  using difference_type = typename It::difference_type;
3413  using value_type = typename It::value_type;
3414  using pointer = typename It::pointer;
3415  using reference = typename It::reference;
3416  using iterator_category = typename It::iterator_category;
3417 };
3418 
3419 // This is required as some compilers implement std::iterator_traits in a way that
3420 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3421 template<typename T, typename = void>
3423 {
3424 };
3425 
3426 template<typename T>
3427 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3428  : iterator_types<T>
3429 {
3430 };
3431 
3432 template<typename T>
3434 {
3435  using iterator_category = std::random_access_iterator_tag;
3436  using value_type = T;
3437  using difference_type = ptrdiff_t;
3438  using pointer = T*;
3439  using reference = T&;
3440 };
3441 
3442 } // namespace detail
3444 
3445 // #include <nlohmann/detail/macro_scope.hpp>
3446 
3447 // #include <nlohmann/detail/meta/call_std/begin.hpp>
3448 // __ _____ _____ _____
3449 // __| | __| | | | JSON for Modern C++
3450 // | | |__ | | | | | | version 3.12.0
3451 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3452 //
3453 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3454 // SPDX-License-Identifier: MIT
3455 
3456 
3457 
3458 // #include <nlohmann/detail/macro_scope.hpp>
3459 
3460 
3462 
3464 
3466 
3467 // #include <nlohmann/detail/meta/call_std/end.hpp>
3468 // __ _____ _____ _____
3469 // __| | __| | | | JSON for Modern C++
3470 // | | |__ | | | | | | version 3.12.0
3471 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3472 //
3473 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3474 // SPDX-License-Identifier: MIT
3475 
3476 
3477 
3478 // #include <nlohmann/detail/macro_scope.hpp>
3479 
3480 
3482 
3484 
3486 
3487 // #include <nlohmann/detail/meta/cpp_future.hpp>
3488 
3489 // #include <nlohmann/detail/meta/detected.hpp>
3490 
3491 // #include <nlohmann/json_fwd.hpp>
3492 // __ _____ _____ _____
3493 // __| | __| | | | JSON for Modern C++
3494 // | | |__ | | | | | | version 3.12.0
3495 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3496 //
3497 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3498 // SPDX-License-Identifier: MIT
3499 
3500 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3501  #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3502 
3503  #include <cstdint> // int64_t, uint64_t
3504  #include <map> // map
3505  #include <memory> // allocator
3506  #include <string> // string
3507  #include <vector> // vector
3508 
3509  // #include <nlohmann/detail/abi_macros.hpp>
3510 
3511 
3518 
3526  template<typename T = void, typename SFINAE = void>
3527  struct adl_serializer;
3528 
3531  template<template<typename U, typename V, typename... Args> class ObjectType =
3532  std::map,
3533  template<typename U, typename... Args> class ArrayType = std::vector,
3534  class StringType = std::string, class BooleanType = bool,
3535  class NumberIntegerType = std::int64_t,
3536  class NumberUnsignedType = std::uint64_t,
3537  class NumberFloatType = double,
3538  template<typename U> class AllocatorType = std::allocator,
3539  template<typename T, typename SFINAE = void> class JSONSerializer =
3541  class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
3542  class CustomBaseClass = void>
3543  class basic_json;
3544 
3547  template<typename RefStringType>
3548  class json_pointer;
3549 
3555 
3558  template<class Key, class T, class IgnoredLess, class Allocator>
3559  struct ordered_map;
3560 
3564 
3566 
3567 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3568 
3569 
3579 namespace detail
3580 {
3581 
3583 // helpers //
3585 
3586 // Note to maintainers:
3587 //
3588 // Every trait in this file expects a non-CV-qualified type.
3589 // The only exceptions are in the 'aliases for detected' section
3590 // (i.e., those of the form: decltype(T::member_function(std::declval<T>())))
3591 //
3592 // In this case, T has to be properly CV-qualified to constraint the function arguments
3593 // (e.g., to_json(BasicJsonType&, const T&))
3594 
3595 template<typename> struct is_basic_json : std::false_type {};
3596 
3598 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3599 
3600 // used by exceptions create() member functions
3601 // true_type for the pointer to possibly cv-qualified basic_json or std::nullptr_t
3602 // false_type otherwise
3603 template<typename BasicJsonContext>
3605  std::integral_constant < bool,
3606  is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3607  || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3608 {};
3609 
3611 // json_ref helpers //
3613 
3614 template<typename>
3615 class json_ref;
3616 
3617 template<typename>
3618 struct is_json_ref : std::false_type {};
3619 
3620 template<typename T>
3621 struct is_json_ref<json_ref<T>> : std::true_type {};
3622 
3624 // aliases for detected //
3626 
3627 template<typename T>
3628 using mapped_type_t = typename T::mapped_type;
3629 
3630 template<typename T>
3631 using key_type_t = typename T::key_type;
3632 
3633 template<typename T>
3634 using value_type_t = typename T::value_type;
3635 
3636 template<typename T>
3637 using difference_type_t = typename T::difference_type;
3638 
3639 template<typename T>
3640 using pointer_t = typename T::pointer;
3641 
3642 template<typename T>
3643 using reference_t = typename T::reference;
3644 
3645 template<typename T>
3646 using iterator_category_t = typename T::iterator_category;
3647 
3648 template<typename T, typename... Args>
3649 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3650 
3651 template<typename T, typename... Args>
3652 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3653 
3654 template<typename T, typename U>
3655 using get_template_function = decltype(std::declval<T>().template get<U>());
3656 
3657 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3658 template<typename BasicJsonType, typename T, typename = void>
3659 struct has_from_json : std::false_type {};
3660 
3661 // trait checking if j.get<T> is valid
3662 // use this trait instead of std::is_constructible or std::is_convertible,
3663 // both rely on, or make use of implicit conversions, and thus fail when T
3664 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3665 template <typename BasicJsonType, typename T>
3667 {
3669 };
3670 
3671 template<typename BasicJsonType, typename T>
3672 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3673 {
3674  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3675 
3676  static constexpr bool value =
3678  const BasicJsonType&, T&>::value;
3679 };
3680 
3681 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3682 // this overload is used for non-default-constructible user-defined-types
3683 template<typename BasicJsonType, typename T, typename = void>
3684 struct has_non_default_from_json : std::false_type {};
3685 
3686 template<typename BasicJsonType, typename T>
3687 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3688 {
3689  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3690 
3691  static constexpr bool value =
3693  const BasicJsonType&>::value;
3694 };
3695 
3696 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3697 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3698 template<typename BasicJsonType, typename T, typename = void>
3699 struct has_to_json : std::false_type {};
3700 
3701 template<typename BasicJsonType, typename T>
3702 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3703 {
3704  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3705 
3706  static constexpr bool value =
3707  is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3708  T>::value;
3709 };
3710 
3711 template<typename T>
3712 using detect_key_compare = typename T::key_compare;
3713 
3714 template<typename T>
3715 struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3716 
3717 // obtains the actual object key comparator
3718 template<typename BasicJsonType>
3720 {
3721  using object_t = typename BasicJsonType::object_t;
3722  using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3724  typename object_t::key_compare, object_comparator_t>::type;
3725 };
3726 
3727 template<typename BasicJsonType>
3729 
3731 // char_traits //
3733 
3734 // Primary template of char_traits calls std char_traits
3735 template<typename T>
3736 struct char_traits : std::char_traits<T>
3737 {};
3738 
3739 // Explicitly define char traits for unsigned char since it is not standard
3740 template<>
3741 struct char_traits<unsigned char> : std::char_traits<char>
3742 {
3743  using char_type = unsigned char;
3745 
3746  // Redefine to_int_type function
3747  static int_type to_int_type(char_type c) noexcept
3748  {
3749  return static_cast<int_type>(c);
3750  }
3751 
3752  static char_type to_char_type(int_type i) noexcept
3753  {
3754  return static_cast<char_type>(i);
3755  }
3756 
3757  static constexpr int_type eof() noexcept
3758  {
3759  return static_cast<int_type>(std::char_traits<char>::eof());
3760  }
3761 };
3762 
3763 // Explicitly define char traits for signed char since it is not standard
3764 template<>
3765 struct char_traits<signed char> : std::char_traits<char>
3766 {
3767  using char_type = signed char;
3769 
3770  // Redefine to_int_type function
3771  static int_type to_int_type(char_type c) noexcept
3772  {
3773  return static_cast<int_type>(c);
3774  }
3775 
3776  static char_type to_char_type(int_type i) noexcept
3777  {
3778  return static_cast<char_type>(i);
3779  }
3780 
3781  static constexpr int_type eof() noexcept
3782  {
3783  return static_cast<int_type>(std::char_traits<char>::eof());
3784  }
3785 };
3786 
3787 #if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
3788 template<>
3789 struct char_traits<std::byte> : std::char_traits<char>
3790 {
3791  using char_type = std::byte;
3792  using int_type = uint64_t;
3793 
3794  static int_type to_int_type(char_type c) noexcept
3795  {
3796  return static_cast<int_type>(std::to_integer<unsigned char>(c));
3797  }
3798 
3799  static char_type to_char_type(int_type i) noexcept
3800  {
3801  return std::byte(static_cast<unsigned char>(i));
3802  }
3803 
3804  static constexpr int_type eof() noexcept
3805  {
3806  return static_cast<int_type>(std::char_traits<char>::eof());
3807  }
3808 };
3809 #endif
3810 
3812 // is_ functions //
3814 
3815 // https://en.cppreference.com/w/cpp/types/conjunction
3816 template<class...> struct conjunction : std::true_type { };
3817 template<class B> struct conjunction<B> : B { };
3818 template<class B, class... Bn>
3819 struct conjunction<B, Bn...>
3820 : std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
3821 
3822 // https://en.cppreference.com/w/cpp/types/negation
3823 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3824 
3825 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3826 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3827 // This causes compile errors in e.g., Clang 3.5 or GCC 4.9.
3828 template <typename T>
3829 struct is_default_constructible : std::is_default_constructible<T> {};
3830 
3831 template <typename T1, typename T2>
3832 struct is_default_constructible<std::pair<T1, T2>>
3833  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3834 
3835 template <typename T1, typename T2>
3836 struct is_default_constructible<const std::pair<T1, T2>>
3837  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3838 
3839 template <typename... Ts>
3840 struct is_default_constructible<std::tuple<Ts...>>
3841  : conjunction<is_default_constructible<Ts>...> {};
3842 
3843 template <typename... Ts>
3844 struct is_default_constructible<const std::tuple<Ts...>>
3845  : conjunction<is_default_constructible<Ts>...> {};
3846 
3847 template <typename T, typename... Args>
3848 struct is_constructible : std::is_constructible<T, Args...> {};
3849 
3850 template <typename T1, typename T2>
3851 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3852 
3853 template <typename T1, typename T2>
3854 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3855 
3856 template <typename... Ts>
3857 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3858 
3859 template <typename... Ts>
3860 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3861 
3862 template<typename T, typename = void>
3863 struct is_iterator_traits : std::false_type {};
3864 
3865 template<typename T>
3867 {
3868  private:
3870 
3871  public:
3872  static constexpr auto value =
3878 };
3879 
3880 template<typename T>
3881 struct is_range
3882 {
3883  private:
3885 
3888 
3889  // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3890  // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3891  // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3892  static constexpr auto is_iterator_begin =
3894 
3895  public:
3897 };
3898 
3899 template<typename R>
3900 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3901 
3902 template<typename T>
3904 
3905 // The following implementation of is_complete_type is taken from
3906 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3907 // and is written by Xiang Fan who agreed to use it in this library.
3908 
3909 template<typename T, typename = void>
3910 struct is_complete_type : std::false_type {};
3911 
3912 template<typename T>
3913 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3914 
3915 template<typename BasicJsonType, typename CompatibleObjectType,
3916  typename = void>
3917 struct is_compatible_object_type_impl : std::false_type {};
3918 
3919 template<typename BasicJsonType, typename CompatibleObjectType>
3921  BasicJsonType, CompatibleObjectType,
3922  enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3923  is_detected<key_type_t, CompatibleObjectType>::value >>
3924 {
3925  using object_t = typename BasicJsonType::object_t;
3926 
3927  // macOS's is_constructible does not play well with nonesuch...
3928  static constexpr bool value =
3929  is_constructible<typename object_t::key_type,
3930  typename CompatibleObjectType::key_type>::value &&
3931  is_constructible<typename object_t::mapped_type,
3932  typename CompatibleObjectType::mapped_type>::value;
3933 };
3934 
3935 template<typename BasicJsonType, typename CompatibleObjectType>
3937  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3938 
3939 template<typename BasicJsonType, typename ConstructibleObjectType,
3940  typename = void>
3941 struct is_constructible_object_type_impl : std::false_type {};
3942 
3943 template<typename BasicJsonType, typename ConstructibleObjectType>
3945  BasicJsonType, ConstructibleObjectType,
3946  enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3947  is_detected<key_type_t, ConstructibleObjectType>::value >>
3948 {
3949  using object_t = typename BasicJsonType::object_t;
3950 
3951  static constexpr bool value =
3955  (is_constructible<typename ConstructibleObjectType::key_type,
3956  typename object_t::key_type>::value &&
3957  std::is_same <
3958  typename object_t::mapped_type,
3959  typename ConstructibleObjectType::mapped_type >::value)) ||
3960  (has_from_json<BasicJsonType,
3961  typename ConstructibleObjectType::mapped_type>::value ||
3963  BasicJsonType,
3964  typename ConstructibleObjectType::mapped_type >::value);
3965 };
3966 
3967 template<typename BasicJsonType, typename ConstructibleObjectType>
3969  : is_constructible_object_type_impl<BasicJsonType,
3970  ConstructibleObjectType> {};
3971 
3972 template<typename BasicJsonType, typename CompatibleStringType>
3974 {
3975  static constexpr auto value =
3977 };
3978 
3979 template<typename BasicJsonType, typename ConstructibleStringType>
3981 {
3982  // launder type through decltype() to fix compilation failure on ICPC
3983 #ifdef __INTEL_COMPILER
3984  using laundered_type = decltype(std::declval<ConstructibleStringType>());
3985 #else
3986  using laundered_type = ConstructibleStringType;
3987 #endif
3988 
3989  static constexpr auto value =
3990  conjunction <
3992  is_detected_exact<typename BasicJsonType::string_t::value_type,
3994 };
3995 
3996 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3997 struct is_compatible_array_type_impl : std::false_type {};
3998 
3999 template<typename BasicJsonType, typename CompatibleArrayType>
4001  BasicJsonType, CompatibleArrayType,
4002  enable_if_t <
4003  is_detected<iterator_t, CompatibleArrayType>::value&&
4004  is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
4005 // special case for types like std::filesystem::path whose iterator's value_type are themselves
4006 // c.f. https://github.com/nlohmann/json/pull/3073
4007  !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
4008 {
4009  static constexpr bool value =
4010  is_constructible<BasicJsonType,
4012 };
4013 
4014 template<typename BasicJsonType, typename CompatibleArrayType>
4016  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
4017 
4018 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
4019 struct is_constructible_array_type_impl : std::false_type {};
4020 
4021 template<typename BasicJsonType, typename ConstructibleArrayType>
4023  BasicJsonType, ConstructibleArrayType,
4024  enable_if_t<std::is_same<ConstructibleArrayType,
4025  typename BasicJsonType::value_type>::value >>
4026  : std::true_type {};
4027 
4028 template<typename BasicJsonType, typename ConstructibleArrayType>
4030  BasicJsonType, ConstructibleArrayType,
4031  enable_if_t < !std::is_same<ConstructibleArrayType,
4032  typename BasicJsonType::value_type>::value&&
4033  !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4034  is_default_constructible<ConstructibleArrayType>::value&&
4035 (std::is_move_assignable<ConstructibleArrayType>::value ||
4036  std::is_copy_assignable<ConstructibleArrayType>::value)&&
4037 is_detected<iterator_t, ConstructibleArrayType>::value&&
4038 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
4039 is_detected<range_value_t, ConstructibleArrayType>::value&&
4040 // special case for types like std::filesystem::path whose iterator's value_type are themselves
4041 // c.f. https://github.com/nlohmann/json/pull/3073
4042 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
4044 detected_t<range_value_t, ConstructibleArrayType >>::value >>
4045 {
4047 
4048  static constexpr bool value =
4049  std::is_same<value_type,
4050  typename BasicJsonType::array_t::value_type>::value ||
4051  has_from_json<BasicJsonType,
4052  value_type>::value ||
4054  BasicJsonType,
4055  value_type >::value;
4056 };
4057 
4058 template<typename BasicJsonType, typename ConstructibleArrayType>
4060  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
4061 
4062 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
4063  typename = void>
4064 struct is_compatible_integer_type_impl : std::false_type {};
4065 
4066 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
4068  RealIntegerType, CompatibleNumberIntegerType,
4069  enable_if_t < std::is_integral<RealIntegerType>::value&&
4070  std::is_integral<CompatibleNumberIntegerType>::value&&
4071  !std::is_same<bool, CompatibleNumberIntegerType>::value >>
4072 {
4073  // is there an assert somewhere on overflows?
4074  using RealLimits = std::numeric_limits<RealIntegerType>;
4075  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
4076 
4077  static constexpr auto value =
4078  is_constructible<RealIntegerType,
4079  CompatibleNumberIntegerType>::value &&
4080  CompatibleLimits::is_integer &&
4081  RealLimits::is_signed == CompatibleLimits::is_signed;
4082 };
4083 
4084 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
4086  : is_compatible_integer_type_impl<RealIntegerType,
4087  CompatibleNumberIntegerType> {};
4088 
4089 template<typename BasicJsonType, typename CompatibleType, typename = void>
4090 struct is_compatible_type_impl: std::false_type {};
4091 
4092 template<typename BasicJsonType, typename CompatibleType>
4094  BasicJsonType, CompatibleType,
4095  enable_if_t<is_complete_type<CompatibleType>::value >>
4096 {
4097  static constexpr bool value =
4099 };
4100 
4101 template<typename BasicJsonType, typename CompatibleType>
4103  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
4104 
4105 template<typename T1, typename T2>
4106 struct is_constructible_tuple : std::false_type {};
4107 
4108 template<typename T1, typename... Args>
4109 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
4110 
4111 template<typename BasicJsonType, typename T>
4112 struct is_json_iterator_of : std::false_type {};
4113 
4114 template<typename BasicJsonType>
4115 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
4116 
4117 template<typename BasicJsonType>
4118 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
4119 {};
4120 
4121 // checks if a given type T is a template specialization of Primary
4122 template<template <typename...> class Primary, typename T>
4123 struct is_specialization_of : std::false_type {};
4124 
4125 template<template <typename...> class Primary, typename... Args>
4126 struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
4127 
4128 template<typename T>
4130 
4131 // checks if A and B are comparable using Compare functor
4132 template<typename Compare, typename A, typename B, typename = void>
4133 struct is_comparable : std::false_type {};
4134 
4135 template<typename Compare, typename A, typename B>
4136 struct is_comparable<Compare, A, B, void_t<
4137 decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
4138 decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
4139 >> : std::true_type {};
4140 
4141 template<typename T>
4143 
4144 // type trait to check if KeyType can be used as an object key (without a BasicJsonType)
4145 // see is_usable_as_basic_json_key_type below
4146 template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
4147  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
4148 using is_usable_as_key_type = typename std::conditional <
4150  && !(ExcludeObjectKeyType && std::is_same<KeyType,
4151  ObjectKeyType>::value)
4152  && (!RequireTransparentComparator
4155  std::true_type,
4156  std::false_type >::type;
4157 
4158 // type trait to check if KeyType can be used as an object key
4159 // true if:
4160 // - KeyType is comparable with BasicJsonType::object_t::key_type
4161 // - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
4162 // - the comparator is transparent or RequireTransparentComparator is false
4163 // - KeyType is not a JSON iterator or json_pointer
4164 template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
4165  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
4166 using is_usable_as_basic_json_key_type = typename std::conditional <
4167  is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
4168  typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
4169  RequireTransparentComparator, ExcludeObjectKeyType>::value
4171  std::true_type,
4172  std::false_type >::type;
4173 
4174 template<typename ObjectType, typename KeyType>
4175 using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
4176 
4177 // type trait to check if object_t has an erase() member functions accepting KeyType
4178 template<typename BasicJsonType, typename KeyType>
4179 using has_erase_with_key_type = typename std::conditional <
4180  is_detected <
4182  typename BasicJsonType::object_t, KeyType >::value,
4183  std::true_type,
4184  std::false_type >::type;
4185 
4186 // a naive helper to check if a type is an ordered_map (exploits the fact that
4187 // ordered_map inherits capacity() from std::vector)
4188 template <typename T>
4190 {
4191  using one = char;
4192 
4193  struct two
4194  {
4195  char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4196  };
4197 
4198  template <typename C> static one test( decltype(&C::capacity) ) ;
4199  template <typename C> static two test(...);
4200 
4201  enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
4202 };
4203 
4204 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
4207 {
4208  return static_cast<T>(value);
4209 }
4210 
4212 T conditional_static_cast(U value)
4213 {
4214  return value;
4215 }
4216 
4217 template<typename... Types>
4219 
4220 template<typename... Types>
4222 
4223 template<typename... Types>
4225 
4226 // there's a disjunction trait in another PR; replace when merged
4227 template<typename... Types>
4228 using same_sign = std::integral_constant < bool,
4229  all_signed<Types...>::value || all_unsigned<Types...>::value >;
4230 
4231 template<typename OfType, typename T>
4232 using never_out_of_range = std::integral_constant < bool,
4233  (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
4234  || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
4235 
4236 template<typename OfType, typename T,
4237  bool OfTypeSigned = std::is_signed<OfType>::value,
4238  bool TSigned = std::is_signed<T>::value>
4240 
4241 template<typename OfType, typename T>
4242 struct value_in_range_of_impl2<OfType, T, false, false>
4243 {
4244  static constexpr bool test(T val)
4245  {
4246  using CommonType = typename std::common_type<OfType, T>::type;
4247  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4248  }
4249 };
4250 
4251 template<typename OfType, typename T>
4252 struct value_in_range_of_impl2<OfType, T, true, false>
4253 {
4254  static constexpr bool test(T val)
4255  {
4256  using CommonType = typename std::common_type<OfType, T>::type;
4257  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4258  }
4259 };
4260 
4261 template<typename OfType, typename T>
4262 struct value_in_range_of_impl2<OfType, T, false, true>
4263 {
4264  static constexpr bool test(T val)
4265  {
4266  using CommonType = typename std::common_type<OfType, T>::type;
4267  return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4268  }
4269 };
4270 
4271 template<typename OfType, typename T>
4272 struct value_in_range_of_impl2<OfType, T, true, true>
4273 {
4274  static constexpr bool test(T val)
4275  {
4276  using CommonType = typename std::common_type<OfType, T>::type;
4277  return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
4278  && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4279  }
4280 };
4281 
4282 template<typename OfType, typename T,
4283  bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
4286 
4287 template<typename OfType, typename T>
4288 struct value_in_range_of_impl1<OfType, T, false>
4289 {
4290  static constexpr bool test(T val)
4291  {
4293  }
4294 };
4295 
4296 template<typename OfType, typename T>
4297 struct value_in_range_of_impl1<OfType, T, true>
4298 {
4299  static constexpr bool test(T /*val*/)
4300  {
4301  return true;
4302  }
4303 };
4304 
4305 template<typename OfType, typename T>
4306 constexpr bool value_in_range_of(T val)
4307 {
4309 }
4310 
4311 template<bool Value>
4312 using bool_constant = std::integral_constant<bool, Value>;
4313 
4315 // is_c_string
4317 
4318 namespace impl
4319 {
4320 
4321 template<typename T>
4322 constexpr bool is_c_string()
4323 {
4324  using TUnExt = typename std::remove_extent<T>::type;
4325  using TUnCVExt = typename std::remove_cv<TUnExt>::type;
4326  using TUnPtr = typename std::remove_pointer<T>::type;
4327  using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
4328  return
4331 }
4332 
4333 } // namespace impl
4334 
4335 // checks whether T is a [cv] char */[cv] char[] C string
4336 template<typename T>
4337 struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
4338 
4339 template<typename T>
4341 
4343 // is_transparent
4345 
4346 namespace impl
4347 {
4348 
4349 template<typename T>
4350 constexpr bool is_transparent()
4351 {
4353 }
4354 
4355 } // namespace impl
4356 
4357 // checks whether T has a member named is_transparent
4358 template<typename T>
4359 struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
4360 
4362 
4363 } // namespace detail
4365 
4366 // #include <nlohmann/detail/string_concat.hpp>
4367 // __ _____ _____ _____
4368 // __| | __| | | | JSON for Modern C++
4369 // | | |__ | | | | | | version 3.12.0
4370 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4371 //
4372 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
4373 // SPDX-License-Identifier: MIT
4374 
4375 
4376 
4377 #include <cstring> // strlen
4378 #include <string> // string
4379 #include <utility> // forward
4380 
4381 // #include <nlohmann/detail/meta/cpp_future.hpp>
4382 
4383 // #include <nlohmann/detail/meta/detected.hpp>
4384 
4385 
4387 namespace detail
4388 {
4389 
4390 inline std::size_t concat_length()
4391 {
4392  return 0;
4393 }
4394 
4395 template<typename... Args>
4396 inline std::size_t concat_length(const char* cstr, const Args& ... rest);
4397 
4398 template<typename StringType, typename... Args>
4399 inline std::size_t concat_length(const StringType& str, const Args& ... rest);
4400 
4401 template<typename... Args>
4402 inline std::size_t concat_length(const char /*c*/, const Args& ... rest)
4403 {
4404  return 1 + concat_length(rest...);
4405 }
4406 
4407 template<typename... Args>
4408 inline std::size_t concat_length(const char* cstr, const Args& ... rest)
4409 {
4410  // cppcheck-suppress ignoredReturnValue
4411  return ::strlen(cstr) + concat_length(rest...);
4412 }
4413 
4414 template<typename StringType, typename... Args>
4415 inline std::size_t concat_length(const StringType& str, const Args& ... rest)
4416 {
4417  return str.size() + concat_length(rest...);
4418 }
4419 
4420 template<typename OutStringType>
4421 inline void concat_into(OutStringType& /*out*/)
4422 {}
4423 
4424 template<typename StringType, typename Arg>
4425 using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
4426 
4427 template<typename StringType, typename Arg>
4429 
4430 template<typename StringType, typename Arg>
4431 using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
4432 
4433 template<typename StringType, typename Arg>
4435 
4436 template<typename StringType, typename Arg>
4437 using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
4438 
4439 template<typename StringType, typename Arg>
4441 
4442 template<typename StringType, typename Arg>
4443 using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
4444 
4445 template<typename StringType, typename Arg>
4447 
4448 template < typename OutStringType, typename Arg, typename... Args,
4451 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
4452 
4453 template < typename OutStringType, typename Arg, typename... Args,
4457 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4458 
4459 template < typename OutStringType, typename Arg, typename... Args,
4464 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4465 
4466 template<typename OutStringType, typename Arg, typename... Args,
4468 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
4469 {
4470  out.append(std::forward<Arg>(arg));
4471  concat_into(out, std::forward<Args>(rest)...);
4472 }
4473 
4474 template < typename OutStringType, typename Arg, typename... Args,
4477 inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
4478 {
4479  out += std::forward<Arg>(arg);
4480  concat_into(out, std::forward<Args>(rest)...);
4481 }
4482 
4483 template < typename OutStringType, typename Arg, typename... Args,
4487 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4488 {
4489  out.append(arg.begin(), arg.end());
4490  concat_into(out, std::forward<Args>(rest)...);
4491 }
4492 
4493 template < typename OutStringType, typename Arg, typename... Args,
4498 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4499 {
4500  out.append(arg.data(), arg.size());
4501  concat_into(out, std::forward<Args>(rest)...);
4502 }
4503 
4504 template<typename OutStringType = std::string, typename... Args>
4505 inline OutStringType concat(Args && ... args)
4506 {
4507  OutStringType str;
4508  str.reserve(concat_length(args...));
4509  concat_into(str, std::forward<Args>(args)...);
4510  return str;
4511 }
4512 
4513 } // namespace detail
4515 
4516 
4517 // With -Wweak-vtables, Clang will complain about the exception classes as they
4518 // have no out-of-line virtual method definitions and their vtable will be
4519 // emitted in every translation unit. This issue cannot be fixed with a
4520 // header-only library as there is no implementation file to move these
4521 // functions to. As a result, we suppress this warning here to avoid client
4522 // code stumbling over this. See https://github.com/nlohmann/json/issues/4087
4523 // for a discussion.
4524 #if defined(__clang__)
4525  #pragma clang diagnostic push
4526  #pragma clang diagnostic ignored "-Wweak-vtables"
4527 #endif
4528 
4530 namespace detail
4531 {
4532 
4534 // exceptions //
4536 
4539 class exception : public std::exception
4540 {
4541  public:
4543  const char* what() const noexcept override
4544  {
4545  return m.what();
4546  }
4547 
4549  const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4550 
4551  protected:
4553  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
4554 
4555  static std::string name(const std::string& ename, int id_)
4556  {
4557  return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
4558  }
4559 
4560  static std::string diagnostics(std::nullptr_t /*leaf_element*/)
4561  {
4562  return "";
4563  }
4564 
4565  template<typename BasicJsonType>
4566  static std::string diagnostics(const BasicJsonType* leaf_element)
4567  {
4568 #if JSON_DIAGNOSTICS
4569  std::vector<std::string> tokens;
4570  for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
4571  {
4572  switch (current->m_parent->type())
4573  {
4574  case value_t::array:
4575  {
4576  for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i)
4577  {
4578  if (&current->m_parent->m_data.m_value.array->operator[](i) == current)
4579  {
4580  tokens.emplace_back(std::to_string(i));
4581  break;
4582  }
4583  }
4584  break;
4585  }
4586 
4587  case value_t::object:
4588  {
4589  for (const auto& element : *current->m_parent->m_data.m_value.object)
4590  {
4591  if (&element.second == current)
4592  {
4593  tokens.emplace_back(element.first.c_str());
4594  break;
4595  }
4596  }
4597  break;
4598  }
4599 
4600  case value_t::null: // LCOV_EXCL_LINE
4601  case value_t::string: // LCOV_EXCL_LINE
4602  case value_t::boolean: // LCOV_EXCL_LINE
4603  case value_t::number_integer: // LCOV_EXCL_LINE
4604  case value_t::number_unsigned: // LCOV_EXCL_LINE
4605  case value_t::number_float: // LCOV_EXCL_LINE
4606  case value_t::binary: // LCOV_EXCL_LINE
4607  case value_t::discarded: // LCOV_EXCL_LINE
4608  default: // LCOV_EXCL_LINE
4609  break; // LCOV_EXCL_LINE
4610  }
4611  }
4612 
4613  if (tokens.empty())
4614  {
4615  return "";
4616  }
4617 
4618  auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4619  [](const std::string & a, const std::string & b)
4620  {
4621  return concat(a, '/', detail::escape(b));
4622  });
4623 
4624  return concat('(', str, ") ", get_byte_positions(leaf_element));
4625 #else
4626  return get_byte_positions(leaf_element);
4627 #endif
4628  }
4629 
4630  private:
4632  std::runtime_error m;
4633 #if JSON_DIAGNOSTIC_POSITIONS
4634  template<typename BasicJsonType>
4635  static std::string get_byte_positions(const BasicJsonType* leaf_element)
4636  {
4637  if ((leaf_element->start_pos() != std::string::npos) && (leaf_element->end_pos() != std::string::npos))
4638  {
4639  return concat("(bytes ", std::to_string(leaf_element->start_pos()), "-", std::to_string(leaf_element->end_pos()), ") ");
4640  }
4641  return "";
4642  }
4643 #else
4644  template<typename BasicJsonType>
4645  static std::string get_byte_positions(const BasicJsonType* leaf_element)
4646  {
4647  static_cast<void>(leaf_element);
4648  return "";
4649  }
4650 #endif
4651 };
4652 
4655 class parse_error : public exception
4656 {
4657  public:
4668  static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4669  {
4670  const std::string w = concat(exception::name("parse_error", id_), "parse error",
4671  position_string(pos), ": ", exception::diagnostics(context), what_arg);
4672  return {id_, pos.chars_read_total, w.c_str()};
4673  }
4674 
4676  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4677  {
4678  const std::string w = concat(exception::name("parse_error", id_), "parse error",
4679  (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4680  ": ", exception::diagnostics(context), what_arg);
4681  return {id_, byte_, w.c_str()};
4682  }
4683 
4693  const std::size_t byte;
4694 
4695  private:
4696  parse_error(int id_, std::size_t byte_, const char* what_arg)
4697  : exception(id_, what_arg), byte(byte_) {}
4698 
4699  static std::string position_string(const position_t& pos)
4700  {
4701  return concat(" at line ", std::to_string(pos.lines_read + 1),
4702  ", column ", std::to_string(pos.chars_read_current_line));
4703  }
4704 };
4705 
4709 {
4710  public:
4712  static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4713  {
4714  const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4715  return {id_, w.c_str()};
4716  }
4717 
4718  private:
4720  invalid_iterator(int id_, const char* what_arg)
4721  : exception(id_, what_arg) {}
4722 };
4723 
4726 class type_error : public exception
4727 {
4728  public:
4730  static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4731  {
4732  const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4733  return {id_, w.c_str()};
4734  }
4735 
4736  private:
4738  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4739 };
4740 
4743 class out_of_range : public exception
4744 {
4745  public:
4747  static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4748  {
4749  const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4750  return {id_, w.c_str()};
4751  }
4752 
4753  private:
4755  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4756 };
4757 
4760 class other_error : public exception
4761 {
4762  public:
4764  static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4765  {
4766  const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4767  return {id_, w.c_str()};
4768  }
4769 
4770  private:
4772  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4773 };
4774 
4775 } // namespace detail
4777 
4778 #if defined(__clang__)
4779  #pragma clang diagnostic pop
4780 #endif
4781 
4782 // #include <nlohmann/detail/macro_scope.hpp>
4783 
4784 // #include <nlohmann/detail/meta/cpp_future.hpp>
4785 
4786 // #include <nlohmann/detail/meta/identity_tag.hpp>
4787 // __ _____ _____ _____
4788 // __| | __| | | | JSON for Modern C++
4789 // | | |__ | | | | | | version 3.12.0
4790 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4791 //
4792 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
4793 // SPDX-License-Identifier: MIT
4794 
4795 
4796 
4797 // #include <nlohmann/detail/abi_macros.hpp>
4798 
4799 
4801 namespace detail
4802 {
4803 
4804 // dispatching helper struct
4805 template <class T> struct identity_tag {};
4806 
4807 } // namespace detail
4809 
4810 // #include <nlohmann/detail/meta/std_fs.hpp>
4811 // __ _____ _____ _____
4812 // __| | __| | | | JSON for Modern C++
4813 // | | |__ | | | | | | version 3.12.0
4814 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4815 //
4816 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
4817 // SPDX-License-Identifier: MIT
4818 
4819 
4820 
4821 // #include <nlohmann/detail/macro_scope.hpp>
4822 
4823 
4824 #if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4825 #include <experimental/filesystem>
4827 namespace detail
4828 {
4829 namespace std_fs = std::experimental::filesystem;
4830 } // namespace detail
4832 #elif JSON_HAS_FILESYSTEM
4833 #include <filesystem> // NOLINT(build/c++17)
4835 namespace detail
4836 {
4837 namespace std_fs = std::filesystem;
4838 } // namespace detail
4840 #endif
4841 
4842 // #include <nlohmann/detail/meta/type_traits.hpp>
4843 
4844 // #include <nlohmann/detail/string_concat.hpp>
4845 
4846 // #include <nlohmann/detail/value_t.hpp>
4847 
4848 
4849 // include after macro_scope.hpp
4850 #ifdef JSON_HAS_CPP_17
4851  #include <optional> // optional
4852 #endif
4853 
4854 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
4855  #include <string_view> // u8string_view
4856 #endif
4857 
4859 namespace detail
4860 {
4861 
4862 template<typename BasicJsonType>
4863 inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4864 {
4865  if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4866  {
4867  JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4868  }
4869  n = nullptr;
4870 }
4871 
4872 #ifdef JSON_HAS_CPP_17
4873 template<typename BasicJsonType, typename T>
4874 void from_json(const BasicJsonType& j, std::optional<T>& opt)
4875 {
4876  if (j.is_null())
4877  {
4878  opt = std::nullopt;
4879  }
4880  else
4881  {
4882  opt.emplace(j.template get<T>());
4883  }
4884 }
4885 #endif // JSON_HAS_CPP_17
4886 
4887 // overloads for basic_json template parameters
4888 template < typename BasicJsonType, typename ArithmeticType,
4891  int > = 0 >
4892 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4893 {
4894  switch (static_cast<value_t>(j))
4895  {
4897  {
4898  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4899  break;
4900  }
4902  {
4903  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4904  break;
4905  }
4906  case value_t::number_float:
4907  {
4908  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4909  break;
4910  }
4911 
4912  case value_t::null:
4913  case value_t::object:
4914  case value_t::array:
4915  case value_t::string:
4916  case value_t::boolean:
4917  case value_t::binary:
4918  case value_t::discarded:
4919  default:
4920  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4921  }
4922 }
4923 
4924 template<typename BasicJsonType>
4925 inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4926 {
4927  if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4928  {
4929  JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4930  }
4931  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4932 }
4933 
4934 template<typename BasicJsonType>
4935 inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4936 {
4937  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4938  {
4939  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4940  }
4941  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4942 }
4943 
4944 template <
4945  typename BasicJsonType, typename StringType,
4946  enable_if_t <
4950  && !is_json_ref<StringType>::value, int > = 0 >
4951 inline void from_json(const BasicJsonType& j, StringType& s)
4952 {
4953  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4954  {
4955  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4956  }
4957 
4958  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4959 }
4960 
4961 template<typename BasicJsonType>
4962 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4963 {
4964  get_arithmetic_value(j, val);
4965 }
4966 
4967 template<typename BasicJsonType>
4968 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4969 {
4970  get_arithmetic_value(j, val);
4971 }
4972 
4973 template<typename BasicJsonType>
4974 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4975 {
4976  get_arithmetic_value(j, val);
4977 }
4978 
4979 #if !JSON_DISABLE_ENUM_SERIALIZATION
4980 template<typename BasicJsonType, typename EnumType,
4982 inline void from_json(const BasicJsonType& j, EnumType& e)
4983 {
4985  get_arithmetic_value(j, val);
4986  e = static_cast<EnumType>(val);
4987 }
4988 #endif // JSON_DISABLE_ENUM_SERIALIZATION
4989 
4990 // forward_list doesn't have an insert method
4991 template<typename BasicJsonType, typename T, typename Allocator,
4993 inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4994 {
4995  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4996  {
4997  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4998  }
4999  l.clear();
5000  std::transform(j.rbegin(), j.rend(),
5001  std::front_inserter(l), [](const BasicJsonType & i)
5002  {
5003  return i.template get<T>();
5004  });
5005 }
5006 
5007 // valarray doesn't have an insert method
5008 template<typename BasicJsonType, typename T,
5010 inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
5011 {
5012  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5013  {
5014  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5015  }
5016  l.resize(j.size());
5017  std::transform(j.begin(), j.end(), std::begin(l),
5018  [](const BasicJsonType & elem)
5019  {
5020  return elem.template get<T>();
5021  });
5022 }
5023 
5024 template<typename BasicJsonType, typename T, std::size_t N>
5025 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5026 -> decltype(j.template get<T>(), void())
5027 {
5028  for (std::size_t i = 0; i < N; ++i)
5029  {
5030  arr[i] = j.at(i).template get<T>();
5031  }
5032 }
5033 
5034 template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2>
5035 auto from_json(const BasicJsonType& j, T (&arr)[N1][N2]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5036 -> decltype(j.template get<T>(), void())
5037 {
5038  for (std::size_t i1 = 0; i1 < N1; ++i1)
5039  {
5040  for (std::size_t i2 = 0; i2 < N2; ++i2)
5041  {
5042  arr[i1][i2] = j.at(i1).at(i2).template get<T>();
5043  }
5044  }
5045 }
5046 
5047 template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2, std::size_t N3>
5048 auto from_json(const BasicJsonType& j, T (&arr)[N1][N2][N3]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5049 -> decltype(j.template get<T>(), void())
5050 {
5051  for (std::size_t i1 = 0; i1 < N1; ++i1)
5052  {
5053  for (std::size_t i2 = 0; i2 < N2; ++i2)
5054  {
5055  for (std::size_t i3 = 0; i3 < N3; ++i3)
5056  {
5057  arr[i1][i2][i3] = j.at(i1).at(i2).at(i3).template get<T>();
5058  }
5059  }
5060  }
5061 }
5062 
5063 template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2, std::size_t N3, std::size_t N4>
5064 auto from_json(const BasicJsonType& j, T (&arr)[N1][N2][N3][N4]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5065 -> decltype(j.template get<T>(), void())
5066 {
5067  for (std::size_t i1 = 0; i1 < N1; ++i1)
5068  {
5069  for (std::size_t i2 = 0; i2 < N2; ++i2)
5070  {
5071  for (std::size_t i3 = 0; i3 < N3; ++i3)
5072  {
5073  for (std::size_t i4 = 0; i4 < N4; ++i4)
5074  {
5075  arr[i1][i2][i3][i4] = j.at(i1).at(i2).at(i3).at(i4).template get<T>();
5076  }
5077  }
5078  }
5079  }
5080 }
5081 
5082 template<typename BasicJsonType>
5083 inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
5084 {
5085  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
5086 }
5087 
5088 template<typename BasicJsonType, typename T, std::size_t N>
5089 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
5090  priority_tag<2> /*unused*/)
5091 -> decltype(j.template get<T>(), void())
5092 {
5093  for (std::size_t i = 0; i < N; ++i)
5094  {
5095  arr[i] = j.at(i).template get<T>();
5096  }
5097 }
5098 
5099 template<typename BasicJsonType, typename ConstructibleArrayType,
5100  enable_if_t<
5102  int> = 0>
5103 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
5104 -> decltype(
5105  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
5106  j.template get<typename ConstructibleArrayType::value_type>(),
5107  void())
5108 {
5109  using std::end;
5110 
5111  ConstructibleArrayType ret;
5112  ret.reserve(j.size());
5113  std::transform(j.begin(), j.end(),
5114  std::inserter(ret, end(ret)), [](const BasicJsonType & i)
5115  {
5116  // get<BasicJsonType>() returns *this, this won't call a from_json
5117  // method when value_type is BasicJsonType
5118  return i.template get<typename ConstructibleArrayType::value_type>();
5119  });
5120  arr = std::move(ret);
5121 }
5122 
5123 template<typename BasicJsonType, typename ConstructibleArrayType,
5124  enable_if_t<
5126  int> = 0>
5127 inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
5128  priority_tag<0> /*unused*/)
5129 {
5130  using std::end;
5131 
5132  ConstructibleArrayType ret;
5133  std::transform(
5134  j.begin(), j.end(), std::inserter(ret, end(ret)),
5135  [](const BasicJsonType & i)
5136  {
5137  // get<BasicJsonType>() returns *this, this won't call a from_json
5138  // method when value_type is BasicJsonType
5139  return i.template get<typename ConstructibleArrayType::value_type>();
5140  });
5141  arr = std::move(ret);
5142 }
5143 
5144 template < typename BasicJsonType, typename ConstructibleArrayType,
5145  enable_if_t <
5151  int > = 0 >
5152 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
5153 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
5154 j.template get<typename ConstructibleArrayType::value_type>(),
5155 void())
5156 {
5157  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5158  {
5159  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5160  }
5161 
5162  from_json_array_impl(j, arr, priority_tag<3> {});
5163 }
5164 
5165 template < typename BasicJsonType, typename T, std::size_t... Idx >
5166 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
5167  identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
5168 {
5169  return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
5170 }
5171 
5172 template < typename BasicJsonType, typename T, std::size_t N >
5173 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
5174 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
5175 {
5176  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5177  {
5178  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5179  }
5180 
5181  return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
5182 }
5183 
5184 template<typename BasicJsonType>
5185 inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
5186 {
5187  if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
5188  {
5189  JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
5190  }
5191 
5192  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
5193 }
5194 
5195 template<typename BasicJsonType, typename ConstructibleObjectType,
5197 inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
5198 {
5199  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
5200  {
5201  JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
5202  }
5203 
5204  ConstructibleObjectType ret;
5205  const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
5206  using value_type = typename ConstructibleObjectType::value_type;
5207  std::transform(
5208  inner_object->begin(), inner_object->end(),
5209  std::inserter(ret, ret.begin()),
5210  [](typename BasicJsonType::object_t::value_type const & p)
5211  {
5212  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
5213  });
5214  obj = std::move(ret);
5215 }
5216 
5217 // overload for arithmetic types, not chosen for basic_json template arguments
5218 // (BooleanType, etc.); note: Is it really necessary to provide explicit
5219 // overloads for boolean_t etc. in case of a custom BooleanType which is not
5220 // an arithmetic type?
5221 template < typename BasicJsonType, typename ArithmeticType,
5222  enable_if_t <
5228  int > = 0 >
5229 inline void from_json(const BasicJsonType& j, ArithmeticType& val)
5230 {
5231  switch (static_cast<value_t>(j))
5232  {
5234  {
5235  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
5236  break;
5237  }
5239  {
5240  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
5241  break;
5242  }
5243  case value_t::number_float:
5244  {
5245  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
5246  break;
5247  }
5248  case value_t::boolean:
5249  {
5250  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
5251  break;
5252  }
5253 
5254  case value_t::null:
5255  case value_t::object:
5256  case value_t::array:
5257  case value_t::string:
5258  case value_t::binary:
5259  case value_t::discarded:
5260  default:
5261  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
5262  }
5263 }
5264 
5265 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
5266 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
5267 {
5268  return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
5269 }
5270 
5271 template<typename BasicJsonType>
5272 std::tuple<> from_json_tuple_impl_base(BasicJsonType& /*unused*/, index_sequence<> /*unused*/)
5273 {
5274  return {};
5275 }
5276 
5277 template < typename BasicJsonType, class A1, class A2 >
5278 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
5279 {
5280  return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
5281  std::forward<BasicJsonType>(j).at(1).template get<A2>()};
5282 }
5283 
5284 template<typename BasicJsonType, typename A1, typename A2>
5285 inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
5286 {
5287  p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
5288 }
5289 
5290 template<typename BasicJsonType, typename... Args>
5291 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
5292 {
5293  return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
5294 }
5295 
5296 template<typename BasicJsonType, typename... Args>
5297 inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
5298 {
5299  t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
5300 }
5301 
5302 template<typename BasicJsonType, typename TupleRelated>
5303 auto from_json(BasicJsonType&& j, TupleRelated&& t)
5304 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
5305 {
5306  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5307  {
5308  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5309  }
5310 
5311  return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
5312 }
5313 
5314 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
5315  typename = enable_if_t < !std::is_constructible <
5316  typename BasicJsonType::string_t, Key >::value >>
5317 inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
5318 {
5319  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5320  {
5321  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5322  }
5323  m.clear();
5324  for (const auto& p : j)
5325  {
5326  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5327  {
5328  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5329  }
5330  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5331  }
5332 }
5333 
5334 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
5335  typename = enable_if_t < !std::is_constructible <
5336  typename BasicJsonType::string_t, Key >::value >>
5337 inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
5338 {
5339  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5340  {
5341  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5342  }
5343  m.clear();
5344  for (const auto& p : j)
5345  {
5346  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5347  {
5348  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5349  }
5350  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5351  }
5352 }
5353 
5354 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5355 template<typename BasicJsonType>
5356 inline void from_json(const BasicJsonType& j, std_fs::path& p)
5357 {
5358  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
5359  {
5360  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
5361  }
5362  const auto& s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
5363  // Checking for C++20 standard or later can be insufficient in case the
5364  // library support for char8_t is either incomplete or was disabled
5365  // altogether. Use the __cpp_lib_char8_t feature test instead.
5366 #if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L)
5367  p = std_fs::path(std::u8string_view(reinterpret_cast<const char8_t*>(s.data()), s.size()));
5368 #else
5369  p = std_fs::u8path(s); // accepts UTF-8 encoded std::string in C++17, deprecated in C++20
5370 #endif
5371 }
5372 #endif
5373 
5375 {
5376  template<typename BasicJsonType, typename T>
5377  auto operator()(const BasicJsonType& j, T&& val) const
5378  noexcept(noexcept(from_json(j, std::forward<T>(val))))
5379  -> decltype(from_json(j, std::forward<T>(val)))
5380  {
5381  return from_json(j, std::forward<T>(val));
5382  }
5383 };
5384 
5385 } // namespace detail
5386 
5387 #ifndef JSON_HAS_CPP_17
5391 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5392 {
5393 #endif
5394 JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
5396 #ifndef JSON_HAS_CPP_17
5397 } // namespace
5398 #endif
5399 
5401 
5402 // #include <nlohmann/detail/conversions/to_json.hpp>
5403 // __ _____ _____ _____
5404 // __| | __| | | | JSON for Modern C++
5405 // | | |__ | | | | | | version 3.12.0
5406 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5407 //
5408 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
5409 // SPDX-License-Identifier: MIT
5410 
5411 
5412 
5413 // #include <nlohmann/detail/macro_scope.hpp>
5414 // JSON_HAS_CPP_17
5415 #ifdef JSON_HAS_CPP_17
5416  #include <optional> // optional
5417 #endif
5418 
5419 #include <algorithm> // copy
5420 #include <iterator> // begin, end
5421 #include <memory> // allocator_traits
5422 #include <string> // basic_string, char_traits
5423 #include <tuple> // tuple, get
5424 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
5425 #include <utility> // move, forward, declval, pair
5426 #include <valarray> // valarray
5427 #include <vector> // vector
5428 
5429 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5430 // __ _____ _____ _____
5431 // __| | __| | | | JSON for Modern C++
5432 // | | |__ | | | | | | version 3.12.0
5433 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5434 //
5435 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
5436 // SPDX-License-Identifier: MIT
5437 
5438 
5439 
5440 #include <cstddef> // size_t
5441 #include <iterator> // forward_iterator_tag
5442 #include <tuple> // tuple_size, get, tuple_element
5443 #include <utility> // move
5444 
5445 #if JSON_HAS_RANGES
5446  #include <ranges> // enable_borrowed_range
5447 #endif
5448 
5449 // #include <nlohmann/detail/abi_macros.hpp>
5450 
5451 // #include <nlohmann/detail/meta/type_traits.hpp>
5452 
5453 // #include <nlohmann/detail/string_utils.hpp>
5454 // __ _____ _____ _____
5455 // __| | __| | | | JSON for Modern C++
5456 // | | |__ | | | | | | version 3.12.0
5457 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5458 //
5459 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
5460 // SPDX-License-Identifier: MIT
5461 
5462 
5463 
5464 #include <cstddef> // size_t
5465 #include <string> // string, to_string
5466 
5467 // #include <nlohmann/detail/abi_macros.hpp>
5468 
5469 
5471 namespace detail
5472 {
5473 
5474 template<typename StringType>
5475 void int_to_string(StringType& target, std::size_t value)
5476 {
5477  // For ADL
5478  using std::to_string;
5479  target = to_string(value);
5480 }
5481 
5482 template<typename StringType>
5483 StringType to_string(std::size_t value)
5484 {
5485  StringType result;
5486  int_to_string(result, value);
5487  return result;
5488 }
5489 
5490 } // namespace detail
5492 
5493 // #include <nlohmann/detail/value_t.hpp>
5494 
5495 
5497 namespace detail
5498 {
5499 
5500 template<typename IteratorType> class iteration_proxy_value
5501 {
5502  public:
5503  using difference_type = std::ptrdiff_t;
5505  using pointer = value_type *;
5507  using iterator_category = std::forward_iterator_tag;
5508  using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
5509 
5510  private:
5512  IteratorType anchor{};
5514  std::size_t array_index = 0;
5516  mutable std::size_t array_index_last = 0;
5521 
5522  public:
5523  explicit iteration_proxy_value() = default;
5524  explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
5525  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5526  && std::is_nothrow_default_constructible<string_type>::value)
5527  : anchor(std::move(it))
5528  , array_index(array_index_)
5529  {}
5530 
5533  // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
5535  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5536  && std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
5538  noexcept(std::is_nothrow_move_assignable<IteratorType>::value
5539  && std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
5541 
5543  const iteration_proxy_value& operator*() const
5544  {
5545  return *this;
5546  }
5547 
5550  {
5551  ++anchor;
5552  ++array_index;
5553 
5554  return *this;
5555  }
5556 
5557  iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
5558  {
5560  ++anchor;
5561  ++array_index;
5562  return tmp;
5563  }
5564 
5566  bool operator==(const iteration_proxy_value& o) const
5567  {
5568  return anchor == o.anchor;
5569  }
5570 
5572  bool operator!=(const iteration_proxy_value& o) const
5573  {
5574  return anchor != o.anchor;
5575  }
5576 
5578  const string_type& key() const
5579  {
5580  JSON_ASSERT(anchor.m_object != nullptr);
5581 
5582  switch (anchor.m_object->type())
5583  {
5584  // use integer array index as key
5585  case value_t::array:
5586  {
5588  {
5591  }
5592  return array_index_str;
5593  }
5594 
5595  // use key from the object
5596  case value_t::object:
5597  return anchor.key();
5598 
5599  // use an empty key for all primitive types
5600  case value_t::null:
5601  case value_t::string:
5602  case value_t::boolean:
5605  case value_t::number_float:
5606  case value_t::binary:
5607  case value_t::discarded:
5608  default:
5609  return empty_str;
5610  }
5611  }
5612 
5614  typename IteratorType::reference value() const
5615  {
5616  return anchor.value();
5617  }
5618 };
5619 
5621 template<typename IteratorType> class iteration_proxy
5622 {
5623  private:
5625  typename IteratorType::pointer container = nullptr;
5626 
5627  public:
5628  explicit iteration_proxy() = default;
5629 
5631  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
5632  : container(&cont) {}
5633 
5636  iteration_proxy(iteration_proxy&&) noexcept = default;
5637  iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
5638  ~iteration_proxy() = default;
5639 
5641  iteration_proxy_value<IteratorType> begin() const noexcept
5642  {
5644  }
5645 
5648  {
5650  }
5651 };
5652 
5653 // Structured Bindings Support
5654 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5655 // And see https://github.com/nlohmann/json/pull/1391
5656 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
5658 {
5659  return i.key();
5660 }
5661 // Structured Bindings Support
5662 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5663 // And see https://github.com/nlohmann/json/pull/1391
5664 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
5665 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
5666 {
5667  return i.value();
5668 }
5669 
5670 } // namespace detail
5672 
5673 // The Addition to the STD Namespace is required to add
5674 // Structured Bindings Support to the iteration_proxy_value class
5675 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5676 // And see https://github.com/nlohmann/json/pull/1391
5677 namespace std
5678 {
5679 
5680 #if defined(__clang__)
5681  // Fix: https://github.com/nlohmann/json/issues/1401
5682  #pragma clang diagnostic push
5683  #pragma clang diagnostic ignored "-Wmismatched-tags"
5684 #endif
5685 template<typename IteratorType>
5686 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
5687  : public std::integral_constant<std::size_t, 2> {};
5688 
5689 template<std::size_t N, typename IteratorType>
5690 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)
5691 {
5692  public:
5693  using type = decltype(
5694  get<N>(std::declval <
5696 };
5697 #if defined(__clang__)
5698  #pragma clang diagnostic pop
5699 #endif
5700 
5701 } // namespace std
5702 
5703 #if JSON_HAS_RANGES
5704  template <typename IteratorType>
5705  inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
5706 #endif
5707 
5708 // #include <nlohmann/detail/meta/cpp_future.hpp>
5709 
5710 // #include <nlohmann/detail/meta/std_fs.hpp>
5711 
5712 // #include <nlohmann/detail/meta/type_traits.hpp>
5713 
5714 // #include <nlohmann/detail/value_t.hpp>
5715 
5716 
5718 namespace detail
5719 {
5720 
5722 // constructors //
5724 
5725 /*
5726  * Note all external_constructor<>::construct functions need to call
5727  * j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an
5728  * allocated value (e.g., a string). See bug issue
5729  * https://github.com/nlohmann/json/issues/2865 for more information.
5730  */
5731 
5732 template<value_t> struct external_constructor;
5733 
5734 template<>
5736 {
5737  template<typename BasicJsonType>
5738  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
5739  {
5740  j.m_data.m_value.destroy(j.m_data.m_type);
5741  j.m_data.m_type = value_t::boolean;
5742  j.m_data.m_value = b;
5743  j.assert_invariant();
5744  }
5745 };
5746 
5747 template<>
5749 {
5750  template<typename BasicJsonType>
5751  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
5752  {
5753  j.m_data.m_value.destroy(j.m_data.m_type);
5754  j.m_data.m_type = value_t::string;
5755  j.m_data.m_value = s;
5756  j.assert_invariant();
5757  }
5758 
5759  template<typename BasicJsonType>
5760  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5761  {
5762  j.m_data.m_value.destroy(j.m_data.m_type);
5763  j.m_data.m_type = value_t::string;
5764  j.m_data.m_value = std::move(s);
5765  j.assert_invariant();
5766  }
5767 
5768  template < typename BasicJsonType, typename CompatibleStringType,
5770  int > = 0 >
5771  static void construct(BasicJsonType& j, const CompatibleStringType& str)
5772  {
5773  j.m_data.m_value.destroy(j.m_data.m_type);
5774  j.m_data.m_type = value_t::string;
5775  j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
5776  j.assert_invariant();
5777  }
5778 };
5779 
5780 template<>
5782 {
5783  template<typename BasicJsonType>
5784  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
5785  {
5786  j.m_data.m_value.destroy(j.m_data.m_type);
5787  j.m_data.m_type = value_t::binary;
5788  j.m_data.m_value = typename BasicJsonType::binary_t(b);
5789  j.assert_invariant();
5790  }
5791 
5792  template<typename BasicJsonType>
5793  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
5794  {
5795  j.m_data.m_value.destroy(j.m_data.m_type);
5796  j.m_data.m_type = value_t::binary;
5797  j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
5798  j.assert_invariant();
5799  }
5800 };
5801 
5802 template<>
5804 {
5805  template<typename BasicJsonType>
5806  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5807  {
5808  j.m_data.m_value.destroy(j.m_data.m_type);
5809  j.m_data.m_type = value_t::number_float;
5810  j.m_data.m_value = val;
5811  j.assert_invariant();
5812  }
5813 };
5814 
5815 template<>
5817 {
5818  template<typename BasicJsonType>
5819  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5820  {
5821  j.m_data.m_value.destroy(j.m_data.m_type);
5822  j.m_data.m_type = value_t::number_unsigned;
5823  j.m_data.m_value = val;
5824  j.assert_invariant();
5825  }
5826 };
5827 
5828 template<>
5830 {
5831  template<typename BasicJsonType>
5832  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5833  {
5834  j.m_data.m_value.destroy(j.m_data.m_type);
5835  j.m_data.m_type = value_t::number_integer;
5836  j.m_data.m_value = val;
5837  j.assert_invariant();
5838  }
5839 };
5840 
5841 template<>
5843 {
5844  template<typename BasicJsonType>
5845  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5846  {
5847  j.m_data.m_value.destroy(j.m_data.m_type);
5848  j.m_data.m_type = value_t::array;
5849  j.m_data.m_value = arr;
5850  j.set_parents();
5851  j.assert_invariant();
5852  }
5853 
5854  template<typename BasicJsonType>
5855  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5856  {
5857  j.m_data.m_value.destroy(j.m_data.m_type);
5858  j.m_data.m_type = value_t::array;
5859  j.m_data.m_value = std::move(arr);
5860  j.set_parents();
5861  j.assert_invariant();
5862  }
5863 
5864  template < typename BasicJsonType, typename CompatibleArrayType,
5866  int > = 0 >
5867  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5868  {
5869  using std::begin;
5870  using std::end;
5871 
5872  j.m_data.m_value.destroy(j.m_data.m_type);
5873  j.m_data.m_type = value_t::array;
5874  j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5875  j.set_parents();
5876  j.assert_invariant();
5877  }
5878 
5879  template<typename BasicJsonType>
5880  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5881  {
5882  j.m_data.m_value.destroy(j.m_data.m_type);
5883  j.m_data.m_type = value_t::array;
5884  j.m_data.m_value = value_t::array;
5885  j.m_data.m_value.array->reserve(arr.size());
5886  for (const bool x : arr)
5887  {
5888  j.m_data.m_value.array->push_back(x);
5889  j.set_parent(j.m_data.m_value.array->back());
5890  }
5891  j.assert_invariant();
5892  }
5893 
5894  template<typename BasicJsonType, typename T,
5896  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5897  {
5898  j.m_data.m_value.destroy(j.m_data.m_type);
5899  j.m_data.m_type = value_t::array;
5900  j.m_data.m_value = value_t::array;
5901  j.m_data.m_value.array->resize(arr.size());
5902  if (arr.size() > 0)
5903  {
5904  std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());
5905  }
5906  j.set_parents();
5907  j.assert_invariant();
5908  }
5909 };
5910 
5911 template<>
5913 {
5914  template<typename BasicJsonType>
5915  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5916  {
5917  j.m_data.m_value.destroy(j.m_data.m_type);
5918  j.m_data.m_type = value_t::object;
5919  j.m_data.m_value = obj;
5920  j.set_parents();
5921  j.assert_invariant();
5922  }
5923 
5924  template<typename BasicJsonType>
5925  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5926  {
5927  j.m_data.m_value.destroy(j.m_data.m_type);
5928  j.m_data.m_type = value_t::object;
5929  j.m_data.m_value = std::move(obj);
5930  j.set_parents();
5931  j.assert_invariant();
5932  }
5933 
5934  template < typename BasicJsonType, typename CompatibleObjectType,
5936  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5937  {
5938  using std::begin;
5939  using std::end;
5940 
5941  j.m_data.m_value.destroy(j.m_data.m_type);
5942  j.m_data.m_type = value_t::object;
5943  j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5944  j.set_parents();
5945  j.assert_invariant();
5946  }
5947 };
5948 
5950 // to_json //
5952 
5953 #ifdef JSON_HAS_CPP_17
5954 template<typename BasicJsonType, typename T,
5956 void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept
5957 {
5958  if (opt.has_value())
5959  {
5960  j = *opt;
5961  }
5962  else
5963  {
5964  j = nullptr;
5965  }
5966 }
5967 #endif
5968 
5969 template<typename BasicJsonType, typename T,
5971 inline void to_json(BasicJsonType& j, T b) noexcept
5972 {
5974 }
5975 
5976 template < typename BasicJsonType, typename BoolRef,
5977  enable_if_t <
5978  ((std::is_same<std::vector<bool>::reference, BoolRef>::value
5979  && !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
5980  || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
5981  && !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
5982  typename BasicJsonType::boolean_t >::value))
5984 inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
5985 {
5986  external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
5987 }
5988 
5989 template<typename BasicJsonType, typename CompatibleString,
5991 inline void to_json(BasicJsonType& j, const CompatibleString& s)
5992 {
5994 }
5995 
5996 template<typename BasicJsonType>
5997 inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5998 {
6000 }
6001 
6002 template<typename BasicJsonType, typename FloatType,
6004 inline void to_json(BasicJsonType& j, FloatType val) noexcept
6005 {
6006  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
6007 }
6008 
6009 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
6011 inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
6012 {
6013  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
6014 }
6015 
6016 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
6018 inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
6019 {
6020  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
6021 }
6022 
6023 #if !JSON_DISABLE_ENUM_SERIALIZATION
6024 template<typename BasicJsonType, typename EnumType,
6026 inline void to_json(BasicJsonType& j, EnumType e) noexcept
6027 {
6028  using underlying_type = typename std::underlying_type<EnumType>::type;
6030  external_constructor<integral_value_t>::construct(j, static_cast<underlying_type>(e));
6031 }
6032 #endif // JSON_DISABLE_ENUM_SERIALIZATION
6033 
6034 template<typename BasicJsonType>
6035 inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
6036 {
6038 }
6039 
6040 template < typename BasicJsonType, typename CompatibleArrayType,
6041  enable_if_t < is_compatible_array_type<BasicJsonType,
6042  CompatibleArrayType>::value&&
6047  int > = 0 >
6048 inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
6049 {
6051 }
6052 
6053 template<typename BasicJsonType>
6054 inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
6055 {
6057 }
6058 
6059 template<typename BasicJsonType, typename T,
6061 inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
6062 {
6064 }
6065 
6066 template<typename BasicJsonType>
6067 inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
6068 {
6070 }
6071 
6072 template < typename BasicJsonType, typename CompatibleObjectType,
6074 inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
6075 {
6077 }
6078 
6079 template<typename BasicJsonType>
6080 inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
6081 {
6083 }
6084 
6085 template <
6086  typename BasicJsonType, typename T, std::size_t N,
6087  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
6088  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
6089  int > = 0 >
6090 inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
6091 {
6093 }
6094 
6096 inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
6097 {
6098  j = { p.first, p.second };
6099 }
6100 
6101 // for https://github.com/nlohmann/json/pull/1134
6102 template<typename BasicJsonType, typename T,
6103  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
6104 inline void to_json(BasicJsonType& j, const T& b)
6105 {
6106  j = { {b.key(), b.value()} };
6107 }
6108 
6109 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
6110 inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
6111 {
6112  j = { std::get<Idx>(t)... };
6113 }
6114 
6115 template<typename BasicJsonType, typename Tuple>
6116 inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& /*unused*/, index_sequence<> /*unused*/)
6117 {
6118  using array_t = typename BasicJsonType::array_t;
6119  j = array_t();
6120 }
6121 
6123 inline void to_json(BasicJsonType& j, const T& t)
6124 {
6126 }
6127 
6128 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
6129 #if defined(__cpp_lib_char8_t)
6130 template<typename BasicJsonType, typename Tr, typename Allocator>
6131 inline void to_json(BasicJsonType& j, const std::basic_string<char8_t, Tr, Allocator>& s)
6132 {
6133  using OtherAllocator = typename std::allocator_traits<Allocator>::template rebind_alloc<char>;
6134  j = std::basic_string<char, std::char_traits<char>, OtherAllocator>(s.begin(), s.end(), s.get_allocator());
6135 }
6136 #endif
6137 
6138 template<typename BasicJsonType>
6139 inline void to_json(BasicJsonType& j, const std_fs::path& p)
6140 {
6141  // Returns either a std::string or a std::u8string depending whether library
6142  // support for char8_t is enabled.
6143  j = p.u8string();
6144 }
6145 #endif
6146 
6148 {
6149  template<typename BasicJsonType, typename T>
6150  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
6151  -> decltype(to_json(j, std::forward<T>(val)), void())
6152  {
6153  return to_json(j, std::forward<T>(val));
6154  }
6155 };
6156 } // namespace detail
6157 
6158 #ifndef JSON_HAS_CPP_17
6162 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
6163 {
6164 #endif
6165 JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
6167 #ifndef JSON_HAS_CPP_17
6168 } // namespace
6169 #endif
6170 
6172 
6173 // #include <nlohmann/detail/meta/identity_tag.hpp>
6174 
6175 
6177 
6179 template<typename ValueType, typename>
6181 {
6184  template<typename BasicJsonType, typename TargetType = ValueType>
6185  static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
6186  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
6187  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
6188  {
6189  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
6190  }
6191 
6194  template<typename BasicJsonType, typename TargetType = ValueType>
6195  static auto from_json(BasicJsonType && j) noexcept(
6196  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
6197  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
6198  {
6199  return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
6200  }
6201 
6204  template<typename BasicJsonType, typename TargetType = ValueType>
6205  static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
6206  noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
6207  -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
6208  {
6209  ::nlohmann::to_json(j, std::forward<TargetType>(val));
6210  }
6211 };
6212 
6214 
6215 // #include <nlohmann/byte_container_with_subtype.hpp>
6216 // __ _____ _____ _____
6217 // __| | __| | | | JSON for Modern C++
6218 // | | |__ | | | | | | version 3.12.0
6219 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6220 //
6221 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
6222 // SPDX-License-Identifier: MIT
6223 
6224 
6225 
6226 #include <cstdint> // uint8_t, uint64_t
6227 #include <tuple> // tie
6228 #include <utility> // move
6229 
6230 // #include <nlohmann/detail/abi_macros.hpp>
6231 
6232 
6234 
6237 template<typename BinaryType>
6238 class byte_container_with_subtype : public BinaryType
6239 {
6240  public:
6241  using container_type = BinaryType;
6243 
6246  : container_type()
6247  {}
6248 
6251  : container_type(b)
6252  {}
6253 
6255  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
6256  : container_type(std::move(b))
6257  {}
6258 
6260  byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
6261  : container_type(b)
6262  , m_subtype(subtype_)
6263  , m_has_subtype(true)
6264  {}
6265 
6267  byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
6268  : container_type(std::move(b))
6269  , m_subtype(subtype_)
6270  , m_has_subtype(true)
6271  {}
6272 
6274  {
6275  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
6276  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
6277  }
6278 
6280  {
6281  return !(rhs == *this);
6282  }
6283 
6286  void set_subtype(subtype_type subtype_) noexcept
6287  {
6288  m_subtype = subtype_;
6289  m_has_subtype = true;
6290  }
6291 
6294  constexpr subtype_type subtype() const noexcept
6295  {
6296  return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
6297  }
6298 
6301  constexpr bool has_subtype() const noexcept
6302  {
6303  return m_has_subtype;
6304  }
6305 
6308  void clear_subtype() noexcept
6309  {
6310  m_subtype = 0;
6311  m_has_subtype = false;
6312  }
6313 
6314  private:
6316  bool m_has_subtype = false;
6317 };
6318 
6320 
6321 // #include <nlohmann/detail/conversions/from_json.hpp>
6322 
6323 // #include <nlohmann/detail/conversions/to_json.hpp>
6324 
6325 // #include <nlohmann/detail/exceptions.hpp>
6326 
6327 // #include <nlohmann/detail/hash.hpp>
6328 // __ _____ _____ _____
6329 // __| | __| | | | JSON for Modern C++
6330 // | | |__ | | | | | | version 3.12.0
6331 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6332 //
6333 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
6334 // SPDX-License-Identifier: MIT
6335 
6336 
6337 
6338 #include <cstdint> // uint8_t
6339 #include <cstddef> // size_t
6340 #include <functional> // hash
6341 
6342 // #include <nlohmann/detail/abi_macros.hpp>
6343 
6344 // #include <nlohmann/detail/value_t.hpp>
6345 
6346 
6348 namespace detail
6349 {
6350 
6351 // boost::hash_combine
6352 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
6353 {
6354  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
6355  return seed;
6356 }
6357 
6369 template<typename BasicJsonType>
6370 std::size_t hash(const BasicJsonType& j)
6371 {
6372  using string_t = typename BasicJsonType::string_t;
6373  using number_integer_t = typename BasicJsonType::number_integer_t;
6374  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6375  using number_float_t = typename BasicJsonType::number_float_t;
6376 
6377  const auto type = static_cast<std::size_t>(j.type());
6378  switch (j.type())
6379  {
6380  case BasicJsonType::value_t::null:
6381  case BasicJsonType::value_t::discarded:
6382  {
6383  return combine(type, 0);
6384  }
6385 
6386  case BasicJsonType::value_t::object:
6387  {
6388  auto seed = combine(type, j.size());
6389  for (const auto& element : j.items())
6390  {
6391  const auto h = std::hash<string_t> {}(element.key());
6392  seed = combine(seed, h);
6393  seed = combine(seed, hash(element.value()));
6394  }
6395  return seed;
6396  }
6397 
6398  case BasicJsonType::value_t::array:
6399  {
6400  auto seed = combine(type, j.size());
6401  for (const auto& element : j)
6402  {
6403  seed = combine(seed, hash(element));
6404  }
6405  return seed;
6406  }
6407 
6408  case BasicJsonType::value_t::string:
6409  {
6410  const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
6411  return combine(type, h);
6412  }
6413 
6414  case BasicJsonType::value_t::boolean:
6415  {
6416  const auto h = std::hash<bool> {}(j.template get<bool>());
6417  return combine(type, h);
6418  }
6419 
6420  case BasicJsonType::value_t::number_integer:
6421  {
6422  const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
6423  return combine(type, h);
6424  }
6425 
6426  case BasicJsonType::value_t::number_unsigned:
6427  {
6428  const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
6429  return combine(type, h);
6430  }
6431 
6432  case BasicJsonType::value_t::number_float:
6433  {
6434  const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
6435  return combine(type, h);
6436  }
6437 
6438  case BasicJsonType::value_t::binary:
6439  {
6440  auto seed = combine(type, j.get_binary().size());
6441  const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
6442  seed = combine(seed, h);
6443  seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
6444  for (const auto byte : j.get_binary())
6445  {
6446  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
6447  }
6448  return seed;
6449  }
6450 
6451  default: // LCOV_EXCL_LINE
6452  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
6453  return 0; // LCOV_EXCL_LINE
6454  }
6455 }
6456 
6457 } // namespace detail
6459 
6460 // #include <nlohmann/detail/input/binary_reader.hpp>
6461 // __ _____ _____ _____
6462 // __| | __| | | | JSON for Modern C++
6463 // | | |__ | | | | | | version 3.12.0
6464 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6465 //
6466 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
6467 // SPDX-License-Identifier: MIT
6468 
6469 
6470 
6471 #include <algorithm> // generate_n
6472 #include <array> // array
6473 #include <cmath> // ldexp
6474 #include <cstddef> // size_t
6475 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6476 #include <cstdio> // snprintf
6477 #include <cstring> // memcpy
6478 #include <iterator> // back_inserter
6479 #include <limits> // numeric_limits
6480 #include <string> // char_traits, string
6481 #include <utility> // make_pair, move
6482 #include <vector> // vector
6483 #ifdef __cpp_lib_byteswap
6484  #include <bit> //byteswap
6485 #endif
6486 
6487 // #include <nlohmann/detail/exceptions.hpp>
6488 
6489 // #include <nlohmann/detail/input/input_adapters.hpp>
6490 // __ _____ _____ _____
6491 // __| | __| | | | JSON for Modern C++
6492 // | | |__ | | | | | | version 3.12.0
6493 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6494 //
6495 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
6496 // SPDX-License-Identifier: MIT
6497 
6498 
6499 
6500 #include <array> // array
6501 #include <cstddef> // size_t
6502 #include <cstring> // strlen
6503 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
6504 #include <memory> // shared_ptr, make_shared, addressof
6505 #include <numeric> // accumulate
6506 #include <streambuf> // streambuf
6507 #include <string> // string, char_traits
6508 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
6509 #include <utility> // pair, declval
6510 
6511 #ifndef JSON_NO_IO
6512  #include <cstdio> // FILE *
6513  #include <istream> // istream
6514 #endif // JSON_NO_IO
6515 
6516 // #include <nlohmann/detail/exceptions.hpp>
6517 
6518 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
6519 
6520 // #include <nlohmann/detail/macro_scope.hpp>
6521 
6522 // #include <nlohmann/detail/meta/type_traits.hpp>
6523 
6524 
6526 namespace detail
6527 {
6528 
6531 
6533 // input adapters //
6535 
6536 #ifndef JSON_NO_IO
6542 {
6543  public:
6544  using char_type = char;
6545 
6547  explicit file_input_adapter(std::FILE* f) noexcept
6548  : m_file(f)
6549  {
6550  JSON_ASSERT(m_file != nullptr);
6551  }
6552 
6553  // make class move-only
6557  file_input_adapter& operator=(file_input_adapter&&) = delete;
6558  ~file_input_adapter() = default;
6559 
6560  std::char_traits<char>::int_type get_character() noexcept
6561  {
6562  return std::fgetc(m_file);
6563  }
6564 
6565  // returns the number of characters successfully read
6566  template<class T>
6567  std::size_t get_elements(T* dest, std::size_t count = 1)
6568  {
6569  return fread(dest, 1, sizeof(T) * count, m_file);
6570  }
6571 
6572  private:
6574  std::FILE* m_file;
6575 };
6576 
6587 {
6588  public:
6589  using char_type = char;
6590 
6592  {
6593  // clear stream flags; we use underlying streambuf I/O, do not
6594  // maintain ifstream flags, except eof
6595  if (is != nullptr)
6596  {
6597  is->clear(is->rdstate() & std::ios::eofbit);
6598  }
6599  }
6600 
6601  explicit input_stream_adapter(std::istream& i)
6602  : is(&i), sb(i.rdbuf())
6603  {}
6604 
6605  // deleted because of pointer members
6609 
6611  : is(rhs.is), sb(rhs.sb)
6612  {
6613  rhs.is = nullptr;
6614  rhs.sb = nullptr;
6615  }
6616 
6617  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
6618  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
6619  // end up as the same value, e.g., 0xFFFFFFFF.
6620  std::char_traits<char>::int_type get_character()
6621  {
6622  auto res = sb->sbumpc();
6623  // set eof manually, as we don't use the istream interface.
6624  if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
6625  {
6626  is->clear(is->rdstate() | std::ios::eofbit);
6627  }
6628  return res;
6629  }
6630 
6631  template<class T>
6632  std::size_t get_elements(T* dest, std::size_t count = 1)
6633  {
6634  auto res = static_cast<std::size_t>(sb->sgetn(reinterpret_cast<char*>(dest), static_cast<std::streamsize>(count * sizeof(T))));
6635  if (JSON_HEDLEY_UNLIKELY(res < count * sizeof(T)))
6636  {
6637  is->clear(is->rdstate() | std::ios::eofbit);
6638  }
6639  return res;
6640  }
6641 
6642  private:
6644  std::istream* is = nullptr;
6645  std::streambuf* sb = nullptr;
6646 };
6647 #endif // JSON_NO_IO
6648 
6649 // General-purpose iterator-based adapter. It might not be as fast as
6650 // theoretically possible for some containers, but it is extremely versatile.
6651 template<typename IteratorType>
6653 {
6654  public:
6655  using char_type = typename std::iterator_traits<IteratorType>::value_type;
6656 
6657  iterator_input_adapter(IteratorType first, IteratorType last)
6658  : current(std::move(first)), end(std::move(last))
6659  {}
6660 
6662  {
6663  if (JSON_HEDLEY_LIKELY(current != end))
6664  {
6666  std::advance(current, 1);
6667  return result;
6668  }
6669 
6670  return char_traits<char_type>::eof();
6671  }
6672 
6673  // for general iterators, we cannot really do something better than falling back to processing the range one-by-one
6674  template<class T>
6675  std::size_t get_elements(T* dest, std::size_t count = 1)
6676  {
6677  auto* ptr = reinterpret_cast<char*>(dest);
6678  for (std::size_t read_index = 0; read_index < count * sizeof(T); ++read_index)
6679  {
6680  if (JSON_HEDLEY_LIKELY(current != end))
6681  {
6682  ptr[read_index] = static_cast<char>(*current);
6683  std::advance(current, 1);
6684  }
6685  else
6686  {
6687  return read_index;
6688  }
6689  }
6690  return count * sizeof(T);
6691  }
6692 
6693  private:
6694  IteratorType current;
6695  IteratorType end;
6696 
6697  template<typename BaseInputAdapter, size_t T>
6699 
6700  bool empty() const
6701  {
6702  return current == end;
6703  }
6704 };
6705 
6706 template<typename BaseInputAdapter, size_t T>
6708 
6709 template<typename BaseInputAdapter>
6710 struct wide_string_input_helper<BaseInputAdapter, 4>
6711 {
6712  // UTF-32
6713  static void fill_buffer(BaseInputAdapter& input,
6714  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6715  size_t& utf8_bytes_index,
6716  size_t& utf8_bytes_filled)
6717  {
6718  utf8_bytes_index = 0;
6719 
6720  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6721  {
6722  utf8_bytes[0] = std::char_traits<char>::eof();
6723  utf8_bytes_filled = 1;
6724  }
6725  else
6726  {
6727  // get the current character
6728  const auto wc = input.get_character();
6729 
6730  // UTF-32 to UTF-8 encoding
6731  if (wc < 0x80)
6732  {
6733  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6734  utf8_bytes_filled = 1;
6735  }
6736  else if (wc <= 0x7FF)
6737  {
6738  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
6739  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6740  utf8_bytes_filled = 2;
6741  }
6742  else if (wc <= 0xFFFF)
6743  {
6744  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
6745  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6746  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6747  utf8_bytes_filled = 3;
6748  }
6749  else if (wc <= 0x10FFFF)
6750  {
6751  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
6752  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
6753  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6754  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6755  utf8_bytes_filled = 4;
6756  }
6757  else
6758  {
6759  // unknown character
6760  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6761  utf8_bytes_filled = 1;
6762  }
6763  }
6764  }
6765 };
6766 
6767 template<typename BaseInputAdapter>
6768 struct wide_string_input_helper<BaseInputAdapter, 2>
6769 {
6770  // UTF-16
6771  static void fill_buffer(BaseInputAdapter& input,
6772  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6773  size_t& utf8_bytes_index,
6774  size_t& utf8_bytes_filled)
6775  {
6776  utf8_bytes_index = 0;
6777 
6778  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6779  {
6780  utf8_bytes[0] = std::char_traits<char>::eof();
6781  utf8_bytes_filled = 1;
6782  }
6783  else
6784  {
6785  // get the current character
6786  const auto wc = input.get_character();
6787 
6788  // UTF-16 to UTF-8 encoding
6789  if (wc < 0x80)
6790  {
6791  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6792  utf8_bytes_filled = 1;
6793  }
6794  else if (wc <= 0x7FF)
6795  {
6796  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
6797  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6798  utf8_bytes_filled = 2;
6799  }
6800  else if (0xD800 > wc || wc >= 0xE000)
6801  {
6802  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
6803  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6804  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6805  utf8_bytes_filled = 3;
6806  }
6807  else
6808  {
6809  if (JSON_HEDLEY_UNLIKELY(!input.empty()))
6810  {
6811  const auto wc2 = static_cast<unsigned int>(input.get_character());
6812  const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
6813  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
6814  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
6815  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
6816  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
6817  utf8_bytes_filled = 4;
6818  }
6819  else
6820  {
6821  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6822  utf8_bytes_filled = 1;
6823  }
6824  }
6825  }
6826  }
6827 };
6828 
6829 // Wraps another input adapter to convert wide character types into individual bytes.
6830 template<typename BaseInputAdapter, typename WideCharType>
6832 {
6833  public:
6834  using char_type = char;
6835 
6836  wide_string_input_adapter(BaseInputAdapter base)
6837  : base_adapter(base) {}
6838 
6839  typename std::char_traits<char>::int_type get_character() noexcept
6840  {
6841  // check if the buffer needs to be filled
6843  {
6844  fill_buffer<sizeof(WideCharType)>();
6845 
6848  }
6849 
6850  // use buffer
6853  return utf8_bytes[utf8_bytes_index++];
6854  }
6855 
6856  // parsing binary with wchar doesn't make sense, but since the parsing mode can be runtime, we need something here
6857  template<class T>
6858  std::size_t get_elements(T* /*dest*/, std::size_t /*count*/ = 1)
6859  {
6860  JSON_THROW(parse_error::create(112, 1, "wide string type cannot be interpreted as binary data", nullptr));
6861  }
6862 
6863  private:
6864  BaseInputAdapter base_adapter;
6865 
6866  template<size_t T>
6868  {
6870  }
6871 
6873  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
6874 
6876  std::size_t utf8_bytes_index = 0;
6878  std::size_t utf8_bytes_filled = 0;
6879 };
6880 
6881 template<typename IteratorType, typename Enable = void>
6883 {
6884  using iterator_type = IteratorType;
6885  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6887 
6888  static adapter_type create(IteratorType first, IteratorType last)
6889  {
6890  return adapter_type(std::move(first), std::move(last));
6891  }
6892 };
6893 
6894 template<typename T>
6896 {
6897  using value_type = typename std::iterator_traits<T>::value_type;
6898  enum
6899  {
6900  value = sizeof(value_type) > 1
6901  };
6902 };
6903 
6904 template<typename IteratorType>
6906 {
6907  using iterator_type = IteratorType;
6908  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6911 
6912  static adapter_type create(IteratorType first, IteratorType last)
6913  {
6914  return adapter_type(base_adapter_type(std::move(first), std::move(last)));
6915  }
6916 };
6917 
6918 // General purpose iterator-based input
6919 template<typename IteratorType>
6920 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
6921 {
6922  using factory_type = iterator_input_adapter_factory<IteratorType>;
6923  return factory_type::create(first, last);
6924 }
6925 
6926 // Convenience shorthand from container to iterator
6927 // Enables ADL on begin(container) and end(container)
6928 // Encloses the using declarations in namespace for not to leak them to outside scope
6929 
6930 namespace container_input_adapter_factory_impl
6931 {
6932 
6933 using std::begin;
6934 using std::end;
6935 
6936 template<typename ContainerType, typename Enable = void>
6938 
6939 template<typename ContainerType>
6940 struct container_input_adapter_factory< ContainerType,
6941  void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6942  {
6943  using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6944 
6945  static adapter_type create(const ContainerType& container)
6946 {
6947  return input_adapter(begin(container), end(container));
6948 }
6949  };
6950 
6951 } // namespace container_input_adapter_factory_impl
6952 
6953 template<typename ContainerType>
6955 {
6957 }
6958 
6959 // specialization for std::string
6960 using string_input_adapter_type = decltype(input_adapter(std::declval<std::string>()));
6961 
6962 #ifndef JSON_NO_IO
6963 // Special cases with fast paths
6964 inline file_input_adapter input_adapter(std::FILE* file)
6965 {
6966  if (file == nullptr)
6967  {
6968  JSON_THROW(parse_error::create(101, 0, "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
6969  }
6970  return file_input_adapter(file);
6971 }
6972 
6973 inline input_stream_adapter input_adapter(std::istream& stream)
6974 {
6975  return input_stream_adapter(stream);
6976 }
6977 
6978 inline input_stream_adapter input_adapter(std::istream&& stream)
6979 {
6980  return input_stream_adapter(stream);
6981 }
6982 #endif // JSON_NO_IO
6983 
6984 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6985 
6986 // Null-delimited strings, and the like.
6987 template < typename CharT,
6988  typename std::enable_if <
6992  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6993  int >::type = 0 >
6995 {
6996  if (b == nullptr)
6997  {
6998  JSON_THROW(parse_error::create(101, 0, "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
6999  }
7000  auto length = std::strlen(reinterpret_cast<const char*>(b));
7001  const auto* ptr = reinterpret_cast<const char*>(b);
7002  return input_adapter(ptr, ptr + length); // cppcheck-suppress[nullPointerArithmeticRedundantCheck]
7003 }
7004 
7005 template<typename T, std::size_t N>
7006 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)
7007 {
7008  return input_adapter(array, array + N);
7009 }
7010 
7011 // This class only handles inputs of input_buffer_adapter type.
7012 // It's required so that expressions like {ptr, len} can be implicitly cast
7013 // to the correct adapter.
7015 {
7016  public:
7017  template < typename CharT,
7018  typename std::enable_if <
7021  sizeof(typename std::remove_pointer<CharT>::type) == 1,
7022  int >::type = 0 >
7023  span_input_adapter(CharT b, std::size_t l)
7024  : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
7025 
7026  template<class IteratorType,
7027  typename std::enable_if<
7028  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
7029  int>::type = 0>
7030  span_input_adapter(IteratorType first, IteratorType last)
7031  : ia(input_adapter(first, last)) {}
7032 
7034  {
7035  return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
7036  }
7037 
7038  private:
7040 };
7041 
7042 } // namespace detail
7044 
7045 // #include <nlohmann/detail/input/json_sax.hpp>
7046 // __ _____ _____ _____
7047 // __| | __| | | | JSON for Modern C++
7048 // | | |__ | | | | | | version 3.12.0
7049 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
7050 //
7051 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
7052 // SPDX-License-Identifier: MIT
7053 
7054 
7055 
7056 #include <cstddef>
7057 #include <string> // string
7058 #include <type_traits> // enable_if_t
7059 #include <utility> // move
7060 #include <vector> // vector
7061 
7062 // #include <nlohmann/detail/exceptions.hpp>
7063 
7064 // #include <nlohmann/detail/input/lexer.hpp>
7065 // __ _____ _____ _____
7066 // __| | __| | | | JSON for Modern C++
7067 // | | |__ | | | | | | version 3.12.0
7068 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
7069 //
7070 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
7071 // SPDX-License-Identifier: MIT
7072 
7073 
7074 
7075 #include <array> // array
7076 #include <clocale> // localeconv
7077 #include <cstddef> // size_t
7078 #include <cstdio> // snprintf
7079 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7080 #include <initializer_list> // initializer_list
7081 #include <string> // char_traits, string
7082 #include <utility> // move
7083 #include <vector> // vector
7084 
7085 // #include <nlohmann/detail/input/input_adapters.hpp>
7086 
7087 // #include <nlohmann/detail/input/position_t.hpp>
7088 
7089 // #include <nlohmann/detail/macro_scope.hpp>
7090 
7091 // #include <nlohmann/detail/meta/type_traits.hpp>
7092 
7093 
7095 namespace detail
7096 {
7097 
7099 // lexer //
7101 
7102 template<typename BasicJsonType>
7104 {
7105  public:
7107  enum class token_type
7108  {
7109  uninitialized,
7110  literal_true,
7111  literal_false,
7112  literal_null,
7113  value_string,
7114  value_unsigned,
7115  value_integer,
7116  value_float,
7117  begin_array,
7118  begin_object,
7119  end_array,
7120  end_object,
7121  name_separator,
7122  value_separator,
7123  parse_error,
7124  end_of_input,
7126  };
7127 
7131  static const char* token_type_name(const token_type t) noexcept
7132  {
7133  switch (t)
7134  {
7136  return "<uninitialized>";
7138  return "true literal";
7140  return "false literal";
7142  return "null literal";
7144  return "string literal";
7148  return "number literal";
7150  return "'['";
7152  return "'{'";
7153  case token_type::end_array:
7154  return "']'";
7156  return "'}'";
7158  return "':'";
7160  return "','";
7162  return "<parse error>";
7164  return "end of input";
7166  return "'[', '{', or a literal";
7167  // LCOV_EXCL_START
7168  default: // catch non-enum values
7169  return "unknown token";
7170  // LCOV_EXCL_STOP
7171  }
7172  }
7173 };
7179 template<typename BasicJsonType, typename InputAdapterType>
7180 class lexer : public lexer_base<BasicJsonType>
7181 {
7182  using number_integer_t = typename BasicJsonType::number_integer_t;
7183  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7184  using number_float_t = typename BasicJsonType::number_float_t;
7186  using char_type = typename InputAdapterType::char_type;
7188 
7189  public:
7191 
7192  explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
7193  : ia(std::move(adapter))
7194  , ignore_comments(ignore_comments_)
7196  {}
7197 
7198  // deleted because of pointer members
7199  lexer(const lexer&) = delete;
7200  lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7201  lexer& operator=(lexer&) = delete;
7202  lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7203  ~lexer() = default;
7204 
7205  private:
7207  // locales
7209 
7212  static char get_decimal_point() noexcept
7213  {
7214  const auto* loc = localeconv();
7215  JSON_ASSERT(loc != nullptr);
7216  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7217  }
7218 
7220  // scan functions
7222 
7239  {
7240  // this function only makes sense after reading `\u`
7241  JSON_ASSERT(current == 'u');
7242  int codepoint = 0;
7243 
7244  const auto factors = { 12u, 8u, 4u, 0u };
7245  for (const auto factor : factors)
7246  {
7247  get();
7248 
7249  if (current >= '0' && current <= '9')
7250  {
7251  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7252  }
7253  else if (current >= 'A' && current <= 'F')
7254  {
7255  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7256  }
7257  else if (current >= 'a' && current <= 'f')
7258  {
7259  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7260  }
7261  else
7262  {
7263  return -1;
7264  }
7265  }
7266 
7267  JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7268  return codepoint;
7269  }
7270 
7286  bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7287  {
7288  JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7289  add(current);
7290 
7291  for (auto range = ranges.begin(); range != ranges.end(); ++range)
7292  {
7293  get();
7294  if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) // NOLINT(bugprone-inc-dec-in-conditions)
7295  {
7296  add(current);
7297  }
7298  else
7299  {
7300  error_message = "invalid string: ill-formed UTF-8 byte";
7301  return false;
7302  }
7303  }
7304 
7305  return true;
7306  }
7307 
7324  {
7325  // reset token_buffer (ignore opening quote)
7326  reset();
7327 
7328  // we entered the function by reading an open quote
7329  JSON_ASSERT(current == '\"');
7330 
7331  while (true)
7332  {
7333  // get the next character
7334  switch (get())
7335  {
7336  // end of file while parsing the string
7338  {
7339  error_message = "invalid string: missing closing quote";
7340  return token_type::parse_error;
7341  }
7342 
7343  // closing quote
7344  case '\"':
7345  {
7346  return token_type::value_string;
7347  }
7348 
7349  // escapes
7350  case '\\':
7351  {
7352  switch (get())
7353  {
7354  // quotation mark
7355  case '\"':
7356  add('\"');
7357  break;
7358  // reverse solidus
7359  case '\\':
7360  add('\\');
7361  break;
7362  // solidus
7363  case '/':
7364  add('/');
7365  break;
7366  // backspace
7367  case 'b':
7368  add('\b');
7369  break;
7370  // form feed
7371  case 'f':
7372  add('\f');
7373  break;
7374  // line feed
7375  case 'n':
7376  add('\n');
7377  break;
7378  // carriage return
7379  case 'r':
7380  add('\r');
7381  break;
7382  // tab
7383  case 't':
7384  add('\t');
7385  break;
7386 
7387  // unicode escapes
7388  case 'u':
7389  {
7390  const int codepoint1 = get_codepoint();
7391  int codepoint = codepoint1; // start with codepoint1
7392 
7393  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7394  {
7395  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7396  return token_type::parse_error;
7397  }
7398 
7399  // check if code point is a high surrogate
7400  if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7401  {
7402  // expect next \uxxxx entry
7403  if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7404  {
7405  const int codepoint2 = get_codepoint();
7406 
7407  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7408  {
7409  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7410  return token_type::parse_error;
7411  }
7412 
7413  // check if codepoint2 is a low surrogate
7414  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7415  {
7416  // overwrite codepoint
7417  codepoint = static_cast<int>(
7418  // high surrogate occupies the most significant 22 bits
7419  (static_cast<unsigned int>(codepoint1) << 10u)
7420  // low surrogate occupies the least significant 15 bits
7421  + static_cast<unsigned int>(codepoint2)
7422  // there is still the 0xD800, 0xDC00, and 0x10000 noise
7423  // in the result, so we have to subtract with:
7424  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7425  - 0x35FDC00u);
7426  }
7427  else
7428  {
7429  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7430  return token_type::parse_error;
7431  }
7432  }
7433  else
7434  {
7435  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7436  return token_type::parse_error;
7437  }
7438  }
7439  else
7440  {
7441  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7442  {
7443  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7444  return token_type::parse_error;
7445  }
7446  }
7447 
7448  // the result of the above calculation yields a proper codepoint
7449  JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7450 
7451  // translate codepoint into bytes
7452  if (codepoint < 0x80)
7453  {
7454  // 1-byte characters: 0xxxxxxx (ASCII)
7455  add(static_cast<char_int_type>(codepoint));
7456  }
7457  else if (codepoint <= 0x7FF)
7458  {
7459  // 2-byte characters: 110xxxxx 10xxxxxx
7460  add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7461  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7462  }
7463  else if (codepoint <= 0xFFFF)
7464  {
7465  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7466  add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7467  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7468  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7469  }
7470  else
7471  {
7472  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7473  add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7474  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7475  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7476  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7477  }
7478 
7479  break;
7480  }
7481 
7482  // other characters after escape
7483  default:
7484  error_message = "invalid string: forbidden character after backslash";
7485  return token_type::parse_error;
7486  }
7487 
7488  break;
7489  }
7490 
7491  // invalid control characters
7492  case 0x00:
7493  {
7494  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7495  return token_type::parse_error;
7496  }
7497 
7498  case 0x01:
7499  {
7500  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7501  return token_type::parse_error;
7502  }
7503 
7504  case 0x02:
7505  {
7506  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7507  return token_type::parse_error;
7508  }
7509 
7510  case 0x03:
7511  {
7512  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7513  return token_type::parse_error;
7514  }
7515 
7516  case 0x04:
7517  {
7518  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7519  return token_type::parse_error;
7520  }
7521 
7522  case 0x05:
7523  {
7524  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7525  return token_type::parse_error;
7526  }
7527 
7528  case 0x06:
7529  {
7530  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7531  return token_type::parse_error;
7532  }
7533 
7534  case 0x07:
7535  {
7536  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7537  return token_type::parse_error;
7538  }
7539 
7540  case 0x08:
7541  {
7542  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7543  return token_type::parse_error;
7544  }
7545 
7546  case 0x09:
7547  {
7548  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7549  return token_type::parse_error;
7550  }
7551 
7552  case 0x0A:
7553  {
7554  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7555  return token_type::parse_error;
7556  }
7557 
7558  case 0x0B:
7559  {
7560  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7561  return token_type::parse_error;
7562  }
7563 
7564  case 0x0C:
7565  {
7566  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7567  return token_type::parse_error;
7568  }
7569 
7570  case 0x0D:
7571  {
7572  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7573  return token_type::parse_error;
7574  }
7575 
7576  case 0x0E:
7577  {
7578  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7579  return token_type::parse_error;
7580  }
7581 
7582  case 0x0F:
7583  {
7584  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7585  return token_type::parse_error;
7586  }
7587 
7588  case 0x10:
7589  {
7590  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7591  return token_type::parse_error;
7592  }
7593 
7594  case 0x11:
7595  {
7596  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7597  return token_type::parse_error;
7598  }
7599 
7600  case 0x12:
7601  {
7602  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7603  return token_type::parse_error;
7604  }
7605 
7606  case 0x13:
7607  {
7608  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7609  return token_type::parse_error;
7610  }
7611 
7612  case 0x14:
7613  {
7614  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7615  return token_type::parse_error;
7616  }
7617 
7618  case 0x15:
7619  {
7620  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7621  return token_type::parse_error;
7622  }
7623 
7624  case 0x16:
7625  {
7626  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7627  return token_type::parse_error;
7628  }
7629 
7630  case 0x17:
7631  {
7632  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7633  return token_type::parse_error;
7634  }
7635 
7636  case 0x18:
7637  {
7638  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7639  return token_type::parse_error;
7640  }
7641 
7642  case 0x19:
7643  {
7644  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7645  return token_type::parse_error;
7646  }
7647 
7648  case 0x1A:
7649  {
7650  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7651  return token_type::parse_error;
7652  }
7653 
7654  case 0x1B:
7655  {
7656  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7657  return token_type::parse_error;
7658  }
7659 
7660  case 0x1C:
7661  {
7662  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7663  return token_type::parse_error;
7664  }
7665 
7666  case 0x1D:
7667  {
7668  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7669  return token_type::parse_error;
7670  }
7671 
7672  case 0x1E:
7673  {
7674  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7675  return token_type::parse_error;
7676  }
7677 
7678  case 0x1F:
7679  {
7680  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7681  return token_type::parse_error;
7682  }
7683 
7684  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7685  case 0x20:
7686  case 0x21:
7687  case 0x23:
7688  case 0x24:
7689  case 0x25:
7690  case 0x26:
7691  case 0x27:
7692  case 0x28:
7693  case 0x29:
7694  case 0x2A:
7695  case 0x2B:
7696  case 0x2C:
7697  case 0x2D:
7698  case 0x2E:
7699  case 0x2F:
7700  case 0x30:
7701  case 0x31:
7702  case 0x32:
7703  case 0x33:
7704  case 0x34:
7705  case 0x35:
7706  case 0x36:
7707  case 0x37:
7708  case 0x38:
7709  case 0x39:
7710  case 0x3A:
7711  case 0x3B:
7712  case 0x3C:
7713  case 0x3D:
7714  case 0x3E:
7715  case 0x3F:
7716  case 0x40:
7717  case 0x41:
7718  case 0x42:
7719  case 0x43:
7720  case 0x44:
7721  case 0x45:
7722  case 0x46:
7723  case 0x47:
7724  case 0x48:
7725  case 0x49:
7726  case 0x4A:
7727  case 0x4B:
7728  case 0x4C:
7729  case 0x4D:
7730  case 0x4E:
7731  case 0x4F:
7732  case 0x50:
7733  case 0x51:
7734  case 0x52:
7735  case 0x53:
7736  case 0x54:
7737  case 0x55:
7738  case 0x56:
7739  case 0x57:
7740  case 0x58:
7741  case 0x59:
7742  case 0x5A:
7743  case 0x5B:
7744  case 0x5D:
7745  case 0x5E:
7746  case 0x5F:
7747  case 0x60:
7748  case 0x61:
7749  case 0x62:
7750  case 0x63:
7751  case 0x64:
7752  case 0x65:
7753  case 0x66:
7754  case 0x67:
7755  case 0x68:
7756  case 0x69:
7757  case 0x6A:
7758  case 0x6B:
7759  case 0x6C:
7760  case 0x6D:
7761  case 0x6E:
7762  case 0x6F:
7763  case 0x70:
7764  case 0x71:
7765  case 0x72:
7766  case 0x73:
7767  case 0x74:
7768  case 0x75:
7769  case 0x76:
7770  case 0x77:
7771  case 0x78:
7772  case 0x79:
7773  case 0x7A:
7774  case 0x7B:
7775  case 0x7C:
7776  case 0x7D:
7777  case 0x7E:
7778  case 0x7F:
7779  {
7780  add(current);
7781  break;
7782  }
7783 
7784  // U+0080..U+07FF: bytes C2..DF 80..BF
7785  case 0xC2:
7786  case 0xC3:
7787  case 0xC4:
7788  case 0xC5:
7789  case 0xC6:
7790  case 0xC7:
7791  case 0xC8:
7792  case 0xC9:
7793  case 0xCA:
7794  case 0xCB:
7795  case 0xCC:
7796  case 0xCD:
7797  case 0xCE:
7798  case 0xCF:
7799  case 0xD0:
7800  case 0xD1:
7801  case 0xD2:
7802  case 0xD3:
7803  case 0xD4:
7804  case 0xD5:
7805  case 0xD6:
7806  case 0xD7:
7807  case 0xD8:
7808  case 0xD9:
7809  case 0xDA:
7810  case 0xDB:
7811  case 0xDC:
7812  case 0xDD:
7813  case 0xDE:
7814  case 0xDF:
7815  {
7816  if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7817  {
7818  return token_type::parse_error;
7819  }
7820  break;
7821  }
7822 
7823  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7824  case 0xE0:
7825  {
7826  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7827  {
7828  return token_type::parse_error;
7829  }
7830  break;
7831  }
7832 
7833  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7834  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7835  case 0xE1:
7836  case 0xE2:
7837  case 0xE3:
7838  case 0xE4:
7839  case 0xE5:
7840  case 0xE6:
7841  case 0xE7:
7842  case 0xE8:
7843  case 0xE9:
7844  case 0xEA:
7845  case 0xEB:
7846  case 0xEC:
7847  case 0xEE:
7848  case 0xEF:
7849  {
7850  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7851  {
7852  return token_type::parse_error;
7853  }
7854  break;
7855  }
7856 
7857  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7858  case 0xED:
7859  {
7860  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7861  {
7862  return token_type::parse_error;
7863  }
7864  break;
7865  }
7866 
7867  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7868  case 0xF0:
7869  {
7870  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7871  {
7872  return token_type::parse_error;
7873  }
7874  break;
7875  }
7876 
7877  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7878  case 0xF1:
7879  case 0xF2:
7880  case 0xF3:
7881  {
7882  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7883  {
7884  return token_type::parse_error;
7885  }
7886  break;
7887  }
7888 
7889  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7890  case 0xF4:
7891  {
7892  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7893  {
7894  return token_type::parse_error;
7895  }
7896  break;
7897  }
7898 
7899  // the remaining bytes (80..C1 and F5..FF) are ill-formed
7900  default:
7901  {
7902  error_message = "invalid string: ill-formed UTF-8 byte";
7903  return token_type::parse_error;
7904  }
7905  }
7906  }
7907  }
7908 
7914  {
7915  switch (get())
7916  {
7917  // single-line comments skip input until a newline or EOF is read
7918  case '/':
7919  {
7920  while (true)
7921  {
7922  switch (get())
7923  {
7924  case '\n':
7925  case '\r':
7927  case '\0':
7928  return true;
7929 
7930  default:
7931  break;
7932  }
7933  }
7934  }
7935 
7936  // multi-line comments skip input until */ is read
7937  case '*':
7938  {
7939  while (true)
7940  {
7941  switch (get())
7942  {
7944  case '\0':
7945  {
7946  error_message = "invalid comment; missing closing '*/'";
7947  return false;
7948  }
7949 
7950  case '*':
7951  {
7952  switch (get())
7953  {
7954  case '/':
7955  return true;
7956 
7957  default:
7958  {
7959  unget();
7960  continue;
7961  }
7962  }
7963  }
7964 
7965  default:
7966  continue;
7967  }
7968  }
7969  }
7970 
7971  // unexpected character after reading '/'
7972  default:
7973  {
7974  error_message = "invalid comment; expecting '/' or '*' after '/'";
7975  return false;
7976  }
7977  }
7978  }
7979 
7981  static void strtof(float& f, const char* str, char** endptr) noexcept
7982  {
7983  f = std::strtof(str, endptr);
7984  }
7985 
7987  static void strtof(double& f, const char* str, char** endptr) noexcept
7988  {
7989  f = std::strtod(str, endptr);
7990  }
7991 
7993  static void strtof(long double& f, const char* str, char** endptr) noexcept
7994  {
7995  f = std::strtold(str, endptr);
7996  }
7997 
8038  token_type scan_number() // lgtm [cpp/use-of-goto] `goto` is used in this function to implement the number-parsing state machine described above. By design, any finite input will eventually reach the "done" state or return token_type::parse_error. In each intermediate state, 1 byte of the input is appended to the token_buffer vector, and only the already initialized variables token_buffer, number_type, and error_message are manipulated.
8039  {
8040  // reset token_buffer to store the number's bytes
8041  reset();
8042 
8043  // the type of the parsed number; initially set to unsigned; will be
8044  // changed if minus sign, decimal point, or exponent is read
8045  token_type number_type = token_type::value_unsigned;
8046 
8047  // state (init): we just found out we need to scan a number
8048  switch (current)
8049  {
8050  case '-':
8051  {
8052  add(current);
8053  goto scan_number_minus;
8054  }
8055 
8056  case '0':
8057  {
8058  add(current);
8059  goto scan_number_zero;
8060  }
8061 
8062  case '1':
8063  case '2':
8064  case '3':
8065  case '4':
8066  case '5':
8067  case '6':
8068  case '7':
8069  case '8':
8070  case '9':
8071  {
8072  add(current);
8073  goto scan_number_any1;
8074  }
8075 
8076  // all other characters are rejected outside scan_number()
8077  default: // LCOV_EXCL_LINE
8078  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8079  }
8080 
8081 scan_number_minus:
8082  // state: we just parsed a leading minus sign
8083  number_type = token_type::value_integer;
8084  switch (get())
8085  {
8086  case '0':
8087  {
8088  add(current);
8089  goto scan_number_zero;
8090  }
8091 
8092  case '1':
8093  case '2':
8094  case '3':
8095  case '4':
8096  case '5':
8097  case '6':
8098  case '7':
8099  case '8':
8100  case '9':
8101  {
8102  add(current);
8103  goto scan_number_any1;
8104  }
8105 
8106  default:
8107  {
8108  error_message = "invalid number; expected digit after '-'";
8109  return token_type::parse_error;
8110  }
8111  }
8112 
8113 scan_number_zero:
8114  // state: we just parse a zero (maybe with a leading minus sign)
8115  switch (get())
8116  {
8117  case '.':
8118  {
8120  decimal_point_position = token_buffer.size() - 1;
8121  goto scan_number_decimal1;
8122  }
8123 
8124  case 'e':
8125  case 'E':
8126  {
8127  add(current);
8128  goto scan_number_exponent;
8129  }
8130 
8131  default:
8132  goto scan_number_done;
8133  }
8134 
8135 scan_number_any1:
8136  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8137  switch (get())
8138  {
8139  case '0':
8140  case '1':
8141  case '2':
8142  case '3':
8143  case '4':
8144  case '5':
8145  case '6':
8146  case '7':
8147  case '8':
8148  case '9':
8149  {
8150  add(current);
8151  goto scan_number_any1;
8152  }
8153 
8154  case '.':
8155  {
8157  decimal_point_position = token_buffer.size() - 1;
8158  goto scan_number_decimal1;
8159  }
8160 
8161  case 'e':
8162  case 'E':
8163  {
8164  add(current);
8165  goto scan_number_exponent;
8166  }
8167 
8168  default:
8169  goto scan_number_done;
8170  }
8171 
8172 scan_number_decimal1:
8173  // state: we just parsed a decimal point
8174  number_type = token_type::value_float;
8175  switch (get())
8176  {
8177  case '0':
8178  case '1':
8179  case '2':
8180  case '3':
8181  case '4':
8182  case '5':
8183  case '6':
8184  case '7':
8185  case '8':
8186  case '9':
8187  {
8188  add(current);
8189  goto scan_number_decimal2;
8190  }
8191 
8192  default:
8193  {
8194  error_message = "invalid number; expected digit after '.'";
8195  return token_type::parse_error;
8196  }
8197  }
8198 
8199 scan_number_decimal2:
8200  // we just parsed at least one number after a decimal point
8201  switch (get())
8202  {
8203  case '0':
8204  case '1':
8205  case '2':
8206  case '3':
8207  case '4':
8208  case '5':
8209  case '6':
8210  case '7':
8211  case '8':
8212  case '9':
8213  {
8214  add(current);
8215  goto scan_number_decimal2;
8216  }
8217 
8218  case 'e':
8219  case 'E':
8220  {
8221  add(current);
8222  goto scan_number_exponent;
8223  }
8224 
8225  default:
8226  goto scan_number_done;
8227  }
8228 
8229 scan_number_exponent:
8230  // we just parsed an exponent
8231  number_type = token_type::value_float;
8232  switch (get())
8233  {
8234  case '+':
8235  case '-':
8236  {
8237  add(current);
8238  goto scan_number_sign;
8239  }
8240 
8241  case '0':
8242  case '1':
8243  case '2':
8244  case '3':
8245  case '4':
8246  case '5':
8247  case '6':
8248  case '7':
8249  case '8':
8250  case '9':
8251  {
8252  add(current);
8253  goto scan_number_any2;
8254  }
8255 
8256  default:
8257  {
8258  error_message =
8259  "invalid number; expected '+', '-', or digit after exponent";
8260  return token_type::parse_error;
8261  }
8262  }
8263 
8264 scan_number_sign:
8265  // we just parsed an exponent sign
8266  switch (get())
8267  {
8268  case '0':
8269  case '1':
8270  case '2':
8271  case '3':
8272  case '4':
8273  case '5':
8274  case '6':
8275  case '7':
8276  case '8':
8277  case '9':
8278  {
8279  add(current);
8280  goto scan_number_any2;
8281  }
8282 
8283  default:
8284  {
8285  error_message = "invalid number; expected digit after exponent sign";
8286  return token_type::parse_error;
8287  }
8288  }
8289 
8290 scan_number_any2:
8291  // we just parsed a number after the exponent or exponent sign
8292  switch (get())
8293  {
8294  case '0':
8295  case '1':
8296  case '2':
8297  case '3':
8298  case '4':
8299  case '5':
8300  case '6':
8301  case '7':
8302  case '8':
8303  case '9':
8304  {
8305  add(current);
8306  goto scan_number_any2;
8307  }
8308 
8309  default:
8310  goto scan_number_done;
8311  }
8312 
8313 scan_number_done:
8314  // unget the character after the number (we only read it to know that
8315  // we are done scanning a number)
8316  unget();
8317 
8318  char* endptr = nullptr; // NOLINT(misc-const-correctness,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8319  errno = 0;
8320 
8321  // try to parse integers first and fall back to floats
8322  if (number_type == token_type::value_unsigned)
8323  {
8324  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8325 
8326  // we checked the number format before
8327  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8328 
8329  if (errno != ERANGE)
8330  {
8331  value_unsigned = static_cast<number_unsigned_t>(x);
8332  if (value_unsigned == x)
8333  {
8334  return token_type::value_unsigned;
8335  }
8336  }
8337  }
8338  else if (number_type == token_type::value_integer)
8339  {
8340  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8341 
8342  // we checked the number format before
8343  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8344 
8345  if (errno != ERANGE)
8346  {
8347  value_integer = static_cast<number_integer_t>(x);
8348  if (value_integer == x)
8349  {
8350  return token_type::value_integer;
8351  }
8352  }
8353  }
8354 
8355  // this code is reached if we parse a floating-point number or if an
8356  // integer conversion above failed
8357  strtof(value_float, token_buffer.data(), &endptr);
8358 
8359  // we checked the number format before
8360  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8361 
8362  return token_type::value_float;
8363  }
8364 
8371  token_type scan_literal(const char_type* literal_text, const std::size_t length,
8372  token_type return_type)
8373  {
8375  for (std::size_t i = 1; i < length; ++i)
8376  {
8378  {
8379  error_message = "invalid literal";
8380  return token_type::parse_error;
8381  }
8382  }
8383  return return_type;
8384  }
8385 
8387  // input management
8389 
8391  void reset() noexcept
8392  {
8393  token_buffer.clear();
8394  token_string.clear();
8395  decimal_point_position = std::string::npos;
8397  }
8398 
8399  /*
8400  @brief get next character from the input
8401 
8402  This function provides the interface to the used input adapter. It does
8403  not throw in case the input reached EOF, but returns a
8404  `char_traits<char>::eof()` in that case. Stores the scanned characters
8405  for use in error messages.
8406 
8407  @return character read from the input
8408  */
8410  {
8413 
8414  if (next_unget)
8415  {
8416  // only reset the next_unget variable and work with current
8417  next_unget = false;
8418  }
8419  else
8420  {
8421  current = ia.get_character();
8422  }
8423 
8425  {
8427  }
8428 
8429  if (current == '\n')
8430  {
8431  ++position.lines_read;
8433  }
8434 
8435  return current;
8436  }
8437 
8446  void unget()
8447  {
8448  next_unget = true;
8449 
8451 
8452  // in case we "unget" a newline, we have to also decrement the lines_read
8454  {
8455  if (position.lines_read > 0)
8456  {
8457  --position.lines_read;
8458  }
8459  }
8460  else
8461  {
8463  }
8464 
8466  {
8467  JSON_ASSERT(!token_string.empty());
8468  token_string.pop_back();
8469  }
8470  }
8471 
8474  {
8475  token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8476  }
8477 
8478  public:
8480  // value getters
8482 
8485  {
8486  return value_integer;
8487  }
8488 
8491  {
8492  return value_unsigned;
8493  }
8494 
8497  {
8498  return value_float;
8499  }
8500 
8503  {
8504  // translate decimal points from locale back to '.' (#4084)
8505  if (decimal_point_char != '.' && decimal_point_position != std::string::npos)
8506  {
8508  }
8509  return token_buffer;
8510  }
8511 
8513  // diagnostics
8515 
8517  constexpr position_t get_position() const noexcept
8518  {
8519  return position;
8520  }
8521 
8525  std::string get_token_string() const
8526  {
8527  // escape control characters
8528  std::string result;
8529  for (const auto c : token_string)
8530  {
8531  if (static_cast<unsigned char>(c) <= '\x1F')
8532  {
8533  // escape control characters
8534  std::array<char, 9> cs{{}};
8535  static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8536  result += cs.data();
8537  }
8538  else
8539  {
8540  // add character as is
8541  result.push_back(static_cast<std::string::value_type>(c));
8542  }
8543  }
8544 
8545  return result;
8546  }
8547 
8550  constexpr const char* get_error_message() const noexcept
8551  {
8552  return error_message;
8553  }
8554 
8556  // actual scanner
8558 
8563  bool skip_bom()
8564  {
8565  if (get() == 0xEF)
8566  {
8567  // check if we completely parse the BOM
8568  return get() == 0xBB && get() == 0xBF;
8569  }
8570 
8571  // the first character is not the beginning of the BOM; unget it to
8572  // process is later
8573  unget();
8574  return true;
8575  }
8576 
8578  {
8579  do
8580  {
8581  get();
8582  }
8583  while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8584  }
8585 
8587  {
8588  // initially, skip the BOM
8589  if (position.chars_read_total == 0 && !skip_bom())
8590  {
8591  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8592  return token_type::parse_error;
8593  }
8594 
8595  // read the next character and ignore whitespace
8596  skip_whitespace();
8597 
8598  // ignore comments
8599  while (ignore_comments && current == '/')
8600  {
8601  if (!scan_comment())
8602  {
8603  return token_type::parse_error;
8604  }
8605 
8606  // skip following whitespace
8607  skip_whitespace();
8608  }
8609 
8610  switch (current)
8611  {
8612  // structural characters
8613  case '[':
8614  return token_type::begin_array;
8615  case ']':
8616  return token_type::end_array;
8617  case '{':
8618  return token_type::begin_object;
8619  case '}':
8620  return token_type::end_object;
8621  case ':':
8622  return token_type::name_separator;
8623  case ',':
8624  return token_type::value_separator;
8625 
8626  // literals
8627  case 't':
8628  {
8629  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')}};
8630  return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8631  }
8632  case 'f':
8633  {
8634  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')}};
8635  return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8636  }
8637  case 'n':
8638  {
8639  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')}};
8640  return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8641  }
8642 
8643  // string
8644  case '\"':
8645  return scan_string();
8646 
8647  // number
8648  case '-':
8649  case '0':
8650  case '1':
8651  case '2':
8652  case '3':
8653  case '4':
8654  case '5':
8655  case '6':
8656  case '7':
8657  case '8':
8658  case '9':
8659  return scan_number();
8660 
8661  // end of input (the null byte is needed when parsing from
8662  // string literals)
8663  case '\0':
8665  return token_type::end_of_input;
8666 
8667  // error
8668  default:
8669  error_message = "invalid literal";
8670  return token_type::parse_error;
8671  }
8672  }
8673 
8674  private:
8676  InputAdapterType ia;
8677 
8679  const bool ignore_comments = false;
8680 
8683 
8685  bool next_unget = false;
8686 
8689 
8691  std::vector<char_type> token_string {};
8692 
8695 
8697  const char* error_message = "";
8698 
8699  // number values
8703 
8707  std::size_t decimal_point_position = std::string::npos;
8708 };
8709 
8710 } // namespace detail
8712 
8713 // #include <nlohmann/detail/macro_scope.hpp>
8714 
8715 // #include <nlohmann/detail/string_concat.hpp>
8716 
8718 
8727 template<typename BasicJsonType>
8728 struct json_sax
8729 {
8730  using number_integer_t = typename BasicJsonType::number_integer_t;
8731  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8732  using number_float_t = typename BasicJsonType::number_float_t;
8734  using binary_t = typename BasicJsonType::binary_t;
8735 
8740  virtual bool null() = 0;
8741 
8747  virtual bool boolean(bool val) = 0;
8748 
8754  virtual bool number_integer(number_integer_t val) = 0;
8755 
8761  virtual bool number_unsigned(number_unsigned_t val) = 0;
8762 
8769  virtual bool number_float(number_float_t val, const string_t& s) = 0;
8770 
8777  virtual bool string(string_t& val) = 0;
8778 
8785  virtual bool binary(binary_t& val) = 0;
8786 
8793  virtual bool start_object(std::size_t elements) = 0;
8794 
8801  virtual bool key(string_t& val) = 0;
8802 
8807  virtual bool end_object() = 0;
8808 
8815  virtual bool start_array(std::size_t elements) = 0;
8816 
8821  virtual bool end_array() = 0;
8822 
8830  virtual bool parse_error(std::size_t position,
8831  const std::string& last_token,
8832  const detail::exception& ex) = 0;
8833 
8834  json_sax() = default;
8835  json_sax(const json_sax&) = default;
8836  json_sax(json_sax&&) noexcept = default;
8837  json_sax& operator=(const json_sax&) = default;
8838  json_sax& operator=(json_sax&&) noexcept = default;
8839  virtual ~json_sax() = default;
8840 };
8841 
8842 namespace detail
8843 {
8844 constexpr std::size_t unknown_size()
8845 {
8846  return (std::numeric_limits<std::size_t>::max)();
8847 }
8848 
8862 template<typename BasicJsonType, typename InputAdapterType>
8864 {
8865  public:
8866  using number_integer_t = typename BasicJsonType::number_integer_t;
8867  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8868  using number_float_t = typename BasicJsonType::number_float_t;
8870  using binary_t = typename BasicJsonType::binary_t;
8872 
8878  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true, lexer_t* lexer_ = nullptr)
8879  : root(r), allow_exceptions(allow_exceptions_), m_lexer_ref(lexer_)
8880  {}
8881 
8882  // make class move-only
8884  json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8886  json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8888 
8889  bool null()
8890  {
8891  handle_value(nullptr);
8892  return true;
8893  }
8894 
8895  bool boolean(bool val)
8896  {
8897  handle_value(val);
8898  return true;
8899  }
8900 
8902  {
8903  handle_value(val);
8904  return true;
8905  }
8906 
8908  {
8909  handle_value(val);
8910  return true;
8911  }
8912 
8913  bool number_float(number_float_t val, const string_t& /*unused*/)
8914  {
8915  handle_value(val);
8916  return true;
8917  }
8918 
8919  bool string(string_t& val)
8920  {
8921  handle_value(val);
8922  return true;
8923  }
8924 
8925  bool binary(binary_t& val)
8926  {
8927  handle_value(std::move(val));
8928  return true;
8929  }
8930 
8931  bool start_object(std::size_t len)
8932  {
8933  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
8934 
8935 #if JSON_DIAGNOSTIC_POSITIONS
8936  // Manually set the start position of the object here.
8937  // Ensure this is after the call to handle_value to ensure correct start position.
8938  if (m_lexer_ref)
8939  {
8940  // Lexer has read the first character of the object, so
8941  // subtract 1 from the position to get the correct start position.
8942  ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
8943  }
8944 #endif
8945 
8946  if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
8947  {
8948  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
8949  }
8950 
8951  return true;
8952  }
8953 
8954  bool key(string_t& val)
8955  {
8956  JSON_ASSERT(!ref_stack.empty());
8957  JSON_ASSERT(ref_stack.back()->is_object());
8958 
8959  // add null at the given key and store the reference for later
8960  object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val));
8961  return true;
8962  }
8963 
8964  bool end_object()
8965  {
8966  JSON_ASSERT(!ref_stack.empty());
8967  JSON_ASSERT(ref_stack.back()->is_object());
8968 
8969 #if JSON_DIAGNOSTIC_POSITIONS
8970  if (m_lexer_ref)
8971  {
8972  // Lexer's position is past the closing brace, so set that as the end position.
8973  ref_stack.back()->end_position = m_lexer_ref->get_position();
8974  }
8975 #endif
8976 
8977  ref_stack.back()->set_parents();
8978  ref_stack.pop_back();
8979  return true;
8980  }
8981 
8982  bool start_array(std::size_t len)
8983  {
8984  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
8985 
8986 #if JSON_DIAGNOSTIC_POSITIONS
8987  // Manually set the start position of the array here.
8988  // Ensure this is after the call to handle_value to ensure correct start position.
8989  if (m_lexer_ref)
8990  {
8991  ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
8992  }
8993 #endif
8994 
8995  if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
8996  {
8997  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
8998  }
8999 
9000  return true;
9001  }
9002 
9003  bool end_array()
9004  {
9005  JSON_ASSERT(!ref_stack.empty());
9006  JSON_ASSERT(ref_stack.back()->is_array());
9007 
9008 #if JSON_DIAGNOSTIC_POSITIONS
9009  if (m_lexer_ref)
9010  {
9011  // Lexer's position is past the closing bracket, so set that as the end position.
9012  ref_stack.back()->end_position = m_lexer_ref->get_position();
9013  }
9014 #endif
9015 
9016  ref_stack.back()->set_parents();
9017  ref_stack.pop_back();
9018  return true;
9019  }
9020 
9021  template<class Exception>
9022  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
9023  const Exception& ex)
9024  {
9025  errored = true;
9026  static_cast<void>(ex);
9027  if (allow_exceptions)
9028  {
9029  JSON_THROW(ex);
9030  }
9031  return false;
9032  }
9033 
9034  constexpr bool is_errored() const
9035  {
9036  return errored;
9037  }
9038 
9039  private:
9040 
9041 #if JSON_DIAGNOSTIC_POSITIONS
9042  void handle_diagnostic_positions_for_json_value(BasicJsonType& v)
9043  {
9044  if (m_lexer_ref)
9045  {
9046  // Lexer has read past the current field value, so set the end position to the current position.
9047  // The start position will be set below based on the length of the string representation
9048  // of the value.
9049  v.end_position = m_lexer_ref->get_position();
9050 
9051  switch (v.type())
9052  {
9053  case value_t::boolean:
9054  {
9055  // 4 and 5 are the string length of "true" and "false"
9056  v.start_position = v.end_position - (v.m_data.m_value.boolean ? 4 : 5);
9057  break;
9058  }
9059 
9060  case value_t::null:
9061  {
9062  // 4 is the string length of "null"
9063  v.start_position = v.end_position - 4;
9064  break;
9065  }
9066 
9067  case value_t::string:
9068  {
9069  // include the length of the quotes, which is 2
9070  v.start_position = v.end_position - v.m_data.m_value.string->size() - 2;
9071  break;
9072  }
9073 
9074  // As we handle the start and end positions for values created during parsing,
9075  // we do not expect the following value type to be called. Regardless, set the positions
9076  // in case this is created manually or through a different constructor. Exclude from lcov
9077  // since the exact condition of this switch is esoteric.
9078  // LCOV_EXCL_START
9079  case value_t::discarded:
9080  {
9081  v.end_position = std::string::npos;
9082  v.start_position = v.end_position;
9083  break;
9084  }
9085  // LCOV_EXCL_STOP
9086  case value_t::binary:
9087  case value_t::number_integer:
9088  case value_t::number_unsigned:
9089  case value_t::number_float:
9090  {
9091  v.start_position = v.end_position - m_lexer_ref->get_string().size();
9092  break;
9093  }
9094  case value_t::object:
9095  case value_t::array:
9096  {
9097  // object and array are handled in start_object() and start_array() handlers
9098  // skip setting the values here.
9099  break;
9100  }
9101  default: // LCOV_EXCL_LINE
9102  // Handle all possible types discretely, default handler should never be reached.
9103  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert,-warnings-as-errors) LCOV_EXCL_LINE
9104  }
9105  }
9106  }
9107 #endif
9108 
9115  template<typename Value>
9117  BasicJsonType* handle_value(Value&& v)
9118  {
9119  if (ref_stack.empty())
9120  {
9121  root = BasicJsonType(std::forward<Value>(v));
9122 
9123 #if JSON_DIAGNOSTIC_POSITIONS
9124  handle_diagnostic_positions_for_json_value(root);
9125 #endif
9126 
9127  return &root;
9128  }
9129 
9130  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
9131 
9132  if (ref_stack.back()->is_array())
9133  {
9134  ref_stack.back()->m_data.m_value.array->emplace_back(std::forward<Value>(v));
9135 
9136 #if JSON_DIAGNOSTIC_POSITIONS
9137  handle_diagnostic_positions_for_json_value(ref_stack.back()->m_data.m_value.array->back());
9138 #endif
9139 
9140  return &(ref_stack.back()->m_data.m_value.array->back());
9141  }
9142 
9143  JSON_ASSERT(ref_stack.back()->is_object());
9144  JSON_ASSERT(object_element);
9145  *object_element = BasicJsonType(std::forward<Value>(v));
9146 
9147 #if JSON_DIAGNOSTIC_POSITIONS
9148  handle_diagnostic_positions_for_json_value(*object_element);
9149 #endif
9150 
9151  return object_element;
9152  }
9153 
9155  BasicJsonType& root;
9157  std::vector<BasicJsonType*> ref_stack {};
9159  BasicJsonType* object_element = nullptr;
9161  bool errored = false;
9163  const bool allow_exceptions = true;
9165  lexer_t* m_lexer_ref = nullptr;
9166 };
9167 
9168 template<typename BasicJsonType, typename InputAdapterType>
9170 {
9171  public:
9172  using number_integer_t = typename BasicJsonType::number_integer_t;
9173  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9174  using number_float_t = typename BasicJsonType::number_float_t;
9176  using binary_t = typename BasicJsonType::binary_t;
9180 
9182  parser_callback_t cb,
9183  const bool allow_exceptions_ = true,
9184  lexer_t* lexer_ = nullptr)
9185  : root(r), callback(std::move(cb)), allow_exceptions(allow_exceptions_), m_lexer_ref(lexer_)
9186  {
9187  keep_stack.push_back(true);
9188  }
9189 
9190  // make class move-only
9192  json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9194  json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9196 
9197  bool null()
9198  {
9199  handle_value(nullptr);
9200  return true;
9201  }
9202 
9203  bool boolean(bool val)
9204  {
9205  handle_value(val);
9206  return true;
9207  }
9208 
9210  {
9211  handle_value(val);
9212  return true;
9213  }
9214 
9216  {
9217  handle_value(val);
9218  return true;
9219  }
9220 
9221  bool number_float(number_float_t val, const string_t& /*unused*/)
9222  {
9223  handle_value(val);
9224  return true;
9225  }
9226 
9227  bool string(string_t& val)
9228  {
9229  handle_value(val);
9230  return true;
9231  }
9232 
9233  bool binary(binary_t& val)
9234  {
9235  handle_value(std::move(val));
9236  return true;
9237  }
9238 
9239  bool start_object(std::size_t len)
9240  {
9241  // check callback for object start
9242  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
9243  keep_stack.push_back(keep);
9244 
9245  auto val = handle_value(BasicJsonType::value_t::object, true);
9246  ref_stack.push_back(val.second);
9247 
9248  if (ref_stack.back())
9249  {
9250 
9251 #if JSON_DIAGNOSTIC_POSITIONS
9252  // Manually set the start position of the object here.
9253  // Ensure this is after the call to handle_value to ensure correct start position.
9254  if (m_lexer_ref)
9255  {
9256  // Lexer has read the first character of the object, so
9257  // subtract 1 from the position to get the correct start position.
9258  ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
9259  }
9260 #endif
9261 
9262  // check object limit
9263  if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
9264  {
9265  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
9266  }
9267  }
9268  return true;
9269  }
9270 
9271  bool key(string_t& val)
9272  {
9273  BasicJsonType k = BasicJsonType(val);
9274 
9275  // check callback for the key
9276  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
9277  key_keep_stack.push_back(keep);
9278 
9279  // add discarded value at the given key and store the reference for later
9280  if (keep && ref_stack.back())
9281  {
9282  object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded);
9283  }
9284 
9285  return true;
9286  }
9287 
9288  bool end_object()
9289  {
9290  if (ref_stack.back())
9291  {
9292  if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
9293  {
9294  // discard object
9295  *ref_stack.back() = discarded;
9296 
9297 #if JSON_DIAGNOSTIC_POSITIONS
9298  // Set start/end positions for discarded object.
9299  handle_diagnostic_positions_for_json_value(*ref_stack.back());
9300 #endif
9301  }
9302  else
9303  {
9304 
9305 #if JSON_DIAGNOSTIC_POSITIONS
9306  if (m_lexer_ref)
9307  {
9308  // Lexer's position is past the closing brace, so set that as the end position.
9309  ref_stack.back()->end_position = m_lexer_ref->get_position();
9310  }
9311 #endif
9312 
9313  ref_stack.back()->set_parents();
9314  }
9315  }
9316 
9317  JSON_ASSERT(!ref_stack.empty());
9318  JSON_ASSERT(!keep_stack.empty());
9319  ref_stack.pop_back();
9320  keep_stack.pop_back();
9321 
9322  if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
9323  {
9324  // remove discarded value
9325  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
9326  {
9327  if (it->is_discarded())
9328  {
9329  ref_stack.back()->erase(it);
9330  break;
9331  }
9332  }
9333  }
9334 
9335  return true;
9336  }
9337 
9338  bool start_array(std::size_t len)
9339  {
9340  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
9341  keep_stack.push_back(keep);
9342 
9343  auto val = handle_value(BasicJsonType::value_t::array, true);
9344  ref_stack.push_back(val.second);
9345 
9346  if (ref_stack.back())
9347  {
9348 
9349 #if JSON_DIAGNOSTIC_POSITIONS
9350  // Manually set the start position of the array here.
9351  // Ensure this is after the call to handle_value to ensure correct start position.
9352  if (m_lexer_ref)
9353  {
9354  // Lexer has read the first character of the array, so
9355  // subtract 1 from the position to get the correct start position.
9356  ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
9357  }
9358 #endif
9359 
9360  // check array limit
9361  if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
9362  {
9363  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
9364  }
9365  }
9366 
9367  return true;
9368  }
9369 
9370  bool end_array()
9371  {
9372  bool keep = true;
9373 
9374  if (ref_stack.back())
9375  {
9376  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
9377  if (keep)
9378  {
9379 
9380 #if JSON_DIAGNOSTIC_POSITIONS
9381  if (m_lexer_ref)
9382  {
9383  // Lexer's position is past the closing bracket, so set that as the end position.
9384  ref_stack.back()->end_position = m_lexer_ref->get_position();
9385  }
9386 #endif
9387 
9388  ref_stack.back()->set_parents();
9389  }
9390  else
9391  {
9392  // discard array
9393  *ref_stack.back() = discarded;
9394 
9395 #if JSON_DIAGNOSTIC_POSITIONS
9396  // Set start/end positions for discarded array.
9397  handle_diagnostic_positions_for_json_value(*ref_stack.back());
9398 #endif
9399  }
9400  }
9401 
9402  JSON_ASSERT(!ref_stack.empty());
9403  JSON_ASSERT(!keep_stack.empty());
9404  ref_stack.pop_back();
9405  keep_stack.pop_back();
9406 
9407  // remove discarded value
9408  if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
9409  {
9410  ref_stack.back()->m_data.m_value.array->pop_back();
9411  }
9412 
9413  return true;
9414  }
9415 
9416  template<class Exception>
9417  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
9418  const Exception& ex)
9419  {
9420  errored = true;
9421  static_cast<void>(ex);
9422  if (allow_exceptions)
9423  {
9424  JSON_THROW(ex);
9425  }
9426  return false;
9427  }
9428 
9429  constexpr bool is_errored() const
9430  {
9431  return errored;
9432  }
9433 
9434  private:
9435 
9436 #if JSON_DIAGNOSTIC_POSITIONS
9437  void handle_diagnostic_positions_for_json_value(BasicJsonType& v)
9438  {
9439  if (m_lexer_ref)
9440  {
9441  // Lexer has read past the current field value, so set the end position to the current position.
9442  // The start position will be set below based on the length of the string representation
9443  // of the value.
9444  v.end_position = m_lexer_ref->get_position();
9445 
9446  switch (v.type())
9447  {
9448  case value_t::boolean:
9449  {
9450  // 4 and 5 are the string length of "true" and "false"
9451  v.start_position = v.end_position - (v.m_data.m_value.boolean ? 4 : 5);
9452  break;
9453  }
9454 
9455  case value_t::null:
9456  {
9457  // 4 is the string length of "null"
9458  v.start_position = v.end_position - 4;
9459  break;
9460  }
9461 
9462  case value_t::string:
9463  {
9464  // include the length of the quotes, which is 2
9465  v.start_position = v.end_position - v.m_data.m_value.string->size() - 2;
9466  break;
9467  }
9468 
9469  case value_t::discarded:
9470  {
9471  v.end_position = std::string::npos;
9472  v.start_position = v.end_position;
9473  break;
9474  }
9475 
9476  case value_t::binary:
9477  case value_t::number_integer:
9478  case value_t::number_unsigned:
9479  case value_t::number_float:
9480  {
9481  v.start_position = v.end_position - m_lexer_ref->get_string().size();
9482  break;
9483  }
9484 
9485  case value_t::object:
9486  case value_t::array:
9487  {
9488  // object and array are handled in start_object() and start_array() handlers
9489  // skip setting the values here.
9490  break;
9491  }
9492  default: // LCOV_EXCL_LINE
9493  // Handle all possible types discretely, default handler should never be reached.
9494  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert,-warnings-as-errors) LCOV_EXCL_LINE
9495  }
9496  }
9497  }
9498 #endif
9499 
9515  template<typename Value>
9516  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
9517  {
9518  JSON_ASSERT(!keep_stack.empty());
9519 
9520  // do not handle this value if we know it would be added to a discarded
9521  // container
9522  if (!keep_stack.back())
9523  {
9524  return {false, nullptr};
9525  }
9526 
9527  // create value
9528  auto value = BasicJsonType(std::forward<Value>(v));
9529 
9530 #if JSON_DIAGNOSTIC_POSITIONS
9531  handle_diagnostic_positions_for_json_value(value);
9532 #endif
9533 
9534  // check callback
9535  const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
9536 
9537  // do not handle this value if we just learnt it shall be discarded
9538  if (!keep)
9539  {
9540  return {false, nullptr};
9541  }
9542 
9543  if (ref_stack.empty())
9544  {
9545  root = std::move(value);
9546  return {true, & root};
9547  }
9548 
9549  // skip this value if we already decided to skip the parent
9550  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
9551  if (!ref_stack.back())
9552  {
9553  return {false, nullptr};
9554  }
9555 
9556  // we now only expect arrays and objects
9557  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
9558 
9559  // array
9560  if (ref_stack.back()->is_array())
9561  {
9562  ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));
9563  return {true, & (ref_stack.back()->m_data.m_value.array->back())};
9564  }
9565 
9566  // object
9567  JSON_ASSERT(ref_stack.back()->is_object());
9568  // check if we should store an element for the current key
9569  JSON_ASSERT(!key_keep_stack.empty());
9570  const bool store_element = key_keep_stack.back();
9571  key_keep_stack.pop_back();
9572 
9573  if (!store_element)
9574  {
9575  return {false, nullptr};
9576  }
9577 
9578  JSON_ASSERT(object_element);
9579  *object_element = std::move(value);
9580  return {true, object_element};
9581  }
9582 
9584  BasicJsonType& root;
9586  std::vector<BasicJsonType*> ref_stack {};
9588  std::vector<bool> keep_stack {}; // NOLINT(readability-redundant-member-init)
9590  std::vector<bool> key_keep_stack {}; // NOLINT(readability-redundant-member-init)
9592  BasicJsonType* object_element = nullptr;
9594  bool errored = false;
9596  const parser_callback_t callback = nullptr;
9598  const bool allow_exceptions = true;
9600  BasicJsonType discarded = BasicJsonType::value_t::discarded;
9602  lexer_t* m_lexer_ref = nullptr;
9603 };
9604 
9605 template<typename BasicJsonType>
9607 {
9608  public:
9609  using number_integer_t = typename BasicJsonType::number_integer_t;
9610  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9611  using number_float_t = typename BasicJsonType::number_float_t;
9613  using binary_t = typename BasicJsonType::binary_t;
9614 
9615  bool null()
9616  {
9617  return true;
9618  }
9619 
9620  bool boolean(bool /*unused*/)
9621  {
9622  return true;
9623  }
9624 
9626  {
9627  return true;
9628  }
9629 
9631  {
9632  return true;
9633  }
9634 
9635  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
9636  {
9637  return true;
9638  }
9639 
9640  bool string(string_t& /*unused*/)
9641  {
9642  return true;
9643  }
9644 
9645  bool binary(binary_t& /*unused*/)
9646  {
9647  return true;
9648  }
9649 
9650  bool start_object(std::size_t /*unused*/ = detail::unknown_size())
9651  {
9652  return true;
9653  }
9654 
9655  bool key(string_t& /*unused*/)
9656  {
9657  return true;
9658  }
9659 
9660  bool end_object()
9661  {
9662  return true;
9663  }
9664 
9665  bool start_array(std::size_t /*unused*/ = detail::unknown_size())
9666  {
9667  return true;
9668  }
9669 
9670  bool end_array()
9671  {
9672  return true;
9673  }
9674 
9675  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
9676  {
9677  return false;
9678  }
9679 };
9680 
9681 } // namespace detail
9683 
9684 // #include <nlohmann/detail/input/lexer.hpp>
9685 
9686 // #include <nlohmann/detail/macro_scope.hpp>
9687 
9688 // #include <nlohmann/detail/meta/is_sax.hpp>
9689 // __ _____ _____ _____
9690 // __| | __| | | | JSON for Modern C++
9691 // | | |__ | | | | | | version 3.12.0
9692 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
9693 //
9694 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
9695 // SPDX-License-Identifier: MIT
9696 
9697 
9698 
9699 #include <cstdint> // size_t
9700 #include <utility> // declval
9701 #include <string> // string
9702 
9703 // #include <nlohmann/detail/abi_macros.hpp>
9704 
9705 // #include <nlohmann/detail/meta/detected.hpp>
9706 
9707 // #include <nlohmann/detail/meta/type_traits.hpp>
9708 
9709 
9711 namespace detail
9712 {
9713 
9714 template<typename T>
9715 using null_function_t = decltype(std::declval<T&>().null());
9716 
9717 template<typename T>
9719  decltype(std::declval<T&>().boolean(std::declval<bool>()));
9720 
9721 template<typename T, typename Integer>
9723  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
9724 
9725 template<typename T, typename Unsigned>
9727  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
9728 
9729 template<typename T, typename Float, typename String>
9730 using number_float_function_t = decltype(std::declval<T&>().number_float(
9731  std::declval<Float>(), std::declval<const String&>()));
9732 
9733 template<typename T, typename String>
9735  decltype(std::declval<T&>().string(std::declval<String&>()));
9736 
9737 template<typename T, typename Binary>
9739  decltype(std::declval<T&>().binary(std::declval<Binary&>()));
9740 
9741 template<typename T>
9743  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
9744 
9745 template<typename T, typename String>
9747  decltype(std::declval<T&>().key(std::declval<String&>()));
9748 
9749 template<typename T>
9750 using end_object_function_t = decltype(std::declval<T&>().end_object());
9751 
9752 template<typename T>
9754  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
9755 
9756 template<typename T>
9757 using end_array_function_t = decltype(std::declval<T&>().end_array());
9758 
9759 template<typename T, typename Exception>
9760 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
9761  std::declval<std::size_t>(), std::declval<const std::string&>(),
9762  std::declval<const Exception&>()));
9763 
9764 template<typename SAX, typename BasicJsonType>
9765 struct is_sax
9766 {
9767  private:
9769  "BasicJsonType must be of type basic_json<...>");
9770 
9771  using number_integer_t = typename BasicJsonType::number_integer_t;
9772  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9773  using number_float_t = typename BasicJsonType::number_float_t;
9775  using binary_t = typename BasicJsonType::binary_t;
9776  using exception_t = typename BasicJsonType::exception;
9777 
9778  public:
9779  static constexpr bool value =
9793 };
9794 
9795 template<typename SAX, typename BasicJsonType>
9797 {
9798  private:
9800  "BasicJsonType must be of type basic_json<...>");
9801 
9802  using number_integer_t = typename BasicJsonType::number_integer_t;
9803  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9804  using number_float_t = typename BasicJsonType::number_float_t;
9806  using binary_t = typename BasicJsonType::binary_t;
9807  using exception_t = typename BasicJsonType::exception;
9808 
9809  public:
9811  "Missing/invalid function: bool null()");
9813  "Missing/invalid function: bool boolean(bool)");
9815  "Missing/invalid function: bool boolean(bool)");
9816  static_assert(
9819  "Missing/invalid function: bool number_integer(number_integer_t)");
9820  static_assert(
9823  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
9824  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
9826  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
9827  static_assert(
9829  "Missing/invalid function: bool string(string_t&)");
9830  static_assert(
9832  "Missing/invalid function: bool binary(binary_t&)");
9834  "Missing/invalid function: bool start_object(std::size_t)");
9836  "Missing/invalid function: bool key(string_t&)");
9838  "Missing/invalid function: bool end_object()");
9840  "Missing/invalid function: bool start_array(std::size_t)");
9842  "Missing/invalid function: bool end_array()");
9843  static_assert(
9845  "Missing/invalid function: bool parse_error(std::size_t, const "
9846  "std::string&, const exception&)");
9847 };
9848 
9849 } // namespace detail
9851 
9852 // #include <nlohmann/detail/meta/type_traits.hpp>
9853 
9854 // #include <nlohmann/detail/string_concat.hpp>
9855 
9856 // #include <nlohmann/detail/value_t.hpp>
9857 
9858 
9860 namespace detail
9861 {
9862 
9865 {
9866  error,
9867  ignore,
9868  store
9869 };
9870 
9878 inline bool little_endianness(int num = 1) noexcept
9879 {
9880  return *reinterpret_cast<char*>(&num) == 1;
9881 }
9882 
9884 // binary reader //
9886 
9890 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType, InputAdapterType>>
9892 {
9893  using number_integer_t = typename BasicJsonType::number_integer_t;
9894  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9895  using number_float_t = typename BasicJsonType::number_float_t;
9897  using binary_t = typename BasicJsonType::binary_t;
9898  using json_sax_t = SAX;
9899  using char_type = typename InputAdapterType::char_type;
9901 
9902  public:
9908  explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
9909  {
9911  }
9912 
9913  // make class move-only
9914  binary_reader(const binary_reader&) = delete;
9915  binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9917  binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9918  ~binary_reader() = default;
9919 
9929  bool sax_parse(const input_format_t format,
9930  json_sax_t* sax_,
9931  const bool strict = true,
9932  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
9933  {
9934  sax = sax_;
9935  bool result = false;
9936 
9937  switch (format)
9938  {
9939  case input_format_t::bson:
9940  result = parse_bson_internal();
9941  break;
9942 
9943  case input_format_t::cbor:
9944  result = parse_cbor_internal(true, tag_handler);
9945  break;
9946 
9947  case input_format_t::msgpack:
9948  result = parse_msgpack_internal();
9949  break;
9950 
9951  case input_format_t::ubjson:
9952  case input_format_t::bjdata:
9953  result = parse_ubjson_internal();
9954  break;
9955 
9956  case input_format_t::json: // LCOV_EXCL_LINE
9957  default: // LCOV_EXCL_LINE
9958  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9959  }
9960 
9961  // strict mode: next byte must be EOF
9962  if (result && strict)
9963  {
9964  if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
9965  {
9966  get_ignore_noop();
9967  }
9968  else
9969  {
9970  get();
9971  }
9972 
9974  {
9975  return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
9976  exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
9977  }
9978  }
9979 
9980  return result;
9981  }
9982 
9983  private:
9985  // BSON //
9987 
9993  {
9994  std::int32_t document_size{};
9995  get_number<std::int32_t, true>(input_format_t::bson, document_size);
9996 
9997  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
9998  {
9999  return false;
10000  }
10001 
10002  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
10003  {
10004  return false;
10005  }
10006 
10007  return sax->end_object();
10008  }
10009 
10017  bool get_bson_cstr(string_t& result)
10018  {
10019  auto out = std::back_inserter(result);
10020  while (true)
10021  {
10022  get();
10023  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
10024  {
10025  return false;
10026  }
10027  if (current == 0x00)
10028  {
10029  return true;
10030  }
10031  *out++ = static_cast<typename string_t::value_type>(current);
10032  }
10033  }
10034 
10046  template<typename NumberType>
10047  bool get_bson_string(const NumberType len, string_t& result)
10048  {
10049  if (JSON_HEDLEY_UNLIKELY(len < 1))
10050  {
10051  auto last_token = get_token_string();
10052  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10053  exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
10054  }
10055 
10056  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != char_traits<char_type>::eof();
10057  }
10058 
10068  template<typename NumberType>
10069  bool get_bson_binary(const NumberType len, binary_t& result)
10070  {
10071  if (JSON_HEDLEY_UNLIKELY(len < 0))
10072  {
10073  auto last_token = get_token_string();
10074  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10075  exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
10076  }
10077 
10078  // All BSON binary values have a subtype
10079  std::uint8_t subtype{};
10080  get_number<std::uint8_t>(input_format_t::bson, subtype);
10081  result.set_subtype(subtype);
10082 
10083  return get_binary(input_format_t::bson, len, result);
10084  }
10085 
10097  const std::size_t element_type_parse_position)
10098  {
10099  switch (element_type)
10100  {
10101  case 0x01: // double
10102  {
10103  double number{};
10104  return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10105  }
10106 
10107  case 0x02: // string
10108  {
10109  std::int32_t len{};
10110  string_t value;
10111  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
10112  }
10113 
10114  case 0x03: // object
10115  {
10116  return parse_bson_internal();
10117  }
10118 
10119  case 0x04: // array
10120  {
10121  return parse_bson_array();
10122  }
10123 
10124  case 0x05: // binary
10125  {
10126  std::int32_t len{};
10127  binary_t value;
10128  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
10129  }
10130 
10131  case 0x08: // boolean
10132  {
10133  return sax->boolean(get() != 0);
10134  }
10135 
10136  case 0x0A: // null
10137  {
10138  return sax->null();
10139  }
10140 
10141  case 0x10: // int32
10142  {
10143  std::int32_t value{};
10144  return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
10145  }
10146 
10147  case 0x12: // int64
10148  {
10149  std::int64_t value{};
10150  return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
10151  }
10152 
10153  case 0x11: // uint64
10154  {
10155  std::uint64_t value{};
10156  return get_number<std::uint64_t, true>(input_format_t::bson, value) && sax->number_unsigned(value);
10157  }
10158 
10159  default: // anything else is not supported (yet)
10160  {
10161  std::array<char, 3> cr{{}};
10162  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10163  const std::string cr_str{cr.data()};
10164  return sax->parse_error(element_type_parse_position, cr_str,
10165  parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
10166  }
10167  }
10168  }
10169 
10182  bool parse_bson_element_list(const bool is_array)
10183  {
10184  string_t key;
10185 
10186  while (auto element_type = get())
10187  {
10188  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
10189  {
10190  return false;
10191  }
10192 
10193  const std::size_t element_type_parse_position = chars_read;
10194  if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
10195  {
10196  return false;
10197  }
10198 
10199  if (!is_array && !sax->key(key))
10200  {
10201  return false;
10202  }
10203 
10204  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
10205  {
10206  return false;
10207  }
10208 
10209  // get_bson_cstr only appends
10210  key.clear();
10211  }
10212 
10213  return true;
10214  }
10215 
10221  {
10222  std::int32_t document_size{};
10223  get_number<std::int32_t, true>(input_format_t::bson, document_size);
10224 
10225  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
10226  {
10227  return false;
10228  }
10229 
10230  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
10231  {
10232  return false;
10233  }
10234 
10235  return sax->end_array();
10236  }
10237 
10239  // CBOR //
10241 
10250  bool parse_cbor_internal(const bool get_char,
10251  const cbor_tag_handler_t tag_handler)
10252  {
10253  switch (get_char ? get() : current)
10254  {
10255  // EOF
10257  return unexpect_eof(input_format_t::cbor, "value");
10258 
10259  // Integer 0x00..0x17 (0..23)
10260  case 0x00:
10261  case 0x01:
10262  case 0x02:
10263  case 0x03:
10264  case 0x04:
10265  case 0x05:
10266  case 0x06:
10267  case 0x07:
10268  case 0x08:
10269  case 0x09:
10270  case 0x0A:
10271  case 0x0B:
10272  case 0x0C:
10273  case 0x0D:
10274  case 0x0E:
10275  case 0x0F:
10276  case 0x10:
10277  case 0x11:
10278  case 0x12:
10279  case 0x13:
10280  case 0x14:
10281  case 0x15:
10282  case 0x16:
10283  case 0x17:
10284  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
10285 
10286  case 0x18: // Unsigned integer (one-byte uint8_t follows)
10287  {
10288  std::uint8_t number{};
10289  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
10290  }
10291 
10292  case 0x19: // Unsigned integer (two-byte uint16_t follows)
10293  {
10294  std::uint16_t number{};
10295  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
10296  }
10297 
10298  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
10299  {
10300  std::uint32_t number{};
10301  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
10302  }
10303 
10304  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
10305  {
10306  std::uint64_t number{};
10307  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
10308  }
10309 
10310  // Negative integer -1-0x00..-1-0x17 (-1..-24)
10311  case 0x20:
10312  case 0x21:
10313  case 0x22:
10314  case 0x23:
10315  case 0x24:
10316  case 0x25:
10317  case 0x26:
10318  case 0x27:
10319  case 0x28:
10320  case 0x29:
10321  case 0x2A:
10322  case 0x2B:
10323  case 0x2C:
10324  case 0x2D:
10325  case 0x2E:
10326  case 0x2F:
10327  case 0x30:
10328  case 0x31:
10329  case 0x32:
10330  case 0x33:
10331  case 0x34:
10332  case 0x35:
10333  case 0x36:
10334  case 0x37:
10335  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
10336 
10337  case 0x38: // Negative integer (one-byte uint8_t follows)
10338  {
10339  std::uint8_t number{};
10340  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
10341  }
10342 
10343  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
10344  {
10345  std::uint16_t number{};
10346  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
10347  }
10348 
10349  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
10350  {
10351  std::uint32_t number{};
10352  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
10353  }
10354 
10355  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
10356  {
10357  std::uint64_t number{};
10358  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
10359  - static_cast<number_integer_t>(number));
10360  }
10361 
10362  // Binary data (0x00..0x17 bytes follow)
10363  case 0x40:
10364  case 0x41:
10365  case 0x42:
10366  case 0x43:
10367  case 0x44:
10368  case 0x45:
10369  case 0x46:
10370  case 0x47:
10371  case 0x48:
10372  case 0x49:
10373  case 0x4A:
10374  case 0x4B:
10375  case 0x4C:
10376  case 0x4D:
10377  case 0x4E:
10378  case 0x4F:
10379  case 0x50:
10380  case 0x51:
10381  case 0x52:
10382  case 0x53:
10383  case 0x54:
10384  case 0x55:
10385  case 0x56:
10386  case 0x57:
10387  case 0x58: // Binary data (one-byte uint8_t for n follows)
10388  case 0x59: // Binary data (two-byte uint16_t for n follow)
10389  case 0x5A: // Binary data (four-byte uint32_t for n follow)
10390  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10391  case 0x5F: // Binary data (indefinite length)
10392  {
10393  binary_t b;
10394  return get_cbor_binary(b) && sax->binary(b);
10395  }
10396 
10397  // UTF-8 string (0x00..0x17 bytes follow)
10398  case 0x60:
10399  case 0x61:
10400  case 0x62:
10401  case 0x63:
10402  case 0x64:
10403  case 0x65:
10404  case 0x66:
10405  case 0x67:
10406  case 0x68:
10407  case 0x69:
10408  case 0x6A:
10409  case 0x6B:
10410  case 0x6C:
10411  case 0x6D:
10412  case 0x6E:
10413  case 0x6F:
10414  case 0x70:
10415  case 0x71:
10416  case 0x72:
10417  case 0x73:
10418  case 0x74:
10419  case 0x75:
10420  case 0x76:
10421  case 0x77:
10422  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
10423  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
10424  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
10425  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
10426  case 0x7F: // UTF-8 string (indefinite length)
10427  {
10428  string_t s;
10429  return get_cbor_string(s) && sax->string(s);
10430  }
10431 
10432  // array (0x00..0x17 data items follow)
10433  case 0x80:
10434  case 0x81:
10435  case 0x82:
10436  case 0x83:
10437  case 0x84:
10438  case 0x85:
10439  case 0x86:
10440  case 0x87:
10441  case 0x88:
10442  case 0x89:
10443  case 0x8A:
10444  case 0x8B:
10445  case 0x8C:
10446  case 0x8D:
10447  case 0x8E:
10448  case 0x8F:
10449  case 0x90:
10450  case 0x91:
10451  case 0x92:
10452  case 0x93:
10453  case 0x94:
10454  case 0x95:
10455  case 0x96:
10456  case 0x97:
10457  return get_cbor_array(
10458  conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
10459 
10460  case 0x98: // array (one-byte uint8_t for n follows)
10461  {
10462  std::uint8_t len{};
10463  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
10464  }
10465 
10466  case 0x99: // array (two-byte uint16_t for n follow)
10467  {
10468  std::uint16_t len{};
10469  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
10470  }
10471 
10472  case 0x9A: // array (four-byte uint32_t for n follow)
10473  {
10474  std::uint32_t len{};
10475  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
10476  }
10477 
10478  case 0x9B: // array (eight-byte uint64_t for n follow)
10479  {
10480  std::uint64_t len{};
10481  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
10482  }
10483 
10484  case 0x9F: // array (indefinite length)
10485  return get_cbor_array(detail::unknown_size(), tag_handler);
10486 
10487  // map (0x00..0x17 pairs of data items follow)
10488  case 0xA0:
10489  case 0xA1:
10490  case 0xA2:
10491  case 0xA3:
10492  case 0xA4:
10493  case 0xA5:
10494  case 0xA6:
10495  case 0xA7:
10496  case 0xA8:
10497  case 0xA9:
10498  case 0xAA:
10499  case 0xAB:
10500  case 0xAC:
10501  case 0xAD:
10502  case 0xAE:
10503  case 0xAF:
10504  case 0xB0:
10505  case 0xB1:
10506  case 0xB2:
10507  case 0xB3:
10508  case 0xB4:
10509  case 0xB5:
10510  case 0xB6:
10511  case 0xB7:
10512  return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
10513 
10514  case 0xB8: // map (one-byte uint8_t for n follows)
10515  {
10516  std::uint8_t len{};
10517  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
10518  }
10519 
10520  case 0xB9: // map (two-byte uint16_t for n follow)
10521  {
10522  std::uint16_t len{};
10523  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
10524  }
10525 
10526  case 0xBA: // map (four-byte uint32_t for n follow)
10527  {
10528  std::uint32_t len{};
10529  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
10530  }
10531 
10532  case 0xBB: // map (eight-byte uint64_t for n follow)
10533  {
10534  std::uint64_t len{};
10535  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
10536  }
10537 
10538  case 0xBF: // map (indefinite length)
10539  return get_cbor_object(detail::unknown_size(), tag_handler);
10540 
10541  case 0xC6: // tagged item
10542  case 0xC7:
10543  case 0xC8:
10544  case 0xC9:
10545  case 0xCA:
10546  case 0xCB:
10547  case 0xCC:
10548  case 0xCD:
10549  case 0xCE:
10550  case 0xCF:
10551  case 0xD0:
10552  case 0xD1:
10553  case 0xD2:
10554  case 0xD3:
10555  case 0xD4:
10556  case 0xD8: // tagged item (1 byte follows)
10557  case 0xD9: // tagged item (2 bytes follow)
10558  case 0xDA: // tagged item (4 bytes follow)
10559  case 0xDB: // tagged item (8 bytes follow)
10560  {
10561  switch (tag_handler)
10562  {
10563  case cbor_tag_handler_t::error:
10564  {
10565  auto last_token = get_token_string();
10566  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10567  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
10568  }
10569 
10570  case cbor_tag_handler_t::ignore:
10571  {
10572  // ignore binary subtype
10573  switch (current)
10574  {
10575  case 0xD8:
10576  {
10577  std::uint8_t subtype_to_ignore{};
10578  get_number(input_format_t::cbor, subtype_to_ignore);
10579  break;
10580  }
10581  case 0xD9:
10582  {
10583  std::uint16_t subtype_to_ignore{};
10584  get_number(input_format_t::cbor, subtype_to_ignore);
10585  break;
10586  }
10587  case 0xDA:
10588  {
10589  std::uint32_t subtype_to_ignore{};
10590  get_number(input_format_t::cbor, subtype_to_ignore);
10591  break;
10592  }
10593  case 0xDB:
10594  {
10595  std::uint64_t subtype_to_ignore{};
10596  get_number(input_format_t::cbor, subtype_to_ignore);
10597  break;
10598  }
10599  default:
10600  break;
10601  }
10602  return parse_cbor_internal(true, tag_handler);
10603  }
10604 
10605  case cbor_tag_handler_t::store:
10606  {
10607  binary_t b;
10608  // use binary subtype and store in a binary container
10609  switch (current)
10610  {
10611  case 0xD8:
10612  {
10613  std::uint8_t subtype{};
10614  get_number(input_format_t::cbor, subtype);
10615  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
10616  break;
10617  }
10618  case 0xD9:
10619  {
10620  std::uint16_t subtype{};
10621  get_number(input_format_t::cbor, subtype);
10622  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
10623  break;
10624  }
10625  case 0xDA:
10626  {
10627  std::uint32_t subtype{};
10628  get_number(input_format_t::cbor, subtype);
10629  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
10630  break;
10631  }
10632  case 0xDB:
10633  {
10634  std::uint64_t subtype{};
10635  get_number(input_format_t::cbor, subtype);
10636  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
10637  break;
10638  }
10639  default:
10640  return parse_cbor_internal(true, tag_handler);
10641  }
10642  get();
10643  return get_cbor_binary(b) && sax->binary(b);
10644  }
10645 
10646  default: // LCOV_EXCL_LINE
10647  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10648  return false; // LCOV_EXCL_LINE
10649  }
10650  }
10651 
10652  case 0xF4: // false
10653  return sax->boolean(false);
10654 
10655  case 0xF5: // true
10656  return sax->boolean(true);
10657 
10658  case 0xF6: // null
10659  return sax->null();
10660 
10661  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
10662  {
10663  const auto byte1_raw = get();
10664  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
10665  {
10666  return false;
10667  }
10668  const auto byte2_raw = get();
10669  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
10670  {
10671  return false;
10672  }
10673 
10674  const auto byte1 = static_cast<unsigned char>(byte1_raw);
10675  const auto byte2 = static_cast<unsigned char>(byte2_raw);
10676 
10677  // Code from RFC 7049, Appendix D, Figure 3:
10678  // As half-precision floating-point numbers were only added
10679  // to IEEE 754 in 2008, today's programming platforms often
10680  // still only have limited support for them. It is very
10681  // easy to include at least decoding support for them even
10682  // without such support. An example of a small decoder for
10683  // half-precision floating-point numbers in the C language
10684  // is shown in Fig. 3.
10685  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
10686  const double val = [&half]
10687  {
10688  const int exp = (half >> 10u) & 0x1Fu;
10689  const unsigned int mant = half & 0x3FFu;
10690  JSON_ASSERT(0 <= exp&& exp <= 32);
10691  JSON_ASSERT(mant <= 1024);
10692  switch (exp)
10693  {
10694  case 0:
10695  return std::ldexp(mant, -24);
10696  case 31:
10697  return (mant == 0)
10698  ? std::numeric_limits<double>::infinity()
10699  : std::numeric_limits<double>::quiet_NaN();
10700  default:
10701  return std::ldexp(mant + 1024, exp - 25);
10702  }
10703  }();
10704  return sax->number_float((half & 0x8000u) != 0
10705  ? static_cast<number_float_t>(-val)
10706  : static_cast<number_float_t>(val), "");
10707  }
10708 
10709  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
10710  {
10711  float number{};
10712  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
10713  }
10714 
10715  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
10716  {
10717  double number{};
10718  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
10719  }
10720 
10721  default: // anything else (0xFF is handled inside the other types)
10722  {
10723  auto last_token = get_token_string();
10724  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10725  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
10726  }
10727  }
10728  }
10729 
10742  {
10743  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
10744  {
10745  return false;
10746  }
10747 
10748  switch (current)
10749  {
10750  // UTF-8 string (0x00..0x17 bytes follow)
10751  case 0x60:
10752  case 0x61:
10753  case 0x62:
10754  case 0x63:
10755  case 0x64:
10756  case 0x65:
10757  case 0x66:
10758  case 0x67:
10759  case 0x68:
10760  case 0x69:
10761  case 0x6A:
10762  case 0x6B:
10763  case 0x6C:
10764  case 0x6D:
10765  case 0x6E:
10766  case 0x6F:
10767  case 0x70:
10768  case 0x71:
10769  case 0x72:
10770  case 0x73:
10771  case 0x74:
10772  case 0x75:
10773  case 0x76:
10774  case 0x77:
10775  {
10776  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10777  }
10778 
10779  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
10780  {
10781  std::uint8_t len{};
10782  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10783  }
10784 
10785  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
10786  {
10787  std::uint16_t len{};
10788  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10789  }
10790 
10791  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
10792  {
10793  std::uint32_t len{};
10794  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10795  }
10796 
10797  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
10798  {
10799  std::uint64_t len{};
10800  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10801  }
10802 
10803  case 0x7F: // UTF-8 string (indefinite length)
10804  {
10805  while (get() != 0xFF)
10806  {
10807  string_t chunk;
10808  if (!get_cbor_string(chunk))
10809  {
10810  return false;
10811  }
10812  result.append(chunk);
10813  }
10814  return true;
10815  }
10816 
10817  default:
10818  {
10819  auto last_token = get_token_string();
10820  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10821  exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
10822  }
10823  }
10824  }
10825 
10838  {
10839  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
10840  {
10841  return false;
10842  }
10843 
10844  switch (current)
10845  {
10846  // Binary data (0x00..0x17 bytes follow)
10847  case 0x40:
10848  case 0x41:
10849  case 0x42:
10850  case 0x43:
10851  case 0x44:
10852  case 0x45:
10853  case 0x46:
10854  case 0x47:
10855  case 0x48:
10856  case 0x49:
10857  case 0x4A:
10858  case 0x4B:
10859  case 0x4C:
10860  case 0x4D:
10861  case 0x4E:
10862  case 0x4F:
10863  case 0x50:
10864  case 0x51:
10865  case 0x52:
10866  case 0x53:
10867  case 0x54:
10868  case 0x55:
10869  case 0x56:
10870  case 0x57:
10871  {
10872  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10873  }
10874 
10875  case 0x58: // Binary data (one-byte uint8_t for n follows)
10876  {
10877  std::uint8_t len{};
10878  return get_number(input_format_t::cbor, len) &&
10879  get_binary(input_format_t::cbor, len, result);
10880  }
10881 
10882  case 0x59: // Binary data (two-byte uint16_t for n follow)
10883  {
10884  std::uint16_t len{};
10885  return get_number(input_format_t::cbor, len) &&
10886  get_binary(input_format_t::cbor, len, result);
10887  }
10888 
10889  case 0x5A: // Binary data (four-byte uint32_t for n follow)
10890  {
10891  std::uint32_t len{};
10892  return get_number(input_format_t::cbor, len) &&
10893  get_binary(input_format_t::cbor, len, result);
10894  }
10895 
10896  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10897  {
10898  std::uint64_t len{};
10899  return get_number(input_format_t::cbor, len) &&
10900  get_binary(input_format_t::cbor, len, result);
10901  }
10902 
10903  case 0x5F: // Binary data (indefinite length)
10904  {
10905  while (get() != 0xFF)
10906  {
10907  binary_t chunk;
10908  if (!get_cbor_binary(chunk))
10909  {
10910  return false;
10911  }
10912  result.insert(result.end(), chunk.begin(), chunk.end());
10913  }
10914  return true;
10915  }
10916 
10917  default:
10918  {
10919  auto last_token = get_token_string();
10920  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10921  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));
10922  }
10923  }
10924  }
10925 
10932  bool get_cbor_array(const std::size_t len,
10933  const cbor_tag_handler_t tag_handler)
10934  {
10935  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10936  {
10937  return false;
10938  }
10939 
10940  if (len != detail::unknown_size())
10941  {
10942  for (std::size_t i = 0; i < len; ++i)
10943  {
10944  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10945  {
10946  return false;
10947  }
10948  }
10949  }
10950  else
10951  {
10952  while (get() != 0xFF)
10953  {
10954  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
10955  {
10956  return false;
10957  }
10958  }
10959  }
10960 
10961  return sax->end_array();
10962  }
10963 
10970  bool get_cbor_object(const std::size_t len,
10971  const cbor_tag_handler_t tag_handler)
10972  {
10973  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10974  {
10975  return false;
10976  }
10977 
10978  if (len != 0)
10979  {
10980  string_t key;
10981  if (len != detail::unknown_size())
10982  {
10983  for (std::size_t i = 0; i < len; ++i)
10984  {
10985  get();
10986  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10987  {
10988  return false;
10989  }
10990 
10991  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10992  {
10993  return false;
10994  }
10995  key.clear();
10996  }
10997  }
10998  else
10999  {
11000  while (get() != 0xFF)
11001  {
11002  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
11003  {
11004  return false;
11005  }
11006 
11007  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
11008  {
11009  return false;
11010  }
11011  key.clear();
11012  }
11013  }
11014  }
11015 
11016  return sax->end_object();
11017  }
11018 
11020  // MsgPack //
11022 
11027  {
11028  switch (get())
11029  {
11030  // EOF
11032  return unexpect_eof(input_format_t::msgpack, "value");
11033 
11034  // positive fixint
11035  case 0x00:
11036  case 0x01:
11037  case 0x02:
11038  case 0x03:
11039  case 0x04:
11040  case 0x05:
11041  case 0x06:
11042  case 0x07:
11043  case 0x08:
11044  case 0x09:
11045  case 0x0A:
11046  case 0x0B:
11047  case 0x0C:
11048  case 0x0D:
11049  case 0x0E:
11050  case 0x0F:
11051  case 0x10:
11052  case 0x11:
11053  case 0x12:
11054  case 0x13:
11055  case 0x14:
11056  case 0x15:
11057  case 0x16:
11058  case 0x17:
11059  case 0x18:
11060  case 0x19:
11061  case 0x1A:
11062  case 0x1B:
11063  case 0x1C:
11064  case 0x1D:
11065  case 0x1E:
11066  case 0x1F:
11067  case 0x20:
11068  case 0x21:
11069  case 0x22:
11070  case 0x23:
11071  case 0x24:
11072  case 0x25:
11073  case 0x26:
11074  case 0x27:
11075  case 0x28:
11076  case 0x29:
11077  case 0x2A:
11078  case 0x2B:
11079  case 0x2C:
11080  case 0x2D:
11081  case 0x2E:
11082  case 0x2F:
11083  case 0x30:
11084  case 0x31:
11085  case 0x32:
11086  case 0x33:
11087  case 0x34:
11088  case 0x35:
11089  case 0x36:
11090  case 0x37:
11091  case 0x38:
11092  case 0x39:
11093  case 0x3A:
11094  case 0x3B:
11095  case 0x3C:
11096  case 0x3D:
11097  case 0x3E:
11098  case 0x3F:
11099  case 0x40:
11100  case 0x41:
11101  case 0x42:
11102  case 0x43:
11103  case 0x44:
11104  case 0x45:
11105  case 0x46:
11106  case 0x47:
11107  case 0x48:
11108  case 0x49:
11109  case 0x4A:
11110  case 0x4B:
11111  case 0x4C:
11112  case 0x4D:
11113  case 0x4E:
11114  case 0x4F:
11115  case 0x50:
11116  case 0x51:
11117  case 0x52:
11118  case 0x53:
11119  case 0x54:
11120  case 0x55:
11121  case 0x56:
11122  case 0x57:
11123  case 0x58:
11124  case 0x59:
11125  case 0x5A:
11126  case 0x5B:
11127  case 0x5C:
11128  case 0x5D:
11129  case 0x5E:
11130  case 0x5F:
11131  case 0x60:
11132  case 0x61:
11133  case 0x62:
11134  case 0x63:
11135  case 0x64:
11136  case 0x65:
11137  case 0x66:
11138  case 0x67:
11139  case 0x68:
11140  case 0x69:
11141  case 0x6A:
11142  case 0x6B:
11143  case 0x6C:
11144  case 0x6D:
11145  case 0x6E:
11146  case 0x6F:
11147  case 0x70:
11148  case 0x71:
11149  case 0x72:
11150  case 0x73:
11151  case 0x74:
11152  case 0x75:
11153  case 0x76:
11154  case 0x77:
11155  case 0x78:
11156  case 0x79:
11157  case 0x7A:
11158  case 0x7B:
11159  case 0x7C:
11160  case 0x7D:
11161  case 0x7E:
11162  case 0x7F:
11163  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
11164 
11165  // fixmap
11166  case 0x80:
11167  case 0x81:
11168  case 0x82:
11169  case 0x83:
11170  case 0x84:
11171  case 0x85:
11172  case 0x86:
11173  case 0x87:
11174  case 0x88:
11175  case 0x89:
11176  case 0x8A:
11177  case 0x8B:
11178  case 0x8C:
11179  case 0x8D:
11180  case 0x8E:
11181  case 0x8F:
11182  return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
11183 
11184  // fixarray
11185  case 0x90:
11186  case 0x91:
11187  case 0x92:
11188  case 0x93:
11189  case 0x94:
11190  case 0x95:
11191  case 0x96:
11192  case 0x97:
11193  case 0x98:
11194  case 0x99:
11195  case 0x9A:
11196  case 0x9B:
11197  case 0x9C:
11198  case 0x9D:
11199  case 0x9E:
11200  case 0x9F:
11201  return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
11202 
11203  // fixstr
11204  case 0xA0:
11205  case 0xA1:
11206  case 0xA2:
11207  case 0xA3:
11208  case 0xA4:
11209  case 0xA5:
11210  case 0xA6:
11211  case 0xA7:
11212  case 0xA8:
11213  case 0xA9:
11214  case 0xAA:
11215  case 0xAB:
11216  case 0xAC:
11217  case 0xAD:
11218  case 0xAE:
11219  case 0xAF:
11220  case 0xB0:
11221  case 0xB1:
11222  case 0xB2:
11223  case 0xB3:
11224  case 0xB4:
11225  case 0xB5:
11226  case 0xB6:
11227  case 0xB7:
11228  case 0xB8:
11229  case 0xB9:
11230  case 0xBA:
11231  case 0xBB:
11232  case 0xBC:
11233  case 0xBD:
11234  case 0xBE:
11235  case 0xBF:
11236  case 0xD9: // str 8
11237  case 0xDA: // str 16
11238  case 0xDB: // str 32
11239  {
11240  string_t s;
11241  return get_msgpack_string(s) && sax->string(s);
11242  }
11243 
11244  case 0xC0: // nil
11245  return sax->null();
11246 
11247  case 0xC2: // false
11248  return sax->boolean(false);
11249 
11250  case 0xC3: // true
11251  return sax->boolean(true);
11252 
11253  case 0xC4: // bin 8
11254  case 0xC5: // bin 16
11255  case 0xC6: // bin 32
11256  case 0xC7: // ext 8
11257  case 0xC8: // ext 16
11258  case 0xC9: // ext 32
11259  case 0xD4: // fixext 1
11260  case 0xD5: // fixext 2
11261  case 0xD6: // fixext 4
11262  case 0xD7: // fixext 8
11263  case 0xD8: // fixext 16
11264  {
11265  binary_t b;
11266  return get_msgpack_binary(b) && sax->binary(b);
11267  }
11268 
11269  case 0xCA: // float 32
11270  {
11271  float number{};
11272  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
11273  }
11274 
11275  case 0xCB: // float 64
11276  {
11277  double number{};
11278  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
11279  }
11280 
11281  case 0xCC: // uint 8
11282  {
11283  std::uint8_t number{};
11284  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
11285  }
11286 
11287  case 0xCD: // uint 16
11288  {
11289  std::uint16_t number{};
11290  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
11291  }
11292 
11293  case 0xCE: // uint 32
11294  {
11295  std::uint32_t number{};
11296  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
11297  }
11298 
11299  case 0xCF: // uint 64
11300  {
11301  std::uint64_t number{};
11302  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
11303  }
11304 
11305  case 0xD0: // int 8
11306  {
11307  std::int8_t number{};
11308  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
11309  }
11310 
11311  case 0xD1: // int 16
11312  {
11313  std::int16_t number{};
11314  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
11315  }
11316 
11317  case 0xD2: // int 32
11318  {
11319  std::int32_t number{};
11320  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
11321  }
11322 
11323  case 0xD3: // int 64
11324  {
11325  std::int64_t number{};
11326  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
11327  }
11328 
11329  case 0xDC: // array 16
11330  {
11331  std::uint16_t len{};
11332  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
11333  }
11334 
11335  case 0xDD: // array 32
11336  {
11337  std::uint32_t len{};
11338  return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));
11339  }
11340 
11341  case 0xDE: // map 16
11342  {
11343  std::uint16_t len{};
11344  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
11345  }
11346 
11347  case 0xDF: // map 32
11348  {
11349  std::uint32_t len{};
11350  return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));
11351  }
11352 
11353  // negative fixint
11354  case 0xE0:
11355  case 0xE1:
11356  case 0xE2:
11357  case 0xE3:
11358  case 0xE4:
11359  case 0xE5:
11360  case 0xE6:
11361  case 0xE7:
11362  case 0xE8:
11363  case 0xE9:
11364  case 0xEA:
11365  case 0xEB:
11366  case 0xEC:
11367  case 0xED:
11368  case 0xEE:
11369  case 0xEF:
11370  case 0xF0:
11371  case 0xF1:
11372  case 0xF2:
11373  case 0xF3:
11374  case 0xF4:
11375  case 0xF5:
11376  case 0xF6:
11377  case 0xF7:
11378  case 0xF8:
11379  case 0xF9:
11380  case 0xFA:
11381  case 0xFB:
11382  case 0xFC:
11383  case 0xFD:
11384  case 0xFE:
11385  case 0xFF:
11386  return sax->number_integer(static_cast<std::int8_t>(current));
11387 
11388  default: // anything else
11389  {
11390  auto last_token = get_token_string();
11391  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11392  exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
11393  }
11394  }
11395  }
11396 
11408  {
11409  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
11410  {
11411  return false;
11412  }
11413 
11414  switch (current)
11415  {
11416  // fixstr
11417  case 0xA0:
11418  case 0xA1:
11419  case 0xA2:
11420  case 0xA3:
11421  case 0xA4:
11422  case 0xA5:
11423  case 0xA6:
11424  case 0xA7:
11425  case 0xA8:
11426  case 0xA9:
11427  case 0xAA:
11428  case 0xAB:
11429  case 0xAC:
11430  case 0xAD:
11431  case 0xAE:
11432  case 0xAF:
11433  case 0xB0:
11434  case 0xB1:
11435  case 0xB2:
11436  case 0xB3:
11437  case 0xB4:
11438  case 0xB5:
11439  case 0xB6:
11440  case 0xB7:
11441  case 0xB8:
11442  case 0xB9:
11443  case 0xBA:
11444  case 0xBB:
11445  case 0xBC:
11446  case 0xBD:
11447  case 0xBE:
11448  case 0xBF:
11449  {
11450  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
11451  }
11452 
11453  case 0xD9: // str 8
11454  {
11455  std::uint8_t len{};
11456  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
11457  }
11458 
11459  case 0xDA: // str 16
11460  {
11461  std::uint16_t len{};
11462  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
11463  }
11464 
11465  case 0xDB: // str 32
11466  {
11467  std::uint32_t len{};
11468  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
11469  }
11470 
11471  default:
11472  {
11473  auto last_token = get_token_string();
11474  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11475  exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
11476  }
11477  }
11478  }
11479 
11491  {
11492  // helper function to set the subtype
11493  auto assign_and_return_true = [&result](std::int8_t subtype)
11494  {
11495  result.set_subtype(static_cast<std::uint8_t>(subtype));
11496  return true;
11497  };
11498 
11499  switch (current)
11500  {
11501  case 0xC4: // bin 8
11502  {
11503  std::uint8_t len{};
11504  return get_number(input_format_t::msgpack, len) &&
11505  get_binary(input_format_t::msgpack, len, result);
11506  }
11507 
11508  case 0xC5: // bin 16
11509  {
11510  std::uint16_t len{};
11511  return get_number(input_format_t::msgpack, len) &&
11512  get_binary(input_format_t::msgpack, len, result);
11513  }
11514 
11515  case 0xC6: // bin 32
11516  {
11517  std::uint32_t len{};
11518  return get_number(input_format_t::msgpack, len) &&
11519  get_binary(input_format_t::msgpack, len, result);
11520  }
11521 
11522  case 0xC7: // ext 8
11523  {
11524  std::uint8_t len{};
11525  std::int8_t subtype{};
11526  return get_number(input_format_t::msgpack, len) &&
11527  get_number(input_format_t::msgpack, subtype) &&
11528  get_binary(input_format_t::msgpack, len, result) &&
11529  assign_and_return_true(subtype);
11530  }
11531 
11532  case 0xC8: // ext 16
11533  {
11534  std::uint16_t len{};
11535  std::int8_t subtype{};
11536  return get_number(input_format_t::msgpack, len) &&
11537  get_number(input_format_t::msgpack, subtype) &&
11538  get_binary(input_format_t::msgpack, len, result) &&
11539  assign_and_return_true(subtype);
11540  }
11541 
11542  case 0xC9: // ext 32
11543  {
11544  std::uint32_t len{};
11545  std::int8_t subtype{};
11546  return get_number(input_format_t::msgpack, len) &&
11547  get_number(input_format_t::msgpack, subtype) &&
11548  get_binary(input_format_t::msgpack, len, result) &&
11549  assign_and_return_true(subtype);
11550  }
11551 
11552  case 0xD4: // fixext 1
11553  {
11554  std::int8_t subtype{};
11555  return get_number(input_format_t::msgpack, subtype) &&
11556  get_binary(input_format_t::msgpack, 1, result) &&
11557  assign_and_return_true(subtype);
11558  }
11559 
11560  case 0xD5: // fixext 2
11561  {
11562  std::int8_t subtype{};
11563  return get_number(input_format_t::msgpack, subtype) &&
11564  get_binary(input_format_t::msgpack, 2, result) &&
11565  assign_and_return_true(subtype);
11566  }
11567 
11568  case 0xD6: // fixext 4
11569  {
11570  std::int8_t subtype{};
11571  return get_number(input_format_t::msgpack, subtype) &&
11572  get_binary(input_format_t::msgpack, 4, result) &&
11573  assign_and_return_true(subtype);
11574  }
11575 
11576  case 0xD7: // fixext 8
11577  {
11578  std::int8_t subtype{};
11579  return get_number(input_format_t::msgpack, subtype) &&
11580  get_binary(input_format_t::msgpack, 8, result) &&
11581  assign_and_return_true(subtype);
11582  }
11583 
11584  case 0xD8: // fixext 16
11585  {
11586  std::int8_t subtype{};
11587  return get_number(input_format_t::msgpack, subtype) &&
11588  get_binary(input_format_t::msgpack, 16, result) &&
11589  assign_and_return_true(subtype);
11590  }
11591 
11592  default: // LCOV_EXCL_LINE
11593  return false; // LCOV_EXCL_LINE
11594  }
11595  }
11596 
11601  bool get_msgpack_array(const std::size_t len)
11602  {
11603  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
11604  {
11605  return false;
11606  }
11607 
11608  for (std::size_t i = 0; i < len; ++i)
11609  {
11610  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
11611  {
11612  return false;
11613  }
11614  }
11615 
11616  return sax->end_array();
11617  }
11618 
11623  bool get_msgpack_object(const std::size_t len)
11624  {
11625  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
11626  {
11627  return false;
11628  }
11629 
11630  string_t key;
11631  for (std::size_t i = 0; i < len; ++i)
11632  {
11633  get();
11634  if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
11635  {
11636  return false;
11637  }
11638 
11639  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
11640  {
11641  return false;
11642  }
11643  key.clear();
11644  }
11645 
11646  return sax->end_object();
11647  }
11648 
11650  // UBJSON //
11652 
11660  bool parse_ubjson_internal(const bool get_char = true)
11661  {
11662  return get_ubjson_value(get_char ? get_ignore_noop() : current);
11663  }
11664 
11679  bool get_ubjson_string(string_t& result, const bool get_char = true)
11680  {
11681  if (get_char)
11682  {
11683  get(); // TODO(niels): may we ignore N here?
11684  }
11685 
11686  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
11687  {
11688  return false;
11689  }
11690 
11691  switch (current)
11692  {
11693  case 'U':
11694  {
11695  std::uint8_t len{};
11696  return get_number(input_format, len) && get_string(input_format, len, result);
11697  }
11698 
11699  case 'i':
11700  {
11701  std::int8_t len{};
11702  return get_number(input_format, len) && get_string(input_format, len, result);
11703  }
11704 
11705  case 'I':
11706  {
11707  std::int16_t len{};
11708  return get_number(input_format, len) && get_string(input_format, len, result);
11709  }
11710 
11711  case 'l':
11712  {
11713  std::int32_t len{};
11714  return get_number(input_format, len) && get_string(input_format, len, result);
11715  }
11716 
11717  case 'L':
11718  {
11719  std::int64_t len{};
11720  return get_number(input_format, len) && get_string(input_format, len, result);
11721  }
11722 
11723  case 'u':
11724  {
11725  if (input_format != input_format_t::bjdata)
11726  {
11727  break;
11728  }
11729  std::uint16_t len{};
11730  return get_number(input_format, len) && get_string(input_format, len, result);
11731  }
11732 
11733  case 'm':
11734  {
11735  if (input_format != input_format_t::bjdata)
11736  {
11737  break;
11738  }
11739  std::uint32_t len{};
11740  return get_number(input_format, len) && get_string(input_format, len, result);
11741  }
11742 
11743  case 'M':
11744  {
11745  if (input_format != input_format_t::bjdata)
11746  {
11747  break;
11748  }
11749  std::uint64_t len{};
11750  return get_number(input_format, len) && get_string(input_format, len, result);
11751  }
11752 
11753  default:
11754  break;
11755  }
11756  auto last_token = get_token_string();
11757  std::string message;
11758 
11759  if (input_format != input_format_t::bjdata)
11760  {
11761  message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
11762  }
11763  else
11764  {
11765  message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
11766  }
11767  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
11768  }
11769 
11774  bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
11775  {
11776  std::pair<std::size_t, char_int_type> size_and_type;
11777  size_t dimlen = 0;
11778  bool no_ndarray = true;
11779 
11780  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
11781  {
11782  return false;
11783  }
11784 
11785  if (size_and_type.first != npos)
11786  {
11787  if (size_and_type.second != 0)
11788  {
11789  if (size_and_type.second != 'N')
11790  {
11791  for (std::size_t i = 0; i < size_and_type.first; ++i)
11792  {
11793  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
11794  {
11795  return false;
11796  }
11797  dim.push_back(dimlen);
11798  }
11799  }
11800  }
11801  else
11802  {
11803  for (std::size_t i = 0; i < size_and_type.first; ++i)
11804  {
11805  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
11806  {
11807  return false;
11808  }
11809  dim.push_back(dimlen);
11810  }
11811  }
11812  }
11813  else
11814  {
11815  while (current != ']')
11816  {
11817  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
11818  {
11819  return false;
11820  }
11821  dim.push_back(dimlen);
11822  get_ignore_noop();
11823  }
11824  }
11825  return true;
11826  }
11827 
11839  bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
11840  {
11841  if (prefix == 0)
11842  {
11843  prefix = get_ignore_noop();
11844  }
11845 
11846  switch (prefix)
11847  {
11848  case 'U':
11849  {
11850  std::uint8_t number{};
11851  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11852  {
11853  return false;
11854  }
11855  result = static_cast<std::size_t>(number);
11856  return true;
11857  }
11858 
11859  case 'i':
11860  {
11861  std::int8_t number{};
11862  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11863  {
11864  return false;
11865  }
11866  if (number < 0)
11867  {
11868  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11869  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11870  }
11871  result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
11872  return true;
11873  }
11874 
11875  case 'I':
11876  {
11877  std::int16_t number{};
11878  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11879  {
11880  return false;
11881  }
11882  if (number < 0)
11883  {
11884  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11885  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11886  }
11887  result = static_cast<std::size_t>(number);
11888  return true;
11889  }
11890 
11891  case 'l':
11892  {
11893  std::int32_t number{};
11894  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11895  {
11896  return false;
11897  }
11898  if (number < 0)
11899  {
11900  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11901  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11902  }
11903  result = static_cast<std::size_t>(number);
11904  return true;
11905  }
11906 
11907  case 'L':
11908  {
11909  std::int64_t number{};
11910  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11911  {
11912  return false;
11913  }
11914  if (number < 0)
11915  {
11916  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11917  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11918  }
11919  if (!value_in_range_of<std::size_t>(number))
11920  {
11921  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11922  exception_message(input_format, "integer value overflow", "size"), nullptr));
11923  }
11924  result = static_cast<std::size_t>(number);
11925  return true;
11926  }
11927 
11928  case 'u':
11929  {
11930  if (input_format != input_format_t::bjdata)
11931  {
11932  break;
11933  }
11934  std::uint16_t number{};
11935  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11936  {
11937  return false;
11938  }
11939  result = static_cast<std::size_t>(number);
11940  return true;
11941  }
11942 
11943  case 'm':
11944  {
11945  if (input_format != input_format_t::bjdata)
11946  {
11947  break;
11948  }
11949  std::uint32_t number{};
11950  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11951  {
11952  return false;
11953  }
11954  result = conditional_static_cast<std::size_t>(number);
11955  return true;
11956  }
11957 
11958  case 'M':
11959  {
11960  if (input_format != input_format_t::bjdata)
11961  {
11962  break;
11963  }
11964  std::uint64_t number{};
11965  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11966  {
11967  return false;
11968  }
11969  if (!value_in_range_of<std::size_t>(number))
11970  {
11971  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11972  exception_message(input_format, "integer value overflow", "size"), nullptr));
11973  }
11974  result = detail::conditional_static_cast<std::size_t>(number);
11975  return true;
11976  }
11977 
11978  case '[':
11979  {
11980  if (input_format != input_format_t::bjdata)
11981  {
11982  break;
11983  }
11984  if (is_ndarray) // ndarray dimensional vector can only contain integers and cannot embed another array
11985  {
11986  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));
11987  }
11988  std::vector<size_t> dim;
11989  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
11990  {
11991  return false;
11992  }
11993  if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
11994  {
11995  result = dim.at(dim.size() - 1);
11996  return true;
11997  }
11998  if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
11999  {
12000  for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
12001  {
12002  if ( i == 0 )
12003  {
12004  result = 0;
12005  return true;
12006  }
12007  }
12008 
12009  string_t key = "_ArraySize_";
12010  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
12011  {
12012  return false;
12013  }
12014  result = 1;
12015  for (auto i : dim)
12016  {
12017  // Pre-multiplication overflow check: if i > 0 and result > SIZE_MAX/i, then result*i would overflow.
12018  // This check must happen before multiplication since overflow detection after the fact is unreliable
12019  // as modular arithmetic can produce any value, not just 0 or SIZE_MAX.
12020  if (JSON_HEDLEY_UNLIKELY(i > 0 && result > (std::numeric_limits<std::size_t>::max)() / i))
12021  {
12022  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));
12023  }
12024  result *= i;
12025  // Additional post-multiplication check to catch any edge cases the pre-check might miss
12026  if (result == 0 || result == npos)
12027  {
12028  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));
12029  }
12030  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
12031  {
12032  return false;
12033  }
12034  }
12035  is_ndarray = true;
12036  return sax->end_array();
12037  }
12038  result = 0;
12039  return true;
12040  }
12041 
12042  default:
12043  break;
12044  }
12045  auto last_token = get_token_string();
12046  std::string message;
12047 
12048  if (input_format != input_format_t::bjdata)
12049  {
12050  message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
12051  }
12052  else
12053  {
12054  message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
12055  }
12056  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
12057  }
12058 
12070  bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
12071  {
12072  result.first = npos; // size
12073  result.second = 0; // type
12074  bool is_ndarray = false;
12075 
12076  get_ignore_noop();
12077 
12078  if (current == '$')
12079  {
12080  result.second = get(); // must not ignore 'N', because 'N' maybe the type
12081  if (input_format == input_format_t::bjdata
12082  && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
12083  {
12084  auto last_token = get_token_string();
12085  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
12086  exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
12087  }
12088 
12089  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
12090  {
12091  return false;
12092  }
12093 
12094  get_ignore_noop();
12095  if (JSON_HEDLEY_UNLIKELY(current != '#'))
12096  {
12097  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
12098  {
12099  return false;
12100  }
12101  auto last_token = get_token_string();
12102  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
12103  exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
12104  }
12105 
12106  const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
12107  if (input_format == input_format_t::bjdata && is_ndarray)
12108  {
12109  if (inside_ndarray)
12110  {
12111  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
12112  exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
12113  }
12114  result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
12115  }
12116  return is_error;
12117  }
12118 
12119  if (current == '#')
12120  {
12121  const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
12122  if (input_format == input_format_t::bjdata && is_ndarray)
12123  {
12124  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
12125  exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
12126  }
12127  return is_error;
12128  }
12129 
12130  return true;
12131  }
12132 
12137  bool get_ubjson_value(const char_int_type prefix)
12138  {
12139  switch (prefix)
12140  {
12141  case char_traits<char_type>::eof(): // EOF
12142  return unexpect_eof(input_format, "value");
12143 
12144  case 'T': // true
12145  return sax->boolean(true);
12146  case 'F': // false
12147  return sax->boolean(false);
12148 
12149  case 'Z': // null
12150  return sax->null();
12151 
12152  case 'B': // byte
12153  {
12154  if (input_format != input_format_t::bjdata)
12155  {
12156  break;
12157  }
12158  std::uint8_t number{};
12159  return get_number(input_format, number) && sax->number_unsigned(number);
12160  }
12161 
12162  case 'U':
12163  {
12164  std::uint8_t number{};
12165  return get_number(input_format, number) && sax->number_unsigned(number);
12166  }
12167 
12168  case 'i':
12169  {
12170  std::int8_t number{};
12171  return get_number(input_format, number) && sax->number_integer(number);
12172  }
12173 
12174  case 'I':
12175  {
12176  std::int16_t number{};
12177  return get_number(input_format, number) && sax->number_integer(number);
12178  }
12179 
12180  case 'l':
12181  {
12182  std::int32_t number{};
12183  return get_number(input_format, number) && sax->number_integer(number);
12184  }
12185 
12186  case 'L':
12187  {
12188  std::int64_t number{};
12189  return get_number(input_format, number) && sax->number_integer(number);
12190  }
12191 
12192  case 'u':
12193  {
12194  if (input_format != input_format_t::bjdata)
12195  {
12196  break;
12197  }
12198  std::uint16_t number{};
12199  return get_number(input_format, number) && sax->number_unsigned(number);
12200  }
12201 
12202  case 'm':
12203  {
12204  if (input_format != input_format_t::bjdata)
12205  {
12206  break;
12207  }
12208  std::uint32_t number{};
12209  return get_number(input_format, number) && sax->number_unsigned(number);
12210  }
12211 
12212  case 'M':
12213  {
12214  if (input_format != input_format_t::bjdata)
12215  {
12216  break;
12217  }
12218  std::uint64_t number{};
12219  return get_number(input_format, number) && sax->number_unsigned(number);
12220  }
12221 
12222  case 'h':
12223  {
12224  if (input_format != input_format_t::bjdata)
12225  {
12226  break;
12227  }
12228  const auto byte1_raw = get();
12229  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
12230  {
12231  return false;
12232  }
12233  const auto byte2_raw = get();
12234  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
12235  {
12236  return false;
12237  }
12238 
12239  const auto byte1 = static_cast<unsigned char>(byte1_raw);
12240  const auto byte2 = static_cast<unsigned char>(byte2_raw);
12241 
12242  // Code from RFC 7049, Appendix D, Figure 3:
12243  // As half-precision floating-point numbers were only added
12244  // to IEEE 754 in 2008, today's programming platforms often
12245  // still only have limited support for them. It is very
12246  // easy to include at least decoding support for them even
12247  // without such support. An example of a small decoder for
12248  // half-precision floating-point numbers in the C language
12249  // is shown in Fig. 3.
12250  const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
12251  const double val = [&half]
12252  {
12253  const int exp = (half >> 10u) & 0x1Fu;
12254  const unsigned int mant = half & 0x3FFu;
12255  JSON_ASSERT(0 <= exp&& exp <= 32);
12256  JSON_ASSERT(mant <= 1024);
12257  switch (exp)
12258  {
12259  case 0:
12260  return std::ldexp(mant, -24);
12261  case 31:
12262  return (mant == 0)
12263  ? std::numeric_limits<double>::infinity()
12264  : std::numeric_limits<double>::quiet_NaN();
12265  default:
12266  return std::ldexp(mant + 1024, exp - 25);
12267  }
12268  }();
12269  return sax->number_float((half & 0x8000u) != 0
12270  ? static_cast<number_float_t>(-val)
12271  : static_cast<number_float_t>(val), "");
12272  }
12273 
12274  case 'd':
12275  {
12276  float number{};
12277  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
12278  }
12279 
12280  case 'D':
12281  {
12282  double number{};
12283  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
12284  }
12285 
12286  case 'H':
12287  {
12288  return get_ubjson_high_precision_number();
12289  }
12290 
12291  case 'C': // char
12292  {
12293  get();
12294  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
12295  {
12296  return false;
12297  }
12298  if (JSON_HEDLEY_UNLIKELY(current > 127))
12299  {
12300  auto last_token = get_token_string();
12301  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
12302  exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
12303  }
12304  string_t s(1, static_cast<typename string_t::value_type>(current));
12305  return sax->string(s);
12306  }
12307 
12308  case 'S': // string
12309  {
12310  string_t s;
12311  return get_ubjson_string(s) && sax->string(s);
12312  }
12313 
12314  case '[': // array
12315  return get_ubjson_array();
12316 
12317  case '{': // object
12318  return get_ubjson_object();
12319 
12320  default: // anything else
12321  break;
12322  }
12323  auto last_token = get_token_string();
12324  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));
12325  }
12326 
12331  {
12332  std::pair<std::size_t, char_int_type> size_and_type;
12333  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
12334  {
12335  return false;
12336  }
12337 
12338  // 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):
12339  // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
12340 
12341  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
12342  {
12343  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
12344  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)
12345  {
12346  return p.first < t;
12347  });
12348  string_t key = "_ArrayType_";
12349  if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
12350  {
12351  auto last_token = get_token_string();
12352  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
12353  exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
12354  }
12355 
12356  string_t type = it->second; // sax->string() takes a reference
12357  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type)))
12358  {
12359  return false;
12360  }
12361 
12362  if (size_and_type.second == 'C' || size_and_type.second == 'B')
12363  {
12364  size_and_type.second = 'U';
12365  }
12366 
12367  key = "_ArrayData_";
12368  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) ))
12369  {
12370  return false;
12371  }
12372 
12373  for (std::size_t i = 0; i < size_and_type.first; ++i)
12374  {
12375  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
12376  {
12377  return false;
12378  }
12379  }
12380 
12381  return (sax->end_array() && sax->end_object());
12382  }
12383 
12384  // If BJData type marker is 'B' decode as binary
12385  if (input_format == input_format_t::bjdata && size_and_type.first != npos && size_and_type.second == 'B')
12386  {
12387  binary_t result;
12388  return get_binary(input_format, size_and_type.first, result) && sax->binary(result);
12389  }
12390 
12391  if (size_and_type.first != npos)
12392  {
12393  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
12394  {
12395  return false;
12396  }
12397 
12398  if (size_and_type.second != 0)
12399  {
12400  if (size_and_type.second != 'N')
12401  {
12402  for (std::size_t i = 0; i < size_and_type.first; ++i)
12403  {
12404  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
12405  {
12406  return false;
12407  }
12408  }
12409  }
12410  }
12411  else
12412  {
12413  for (std::size_t i = 0; i < size_and_type.first; ++i)
12414  {
12415  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
12416  {
12417  return false;
12418  }
12419  }
12420  }
12421  }
12422  else
12423  {
12424  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
12425  {
12426  return false;
12427  }
12428 
12429  while (current != ']')
12430  {
12431  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
12432  {
12433  return false;
12434  }
12435  get_ignore_noop();
12436  }
12437  }
12438 
12439  return sax->end_array();
12440  }
12441 
12446  {
12447  std::pair<std::size_t, char_int_type> size_and_type;
12448  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
12449  {
12450  return false;
12451  }
12452 
12453  // do not accept ND-array size in objects in BJData
12454  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
12455  {
12456  auto last_token = get_token_string();
12457  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
12458  exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
12459  }
12460 
12461  string_t key;
12462  if (size_and_type.first != npos)
12463  {
12464  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
12465  {
12466  return false;
12467  }
12468 
12469  if (size_and_type.second != 0)
12470  {
12471  for (std::size_t i = 0; i < size_and_type.first; ++i)
12472  {
12473  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
12474  {
12475  return false;
12476  }
12477  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
12478  {
12479  return false;
12480  }
12481  key.clear();
12482  }
12483  }
12484  else
12485  {
12486  for (std::size_t i = 0; i < size_and_type.first; ++i)
12487  {
12488  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
12489  {
12490  return false;
12491  }
12492  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
12493  {
12494  return false;
12495  }
12496  key.clear();
12497  }
12498  }
12499  }
12500  else
12501  {
12502  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
12503  {
12504  return false;
12505  }
12506 
12507  while (current != '}')
12508  {
12509  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
12510  {
12511  return false;
12512  }
12513  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
12514  {
12515  return false;
12516  }
12517  get_ignore_noop();
12518  key.clear();
12519  }
12520  }
12521 
12522  return sax->end_object();
12523  }
12524 
12525  // Note, no reader for UBJSON binary types is implemented because they do
12526  // not exist
12527 
12529  {
12530  // get the size of the following number string
12531  std::size_t size{};
12532  bool no_ndarray = true;
12533  auto res = get_ubjson_size_value(size, no_ndarray);
12534  if (JSON_HEDLEY_UNLIKELY(!res))
12535  {
12536  return res;
12537  }
12538 
12539  // get number string
12540  std::vector<char> number_vector;
12541  for (std::size_t i = 0; i < size; ++i)
12542  {
12543  get();
12544  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
12545  {
12546  return false;
12547  }
12548  number_vector.push_back(static_cast<char>(current));
12549  }
12550 
12551  // parse number string
12552  using ia_type = decltype(detail::input_adapter(number_vector));
12553  auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
12554  const auto result_number = number_lexer.scan();
12555  const auto number_string = number_lexer.get_token_string();
12556  const auto result_remainder = number_lexer.scan();
12557 
12558  using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
12559 
12560  if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
12561  {
12562  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
12563  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
12564  }
12565 
12566  switch (result_number)
12567  {
12568  case token_type::value_integer:
12569  return sax->number_integer(number_lexer.get_number_integer());
12570  case token_type::value_unsigned:
12571  return sax->number_unsigned(number_lexer.get_number_unsigned());
12572  case token_type::value_float:
12573  return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
12574  case token_type::uninitialized:
12575  case token_type::literal_true:
12576  case token_type::literal_false:
12577  case token_type::literal_null:
12578  case token_type::value_string:
12579  case token_type::begin_array:
12580  case token_type::begin_object:
12581  case token_type::end_array:
12582  case token_type::end_object:
12583  case token_type::name_separator:
12584  case token_type::value_separator:
12585  case token_type::parse_error:
12586  case token_type::end_of_input:
12587  case token_type::literal_or_value:
12588  default:
12589  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
12590  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
12591  }
12592  }
12593 
12595  // Utility functions //
12597 
12608  {
12609  ++chars_read;
12610  return current = ia.get_character();
12611  }
12612 
12621  template<class T>
12622  bool get_to(T& dest, const input_format_t format, const char* context)
12623  {
12624  auto new_chars_read = ia.get_elements(&dest);
12625  chars_read += new_chars_read;
12626  if (JSON_HEDLEY_UNLIKELY(new_chars_read < sizeof(T)))
12627  {
12628  // in case of failure, advance position by 1 to report the failing location
12629  ++chars_read;
12630  sax->parse_error(chars_read, "<end of file>", parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
12631  return false;
12632  }
12633  return true;
12634  }
12635 
12640  {
12641  do
12642  {
12643  get();
12644  }
12645  while (current == 'N');
12646 
12647  return current;
12648  }
12649 
12650  template<class NumberType>
12651  static void byte_swap(NumberType& number)
12652  {
12653  constexpr std::size_t sz = sizeof(number);
12654 #ifdef __cpp_lib_byteswap
12655  if constexpr (sz == 1)
12656  {
12657  return;
12658  }
12659  else if constexpr(std::is_integral_v<NumberType>)
12660  {
12661  number = std::byteswap(number);
12662  return;
12663  }
12664  else
12665  {
12666 #endif
12667  auto* ptr = reinterpret_cast<std::uint8_t*>(&number);
12668  for (std::size_t i = 0; i < sz / 2; ++i)
12669  {
12670  std::swap(ptr[i], ptr[sz - i - 1]);
12671  }
12672 #ifdef __cpp_lib_byteswap
12673  }
12674 #endif
12675  }
12676 
12677  /*
12678  @brief read a number from the input
12679 
12680  @tparam NumberType the type of the number
12681  @param[in] format the current format (for diagnostics)
12682  @param[out] result number of type @a NumberType
12683 
12684  @return whether conversion completed
12685 
12686  @note This function needs to respect the system's endianness, because
12687  bytes in CBOR, MessagePack, and UBJSON are stored in network order
12688  (big endian) and therefore need reordering on little endian systems.
12689  On the other hand, BSON and BJData use little endian and should reorder
12690  on big endian systems.
12691  */
12692  template<typename NumberType, bool InputIsLittleEndian = false>
12693  bool get_number(const input_format_t format, NumberType& result)
12694  {
12695  // read in the original format
12696 
12697  if (JSON_HEDLEY_UNLIKELY(!get_to(result, format, "number")))
12698  {
12699  return false;
12700  }
12701  if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
12702  {
12703  byte_swap(result);
12704  }
12705  return true;
12706  }
12707 
12722  template<typename NumberType>
12723  bool get_string(const input_format_t format,
12724  const NumberType len,
12725  string_t& result)
12726  {
12727  bool success = true;
12728  for (NumberType i = 0; i < len; i++)
12729  {
12730  get();
12731  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
12732  {
12733  success = false;
12734  break;
12735  }
12736  result.push_back(static_cast<typename string_t::value_type>(current));
12737  }
12738  return success;
12739  }
12740 
12755  template<typename NumberType>
12756  bool get_binary(const input_format_t format,
12757  const NumberType len,
12758  binary_t& result)
12759  {
12760  bool success = true;
12761  for (NumberType i = 0; i < len; i++)
12762  {
12763  get();
12764  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
12765  {
12766  success = false;
12767  break;
12768  }
12769  result.push_back(static_cast<typename binary_t::value_type>(current));
12770  }
12771  return success;
12772  }
12773 
12780  bool unexpect_eof(const input_format_t format, const char* context) const
12781  {
12783  {
12784  return sax->parse_error(chars_read, "<end of file>",
12785  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
12786  }
12787  return true;
12788  }
12789 
12793  std::string get_token_string() const
12794  {
12795  std::array<char, 3> cr{{}};
12796  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
12797  return std::string{cr.data()};
12798  }
12799 
12806  std::string exception_message(const input_format_t format,
12807  const std::string& detail,
12808  const std::string& context) const
12809  {
12810  std::string error_msg = "syntax error while parsing ";
12811 
12812  switch (format)
12813  {
12814  case input_format_t::cbor:
12815  error_msg += "CBOR";
12816  break;
12817 
12818  case input_format_t::msgpack:
12819  error_msg += "MessagePack";
12820  break;
12821 
12822  case input_format_t::ubjson:
12823  error_msg += "UBJSON";
12824  break;
12825 
12826  case input_format_t::bson:
12827  error_msg += "BSON";
12828  break;
12829 
12830  case input_format_t::bjdata:
12831  error_msg += "BJData";
12832  break;
12833 
12834  case input_format_t::json: // LCOV_EXCL_LINE
12835  default: // LCOV_EXCL_LINE
12836  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
12837  }
12838 
12839  return concat(error_msg, ' ', context, ": ", detail);
12840  }
12841 
12842  private:
12843  static JSON_INLINE_VARIABLE constexpr std::size_t npos = detail::unknown_size();
12844 
12846  InputAdapterType ia;
12847 
12850 
12852  std::size_t chars_read = 0;
12853 
12856 
12858  const input_format_t input_format = input_format_t::json;
12859 
12861  json_sax_t* sax = nullptr;
12862 
12863  // excluded markers in bjdata optimized type
12864 #define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \
12865  make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
12866 
12867 #define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
12868  make_array<bjd_type>( \
12869  bjd_type{'B', "byte"}, \
12870  bjd_type{'C', "char"}, \
12871  bjd_type{'D', "double"}, \
12872  bjd_type{'I', "int16"}, \
12873  bjd_type{'L', "int64"}, \
12874  bjd_type{'M', "uint64"}, \
12875  bjd_type{'U', "uint8"}, \
12876  bjd_type{'d', "single"}, \
12877  bjd_type{'i', "int8"}, \
12878  bjd_type{'l', "int32"}, \
12879  bjd_type{'m', "uint32"}, \
12880  bjd_type{'u', "uint16"})
12881 
12883  // lookup tables
12884  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12885  const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =
12887 
12888  using bjd_type = std::pair<char_int_type, string_t>;
12889  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12890  const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map =
12892 
12893 #undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
12894 #undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
12895 };
12896 
12897 #ifndef JSON_HAS_CPP_17
12898  template<typename BasicJsonType, typename InputAdapterType, typename SAX>
12900 #endif
12901 
12902 } // namespace detail
12904 
12905 // #include <nlohmann/detail/input/input_adapters.hpp>
12906 
12907 // #include <nlohmann/detail/input/lexer.hpp>
12908 
12909 // #include <nlohmann/detail/input/parser.hpp>
12910 // __ _____ _____ _____
12911 // __| | __| | | | JSON for Modern C++
12912 // | | |__ | | | | | | version 3.12.0
12913 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12914 //
12915 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
12916 // SPDX-License-Identifier: MIT
12917 
12918 
12919 
12920 #include <cmath> // isfinite
12921 #include <cstdint> // uint8_t
12922 #include <functional> // function
12923 #include <string> // string
12924 #include <utility> // move
12925 #include <vector> // vector
12926 
12927 // #include <nlohmann/detail/exceptions.hpp>
12928 
12929 // #include <nlohmann/detail/input/input_adapters.hpp>
12930 
12931 // #include <nlohmann/detail/input/json_sax.hpp>
12932 
12933 // #include <nlohmann/detail/input/lexer.hpp>
12934 
12935 // #include <nlohmann/detail/macro_scope.hpp>
12936 
12937 // #include <nlohmann/detail/meta/is_sax.hpp>
12938 
12939 // #include <nlohmann/detail/string_concat.hpp>
12940 
12941 // #include <nlohmann/detail/value_t.hpp>
12942 
12943 
12945 namespace detail
12946 {
12948 // parser //
12950 
12952 {
12954  object_start,
12956  object_end,
12958  array_start,
12960  array_end,
12962  key,
12964  value
12965 };
12966 
12967 template<typename BasicJsonType>
12969  std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
12970 
12976 template<typename BasicJsonType, typename InputAdapterType>
12977 class parser
12978 {
12979  using number_integer_t = typename BasicJsonType::number_integer_t;
12980  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12981  using number_float_t = typename BasicJsonType::number_float_t;
12985 
12986  public:
12988  explicit parser(InputAdapterType&& adapter,
12989  parser_callback_t<BasicJsonType> cb = nullptr,
12990  const bool allow_exceptions_ = true,
12991  const bool ignore_comments = false,
12992  const bool ignore_trailing_commas_ = false)
12993  : callback(std::move(cb))
12994  , m_lexer(std::move(adapter), ignore_comments)
12995  , allow_exceptions(allow_exceptions_)
12996  , ignore_trailing_commas(ignore_trailing_commas_)
12997  {
12998  // read first token
12999  get_token();
13000  }
13001 
13012  void parse(const bool strict, BasicJsonType& result)
13013  {
13014  if (callback)
13015  {
13016  json_sax_dom_callback_parser<BasicJsonType, InputAdapterType> sdp(result, callback, allow_exceptions, &m_lexer);
13017  sax_parse_internal(&sdp);
13018 
13019  // in strict mode, input must be completely read
13020  if (strict && (get_token() != token_type::end_of_input))
13021  {
13022  sdp.parse_error(m_lexer.get_position(),
13023  m_lexer.get_token_string(),
13024  parse_error::create(101, m_lexer.get_position(),
13025  exception_message(token_type::end_of_input, "value"), nullptr));
13026  }
13027 
13028  // in case of an error, return a discarded value
13029  if (sdp.is_errored())
13030  {
13031  result = value_t::discarded;
13032  return;
13033  }
13034 
13035  // set top-level value to null if it was discarded by the callback
13036  // function
13037  if (result.is_discarded())
13038  {
13039  result = nullptr;
13040  }
13041  }
13042  else
13043  {
13044  json_sax_dom_parser<BasicJsonType, InputAdapterType> sdp(result, allow_exceptions, &m_lexer);
13045  sax_parse_internal(&sdp);
13046 
13047  // in strict mode, input must be completely read
13048  if (strict && (get_token() != token_type::end_of_input))
13049  {
13050  sdp.parse_error(m_lexer.get_position(),
13051  m_lexer.get_token_string(),
13052  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
13053  }
13054 
13055  // in case of an error, return a discarded value
13056  if (sdp.is_errored())
13057  {
13058  result = value_t::discarded;
13059  return;
13060  }
13061  }
13062 
13063  result.assert_invariant();
13064  }
13065 
13072  bool accept(const bool strict = true)
13073  {
13074  json_sax_acceptor<BasicJsonType> sax_acceptor;
13075  return sax_parse(&sax_acceptor, strict);
13076  }
13077 
13078  template<typename SAX>
13080  bool sax_parse(SAX* sax, const bool strict = true)
13081  {
13083  const bool result = sax_parse_internal(sax);
13084 
13085  // strict mode: next byte must be EOF
13086  if (result && strict && (get_token() != token_type::end_of_input))
13087  {
13088  return sax->parse_error(m_lexer.get_position(),
13089  m_lexer.get_token_string(),
13090  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
13091  }
13092 
13093  return result;
13094  }
13095 
13096  private:
13097  template<typename SAX>
13099  bool sax_parse_internal(SAX* sax)
13100  {
13101  // stack to remember the hierarchy of structured values we are parsing
13102  // true = array; false = object
13103  std::vector<bool> states;
13104  // value to avoid a goto (see comment where set to true)
13105  bool skip_to_state_evaluation = false;
13106 
13107  while (true)
13108  {
13109  if (!skip_to_state_evaluation)
13110  {
13111  // invariant: get_token() was called before each iteration
13112  switch (last_token)
13113  {
13114  case token_type::begin_object:
13115  {
13116  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
13117  {
13118  return false;
13119  }
13120 
13121  // closing } -> we are done
13122  if (get_token() == token_type::end_object)
13123  {
13124  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
13125  {
13126  return false;
13127  }
13128  break;
13129  }
13130 
13131  // parse key
13132  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
13133  {
13134  return sax->parse_error(m_lexer.get_position(),
13135  m_lexer.get_token_string(),
13136  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
13137  }
13138  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
13139  {
13140  return false;
13141  }
13142 
13143  // parse separator (:)
13144  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
13145  {
13146  return sax->parse_error(m_lexer.get_position(),
13147  m_lexer.get_token_string(),
13148  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
13149  }
13150 
13151  // remember we are now inside an object
13152  states.push_back(false);
13153 
13154  // parse values
13155  get_token();
13156  continue;
13157  }
13158 
13159  case token_type::begin_array:
13160  {
13161  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
13162  {
13163  return false;
13164  }
13165 
13166  // closing ] -> we are done
13167  if (get_token() == token_type::end_array)
13168  {
13169  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
13170  {
13171  return false;
13172  }
13173  break;
13174  }
13175 
13176  // remember we are now inside an array
13177  states.push_back(true);
13178 
13179  // parse values (no need to call get_token)
13180  continue;
13181  }
13182 
13183  case token_type::value_float:
13184  {
13185  const auto res = m_lexer.get_number_float();
13186 
13187  if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
13188  {
13189  return sax->parse_error(m_lexer.get_position(),
13190  m_lexer.get_token_string(),
13191  out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
13192  }
13193 
13194  if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
13195  {
13196  return false;
13197  }
13198 
13199  break;
13200  }
13201 
13202  case token_type::literal_false:
13203  {
13204  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
13205  {
13206  return false;
13207  }
13208  break;
13209  }
13210 
13211  case token_type::literal_null:
13212  {
13213  if (JSON_HEDLEY_UNLIKELY(!sax->null()))
13214  {
13215  return false;
13216  }
13217  break;
13218  }
13219 
13220  case token_type::literal_true:
13221  {
13222  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
13223  {
13224  return false;
13225  }
13226  break;
13227  }
13228 
13229  case token_type::value_integer:
13230  {
13231  if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
13232  {
13233  return false;
13234  }
13235  break;
13236  }
13237 
13238  case token_type::value_string:
13239  {
13240  if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
13241  {
13242  return false;
13243  }
13244  break;
13245  }
13246 
13247  case token_type::value_unsigned:
13248  {
13249  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
13250  {
13251  return false;
13252  }
13253  break;
13254  }
13255 
13256  case token_type::parse_error:
13257  {
13258  // using "uninitialized" to avoid an "expected" message
13259  return sax->parse_error(m_lexer.get_position(),
13260  m_lexer.get_token_string(),
13261  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
13262  }
13263  case token_type::end_of_input:
13264  {
13265  if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1))
13266  {
13267  return sax->parse_error(m_lexer.get_position(),
13268  m_lexer.get_token_string(),
13269  parse_error::create(101, m_lexer.get_position(),
13270  "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
13271  }
13272 
13273  return sax->parse_error(m_lexer.get_position(),
13274  m_lexer.get_token_string(),
13275  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
13276  }
13277  case token_type::uninitialized:
13278  case token_type::end_array:
13279  case token_type::end_object:
13280  case token_type::name_separator:
13281  case token_type::value_separator:
13282  case token_type::literal_or_value:
13283  default: // the last token was unexpected
13284  {
13285  return sax->parse_error(m_lexer.get_position(),
13286  m_lexer.get_token_string(),
13287  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
13288  }
13289  }
13290  }
13291  else
13292  {
13293  skip_to_state_evaluation = false;
13294  }
13295 
13296  // we reached this line after we successfully parsed a value
13297  if (states.empty())
13298  {
13299  // empty stack: we reached the end of the hierarchy: done
13300  return true;
13301  }
13302 
13303  if (states.back()) // array
13304  {
13305  // comma -> next value
13306  // or end of array (ignore_trailing_commas = true)
13307  if (get_token() == token_type::value_separator)
13308  {
13309  // parse a new value
13310  get_token();
13311 
13312  // if ignore_trailing_commas and last_token is ], we can continue to "closing ]"
13313  if (!(ignore_trailing_commas && last_token == token_type::end_array))
13314  {
13315  continue;
13316  }
13317  }
13318 
13319  // closing ]
13320  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
13321  {
13322  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
13323  {
13324  return false;
13325  }
13326 
13327  // We are done with this array. Before we can parse a
13328  // new value, we need to evaluate the new state first.
13329  // By setting skip_to_state_evaluation to false, we
13330  // are effectively jumping to the beginning of this if.
13331  JSON_ASSERT(!states.empty());
13332  states.pop_back();
13333  skip_to_state_evaluation = true;
13334  continue;
13335  }
13336 
13337  return sax->parse_error(m_lexer.get_position(),
13338  m_lexer.get_token_string(),
13339  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
13340  }
13341 
13342  // states.back() is false -> object
13343 
13344  // comma -> next value
13345  // or end of object (ignore_trailing_commas = true)
13346  if (get_token() == token_type::value_separator)
13347  {
13348  get_token();
13349 
13350  // if ignore_trailing_commas and last_token is }, we can continue to "closing }"
13351  if (!(ignore_trailing_commas && last_token == token_type::end_object))
13352  {
13353  // parse key
13354  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
13355  {
13356  return sax->parse_error(m_lexer.get_position(),
13357  m_lexer.get_token_string(),
13358  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
13359  }
13360 
13361  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
13362  {
13363  return false;
13364  }
13365 
13366  // parse separator (:)
13367  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
13368  {
13369  return sax->parse_error(m_lexer.get_position(),
13370  m_lexer.get_token_string(),
13371  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
13372  }
13373 
13374  // parse values
13375  get_token();
13376  continue;
13377  }
13378  }
13379 
13380  // closing }
13381  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
13382  {
13383  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
13384  {
13385  return false;
13386  }
13387 
13388  // We are done with this object. Before we can parse a
13389  // new value, we need to evaluate the new state first.
13390  // By setting skip_to_state_evaluation to false, we
13391  // are effectively jumping to the beginning of this if.
13392  JSON_ASSERT(!states.empty());
13393  states.pop_back();
13394  skip_to_state_evaluation = true;
13395  continue;
13396  }
13397 
13398  return sax->parse_error(m_lexer.get_position(),
13399  m_lexer.get_token_string(),
13400  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
13401  }
13402  }
13403 
13406  {
13407  return last_token = m_lexer.scan();
13408  }
13409 
13410  std::string exception_message(const token_type expected, const std::string& context)
13411  {
13412  std::string error_msg = "syntax error ";
13413 
13414  if (!context.empty())
13415  {
13416  error_msg += concat("while parsing ", context, ' ');
13417  }
13418 
13419  error_msg += "- ";
13420 
13421  if (last_token == token_type::parse_error)
13422  {
13423  error_msg += concat(m_lexer.get_error_message(), "; last read: '",
13424  m_lexer.get_token_string(), '\'');
13425  }
13426  else
13427  {
13428  error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
13429  }
13430 
13431  if (expected != token_type::uninitialized)
13432  {
13433  error_msg += concat("; expected ", lexer_t::token_type_name(expected));
13434  }
13435 
13436  return error_msg;
13437  }
13438 
13439  private:
13441  const parser_callback_t<BasicJsonType> callback = nullptr;
13443  token_type last_token = token_type::uninitialized;
13447  const bool allow_exceptions = true;
13449  const bool ignore_trailing_commas = false;
13450 };
13451 
13452 } // namespace detail
13454 
13455 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
13456 // __ _____ _____ _____
13457 // __| | __| | | | JSON for Modern C++
13458 // | | |__ | | | | | | version 3.12.0
13459 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13460 //
13461 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
13462 // SPDX-License-Identifier: MIT
13463 
13464 
13465 
13466 // #include <nlohmann/detail/abi_macros.hpp>
13467 
13468 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13469 // __ _____ _____ _____
13470 // __| | __| | | | JSON for Modern C++
13471 // | | |__ | | | | | | version 3.12.0
13472 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13473 //
13474 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
13475 // SPDX-License-Identifier: MIT
13476 
13477 
13478 
13479 #include <cstddef> // ptrdiff_t
13480 #include <limits> // numeric_limits
13481 
13482 // #include <nlohmann/detail/macro_scope.hpp>
13483 
13484 
13486 namespace detail
13487 {
13488 
13489 /*
13490 @brief an iterator for primitive JSON types
13491 
13492 This class models an iterator for primitive JSON types (boolean, number,
13493 string). Its only purpose is to allow the iterator/const_iterator classes
13494 to "iterate" over primitive values. Internally, the iterator is modeled by
13495 a `difference_type` variable. Value begin_value (`0`) models the begin and
13496 end_value (`1`) models past the end.
13497 */
13499 {
13500  private:
13501  using difference_type = std::ptrdiff_t;
13502  static constexpr difference_type begin_value = 0;
13503  static constexpr difference_type end_value = begin_value + 1;
13504 
13507  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
13508 
13509  public:
13510  constexpr difference_type get_value() const noexcept
13511  {
13512  return m_it;
13513  }
13514 
13516  void set_begin() noexcept
13517  {
13518  m_it = begin_value;
13519  }
13520 
13522  void set_end() noexcept
13523  {
13524  m_it = end_value;
13525  }
13526 
13528  constexpr bool is_begin() const noexcept
13529  {
13530  return m_it == begin_value;
13531  }
13532 
13534  constexpr bool is_end() const noexcept
13535  {
13536  return m_it == end_value;
13537  }
13538 
13539  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
13540  {
13541  return lhs.m_it == rhs.m_it;
13542  }
13543 
13544  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
13545  {
13546  return lhs.m_it < rhs.m_it;
13547  }
13548 
13550  {
13551  auto result = *this;
13552  result += n;
13553  return result;
13554  }
13555 
13557  {
13558  return lhs.m_it - rhs.m_it;
13559  }
13560 
13562  {
13563  ++m_it;
13564  return *this;
13565  }
13566 
13567  primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
13568  {
13569  auto result = *this;
13570  ++m_it;
13571  return result;
13572  }
13573 
13575  {
13576  --m_it;
13577  return *this;
13578  }
13579 
13580  primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
13581  {
13582  auto result = *this;
13583  --m_it;
13584  return result;
13585  }
13586 
13588  {
13589  m_it += n;
13590  return *this;
13591  }
13592 
13594  {
13595  m_it -= n;
13596  return *this;
13597  }
13598 };
13599 
13600 } // namespace detail
13602 
13603 
13605 namespace detail
13606 {
13607 
13614 template<typename BasicJsonType> struct internal_iterator
13615 {
13617  typename BasicJsonType::object_t::iterator object_iterator {};
13619  typename BasicJsonType::array_t::iterator array_iterator {};
13621  primitive_iterator_t primitive_iterator {};
13622 };
13623 
13624 } // namespace detail
13626 
13627 // #include <nlohmann/detail/iterators/iter_impl.hpp>
13628 // __ _____ _____ _____
13629 // __| | __| | | | JSON for Modern C++
13630 // | | |__ | | | | | | version 3.12.0
13631 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13632 //
13633 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
13634 // SPDX-License-Identifier: MIT
13635 
13636 
13637 
13638 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
13639 #include <type_traits> // conditional, is_const, remove_const
13640 
13641 // #include <nlohmann/detail/exceptions.hpp>
13642 
13643 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
13644 
13645 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13646 
13647 // #include <nlohmann/detail/macro_scope.hpp>
13648 
13649 // #include <nlohmann/detail/meta/cpp_future.hpp>
13650 
13651 // #include <nlohmann/detail/meta/type_traits.hpp>
13652 
13653 // #include <nlohmann/detail/value_t.hpp>
13654 
13655 
13657 namespace detail
13658 {
13659 
13660 // forward declare to be able to friend it later on
13661 template<typename IteratorType> class iteration_proxy;
13662 template<typename IteratorType> class iteration_proxy_value;
13663 
13680 template<typename BasicJsonType>
13681 class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
13682 {
13690 
13691  using object_t = typename BasicJsonType::object_t;
13692  using array_t = typename BasicJsonType::array_t;
13693  // make sure BasicJsonType is basic_json or const basic_json
13695  "iter_impl only accepts (const) basic_json");
13696  // superficial check for the LegacyBidirectionalIterator named requirement
13698  && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
13699  "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
13700 
13701  public:
13707  using iterator_category = std::bidirectional_iterator_tag;
13708 
13710  using value_type = typename BasicJsonType::value_type;
13712  using difference_type = typename BasicJsonType::difference_type;
13715  typename BasicJsonType::const_pointer,
13716  typename BasicJsonType::pointer>::type;
13718  using reference =
13720  typename BasicJsonType::const_reference,
13721  typename BasicJsonType::reference>::type;
13722 
13723  iter_impl() = default;
13724  ~iter_impl() = default;
13725  iter_impl(iter_impl&&) noexcept = default;
13726  iter_impl& operator=(iter_impl&&) noexcept = default;
13727 
13734  explicit iter_impl(pointer object) noexcept : m_object(object)
13735  {
13736  JSON_ASSERT(m_object != nullptr);
13737 
13738  switch (m_object->m_data.m_type)
13739  {
13740  case value_t::object:
13741  {
13742  m_it.object_iterator = typename object_t::iterator();
13743  break;
13744  }
13745 
13746  case value_t::array:
13747  {
13748  m_it.array_iterator = typename array_t::iterator();
13749  break;
13750  }
13751 
13752  case value_t::null:
13753  case value_t::string:
13754  case value_t::boolean:
13755  case value_t::number_integer:
13756  case value_t::number_unsigned:
13757  case value_t::number_float:
13758  case value_t::binary:
13759  case value_t::discarded:
13760  default:
13761  {
13762  m_it.primitive_iterator = primitive_iterator_t();
13763  break;
13764  }
13765  }
13766  }
13767 
13785  : m_object(other.m_object), m_it(other.m_it)
13786  {}
13787 
13795  {
13796  if (&other != this)
13797  {
13798  m_object = other.m_object;
13799  m_it = other.m_it;
13800  }
13801  return *this;
13802  }
13803 
13810  : m_object(other.m_object), m_it(other.m_it)
13811  {}
13812 
13819  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
13820  {
13821  m_object = other.m_object;
13822  m_it = other.m_it;
13823  return *this;
13824  }
13825 
13831  void set_begin() noexcept
13832  {
13833  JSON_ASSERT(m_object != nullptr);
13834 
13835  switch (m_object->m_data.m_type)
13836  {
13837  case value_t::object:
13838  {
13839  m_it.object_iterator = m_object->m_data.m_value.object->begin();
13840  break;
13841  }
13842 
13843  case value_t::array:
13844  {
13845  m_it.array_iterator = m_object->m_data.m_value.array->begin();
13846  break;
13847  }
13848 
13849  case value_t::null:
13850  {
13851  // set to end so begin()==end() is true: null is empty
13852  m_it.primitive_iterator.set_end();
13853  break;
13854  }
13855 
13856  case value_t::string:
13857  case value_t::boolean:
13858  case value_t::number_integer:
13859  case value_t::number_unsigned:
13860  case value_t::number_float:
13861  case value_t::binary:
13862  case value_t::discarded:
13863  default:
13864  {
13865  m_it.primitive_iterator.set_begin();
13866  break;
13867  }
13868  }
13869  }
13870 
13875  void set_end() noexcept
13876  {
13877  JSON_ASSERT(m_object != nullptr);
13878 
13879  switch (m_object->m_data.m_type)
13880  {
13881  case value_t::object:
13882  {
13883  m_it.object_iterator = m_object->m_data.m_value.object->end();
13884  break;
13885  }
13886 
13887  case value_t::array:
13888  {
13889  m_it.array_iterator = m_object->m_data.m_value.array->end();
13890  break;
13891  }
13892 
13893  case value_t::null:
13894  case value_t::string:
13895  case value_t::boolean:
13896  case value_t::number_integer:
13897  case value_t::number_unsigned:
13898  case value_t::number_float:
13899  case value_t::binary:
13900  case value_t::discarded:
13901  default:
13902  {
13903  m_it.primitive_iterator.set_end();
13904  break;
13905  }
13906  }
13907  }
13908 
13909  public:
13915  {
13916  JSON_ASSERT(m_object != nullptr);
13917 
13918  switch (m_object->m_data.m_type)
13919  {
13920  case value_t::object:
13921  {
13922  JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13923  return m_it.object_iterator->second;
13924  }
13925 
13926  case value_t::array:
13927  {
13928  JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13929  return *m_it.array_iterator;
13930  }
13931 
13932  case value_t::null:
13933  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13934 
13935  case value_t::string:
13936  case value_t::boolean:
13937  case value_t::number_integer:
13938  case value_t::number_unsigned:
13939  case value_t::number_float:
13940  case value_t::binary:
13941  case value_t::discarded:
13942  default:
13943  {
13944  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13945  {
13946  return *m_object;
13947  }
13948 
13949  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13950  }
13951  }
13952  }
13953 
13959  {
13960  JSON_ASSERT(m_object != nullptr);
13961 
13962  switch (m_object->m_data.m_type)
13963  {
13964  case value_t::object:
13965  {
13966  JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13967  return &(m_it.object_iterator->second);
13968  }
13969 
13970  case value_t::array:
13971  {
13972  JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13973  return &*m_it.array_iterator;
13974  }
13975 
13976  case value_t::null:
13977  case value_t::string:
13978  case value_t::boolean:
13979  case value_t::number_integer:
13980  case value_t::number_unsigned:
13981  case value_t::number_float:
13982  case value_t::binary:
13983  case value_t::discarded:
13984  default:
13985  {
13986  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13987  {
13988  return m_object;
13989  }
13990 
13991  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13992  }
13993  }
13994  }
13995 
14000  iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
14001  {
14002  auto result = *this;
14003  ++(*this);
14004  return result;
14005  }
14006 
14012  {
14013  JSON_ASSERT(m_object != nullptr);
14014 
14015  switch (m_object->m_data.m_type)
14016  {
14017  case value_t::object:
14018  {
14019  std::advance(m_it.object_iterator, 1);
14020  break;
14021  }
14022 
14023  case value_t::array:
14024  {
14025  std::advance(m_it.array_iterator, 1);
14026  break;
14027  }
14028 
14029  case value_t::null:
14030  case value_t::string:
14031  case value_t::boolean:
14032  case value_t::number_integer:
14033  case value_t::number_unsigned:
14034  case value_t::number_float:
14035  case value_t::binary:
14036  case value_t::discarded:
14037  default:
14038  {
14039  ++m_it.primitive_iterator;
14040  break;
14041  }
14042  }
14043 
14044  return *this;
14045  }
14046 
14051  iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
14052  {
14053  auto result = *this;
14054  --(*this);
14055  return result;
14056  }
14057 
14063  {
14064  JSON_ASSERT(m_object != nullptr);
14065 
14066  switch (m_object->m_data.m_type)
14067  {
14068  case value_t::object:
14069  {
14070  std::advance(m_it.object_iterator, -1);
14071  break;
14072  }
14073 
14074  case value_t::array:
14075  {
14076  std::advance(m_it.array_iterator, -1);
14077  break;
14078  }
14079 
14080  case value_t::null:
14081  case value_t::string:
14082  case value_t::boolean:
14083  case value_t::number_integer:
14084  case value_t::number_unsigned:
14085  case value_t::number_float:
14086  case value_t::binary:
14087  case value_t::discarded:
14088  default:
14089  {
14090  --m_it.primitive_iterator;
14091  break;
14092  }
14093  }
14094 
14095  return *this;
14096  }
14097 
14102  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 >
14103  bool operator==(const IterImpl& other) const
14104  {
14105  // if objects are not the same, the comparison is undefined
14106  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
14107  {
14108  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
14109  }
14110 
14111  // value-initialized forward iterators can be compared, and must compare equal to other value-initialized iterators of the same type #4493
14112  if (m_object == nullptr)
14113  {
14114  return true;
14115  }
14116 
14117  switch (m_object->m_data.m_type)
14118  {
14119  case value_t::object:
14120  return (m_it.object_iterator == other.m_it.object_iterator);
14121 
14122  case value_t::array:
14123  return (m_it.array_iterator == other.m_it.array_iterator);
14124 
14125  case value_t::null:
14126  case value_t::string:
14127  case value_t::boolean:
14128  case value_t::number_integer:
14129  case value_t::number_unsigned:
14130  case value_t::number_float:
14131  case value_t::binary:
14132  case value_t::discarded:
14133  default:
14134  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
14135  }
14136  }
14137 
14142  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 >
14143  bool operator!=(const IterImpl& other) const
14144  {
14145  return !operator==(other);
14146  }
14147 
14152  bool operator<(const iter_impl& other) const
14153  {
14154  // if objects are not the same, the comparison is undefined
14155  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
14156  {
14157  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
14158  }
14159 
14160  // value-initialized forward iterators can be compared, and must compare equal to other value-initialized iterators of the same type #4493
14161  if (m_object == nullptr)
14162  {
14163  // the iterators are both value-initialized and are to be considered equal, but this function checks for smaller, so we return false
14164  return false;
14165  }
14166 
14167  switch (m_object->m_data.m_type)
14168  {
14169  case value_t::object:
14170  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
14171 
14172  case value_t::array:
14173  return (m_it.array_iterator < other.m_it.array_iterator);
14174 
14175  case value_t::null:
14176  case value_t::string:
14177  case value_t::boolean:
14178  case value_t::number_integer:
14179  case value_t::number_unsigned:
14180  case value_t::number_float:
14181  case value_t::binary:
14182  case value_t::discarded:
14183  default:
14184  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
14185  }
14186  }
14187 
14192  bool operator<=(const iter_impl& other) const
14193  {
14194  return !other.operator < (*this);
14195  }
14196 
14201  bool operator>(const iter_impl& other) const
14202  {
14203  return !operator<=(other);
14204  }
14205 
14210  bool operator>=(const iter_impl& other) const
14211  {
14212  return !operator<(other);
14213  }
14214 
14220  {
14221  JSON_ASSERT(m_object != nullptr);
14222 
14223  switch (m_object->m_data.m_type)
14224  {
14225  case value_t::object:
14226  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
14227 
14228  case value_t::array:
14229  {
14230  std::advance(m_it.array_iterator, i);
14231  break;
14232  }
14233 
14234  case value_t::null:
14235  case value_t::string:
14236  case value_t::boolean:
14237  case value_t::number_integer:
14238  case value_t::number_unsigned:
14239  case value_t::number_float:
14240  case value_t::binary:
14241  case value_t::discarded:
14242  default:
14243  {
14244  m_it.primitive_iterator += i;
14245  break;
14246  }
14247  }
14248 
14249  return *this;
14250  }
14251 
14257  {
14258  return operator+=(-i);
14259  }
14260 
14266  {
14267  auto result = *this;
14268  result += i;
14269  return result;
14270  }
14271 
14277  {
14278  auto result = it;
14279  result += i;
14280  return result;
14281  }
14282 
14288  {
14289  auto result = *this;
14290  result -= i;
14291  return result;
14292  }
14293 
14299  {
14300  JSON_ASSERT(m_object != nullptr);
14301 
14302  switch (m_object->m_data.m_type)
14303  {
14304  case value_t::object:
14305  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
14306 
14307  case value_t::array:
14308  return m_it.array_iterator - other.m_it.array_iterator;
14309 
14310  case value_t::null:
14311  case value_t::string:
14312  case value_t::boolean:
14313  case value_t::number_integer:
14314  case value_t::number_unsigned:
14315  case value_t::number_float:
14316  case value_t::binary:
14317  case value_t::discarded:
14318  default:
14319  return m_it.primitive_iterator - other.m_it.primitive_iterator;
14320  }
14321  }
14322 
14328  {
14329  JSON_ASSERT(m_object != nullptr);
14330 
14331  switch (m_object->m_data.m_type)
14332  {
14333  case value_t::object:
14334  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
14335 
14336  case value_t::array:
14337  return *std::next(m_it.array_iterator, n);
14338 
14339  case value_t::null:
14340  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
14341 
14342  case value_t::string:
14343  case value_t::boolean:
14344  case value_t::number_integer:
14345  case value_t::number_unsigned:
14346  case value_t::number_float:
14347  case value_t::binary:
14348  case value_t::discarded:
14349  default:
14350  {
14351  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
14352  {
14353  return *m_object;
14354  }
14355 
14356  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
14357  }
14358  }
14359  }
14360 
14365  const typename object_t::key_type& key() const
14366  {
14367  JSON_ASSERT(m_object != nullptr);
14368 
14369  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
14370  {
14371  return m_it.object_iterator->first;
14372  }
14373 
14374  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
14375  }
14376 
14382  {
14383  return operator*();
14384  }
14385 
14388  pointer m_object = nullptr;
14391 };
14392 
14393 } // namespace detail
14395 
14396 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
14397 
14398 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
14399 // __ _____ _____ _____
14400 // __| | __| | | | JSON for Modern C++
14401 // | | |__ | | | | | | version 3.12.0
14402 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14403 //
14404 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
14405 // SPDX-License-Identifier: MIT
14406 
14407 
14408 
14409 #include <cstddef> // ptrdiff_t
14410 #include <iterator> // reverse_iterator
14411 #include <utility> // declval
14412 
14413 // #include <nlohmann/detail/abi_macros.hpp>
14414 
14415 
14417 namespace detail
14418 {
14419 
14421 // reverse_iterator //
14423 
14442 template<typename Base>
14443 class json_reverse_iterator : public std::reverse_iterator<Base>
14444 {
14445  public:
14446  using difference_type = std::ptrdiff_t;
14448  using base_iterator = std::reverse_iterator<Base>;
14450  using reference = typename Base::reference;
14451 
14453  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
14454  : base_iterator(it) {}
14455 
14457  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
14458 
14460  json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
14461  {
14462  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
14463  }
14464 
14467  {
14468  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
14469  }
14470 
14472  json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
14473  {
14474  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
14475  }
14476 
14479  {
14480  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
14481  }
14482 
14485  {
14486  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
14487  }
14488 
14491  {
14492  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
14493  }
14494 
14497  {
14498  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
14499  }
14500 
14503  {
14504  return base_iterator(*this) - base_iterator(other);
14505  }
14506 
14509  {
14510  return *(this->operator+(n));
14511  }
14512 
14514  auto key() const -> decltype(std::declval<Base>().key())
14515  {
14516  auto it = --this->base();
14517  return it.key();
14518  }
14519 
14522  {
14523  auto it = --this->base();
14524  return it.operator * ();
14525  }
14526 };
14527 
14528 } // namespace detail
14530 
14531 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
14532 
14533 // #include <nlohmann/detail/json_custom_base_class.hpp>
14534 // __ _____ _____ _____
14535 // __| | __| | | | JSON for Modern C++
14536 // | | |__ | | | | | | version 3.12.0
14537 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14538 //
14539 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
14540 // SPDX-License-Identifier: MIT
14541 
14542 
14543 
14544 #include <type_traits> // conditional, is_same
14545 
14546 // #include <nlohmann/detail/abi_macros.hpp>
14547 
14548 
14550 namespace detail
14551 {
14552 
14564 
14565 template<class T>
14566 using json_base_class = typename std::conditional <
14569  T
14570  >::type;
14571 
14572 } // namespace detail
14574 
14575 // #include <nlohmann/detail/json_pointer.hpp>
14576 // __ _____ _____ _____
14577 // __| | __| | | | JSON for Modern C++
14578 // | | |__ | | | | | | version 3.12.0
14579 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14580 //
14581 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
14582 // SPDX-License-Identifier: MIT
14583 
14584 
14585 
14586 #include <algorithm> // all_of
14587 #include <cctype> // isdigit
14588 #include <cerrno> // errno, ERANGE
14589 #include <cstdlib> // strtoull
14590 #ifndef JSON_NO_IO
14591  #include <iosfwd> // ostream
14592 #endif // JSON_NO_IO
14593 #include <limits> // max
14594 #include <numeric> // accumulate
14595 #include <string> // string
14596 #include <utility> // move
14597 #include <vector> // vector
14598 
14599 // #include <nlohmann/detail/exceptions.hpp>
14600 
14601 // #include <nlohmann/detail/macro_scope.hpp>
14602 
14603 // #include <nlohmann/detail/string_concat.hpp>
14604 
14605 // #include <nlohmann/detail/string_escape.hpp>
14606 
14607 // #include <nlohmann/detail/value_t.hpp>
14608 
14609 
14611 
14614 template<typename RefStringType>
14616 {
14617  // allow basic_json to access private members
14619  friend class basic_json;
14620 
14621  template<typename>
14622  friend class json_pointer;
14623 
14624  template<typename T>
14626  {
14627  using type = T;
14628  };
14629 
14632  {
14633  using type = StringType;
14634  };
14635 
14636  public:
14637  // for backwards compatibility accept BasicJsonType
14639 
14642  explicit json_pointer(const string_t& s = "")
14643  : reference_tokens(split(s))
14644  {}
14645 
14649  {
14650  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
14651  string_t{},
14652  [](const string_t& a, const string_t& b)
14653  {
14654  return detail::concat(a, '/', detail::escape(b));
14655  });
14656  }
14657 
14661  operator string_t() const
14662  {
14663  return to_string();
14664  }
14665 
14666 #ifndef JSON_NO_IO
14669  friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
14670  {
14671  o << ptr.to_string();
14672  return o;
14673  }
14674 #endif
14675 
14679  {
14680  reference_tokens.insert(reference_tokens.end(),
14681  ptr.reference_tokens.begin(),
14682  ptr.reference_tokens.end());
14683  return *this;
14684  }
14685 
14689  {
14690  push_back(std::move(token));
14691  return *this;
14692  }
14693 
14696  json_pointer& operator/=(std::size_t array_idx)
14697  {
14698  return *this /= std::to_string(array_idx);
14699  }
14700 
14704  const json_pointer& rhs)
14705  {
14706  return json_pointer(lhs) /= rhs;
14707  }
14708 
14711  friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
14712  {
14713  return json_pointer(lhs) /= std::move(token);
14714  }
14715 
14718  friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
14719  {
14720  return json_pointer(lhs) /= array_idx;
14721  }
14722 
14726  {
14727  if (empty())
14728  {
14729  return *this;
14730  }
14731 
14732  json_pointer res = *this;
14733  res.pop_back();
14734  return res;
14735  }
14736 
14739  void pop_back()
14740  {
14741  if (JSON_HEDLEY_UNLIKELY(empty()))
14742  {
14743  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
14744  }
14745 
14746  reference_tokens.pop_back();
14747  }
14748 
14751  const string_t& back() const
14752  {
14753  if (JSON_HEDLEY_UNLIKELY(empty()))
14754  {
14755  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
14756  }
14757 
14758  return reference_tokens.back();
14759  }
14760 
14763  void push_back(const string_t& token)
14764  {
14765  reference_tokens.push_back(token);
14766  }
14767 
14770  void push_back(string_t&& token)
14771  {
14772  reference_tokens.push_back(std::move(token));
14773  }
14774 
14777  bool empty() const noexcept
14778  {
14779  return reference_tokens.empty();
14780  }
14781 
14782  private:
14793  template<typename BasicJsonType>
14795  {
14796  using size_type = typename BasicJsonType::size_type;
14797 
14798  // error condition (cf. RFC 6901, Sect. 4)
14799  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
14800  {
14801  JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
14802  }
14803 
14804  // error condition (cf. RFC 6901, Sect. 4)
14805  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
14806  {
14807  JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
14808  }
14809 
14810  const char* p = s.c_str();
14811  char* p_end = nullptr; // NOLINT(misc-const-correctness)
14812  errno = 0; // strtoull doesn't reset errno
14813  const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
14814  if (p == p_end // invalid input or empty string
14815  || errno == ERANGE // out of range
14816  || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
14817  {
14818  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
14819  }
14820 
14821  // only triggered on special platforms (like 32bit), see also
14822  // https://github.com/nlohmann/json/pull/2203
14823  if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
14824  {
14825  JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
14826  }
14827 
14828  return static_cast<size_type>(res);
14829  }
14830 
14832  json_pointer top() const
14833  {
14834  if (JSON_HEDLEY_UNLIKELY(empty()))
14835  {
14836  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
14837  }
14838 
14839  json_pointer result = *this;
14840  result.reference_tokens = {reference_tokens[0]};
14841  return result;
14842  }
14843 
14844  private:
14853  template<typename BasicJsonType>
14854  BasicJsonType& get_and_create(BasicJsonType& j) const
14855  {
14856  auto* result = &j;
14857 
14858  // in case no reference tokens exist, return a reference to the JSON value
14859  // j which will be overwritten by a primitive value
14860  for (const auto& reference_token : reference_tokens)
14861  {
14862  switch (result->type())
14863  {
14864  case detail::value_t::null:
14865  {
14866  if (reference_token == "0")
14867  {
14868  // start a new array if the reference token is 0
14869  result = &result->operator[](0);
14870  }
14871  else
14872  {
14873  // start a new object otherwise
14874  result = &result->operator[](reference_token);
14875  }
14876  break;
14877  }
14878 
14880  {
14881  // create an entry in the object
14882  result = &result->operator[](reference_token);
14883  break;
14884  }
14885 
14887  {
14888  // create an entry in the array
14889  result = &result->operator[](array_index<BasicJsonType>(reference_token));
14890  break;
14891  }
14892 
14893  /*
14894  The following code is only reached if there exists a reference
14895  token _and_ the current value is primitive. In this case, we have
14896  an error situation, because primitive values may only occur as
14897  a single value; that is, with an empty list of reference tokens.
14898  */
14906  default:
14907  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
14908  }
14909  }
14910 
14911  return *result;
14912  }
14913 
14933  template<typename BasicJsonType>
14934  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
14935  {
14936  for (const auto& reference_token : reference_tokens)
14937  {
14938  // convert null values to arrays or objects before continuing
14939  if (ptr->is_null())
14940  {
14941  // check if the reference token is a number
14942  const bool nums =
14943  std::all_of(reference_token.begin(), reference_token.end(),
14944  [](const unsigned char x)
14945  {
14946  return std::isdigit(x);
14947  });
14948 
14949  // change value to an array for numbers or "-" or to object otherwise
14950  *ptr = (nums || reference_token == "-")
14953  }
14954 
14955  switch (ptr->type())
14956  {
14958  {
14959  // use unchecked object access
14960  ptr = &ptr->operator[](reference_token);
14961  break;
14962  }
14963 
14965  {
14966  if (reference_token == "-")
14967  {
14968  // explicitly treat "-" as index beyond the end
14969  ptr = &ptr->operator[](ptr->m_data.m_value.array->size());
14970  }
14971  else
14972  {
14973  // convert array index to number; unchecked access
14974  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14975  }
14976  break;
14977  }
14978 
14979  case detail::value_t::null:
14987  default:
14988  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14989  }
14990  }
14991 
14992  return *ptr;
14993  }
14994 
15001  template<typename BasicJsonType>
15002  BasicJsonType& get_checked(BasicJsonType* ptr) const
15003  {
15004  for (const auto& reference_token : reference_tokens)
15005  {
15006  switch (ptr->type())
15007  {
15009  {
15010  // note: at performs range check
15011  ptr = &ptr->at(reference_token);
15012  break;
15013  }
15014 
15016  {
15017  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
15018  {
15019  // "-" always fails the range check
15021  "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
15022  ") is out of range"), ptr));
15023  }
15024 
15025  // note: at performs range check
15026  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
15027  break;
15028  }
15029 
15030  case detail::value_t::null:
15038  default:
15039  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
15040  }
15041  }
15042 
15043  return *ptr;
15044  }
15045 
15059  template<typename BasicJsonType>
15060  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
15061  {
15062  for (const auto& reference_token : reference_tokens)
15063  {
15064  switch (ptr->type())
15065  {
15067  {
15068  // use unchecked object access
15069  ptr = &ptr->operator[](reference_token);
15070  break;
15071  }
15072 
15074  {
15075  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
15076  {
15077  // "-" cannot be used for const access
15078  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));
15079  }
15080 
15081  // use unchecked array access
15082  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
15083  break;
15084  }
15085 
15086  case detail::value_t::null:
15094  default:
15095  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
15096  }
15097  }
15098 
15099  return *ptr;
15100  }
15101 
15108  template<typename BasicJsonType>
15109  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
15110  {
15111  for (const auto& reference_token : reference_tokens)
15112  {
15113  switch (ptr->type())
15114  {
15116  {
15117  // note: at performs range check
15118  ptr = &ptr->at(reference_token);
15119  break;
15120  }
15121 
15123  {
15124  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
15125  {
15126  // "-" always fails the range check
15128  "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
15129  ") is out of range"), ptr));
15130  }
15131 
15132  // note: at performs range check
15133  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
15134  break;
15135  }
15136 
15137  case detail::value_t::null:
15145  default:
15146  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
15147  }
15148  }
15149 
15150  return *ptr;
15151  }
15152 
15157  template<typename BasicJsonType>
15158  bool contains(const BasicJsonType* ptr) const
15159  {
15160  for (const auto& reference_token : reference_tokens)
15161  {
15162  switch (ptr->type())
15163  {
15165  {
15166  if (!ptr->contains(reference_token))
15167  {
15168  // we did not find the key in the object
15169  return false;
15170  }
15171 
15172  ptr = &ptr->operator[](reference_token);
15173  break;
15174  }
15175 
15177  {
15178  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
15179  {
15180  // "-" always fails the range check
15181  return false;
15182  }
15183  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
15184  {
15185  // invalid char
15186  return false;
15187  }
15188  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
15189  {
15190  if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
15191  {
15192  // the first char should be between '1' and '9'
15193  return false;
15194  }
15195  for (std::size_t i = 1; i < reference_token.size(); i++)
15196  {
15197  if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
15198  {
15199  // other char should be between '0' and '9'
15200  return false;
15201  }
15202  }
15203  }
15204 
15205  const auto idx = array_index<BasicJsonType>(reference_token);
15206  if (idx >= ptr->size())
15207  {
15208  // index out of range
15209  return false;
15210  }
15211 
15212  ptr = &ptr->operator[](idx);
15213  break;
15214  }
15215 
15216  case detail::value_t::null:
15224  default:
15225  {
15226  // we do not expect primitive values if there is still a
15227  // reference token to process
15228  return false;
15229  }
15230  }
15231  }
15232 
15233  // no reference token left means we found a primitive value
15234  return true;
15235  }
15236 
15246  static std::vector<string_t> split(const string_t& reference_string)
15247  {
15248  std::vector<string_t> result;
15249 
15250  // special case: empty reference string -> no reference tokens
15251  if (reference_string.empty())
15252  {
15253  return result;
15254  }
15255 
15256  // check if a nonempty reference string begins with slash
15257  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
15258  {
15259  JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
15260  }
15261 
15262  // extract the reference tokens:
15263  // - slash: position of the last read slash (or end of string)
15264  // - start: position after the previous slash
15265  for (
15266  // search for the first slash after the first character
15267  std::size_t slash = reference_string.find_first_of('/', 1),
15268  // set the beginning of the first reference token
15269  start = 1;
15270  // we can stop if start == 0 (if slash == string_t::npos)
15271  start != 0;
15272  // set the beginning of the next reference token
15273  // (will eventually be 0 if slash == string_t::npos)
15274  start = (slash == string_t::npos) ? 0 : slash + 1,
15275  // find next slash
15276  slash = reference_string.find_first_of('/', start))
15277  {
15278  // use the text between the beginning of the reference token
15279  // (start) and the last slash (slash).
15280  auto reference_token = reference_string.substr(start, slash - start);
15281 
15282  // check reference tokens are properly escaped
15283  for (std::size_t pos = reference_token.find_first_of('~');
15284  pos != string_t::npos;
15285  pos = reference_token.find_first_of('~', pos + 1))
15286  {
15287  JSON_ASSERT(reference_token[pos] == '~');
15288 
15289  // ~ must be followed by 0 or 1
15290  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
15291  (reference_token[pos + 1] != '0' &&
15292  reference_token[pos + 1] != '1')))
15293  {
15294  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
15295  }
15296  }
15297 
15298  // finally, store the reference token
15299  detail::unescape(reference_token);
15300  result.push_back(reference_token);
15301  }
15302 
15303  return result;
15304  }
15305 
15306  private:
15314  template<typename BasicJsonType>
15315  static void flatten(const string_t& reference_string,
15316  const BasicJsonType& value,
15317  BasicJsonType& result)
15318  {
15319  switch (value.type())
15320  {
15322  {
15323  if (value.m_data.m_value.array->empty())
15324  {
15325  // flatten empty array as null
15326  result[reference_string] = nullptr;
15327  }
15328  else
15329  {
15330  // iterate array and use index as a reference string
15331  for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)
15332  {
15333  flatten(detail::concat<string_t>(reference_string, '/', std::to_string(i)),
15334  value.m_data.m_value.array->operator[](i), result);
15335  }
15336  }
15337  break;
15338  }
15339 
15341  {
15342  if (value.m_data.m_value.object->empty())
15343  {
15344  // flatten empty object as null
15345  result[reference_string] = nullptr;
15346  }
15347  else
15348  {
15349  // iterate object and use keys as reference string
15350  for (const auto& element : *value.m_data.m_value.object)
15351  {
15352  flatten(detail::concat<string_t>(reference_string, '/', detail::escape(element.first)), element.second, result);
15353  }
15354  }
15355  break;
15356  }
15357 
15358  case detail::value_t::null:
15366  default:
15367  {
15368  // add a primitive value with its reference string
15369  result[reference_string] = value;
15370  break;
15371  }
15372  }
15373  }
15374 
15385  template<typename BasicJsonType>
15386  static BasicJsonType
15387  unflatten(const BasicJsonType& value)
15388  {
15389  if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
15390  {
15391  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
15392  }
15393 
15394  BasicJsonType result;
15395 
15396  // iterate the JSON object values
15397  for (const auto& element : *value.m_data.m_value.object)
15398  {
15399  if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
15400  {
15401  JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
15402  }
15403 
15404  // Assign the value to the reference pointed to by JSON pointer. Note
15405  // that if the JSON pointer is "" (i.e., points to the whole value),
15406  // function get_and_create returns a reference to the result itself.
15407  // An assignment will then create a primitive value.
15408  json_pointer(element.first).get_and_create(result) = element.second;
15409  }
15410 
15411  return result;
15412  }
15413 
15414  // can't use the conversion operator because of ambiguity
15416  {
15417  json_pointer<string_t> result;
15418  result.reference_tokens = reference_tokens;
15419  return result;
15420  }
15421 
15423  {
15424  json_pointer<string_t> result;
15425  result.reference_tokens = std::move(reference_tokens);
15426  return result;
15427  }
15428 
15429  public:
15430 #if JSON_HAS_THREE_WAY_COMPARISON
15433  template<typename RefStringTypeRhs>
15434  bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept
15435  {
15436  return reference_tokens == rhs.reference_tokens;
15437  }
15438 
15441  JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))
15442  bool operator==(const string_t& rhs) const
15443  {
15444  return *this == json_pointer(rhs);
15445  }
15446 
15448  template<typename RefStringTypeRhs>
15449  std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
15450  {
15451  return reference_tokens <=> rhs.reference_tokens; // *NOPAD*
15452  }
15453 #else
15456  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15457  // NOLINTNEXTLINE(readability-redundant-declaration)
15458  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
15459  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
15460 
15463  template<typename RefStringTypeLhs, typename StringType>
15464  // NOLINTNEXTLINE(readability-redundant-declaration)
15465  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
15466  const StringType& rhs);
15467 
15470  template<typename RefStringTypeRhs, typename StringType>
15471  // NOLINTNEXTLINE(readability-redundant-declaration)
15472  friend bool operator==(const StringType& lhs,
15473  const json_pointer<RefStringTypeRhs>& rhs);
15474 
15477  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15478  // NOLINTNEXTLINE(readability-redundant-declaration)
15479  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
15480  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
15481 
15484  template<typename RefStringTypeLhs, typename StringType>
15485  // NOLINTNEXTLINE(readability-redundant-declaration)
15486  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
15487  const StringType& rhs);
15488 
15491  template<typename RefStringTypeRhs, typename StringType>
15492  // NOLINTNEXTLINE(readability-redundant-declaration)
15493  friend bool operator!=(const StringType& lhs,
15494  const json_pointer<RefStringTypeRhs>& rhs);
15495 
15497  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15498  // NOLINTNEXTLINE(readability-redundant-declaration)
15499  friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
15500  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
15501 #endif
15502 
15503  private:
15505  std::vector<string_t> reference_tokens;
15506 };
15507 
15508 #if !JSON_HAS_THREE_WAY_COMPARISON
15509 // functions cannot be defined inside the class due to ODR violations
15510 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15512  const json_pointer<RefStringTypeRhs>& rhs) noexcept
15513 {
15514  return lhs.reference_tokens == rhs.reference_tokens;
15515 }
15516 
15517 template<typename RefStringTypeLhs,
15518  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
15520 inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
15521  const StringType& rhs)
15522 {
15523  return lhs == json_pointer<RefStringTypeLhs>(rhs);
15524 }
15525 
15526 template<typename RefStringTypeRhs,
15527  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
15529 inline bool operator==(const StringType& lhs,
15530  const json_pointer<RefStringTypeRhs>& rhs)
15531 {
15532  return json_pointer<RefStringTypeRhs>(lhs) == rhs;
15533 }
15534 
15535 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15537  const json_pointer<RefStringTypeRhs>& rhs) noexcept
15538 {
15539  return !(lhs == rhs);
15540 }
15541 
15542 template<typename RefStringTypeLhs,
15543  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
15545 inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
15546  const StringType& rhs)
15547 {
15548  return !(lhs == rhs);
15549 }
15550 
15551 template<typename RefStringTypeRhs,
15552  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
15554 inline bool operator!=(const StringType& lhs,
15555  const json_pointer<RefStringTypeRhs>& rhs)
15556 {
15557  return !(lhs == rhs);
15558 }
15559 
15560 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15562  const json_pointer<RefStringTypeRhs>& rhs) noexcept
15563 {
15564  return lhs.reference_tokens < rhs.reference_tokens;
15565 }
15566 #endif
15567 
15569 
15570 // #include <nlohmann/detail/json_ref.hpp>
15571 // __ _____ _____ _____
15572 // __| | __| | | | JSON for Modern C++
15573 // | | |__ | | | | | | version 3.12.0
15574 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
15575 //
15576 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
15577 // SPDX-License-Identifier: MIT
15578 
15579 
15580 
15581 #include <initializer_list>
15582 #include <utility>
15583 
15584 // #include <nlohmann/detail/abi_macros.hpp>
15585 
15586 // #include <nlohmann/detail/meta/type_traits.hpp>
15587 
15588 
15590 namespace detail
15591 {
15592 
15593 template<typename BasicJsonType>
15595 {
15596  public:
15597  using value_type = BasicJsonType;
15598 
15600  : owned_value(std::move(value))
15601  {}
15602 
15604  : value_ref(&value)
15605  {}
15606 
15607  json_ref(std::initializer_list<json_ref> init)
15608  : owned_value(init)
15609  {}
15610 
15611  template <
15612  class... Args,
15613  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
15614  json_ref(Args && ... args)
15615  : owned_value(std::forward<Args>(args)...)
15616  {}
15617 
15618  // class should be movable only
15619  json_ref(json_ref&&) noexcept = default;
15621  json_ref& operator=(const json_ref&) = delete;
15622  json_ref& operator=(json_ref&&) = delete;
15623  ~json_ref() = default;
15624 
15625  value_type moved_or_copied() const
15626  {
15627  if (value_ref == nullptr)
15628  {
15629  return std::move(owned_value);
15630  }
15631  return *value_ref;
15632  }
15633 
15634  value_type const& operator*() const
15635  {
15636  return value_ref ? *value_ref : owned_value;
15637  }
15638 
15639  value_type const* operator->() const
15640  {
15641  return &** this;
15642  }
15643 
15644  private:
15645  mutable value_type owned_value = nullptr;
15646  value_type const* value_ref = nullptr;
15647 };
15648 
15649 } // namespace detail
15651 
15652 // #include <nlohmann/detail/macro_scope.hpp>
15653 
15654 // #include <nlohmann/detail/string_concat.hpp>
15655 
15656 // #include <nlohmann/detail/string_escape.hpp>
15657 
15658 // #include <nlohmann/detail/string_utils.hpp>
15659 
15660 // #include <nlohmann/detail/meta/cpp_future.hpp>
15661 
15662 // #include <nlohmann/detail/meta/type_traits.hpp>
15663 
15664 // #include <nlohmann/detail/output/binary_writer.hpp>
15665 // __ _____ _____ _____
15666 // __| | __| | | | JSON for Modern C++
15667 // | | |__ | | | | | | version 3.12.0
15668 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
15669 //
15670 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
15671 // SPDX-License-Identifier: MIT
15672 
15673 
15674 
15675 #include <algorithm> // reverse
15676 #include <array> // array
15677 #include <map> // map
15678 #include <cmath> // isnan, isinf
15679 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
15680 #include <cstring> // memcpy
15681 #include <limits> // numeric_limits
15682 #include <string> // string
15683 #include <utility> // move
15684 #include <vector> // vector
15685 
15686 // #include <nlohmann/detail/input/binary_reader.hpp>
15687 
15688 // #include <nlohmann/detail/macro_scope.hpp>
15689 
15690 // #include <nlohmann/detail/output/output_adapters.hpp>
15691 // __ _____ _____ _____
15692 // __| | __| | | | JSON for Modern C++
15693 // | | |__ | | | | | | version 3.12.0
15694 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
15695 //
15696 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
15697 // SPDX-License-Identifier: MIT
15698 
15699 
15700 
15701 #include <algorithm> // copy
15702 #include <cstddef> // size_t
15703 #include <iterator> // back_inserter
15704 #include <memory> // shared_ptr, make_shared
15705 #include <string> // basic_string
15706 #include <vector> // vector
15707 
15708 #ifndef JSON_NO_IO
15709  #include <ios> // streamsize
15710  #include <ostream> // basic_ostream
15711 #endif // JSON_NO_IO
15712 
15713 // #include <nlohmann/detail/macro_scope.hpp>
15714 
15715 
15717 namespace detail
15718 {
15719 
15721 template<typename CharType> struct output_adapter_protocol
15722 {
15723  virtual void write_character(CharType c) = 0;
15724  virtual void write_characters(const CharType* s, std::size_t length) = 0;
15725  virtual ~output_adapter_protocol() = default;
15726 
15731  output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
15732 };
15733 
15735 template<typename CharType>
15736 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
15737 
15739 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
15741 {
15742  public:
15743  explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
15744  : v(vec)
15745  {}
15746 
15747  void write_character(CharType c) override
15748  {
15749  v.push_back(c);
15750  }
15751 
15753  void write_characters(const CharType* s, std::size_t length) override
15754  {
15755  v.insert(v.end(), s, s + length);
15756  }
15757 
15758  private:
15759  std::vector<CharType, AllocatorType>& v;
15760 };
15761 
15762 #ifndef JSON_NO_IO
15764 template<typename CharType>
15766 {
15767  public:
15768  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
15769  : stream(s)
15770  {}
15771 
15772  void write_character(CharType c) override
15773  {
15774  stream.put(c);
15775  }
15776 
15778  void write_characters(const CharType* s, std::size_t length) override
15779  {
15780  stream.write(s, static_cast<std::streamsize>(length));
15781  }
15782 
15783  private:
15784  std::basic_ostream<CharType>& stream;
15785 };
15786 #endif // JSON_NO_IO
15787 
15789 template<typename CharType, typename StringType = std::basic_string<CharType>>
15791 {
15792  public:
15793  explicit output_string_adapter(StringType& s) noexcept
15794  : str(s)
15795  {}
15796 
15797  void write_character(CharType c) override
15798  {
15799  str.push_back(c);
15800  }
15801 
15803  void write_characters(const CharType* s, std::size_t length) override
15804  {
15805  str.append(s, length);
15806  }
15807 
15808  private:
15809  StringType& str;
15810 };
15811 
15812 template<typename CharType, typename StringType = std::basic_string<CharType>>
15814 {
15815  public:
15816  template<typename AllocatorType = std::allocator<CharType>>
15817  output_adapter(std::vector<CharType, AllocatorType>& vec)
15818  : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
15819 
15820 #ifndef JSON_NO_IO
15821  output_adapter(std::basic_ostream<CharType>& s)
15822  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
15823 #endif // JSON_NO_IO
15824 
15825  output_adapter(StringType& s)
15826  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
15827 
15829  {
15830  return oa;
15831  }
15832 
15833  private:
15835 };
15836 
15837 } // namespace detail
15839 
15840 // #include <nlohmann/detail/string_concat.hpp>
15841 
15842 
15844 namespace detail
15845 {
15846 
15849 {
15850  draft2,
15851  draft3,
15852 };
15853 
15855 // binary writer //
15857 
15861 template<typename BasicJsonType, typename CharType>
15863 {
15865  using binary_t = typename BasicJsonType::binary_t;
15866  using number_float_t = typename BasicJsonType::number_float_t;
15867 
15868  public:
15874  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
15875  {
15876  JSON_ASSERT(oa);
15877  }
15878 
15883  void write_bson(const BasicJsonType& j)
15884  {
15885  switch (j.type())
15886  {
15887  case value_t::object:
15888  {
15889  write_bson_object(*j.m_data.m_value.object);
15890  break;
15891  }
15892 
15893  case value_t::null:
15894  case value_t::array:
15895  case value_t::string:
15896  case value_t::boolean:
15897  case value_t::number_integer:
15898  case value_t::number_unsigned:
15899  case value_t::number_float:
15900  case value_t::binary:
15901  case value_t::discarded:
15902  default:
15903  {
15904  JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
15905  }
15906  }
15907  }
15908 
15912  void write_cbor(const BasicJsonType& j)
15913  {
15914  switch (j.type())
15915  {
15916  case value_t::null:
15917  {
15918  oa->write_character(to_char_type(0xF6));
15919  break;
15920  }
15921 
15922  case value_t::boolean:
15923  {
15924  oa->write_character(j.m_data.m_value.boolean
15925  ? to_char_type(0xF5)
15926  : to_char_type(0xF4));
15927  break;
15928  }
15929 
15930  case value_t::number_integer:
15931  {
15932  if (j.m_data.m_value.number_integer >= 0)
15933  {
15934  // CBOR does not differentiate between positive signed
15935  // integers and unsigned integers. Therefore, we used the
15936  // code from the value_t::number_unsigned case here.
15937  if (j.m_data.m_value.number_integer <= 0x17)
15938  {
15939  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15940  }
15941  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15942  {
15943  oa->write_character(to_char_type(0x18));
15944  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15945  }
15946  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
15947  {
15948  oa->write_character(to_char_type(0x19));
15949  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15950  }
15951  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
15952  {
15953  oa->write_character(to_char_type(0x1A));
15954  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15955  }
15956  else
15957  {
15958  oa->write_character(to_char_type(0x1B));
15959  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15960  }
15961  }
15962  else
15963  {
15964  // The conversions below encode the sign in the first
15965  // byte, and the value is converted to a positive number.
15966  const auto positive_number = -1 - j.m_data.m_value.number_integer;
15967  if (j.m_data.m_value.number_integer >= -24)
15968  {
15969  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
15970  }
15971  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
15972  {
15973  oa->write_character(to_char_type(0x38));
15974  write_number(static_cast<std::uint8_t>(positive_number));
15975  }
15976  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
15977  {
15978  oa->write_character(to_char_type(0x39));
15979  write_number(static_cast<std::uint16_t>(positive_number));
15980  }
15981  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
15982  {
15983  oa->write_character(to_char_type(0x3A));
15984  write_number(static_cast<std::uint32_t>(positive_number));
15985  }
15986  else
15987  {
15988  oa->write_character(to_char_type(0x3B));
15989  write_number(static_cast<std::uint64_t>(positive_number));
15990  }
15991  }
15992  break;
15993  }
15994 
15995  case value_t::number_unsigned:
15996  {
15997  if (j.m_data.m_value.number_unsigned <= 0x17)
15998  {
15999  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
16000  }
16001  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
16002  {
16003  oa->write_character(to_char_type(0x18));
16004  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
16005  }
16006  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
16007  {
16008  oa->write_character(to_char_type(0x19));
16009  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
16010  }
16011  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
16012  {
16013  oa->write_character(to_char_type(0x1A));
16014  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
16015  }
16016  else
16017  {
16018  oa->write_character(to_char_type(0x1B));
16019  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
16020  }
16021  break;
16022  }
16023 
16024  case value_t::number_float:
16025  {
16026  if (std::isnan(j.m_data.m_value.number_float))
16027  {
16028  // NaN is 0xf97e00 in CBOR
16029  oa->write_character(to_char_type(0xF9));
16030  oa->write_character(to_char_type(0x7E));
16031  oa->write_character(to_char_type(0x00));
16032  }
16033  else if (std::isinf(j.m_data.m_value.number_float))
16034  {
16035  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
16036  oa->write_character(to_char_type(0xf9));
16037  oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
16038  oa->write_character(to_char_type(0x00));
16039  }
16040  else
16041  {
16042  write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::cbor);
16043  }
16044  break;
16045  }
16046 
16047  case value_t::string:
16048  {
16049  // step 1: write control byte and the string length
16050  const auto N = j.m_data.m_value.string->size();
16051  if (N <= 0x17)
16052  {
16053  write_number(static_cast<std::uint8_t>(0x60 + N));
16054  }
16055  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
16056  {
16057  oa->write_character(to_char_type(0x78));
16058  write_number(static_cast<std::uint8_t>(N));
16059  }
16060  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16061  {
16062  oa->write_character(to_char_type(0x79));
16063  write_number(static_cast<std::uint16_t>(N));
16064  }
16065  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16066  {
16067  oa->write_character(to_char_type(0x7A));
16068  write_number(static_cast<std::uint32_t>(N));
16069  }
16070  // LCOV_EXCL_START
16071  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
16072  {
16073  oa->write_character(to_char_type(0x7B));
16074  write_number(static_cast<std::uint64_t>(N));
16075  }
16076  // LCOV_EXCL_STOP
16077 
16078  // step 2: write the string
16079  oa->write_characters(
16080  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
16081  j.m_data.m_value.string->size());
16082  break;
16083  }
16084 
16085  case value_t::array:
16086  {
16087  // step 1: write control byte and the array size
16088  const auto N = j.m_data.m_value.array->size();
16089  if (N <= 0x17)
16090  {
16091  write_number(static_cast<std::uint8_t>(0x80 + N));
16092  }
16093  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
16094  {
16095  oa->write_character(to_char_type(0x98));
16096  write_number(static_cast<std::uint8_t>(N));
16097  }
16098  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16099  {
16100  oa->write_character(to_char_type(0x99));
16101  write_number(static_cast<std::uint16_t>(N));
16102  }
16103  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16104  {
16105  oa->write_character(to_char_type(0x9A));
16106  write_number(static_cast<std::uint32_t>(N));
16107  }
16108  // LCOV_EXCL_START
16109  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
16110  {
16111  oa->write_character(to_char_type(0x9B));
16112  write_number(static_cast<std::uint64_t>(N));
16113  }
16114  // LCOV_EXCL_STOP
16115 
16116  // step 2: write each element
16117  for (const auto& el : *j.m_data.m_value.array)
16118  {
16119  write_cbor(el);
16120  }
16121  break;
16122  }
16123 
16124  case value_t::binary:
16125  {
16126  if (j.m_data.m_value.binary->has_subtype())
16127  {
16128  if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
16129  {
16130  write_number(static_cast<std::uint8_t>(0xd8));
16131  write_number(static_cast<std::uint8_t>(j.m_data.m_value.binary->subtype()));
16132  }
16133  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
16134  {
16135  write_number(static_cast<std::uint8_t>(0xd9));
16136  write_number(static_cast<std::uint16_t>(j.m_data.m_value.binary->subtype()));
16137  }
16138  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
16139  {
16140  write_number(static_cast<std::uint8_t>(0xda));
16141  write_number(static_cast<std::uint32_t>(j.m_data.m_value.binary->subtype()));
16142  }
16143  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
16144  {
16145  write_number(static_cast<std::uint8_t>(0xdb));
16146  write_number(static_cast<std::uint64_t>(j.m_data.m_value.binary->subtype()));
16147  }
16148  }
16149 
16150  // step 1: write control byte and the binary array size
16151  const auto N = j.m_data.m_value.binary->size();
16152  if (N <= 0x17)
16153  {
16154  write_number(static_cast<std::uint8_t>(0x40 + N));
16155  }
16156  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
16157  {
16158  oa->write_character(to_char_type(0x58));
16159  write_number(static_cast<std::uint8_t>(N));
16160  }
16161  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16162  {
16163  oa->write_character(to_char_type(0x59));
16164  write_number(static_cast<std::uint16_t>(N));
16165  }
16166  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16167  {
16168  oa->write_character(to_char_type(0x5A));
16169  write_number(static_cast<std::uint32_t>(N));
16170  }
16171  // LCOV_EXCL_START
16172  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
16173  {
16174  oa->write_character(to_char_type(0x5B));
16175  write_number(static_cast<std::uint64_t>(N));
16176  }
16177  // LCOV_EXCL_STOP
16178 
16179  // step 2: write each element
16180  oa->write_characters(
16181  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
16182  N);
16183 
16184  break;
16185  }
16186 
16187  case value_t::object:
16188  {
16189  // step 1: write control byte and the object size
16190  const auto N = j.m_data.m_value.object->size();
16191  if (N <= 0x17)
16192  {
16193  write_number(static_cast<std::uint8_t>(0xA0 + N));
16194  }
16195  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
16196  {
16197  oa->write_character(to_char_type(0xB8));
16198  write_number(static_cast<std::uint8_t>(N));
16199  }
16200  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16201  {
16202  oa->write_character(to_char_type(0xB9));
16203  write_number(static_cast<std::uint16_t>(N));
16204  }
16205  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16206  {
16207  oa->write_character(to_char_type(0xBA));
16208  write_number(static_cast<std::uint32_t>(N));
16209  }
16210  // LCOV_EXCL_START
16211  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
16212  {
16213  oa->write_character(to_char_type(0xBB));
16214  write_number(static_cast<std::uint64_t>(N));
16215  }
16216  // LCOV_EXCL_STOP
16217 
16218  // step 2: write each element
16219  for (const auto& el : *j.m_data.m_value.object)
16220  {
16221  write_cbor(el.first);
16222  write_cbor(el.second);
16223  }
16224  break;
16225  }
16226 
16227  case value_t::discarded:
16228  default:
16229  break;
16230  }
16231  }
16232 
16236  void write_msgpack(const BasicJsonType& j)
16237  {
16238  switch (j.type())
16239  {
16240  case value_t::null: // nil
16241  {
16242  oa->write_character(to_char_type(0xC0));
16243  break;
16244  }
16245 
16246  case value_t::boolean: // true and false
16247  {
16248  oa->write_character(j.m_data.m_value.boolean
16249  ? to_char_type(0xC3)
16250  : to_char_type(0xC2));
16251  break;
16252  }
16253 
16254  case value_t::number_integer:
16255  {
16256  if (j.m_data.m_value.number_integer >= 0)
16257  {
16258  // MessagePack does not differentiate between positive
16259  // signed integers and unsigned integers. Therefore, we used
16260  // the code from the value_t::number_unsigned case here.
16261  if (j.m_data.m_value.number_unsigned < 128)
16262  {
16263  // positive fixnum
16264  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
16265  }
16266  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
16267  {
16268  // uint 8
16269  oa->write_character(to_char_type(0xCC));
16270  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
16271  }
16272  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
16273  {
16274  // uint 16
16275  oa->write_character(to_char_type(0xCD));
16276  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
16277  }
16278  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
16279  {
16280  // uint 32
16281  oa->write_character(to_char_type(0xCE));
16282  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
16283  }
16284  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16285  {
16286  // uint 64
16287  oa->write_character(to_char_type(0xCF));
16288  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
16289  }
16290  }
16291  else
16292  {
16293  if (j.m_data.m_value.number_integer >= -32)
16294  {
16295  // negative fixnum
16296  write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
16297  }
16298  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
16299  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
16300  {
16301  // int 8
16302  oa->write_character(to_char_type(0xD0));
16303  write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
16304  }
16305  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
16306  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
16307  {
16308  // int 16
16309  oa->write_character(to_char_type(0xD1));
16310  write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));
16311  }
16312  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
16313  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
16314  {
16315  // int 32
16316  oa->write_character(to_char_type(0xD2));
16317  write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));
16318  }
16319  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
16320  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
16321  {
16322  // int 64
16323  oa->write_character(to_char_type(0xD3));
16324  write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
16325  }
16326  }
16327  break;
16328  }
16329 
16330  case value_t::number_unsigned:
16331  {
16332  if (j.m_data.m_value.number_unsigned < 128)
16333  {
16334  // positive fixnum
16335  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
16336  }
16337  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
16338  {
16339  // uint 8
16340  oa->write_character(to_char_type(0xCC));
16341  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
16342  }
16343  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
16344  {
16345  // uint 16
16346  oa->write_character(to_char_type(0xCD));
16347  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
16348  }
16349  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
16350  {
16351  // uint 32
16352  oa->write_character(to_char_type(0xCE));
16353  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
16354  }
16355  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16356  {
16357  // uint 64
16358  oa->write_character(to_char_type(0xCF));
16359  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
16360  }
16361  break;
16362  }
16363 
16364  case value_t::number_float:
16365  {
16366  write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::msgpack);
16367  break;
16368  }
16369 
16370  case value_t::string:
16371  {
16372  // step 1: write control byte and the string length
16373  const auto N = j.m_data.m_value.string->size();
16374  if (N <= 31)
16375  {
16376  // fixstr
16377  write_number(static_cast<std::uint8_t>(0xA0 | N));
16378  }
16379  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
16380  {
16381  // str 8
16382  oa->write_character(to_char_type(0xD9));
16383  write_number(static_cast<std::uint8_t>(N));
16384  }
16385  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16386  {
16387  // str 16
16388  oa->write_character(to_char_type(0xDA));
16389  write_number(static_cast<std::uint16_t>(N));
16390  }
16391  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16392  {
16393  // str 32
16394  oa->write_character(to_char_type(0xDB));
16395  write_number(static_cast<std::uint32_t>(N));
16396  }
16397 
16398  // step 2: write the string
16399  oa->write_characters(
16400  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
16401  j.m_data.m_value.string->size());
16402  break;
16403  }
16404 
16405  case value_t::array:
16406  {
16407  // step 1: write control byte and the array size
16408  const auto N = j.m_data.m_value.array->size();
16409  if (N <= 15)
16410  {
16411  // fixarray
16412  write_number(static_cast<std::uint8_t>(0x90 | N));
16413  }
16414  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16415  {
16416  // array 16
16417  oa->write_character(to_char_type(0xDC));
16418  write_number(static_cast<std::uint16_t>(N));
16419  }
16420  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16421  {
16422  // array 32
16423  oa->write_character(to_char_type(0xDD));
16424  write_number(static_cast<std::uint32_t>(N));
16425  }
16426 
16427  // step 2: write each element
16428  for (const auto& el : *j.m_data.m_value.array)
16429  {
16430  write_msgpack(el);
16431  }
16432  break;
16433  }
16434 
16435  case value_t::binary:
16436  {
16437  // step 0: determine if the binary type has a set subtype to
16438  // determine whether to use the ext or fixext types
16439  const bool use_ext = j.m_data.m_value.binary->has_subtype();
16440 
16441  // step 1: write control byte and the byte string length
16442  const auto N = j.m_data.m_value.binary->size();
16443  if (N <= (std::numeric_limits<std::uint8_t>::max)())
16444  {
16445  std::uint8_t output_type{};
16446  bool fixed = true;
16447  if (use_ext)
16448  {
16449  switch (N)
16450  {
16451  case 1:
16452  output_type = 0xD4; // fixext 1
16453  break;
16454  case 2:
16455  output_type = 0xD5; // fixext 2
16456  break;
16457  case 4:
16458  output_type = 0xD6; // fixext 4
16459  break;
16460  case 8:
16461  output_type = 0xD7; // fixext 8
16462  break;
16463  case 16:
16464  output_type = 0xD8; // fixext 16
16465  break;
16466  default:
16467  output_type = 0xC7; // ext 8
16468  fixed = false;
16469  break;
16470  }
16471 
16472  }
16473  else
16474  {
16475  output_type = 0xC4; // bin 8
16476  fixed = false;
16477  }
16478 
16479  oa->write_character(to_char_type(output_type));
16480  if (!fixed)
16481  {
16482  write_number(static_cast<std::uint8_t>(N));
16483  }
16484  }
16485  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16486  {
16487  const std::uint8_t output_type = use_ext
16488  ? 0xC8 // ext 16
16489  : 0xC5; // bin 16
16490 
16491  oa->write_character(to_char_type(output_type));
16492  write_number(static_cast<std::uint16_t>(N));
16493  }
16494  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16495  {
16496  const std::uint8_t output_type = use_ext
16497  ? 0xC9 // ext 32
16498  : 0xC6; // bin 32
16499 
16500  oa->write_character(to_char_type(output_type));
16501  write_number(static_cast<std::uint32_t>(N));
16502  }
16503 
16504  // step 1.5: if this is an ext type, write the subtype
16505  if (use_ext)
16506  {
16507  write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));
16508  }
16509 
16510  // step 2: write the byte string
16511  oa->write_characters(
16512  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
16513  N);
16514 
16515  break;
16516  }
16517 
16518  case value_t::object:
16519  {
16520  // step 1: write control byte and the object size
16521  const auto N = j.m_data.m_value.object->size();
16522  if (N <= 15)
16523  {
16524  // fixmap
16525  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
16526  }
16527  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16528  {
16529  // map 16
16530  oa->write_character(to_char_type(0xDE));
16531  write_number(static_cast<std::uint16_t>(N));
16532  }
16533  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16534  {
16535  // map 32
16536  oa->write_character(to_char_type(0xDF));
16537  write_number(static_cast<std::uint32_t>(N));
16538  }
16539 
16540  // step 2: write each element
16541  for (const auto& el : *j.m_data.m_value.object)
16542  {
16543  write_msgpack(el.first);
16544  write_msgpack(el.second);
16545  }
16546  break;
16547  }
16548 
16549  case value_t::discarded:
16550  default:
16551  break;
16552  }
16553  }
16554 
16563  void write_ubjson(const BasicJsonType& j, const bool use_count,
16564  const bool use_type, const bool add_prefix = true,
16565  const bool use_bjdata = false, const bjdata_version_t bjdata_version = bjdata_version_t::draft2)
16566  {
16567  const bool bjdata_draft3 = use_bjdata && bjdata_version == bjdata_version_t::draft3;
16568 
16569  switch (j.type())
16570  {
16571  case value_t::null:
16572  {
16573  if (add_prefix)
16574  {
16575  oa->write_character(to_char_type('Z'));
16576  }
16577  break;
16578  }
16579 
16580  case value_t::boolean:
16581  {
16582  if (add_prefix)
16583  {
16584  oa->write_character(j.m_data.m_value.boolean
16585  ? to_char_type('T')
16586  : to_char_type('F'));
16587  }
16588  break;
16589  }
16590 
16591  case value_t::number_integer:
16592  {
16593  write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);
16594  break;
16595  }
16596 
16597  case value_t::number_unsigned:
16598  {
16599  write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);
16600  break;
16601  }
16602 
16603  case value_t::number_float:
16604  {
16605  write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);
16606  break;
16607  }
16608 
16609  case value_t::string:
16610  {
16611  if (add_prefix)
16612  {
16613  oa->write_character(to_char_type('S'));
16614  }
16615  write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
16616  oa->write_characters(
16617  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
16618  j.m_data.m_value.string->size());
16619  break;
16620  }
16621 
16622  case value_t::array:
16623  {
16624  if (add_prefix)
16625  {
16626  oa->write_character(to_char_type('['));
16627  }
16628 
16629  bool prefix_required = true;
16630  if (use_type && !j.m_data.m_value.array->empty())
16631  {
16632  JSON_ASSERT(use_count);
16633  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
16634  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
16635  [this, first_prefix, use_bjdata](const BasicJsonType & v)
16636  {
16637  return ubjson_prefix(v, use_bjdata) == first_prefix;
16638  });
16639 
16640  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
16641 
16642  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
16643  {
16644  prefix_required = false;
16645  oa->write_character(to_char_type('$'));
16646  oa->write_character(first_prefix);
16647  }
16648  }
16649 
16650  if (use_count)
16651  {
16652  oa->write_character(to_char_type('#'));
16653  write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
16654  }
16655 
16656  for (const auto& el : *j.m_data.m_value.array)
16657  {
16658  write_ubjson(el, use_count, use_type, prefix_required, use_bjdata, bjdata_version);
16659  }
16660 
16661  if (!use_count)
16662  {
16663  oa->write_character(to_char_type(']'));
16664  }
16665 
16666  break;
16667  }
16668 
16669  case value_t::binary:
16670  {
16671  if (add_prefix)
16672  {
16673  oa->write_character(to_char_type('['));
16674  }
16675 
16676  if (use_type && (bjdata_draft3 || !j.m_data.m_value.binary->empty()))
16677  {
16678  JSON_ASSERT(use_count);
16679  oa->write_character(to_char_type('$'));
16680  oa->write_character(bjdata_draft3 ? 'B' : 'U');
16681  }
16682 
16683  if (use_count)
16684  {
16685  oa->write_character(to_char_type('#'));
16686  write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);
16687  }
16688 
16689  if (use_type)
16690  {
16691  oa->write_characters(
16692  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
16693  j.m_data.m_value.binary->size());
16694  }
16695  else
16696  {
16697  for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
16698  {
16699  oa->write_character(to_char_type(bjdata_draft3 ? 'B' : 'U'));
16700  oa->write_character(j.m_data.m_value.binary->data()[i]);
16701  }
16702  }
16703 
16704  if (!use_count)
16705  {
16706  oa->write_character(to_char_type(']'));
16707  }
16708 
16709  break;
16710  }
16711 
16712  case value_t::object:
16713  {
16714  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())
16715  {
16716  if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type, bjdata_version)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
16717  {
16718  break;
16719  }
16720  }
16721 
16722  if (add_prefix)
16723  {
16724  oa->write_character(to_char_type('{'));
16725  }
16726 
16727  bool prefix_required = true;
16728  if (use_type && !j.m_data.m_value.object->empty())
16729  {
16730  JSON_ASSERT(use_count);
16731  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
16732  const bool same_prefix = std::all_of(j.begin(), j.end(),
16733  [this, first_prefix, use_bjdata](const BasicJsonType & v)
16734  {
16735  return ubjson_prefix(v, use_bjdata) == first_prefix;
16736  });
16737 
16738  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
16739 
16740  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
16741  {
16742  prefix_required = false;
16743  oa->write_character(to_char_type('$'));
16744  oa->write_character(first_prefix);
16745  }
16746  }
16747 
16748  if (use_count)
16749  {
16750  oa->write_character(to_char_type('#'));
16751  write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
16752  }
16753 
16754  for (const auto& el : *j.m_data.m_value.object)
16755  {
16756  write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
16757  oa->write_characters(
16758  reinterpret_cast<const CharType*>(el.first.c_str()),
16759  el.first.size());
16760  write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata, bjdata_version);
16761  }
16762 
16763  if (!use_count)
16764  {
16765  oa->write_character(to_char_type('}'));
16766  }
16767 
16768  break;
16769  }
16770 
16771  case value_t::discarded:
16772  default:
16773  break;
16774  }
16775  }
16776 
16777  private:
16779  // BSON //
16781 
16786  static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
16787  {
16788  const auto it = name.find(static_cast<typename string_t::value_type>(0));
16789  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
16790  {
16791  JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
16792  }
16793 
16794  static_cast<void>(j);
16795  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
16796  }
16797 
16802  const std::uint8_t element_type)
16803  {
16804  oa->write_character(to_char_type(element_type)); // boolean
16805  oa->write_characters(
16806  reinterpret_cast<const CharType*>(name.c_str()),
16807  name.size() + 1u);
16808  }
16809 
16813  void write_bson_boolean(const string_t& name,
16814  const bool value)
16815  {
16816  write_bson_entry_header(name, 0x08);
16817  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
16818  }
16819 
16823  void write_bson_double(const string_t& name,
16824  const double value)
16825  {
16826  write_bson_entry_header(name, 0x01);
16827  write_number<double>(value, true);
16828  }
16829 
16833  static std::size_t calc_bson_string_size(const string_t& value)
16834  {
16835  return sizeof(std::int32_t) + value.size() + 1ul;
16836  }
16837 
16841  void write_bson_string(const string_t& name,
16842  const string_t& value)
16843  {
16844  write_bson_entry_header(name, 0x02);
16845 
16846  write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
16847  oa->write_characters(
16848  reinterpret_cast<const CharType*>(value.c_str()),
16849  value.size() + 1);
16850  }
16851 
16855  void write_bson_null(const string_t& name)
16856  {
16857  write_bson_entry_header(name, 0x0A);
16858  }
16859 
16863  static std::size_t calc_bson_integer_size(const std::int64_t value)
16864  {
16865  return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
16866  ? sizeof(std::int32_t)
16867  : sizeof(std::int64_t);
16868  }
16869 
16873  void write_bson_integer(const string_t& name,
16874  const std::int64_t value)
16875  {
16876  if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
16877  {
16878  write_bson_entry_header(name, 0x10); // int32
16879  write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
16880  }
16881  else
16882  {
16883  write_bson_entry_header(name, 0x12); // int64
16884  write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
16885  }
16886  }
16887 
16891  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
16892  {
16893  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16894  ? sizeof(std::int32_t)
16895  : sizeof(std::int64_t);
16896  }
16897 
16901  void write_bson_unsigned(const string_t& name,
16902  const BasicJsonType& j)
16903  {
16904  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16905  {
16906  write_bson_entry_header(name, 0x10 /* int32 */);
16907  write_number<std::int32_t>(static_cast<std::int32_t>(j.m_data.m_value.number_unsigned), true);
16908  }
16909  else if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16910  {
16911  write_bson_entry_header(name, 0x12 /* int64 */);
16912  write_number<std::int64_t>(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned), true);
16913  }
16914  else
16915  {
16916  write_bson_entry_header(name, 0x11 /* uint64 */);
16917  write_number<std::uint64_t>(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned), true);
16918  }
16919  }
16920 
16925  const typename BasicJsonType::object_t& value)
16926  {
16927  write_bson_entry_header(name, 0x03); // object
16928  write_bson_object(value);
16929  }
16930 
16934  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
16935  {
16936  std::size_t array_index = 0ul;
16937 
16938  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)
16939  {
16940  return result + calc_bson_element_size(std::to_string(array_index++), el);
16941  });
16942 
16943  return sizeof(std::int32_t) + embedded_document_size + 1ul;
16944  }
16945 
16949  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
16950  {
16951  return sizeof(std::int32_t) + value.size() + 1ul;
16952  }
16953 
16957  void write_bson_array(const string_t& name,
16958  const typename BasicJsonType::array_t& value)
16959  {
16960  write_bson_entry_header(name, 0x04); // array
16961  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
16962 
16963  std::size_t array_index = 0ul;
16964 
16965  for (const auto& el : value)
16966  {
16967  write_bson_element(std::to_string(array_index++), el);
16968  }
16969 
16970  oa->write_character(to_char_type(0x00));
16971  }
16972 
16976  void write_bson_binary(const string_t& name,
16977  const binary_t& value)
16978  {
16979  write_bson_entry_header(name, 0x05);
16980 
16981  write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
16982  write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
16983 
16984  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
16985  }
16986 
16991  static std::size_t calc_bson_element_size(const string_t& name,
16992  const BasicJsonType& j)
16993  {
16994  const auto header_size = calc_bson_entry_header_size(name, j);
16995  switch (j.type())
16996  {
16997  case value_t::object:
16998  return header_size + calc_bson_object_size(*j.m_data.m_value.object);
16999 
17000  case value_t::array:
17001  return header_size + calc_bson_array_size(*j.m_data.m_value.array);
17002 
17003  case value_t::binary:
17004  return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);
17005 
17006  case value_t::boolean:
17007  return header_size + 1ul;
17008 
17009  case value_t::number_float:
17010  return header_size + 8ul;
17011 
17012  case value_t::number_integer:
17013  return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);
17014 
17015  case value_t::number_unsigned:
17016  return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);
17017 
17018  case value_t::string:
17019  return header_size + calc_bson_string_size(*j.m_data.m_value.string);
17020 
17021  case value_t::null:
17022  return header_size + 0ul;
17023 
17024  // LCOV_EXCL_START
17025  case value_t::discarded:
17026  default:
17027  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
17028  return 0ul;
17029  // LCOV_EXCL_STOP
17030  }
17031  }
17032 
17039  void write_bson_element(const string_t& name,
17040  const BasicJsonType& j)
17041  {
17042  switch (j.type())
17043  {
17044  case value_t::object:
17045  return write_bson_object_entry(name, *j.m_data.m_value.object);
17046 
17047  case value_t::array:
17048  return write_bson_array(name, *j.m_data.m_value.array);
17049 
17050  case value_t::binary:
17051  return write_bson_binary(name, *j.m_data.m_value.binary);
17052 
17053  case value_t::boolean:
17054  return write_bson_boolean(name, j.m_data.m_value.boolean);
17055 
17056  case value_t::number_float:
17057  return write_bson_double(name, j.m_data.m_value.number_float);
17058 
17059  case value_t::number_integer:
17060  return write_bson_integer(name, j.m_data.m_value.number_integer);
17061 
17062  case value_t::number_unsigned:
17063  return write_bson_unsigned(name, j);
17064 
17065  case value_t::string:
17066  return write_bson_string(name, *j.m_data.m_value.string);
17067 
17068  case value_t::null:
17069  return write_bson_null(name);
17070 
17071  // LCOV_EXCL_START
17072  case value_t::discarded:
17073  default:
17074  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
17075  return;
17076  // LCOV_EXCL_STOP
17077  }
17078  }
17079 
17086  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
17087  {
17088  const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
17089  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
17090  {
17091  return result += calc_bson_element_size(el.first, el.second);
17092  });
17093 
17094  return sizeof(std::int32_t) + document_size + 1ul;
17095  }
17096 
17101  void write_bson_object(const typename BasicJsonType::object_t& value)
17102  {
17103  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
17104 
17105  for (const auto& el : value)
17106  {
17107  write_bson_element(el.first, el.second);
17108  }
17109 
17110  oa->write_character(to_char_type(0x00));
17111  }
17112 
17114  // CBOR //
17116 
17117  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
17118  {
17119  return to_char_type(0xFA); // Single-Precision Float
17120  }
17121 
17122  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
17123  {
17124  return to_char_type(0xFB); // Double-Precision Float
17125  }
17126 
17128  // MsgPack //
17130 
17131  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
17132  {
17133  return to_char_type(0xCA); // float 32
17134  }
17135 
17136  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
17137  {
17138  return to_char_type(0xCB); // float 64
17139  }
17140 
17142  // UBJSON //
17144 
17145  // UBJSON: write number (floating point)
17146  template<typename NumberType, typename std::enable_if<
17148  void write_number_with_ubjson_prefix(const NumberType n,
17149  const bool add_prefix,
17150  const bool use_bjdata)
17151  {
17152  if (add_prefix)
17153  {
17154  oa->write_character(get_ubjson_float_prefix(n));
17155  }
17156  write_number(n, use_bjdata);
17157  }
17158 
17159  // UBJSON: write number (unsigned integer)
17160  template<typename NumberType, typename std::enable_if<
17162  void write_number_with_ubjson_prefix(const NumberType n,
17163  const bool add_prefix,
17164  const bool use_bjdata)
17165  {
17166  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
17167  {
17168  if (add_prefix)
17169  {
17170  oa->write_character(to_char_type('i')); // int8
17171  }
17172  write_number(static_cast<std::uint8_t>(n), use_bjdata);
17173  }
17174  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
17175  {
17176  if (add_prefix)
17177  {
17178  oa->write_character(to_char_type('U')); // uint8
17179  }
17180  write_number(static_cast<std::uint8_t>(n), use_bjdata);
17181  }
17182  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
17183  {
17184  if (add_prefix)
17185  {
17186  oa->write_character(to_char_type('I')); // int16
17187  }
17188  write_number(static_cast<std::int16_t>(n), use_bjdata);
17189  }
17190  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
17191  {
17192  if (add_prefix)
17193  {
17194  oa->write_character(to_char_type('u')); // uint16 - bjdata only
17195  }
17196  write_number(static_cast<std::uint16_t>(n), use_bjdata);
17197  }
17198  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
17199  {
17200  if (add_prefix)
17201  {
17202  oa->write_character(to_char_type('l')); // int32
17203  }
17204  write_number(static_cast<std::int32_t>(n), use_bjdata);
17205  }
17206  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
17207  {
17208  if (add_prefix)
17209  {
17210  oa->write_character(to_char_type('m')); // uint32 - bjdata only
17211  }
17212  write_number(static_cast<std::uint32_t>(n), use_bjdata);
17213  }
17214  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
17215  {
17216  if (add_prefix)
17217  {
17218  oa->write_character(to_char_type('L')); // int64
17219  }
17220  write_number(static_cast<std::int64_t>(n), use_bjdata);
17221  }
17222  else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
17223  {
17224  if (add_prefix)
17225  {
17226  oa->write_character(to_char_type('M')); // uint64 - bjdata only
17227  }
17228  write_number(static_cast<std::uint64_t>(n), use_bjdata);
17229  }
17230  else
17231  {
17232  if (add_prefix)
17233  {
17234  oa->write_character(to_char_type('H')); // high-precision number
17235  }
17236 
17237  const auto number = BasicJsonType(n).dump();
17238  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
17239  for (std::size_t i = 0; i < number.size(); ++i)
17240  {
17241  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
17242  }
17243  }
17244  }
17245 
17246  // UBJSON: write number (signed integer)
17247  template < typename NumberType, typename std::enable_if <
17250  void write_number_with_ubjson_prefix(const NumberType n,
17251  const bool add_prefix,
17252  const bool use_bjdata)
17253  {
17254  if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
17255  {
17256  if (add_prefix)
17257  {
17258  oa->write_character(to_char_type('i')); // int8
17259  }
17260  write_number(static_cast<std::int8_t>(n), use_bjdata);
17261  }
17262  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)()))
17263  {
17264  if (add_prefix)
17265  {
17266  oa->write_character(to_char_type('U')); // uint8
17267  }
17268  write_number(static_cast<std::uint8_t>(n), use_bjdata);
17269  }
17270  else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
17271  {
17272  if (add_prefix)
17273  {
17274  oa->write_character(to_char_type('I')); // int16
17275  }
17276  write_number(static_cast<std::int16_t>(n), use_bjdata);
17277  }
17278  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)())))
17279  {
17280  if (add_prefix)
17281  {
17282  oa->write_character(to_char_type('u')); // uint16 - bjdata only
17283  }
17284  write_number(static_cast<uint16_t>(n), use_bjdata);
17285  }
17286  else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
17287  {
17288  if (add_prefix)
17289  {
17290  oa->write_character(to_char_type('l')); // int32
17291  }
17292  write_number(static_cast<std::int32_t>(n), use_bjdata);
17293  }
17294  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)())))
17295  {
17296  if (add_prefix)
17297  {
17298  oa->write_character(to_char_type('m')); // uint32 - bjdata only
17299  }
17300  write_number(static_cast<uint32_t>(n), use_bjdata);
17301  }
17302  else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
17303  {
17304  if (add_prefix)
17305  {
17306  oa->write_character(to_char_type('L')); // int64
17307  }
17308  write_number(static_cast<std::int64_t>(n), use_bjdata);
17309  }
17310  // LCOV_EXCL_START
17311  else
17312  {
17313  if (add_prefix)
17314  {
17315  oa->write_character(to_char_type('H')); // high-precision number
17316  }
17317 
17318  const auto number = BasicJsonType(n).dump();
17319  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
17320  for (std::size_t i = 0; i < number.size(); ++i)
17321  {
17322  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
17323  }
17324  }
17325  // LCOV_EXCL_STOP
17326  }
17327 
17331  CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
17332  {
17333  switch (j.type())
17334  {
17335  case value_t::null:
17336  return 'Z';
17337 
17338  case value_t::boolean:
17339  return j.m_data.m_value.boolean ? 'T' : 'F';
17340 
17341  case value_t::number_integer:
17342  {
17343  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)())
17344  {
17345  return 'i';
17346  }
17347  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)())
17348  {
17349  return 'U';
17350  }
17351  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)())
17352  {
17353  return 'I';
17354  }
17355  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)()))
17356  {
17357  return 'u';
17358  }
17359  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)())
17360  {
17361  return 'l';
17362  }
17363  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)()))
17364  {
17365  return 'm';
17366  }
17367  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)())
17368  {
17369  return 'L';
17370  }
17371  // anything else is treated as a high-precision number
17372  return 'H'; // LCOV_EXCL_LINE
17373  }
17374 
17375  case value_t::number_unsigned:
17376  {
17377  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
17378  {
17379  return 'i';
17380  }
17381  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
17382  {
17383  return 'U';
17384  }
17385  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
17386  {
17387  return 'I';
17388  }
17389  if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
17390  {
17391  return 'u';
17392  }
17393  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
17394  {
17395  return 'l';
17396  }
17397  if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
17398  {
17399  return 'm';
17400  }
17401  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
17402  {
17403  return 'L';
17404  }
17405  if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
17406  {
17407  return 'M';
17408  }
17409  // anything else is treated as a high-precision number
17410  return 'H'; // LCOV_EXCL_LINE
17411  }
17412 
17413  case value_t::number_float:
17414  return get_ubjson_float_prefix(j.m_data.m_value.number_float);
17415 
17416  case value_t::string:
17417  return 'S';
17418 
17419  case value_t::array: // fallthrough
17420  case value_t::binary:
17421  return '[';
17422 
17423  case value_t::object:
17424  return '{';
17425 
17426  case value_t::discarded:
17427  default: // discarded values
17428  return 'N';
17429  }
17430  }
17431 
17432  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
17433  {
17434  return 'd'; // float 32
17435  }
17436 
17437  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
17438  {
17439  return 'D'; // float 64
17440  }
17441 
17445  bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type, const bjdata_version_t bjdata_version)
17446  {
17447  std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
17448  {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'},
17449  {"char", 'C'}, {"byte", 'B'}
17450  };
17451 
17452  string_t key = "_ArrayType_";
17453  auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
17454  if (it == bjdtype.end())
17455  {
17456  return true;
17457  }
17458  CharType dtype = it->second;
17459 
17460  key = "_ArraySize_";
17461  std::size_t len = (value.at(key).empty() ? 0 : 1);
17462  for (const auto& el : value.at(key))
17463  {
17464  len *= static_cast<std::size_t>(el.m_data.m_value.number_unsigned);
17465  }
17466 
17467  key = "_ArrayData_";
17468  if (value.at(key).size() != len)
17469  {
17470  return true;
17471  }
17472 
17473  oa->write_character('[');
17474  oa->write_character('$');
17475  oa->write_character(dtype);
17476  oa->write_character('#');
17477 
17478  key = "_ArraySize_";
17479  write_ubjson(value.at(key), use_count, use_type, true, true, bjdata_version);
17480 
17481  key = "_ArrayData_";
17482  if (dtype == 'U' || dtype == 'C' || dtype == 'B')
17483  {
17484  for (const auto& el : value.at(key))
17485  {
17486  write_number(static_cast<std::uint8_t>(el.m_data.m_value.number_unsigned), true);
17487  }
17488  }
17489  else if (dtype == 'i')
17490  {
17491  for (const auto& el : value.at(key))
17492  {
17493  write_number(static_cast<std::int8_t>(el.m_data.m_value.number_integer), true);
17494  }
17495  }
17496  else if (dtype == 'u')
17497  {
17498  for (const auto& el : value.at(key))
17499  {
17500  write_number(static_cast<std::uint16_t>(el.m_data.m_value.number_unsigned), true);
17501  }
17502  }
17503  else if (dtype == 'I')
17504  {
17505  for (const auto& el : value.at(key))
17506  {
17507  write_number(static_cast<std::int16_t>(el.m_data.m_value.number_integer), true);
17508  }
17509  }
17510  else if (dtype == 'm')
17511  {
17512  for (const auto& el : value.at(key))
17513  {
17514  write_number(static_cast<std::uint32_t>(el.m_data.m_value.number_unsigned), true);
17515  }
17516  }
17517  else if (dtype == 'l')
17518  {
17519  for (const auto& el : value.at(key))
17520  {
17521  write_number(static_cast<std::int32_t>(el.m_data.m_value.number_integer), true);
17522  }
17523  }
17524  else if (dtype == 'M')
17525  {
17526  for (const auto& el : value.at(key))
17527  {
17528  write_number(static_cast<std::uint64_t>(el.m_data.m_value.number_unsigned), true);
17529  }
17530  }
17531  else if (dtype == 'L')
17532  {
17533  for (const auto& el : value.at(key))
17534  {
17535  write_number(static_cast<std::int64_t>(el.m_data.m_value.number_integer), true);
17536  }
17537  }
17538  else if (dtype == 'd')
17539  {
17540  for (const auto& el : value.at(key))
17541  {
17542  write_number(static_cast<float>(el.m_data.m_value.number_float), true);
17543  }
17544  }
17545  else if (dtype == 'D')
17546  {
17547  for (const auto& el : value.at(key))
17548  {
17549  write_number(static_cast<double>(el.m_data.m_value.number_float), true);
17550  }
17551  }
17552  return false;
17553  }
17554 
17556  // Utility functions //
17558 
17559  /*
17560  @brief write a number to output input
17561  @param[in] n number of type @a NumberType
17562  @param[in] OutputIsLittleEndian Set to true if output data is
17563  required to be little endian
17564  @tparam NumberType the type of the number
17565 
17566  @note This function needs to respect the system's endianness, because bytes
17567  in CBOR, MessagePack, and UBJSON are stored in network order (big
17568  endian) and therefore need reordering on little endian systems.
17569  On the other hand, BSON and BJData use little endian and should reorder
17570  on big endian systems.
17571  */
17572  template<typename NumberType>
17573  void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
17574  {
17575  // step 1: write the number to an array of length NumberType
17576  std::array<CharType, sizeof(NumberType)> vec{};
17577  std::memcpy(vec.data(), &n, sizeof(NumberType));
17578 
17579  // step 2: write the array to output (with possible reordering)
17580  if (is_little_endian != OutputIsLittleEndian)
17581  {
17582  // reverse byte order prior to conversion if necessary
17583  std::reverse(vec.begin(), vec.end());
17584  }
17585 
17586  oa->write_characters(vec.data(), sizeof(NumberType));
17587  }
17588 
17590  {
17591 #ifdef __GNUC__
17592 #pragma GCC diagnostic push
17593 #pragma GCC diagnostic ignored "-Wfloat-equal"
17594 #endif
17595  if (!std::isfinite(n) || ((static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
17596  static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
17597  static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))))
17598  {
17599  oa->write_character(format == detail::input_format_t::cbor
17600  ? get_cbor_float_prefix(static_cast<float>(n))
17601  : get_msgpack_float_prefix(static_cast<float>(n)));
17602  write_number(static_cast<float>(n));
17603  }
17604  else
17605  {
17606  oa->write_character(format == detail::input_format_t::cbor
17607  ? get_cbor_float_prefix(n)
17608  : get_msgpack_float_prefix(n));
17609  write_number(n);
17610  }
17611 #ifdef __GNUC__
17612 #pragma GCC diagnostic pop
17613 #endif
17614  }
17615 
17616  public:
17617  // The following to_char_type functions are implement the conversion
17618  // between uint8_t and CharType. In case CharType is not unsigned,
17619  // such a conversion is required to allow values greater than 128.
17620  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
17621  template < typename C = CharType,
17623  static constexpr CharType to_char_type(std::uint8_t x) noexcept
17624  {
17625  return *reinterpret_cast<char*>(&x);
17626  }
17627 
17628  template < typename C = CharType,
17630  static CharType to_char_type(std::uint8_t x) noexcept
17631  {
17632  // The std::is_trivial trait is deprecated in C++26. The replacement is to use
17633  // std::is_trivially_copyable and std::is_trivially_default_constructible.
17634  // However, some older library implementations support std::is_trivial
17635  // but not all the std::is_trivially_* traits.
17636  // Since detecting full support across all libraries is difficult,
17637  // we use std::is_trivial unless we are using a standard where it has been deprecated.
17638  // For more details, see: https://github.com/nlohmann/json/pull/4775#issuecomment-2884361627
17639 #ifdef JSON_HAS_CPP_26
17640  static_assert(std::is_trivially_copyable<CharType>::value, "CharType must be trivially copyable");
17641  static_assert(std::is_trivially_default_constructible<CharType>::value, "CharType must be trivially default constructible");
17642 #else
17643  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
17644 #endif
17645 
17646  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
17647  CharType result;
17648  std::memcpy(&result, &x, sizeof(x));
17649  return result;
17650  }
17651 
17652  template<typename C = CharType,
17654  static constexpr CharType to_char_type(std::uint8_t x) noexcept
17655  {
17656  return x;
17657  }
17658 
17659  template < typename InputCharType, typename C = CharType,
17660  enable_if_t <
17664  > * = nullptr >
17665  static constexpr CharType to_char_type(InputCharType x) noexcept
17666  {
17667  return x;
17668  }
17669 
17670  private:
17673 
17676 };
17677 
17678 } // namespace detail
17680 
17681 // #include <nlohmann/detail/output/output_adapters.hpp>
17682 
17683 // #include <nlohmann/detail/output/serializer.hpp>
17684 // __ _____ _____ _____
17685 // __| | __| | | | JSON for Modern C++
17686 // | | |__ | | | | | | version 3.12.0
17687 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
17688 //
17689 // SPDX-FileCopyrightText: 2008 - 2009 Björn Hoehrmann <bjoern@hoehrmann.de>
17690 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
17691 // SPDX-License-Identifier: MIT
17692 
17693 
17694 
17695 #include <algorithm> // reverse, remove, fill, find, none_of
17696 #include <array> // array
17697 #include <clocale> // localeconv, lconv
17698 #include <cmath> // labs, isfinite, isnan, signbit
17699 #include <cstddef> // size_t, ptrdiff_t
17700 #include <cstdint> // uint8_t
17701 #include <cstdio> // snprintf
17702 #include <limits> // numeric_limits
17703 #include <string> // string, char_traits
17704 #include <iomanip> // setfill, setw
17705 #include <type_traits> // is_same
17706 #include <utility> // move
17707 
17708 // #include <nlohmann/detail/conversions/to_chars.hpp>
17709 // __ _____ _____ _____
17710 // __| | __| | | | JSON for Modern C++
17711 // | | |__ | | | | | | version 3.12.0
17712 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
17713 //
17714 // SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>
17715 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
17716 // SPDX-License-Identifier: MIT
17717 
17718 
17719 
17720 #include <array> // array
17721 #include <cmath> // signbit, isfinite
17722 #include <cstdint> // intN_t, uintN_t
17723 #include <cstring> // memcpy, memmove
17724 #include <limits> // numeric_limits
17725 #include <type_traits> // conditional
17726 
17727 // #include <nlohmann/detail/macro_scope.hpp>
17728 
17729 
17731 namespace detail
17732 {
17733 
17753 namespace dtoa_impl
17754 {
17755 
17756 template<typename Target, typename Source>
17757 Target reinterpret_bits(const Source source)
17758 {
17759  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
17760 
17761  Target target;
17762  std::memcpy(&target, &source, sizeof(Source));
17763  return target;
17764 }
17765 
17766 struct diyfp // f * 2^e
17767 {
17768  static constexpr int kPrecision = 64; // = q
17769 
17771  int e = 0;
17772 
17773  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
17774 
17779  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
17780  {
17781  JSON_ASSERT(x.e == y.e);
17782  JSON_ASSERT(x.f >= y.f);
17783 
17784  return {x.f - y.f, x.e};
17785  }
17786 
17791  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
17792  {
17793  static_assert(kPrecision == 64, "internal error");
17794 
17795  // Computes:
17796  // f = round((x.f * y.f) / 2^q)
17797  // e = x.e + y.e + q
17798 
17799  // Emulate the 64-bit * 64-bit multiplication:
17800  //
17801  // p = u * v
17802  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
17803  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
17804  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
17805  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
17806  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
17807  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
17808  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
17809  //
17810  // (Since Q might be larger than 2^32 - 1)
17811  //
17812  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
17813  //
17814  // (Q_hi + H does not overflow a 64-bit int)
17815  //
17816  // = p_lo + 2^64 p_hi
17817 
17818  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
17819  const std::uint64_t u_hi = x.f >> 32u;
17820  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
17821  const std::uint64_t v_hi = y.f >> 32u;
17822 
17823  const std::uint64_t p0 = u_lo * v_lo;
17824  const std::uint64_t p1 = u_lo * v_hi;
17825  const std::uint64_t p2 = u_hi * v_lo;
17826  const std::uint64_t p3 = u_hi * v_hi;
17827 
17828  const std::uint64_t p0_hi = p0 >> 32u;
17829  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
17830  const std::uint64_t p1_hi = p1 >> 32u;
17831  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
17832  const std::uint64_t p2_hi = p2 >> 32u;
17833 
17834  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
17835 
17836  // The full product might now be computed as
17837  //
17838  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
17839  // p_lo = p0_lo + (Q << 32)
17840  //
17841  // But in this particular case here, the full p_lo is not required.
17842  // Effectively, we only need to add the highest bit in p_lo to p_hi (and
17843  // Q_hi + 1 does not overflow).
17844 
17845  Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
17846 
17847  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
17848 
17849  return {h, x.e + y.e + 64};
17850  }
17851 
17856  static diyfp normalize(diyfp x) noexcept
17857  {
17858  JSON_ASSERT(x.f != 0);
17859 
17860  while ((x.f >> 63u) == 0)
17861  {
17862  x.f <<= 1u;
17863  x.e--;
17864  }
17865 
17866  return x;
17867  }
17868 
17873  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
17874  {
17875  const int delta = x.e - target_exponent;
17876 
17877  JSON_ASSERT(delta >= 0);
17878  JSON_ASSERT(((x.f << delta) >> delta) == x.f);
17879 
17880  return {x.f << delta, target_exponent};
17881  }
17882 };
17883 
17885 {
17889 };
17890 
17897 template<typename FloatType>
17899 {
17900  JSON_ASSERT(std::isfinite(value));
17901  JSON_ASSERT(value > 0);
17902 
17903  // Convert the IEEE representation into a diyfp.
17904  //
17905  // If v is denormal:
17906  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
17907  // If v is normalized:
17908  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
17909 
17910  static_assert(std::numeric_limits<FloatType>::is_iec559,
17911  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
17912 
17913  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
17914  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
17915  constexpr int kMinExp = 1 - kBias;
17916  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
17917 
17919 
17920  const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
17921  const std::uint64_t E = bits >> (kPrecision - 1);
17922  const std::uint64_t F = bits & (kHiddenBit - 1);
17923 
17924  const bool is_denormal = E == 0;
17925  const diyfp v = is_denormal
17926  ? diyfp(F, kMinExp)
17927  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
17928 
17929  // Compute the boundaries m- and m+ of the floating-point value
17930  // v = f * 2^e.
17931  //
17932  // Determine v- and v+, the floating-point predecessor and successor of v,
17933  // respectively.
17934  //
17935  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
17936  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
17937  //
17938  // v+ = v + 2^e
17939  //
17940  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
17941  // between m- and m+ round to v, regardless of how the input rounding
17942  // algorithm breaks ties.
17943  //
17944  // ---+-------------+-------------+-------------+-------------+--- (A)
17945  // v- m- v m+ v+
17946  //
17947  // -----------------+------+------+-------------+-------------+--- (B)
17948  // v- m- v m+ v+
17949 
17950  const bool lower_boundary_is_closer = F == 0 && E > 1;
17951  const diyfp m_plus = diyfp((2 * v.f) + 1, v.e - 1);
17952  const diyfp m_minus = lower_boundary_is_closer
17953  ? diyfp((4 * v.f) - 1, v.e - 2) // (B)
17954  : diyfp((2 * v.f) - 1, v.e - 1); // (A)
17955 
17956  // Determine the normalized w+ = m+.
17957  const diyfp w_plus = diyfp::normalize(m_plus);
17958 
17959  // Determine w- = m- such that e_(w-) = e_(w+).
17960  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
17961 
17962  return {diyfp::normalize(v), w_minus, w_plus};
17963 }
17964 
17965 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
17966 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
17967 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
17968 //
17969 // alpha <= e = e_c + e_w + q <= gamma
17970 //
17971 // or
17972 //
17973 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
17974 // <= f_c * f_w * 2^gamma
17975 //
17976 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
17977 //
17978 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
17979 //
17980 // or
17981 //
17982 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
17983 //
17984 // The choice of (alpha,gamma) determines the size of the table and the form of
17985 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
17986 // in practice:
17987 //
17988 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
17989 // processed independently: An integral part p1, and a fractional part p2:
17990 //
17991 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
17992 // = (f div 2^-e) + (f mod 2^-e) * 2^e
17993 // = p1 + p2 * 2^e
17994 //
17995 // The conversion of p1 into decimal form requires a series of divisions and
17996 // modulos by (a power of) 10. These operations are faster for 32-bit than for
17997 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
17998 // achieved by choosing
17999 //
18000 // -e >= 32 or e <= -32 := gamma
18001 //
18002 // In order to convert the fractional part
18003 //
18004 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
18005 //
18006 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
18007 // d[-i] are extracted in order:
18008 //
18009 // (10 * p2) div 2^-e = d[-1]
18010 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
18011 //
18012 // The multiplication by 10 must not overflow. It is sufficient to choose
18013 //
18014 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
18015 //
18016 // Since p2 = f mod 2^-e < 2^-e,
18017 //
18018 // -e <= 60 or e >= -60 := alpha
18019 
18020 constexpr int kAlpha = -60;
18021 constexpr int kGamma = -32;
18022 
18023 struct cached_power // c = f * 2^e ~= 10^k
18024 {
18026  int e;
18027  int k;
18028 };
18029 
18038 {
18039  // Now
18040  //
18041  // alpha <= e_c + e + q <= gamma (1)
18042  // ==> f_c * 2^alpha <= c * 2^e * 2^q
18043  //
18044  // and since the c's are normalized, 2^(q-1) <= f_c,
18045  //
18046  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
18047  // ==> 2^(alpha - e - 1) <= c
18048  //
18049  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
18050  //
18051  // k = ceil( log_10( 2^(alpha - e - 1) ) )
18052  // = ceil( (alpha - e - 1) * log_10(2) )
18053  //
18054  // From the paper:
18055  // "In theory the result of the procedure could be wrong since c is rounded,
18056  // and the computation itself is approximated [...]. In practice, however,
18057  // this simple function is sufficient."
18058  //
18059  // For IEEE double precision floating-point numbers converted into
18060  // normalized diyfp's w = f * 2^e, with q = 64,
18061  //
18062  // e >= -1022 (min IEEE exponent)
18063  // -52 (p - 1)
18064  // -52 (p - 1, possibly normalize denormal IEEE numbers)
18065  // -11 (normalize the diyfp)
18066  // = -1137
18067  //
18068  // and
18069  //
18070  // e <= +1023 (max IEEE exponent)
18071  // -52 (p - 1)
18072  // -11 (normalize the diyfp)
18073  // = 960
18074  //
18075  // This binary exponent range [-1137,960] results in a decimal exponent
18076  // range [-307,324]. One does not need to store a cached power for each
18077  // k in this range. For each such k it suffices to find a cached power
18078  // such that the exponent of the product lies in [alpha,gamma].
18079  // This implies that the difference of the decimal exponents of adjacent
18080  // table entries must be less than or equal to
18081  //
18082  // floor( (gamma - alpha) * log_10(2) ) = 8.
18083  //
18084  // (A smaller distance gamma-alpha would require a larger table.)
18085 
18086  // NB:
18087  // Actually, this function returns c, such that -60 <= e_c + e + 64 <= -34.
18088 
18089  constexpr int kCachedPowersMinDecExp = -300;
18090  constexpr int kCachedPowersDecStep = 8;
18091 
18092  static constexpr std::array<cached_power, 79> kCachedPowers =
18093  {
18094  {
18095  { 0xAB70FE17C79AC6CA, -1060, -300 },
18096  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
18097  { 0xBE5691EF416BD60C, -1007, -284 },
18098  { 0x8DD01FAD907FFC3C, -980, -276 },
18099  { 0xD3515C2831559A83, -954, -268 },
18100  { 0x9D71AC8FADA6C9B5, -927, -260 },
18101  { 0xEA9C227723EE8BCB, -901, -252 },
18102  { 0xAECC49914078536D, -874, -244 },
18103  { 0x823C12795DB6CE57, -847, -236 },
18104  { 0xC21094364DFB5637, -821, -228 },
18105  { 0x9096EA6F3848984F, -794, -220 },
18106  { 0xD77485CB25823AC7, -768, -212 },
18107  { 0xA086CFCD97BF97F4, -741, -204 },
18108  { 0xEF340A98172AACE5, -715, -196 },
18109  { 0xB23867FB2A35B28E, -688, -188 },
18110  { 0x84C8D4DFD2C63F3B, -661, -180 },
18111  { 0xC5DD44271AD3CDBA, -635, -172 },
18112  { 0x936B9FCEBB25C996, -608, -164 },
18113  { 0xDBAC6C247D62A584, -582, -156 },
18114  { 0xA3AB66580D5FDAF6, -555, -148 },
18115  { 0xF3E2F893DEC3F126, -529, -140 },
18116  { 0xB5B5ADA8AAFF80B8, -502, -132 },
18117  { 0x87625F056C7C4A8B, -475, -124 },
18118  { 0xC9BCFF6034C13053, -449, -116 },
18119  { 0x964E858C91BA2655, -422, -108 },
18120  { 0xDFF9772470297EBD, -396, -100 },
18121  { 0xA6DFBD9FB8E5B88F, -369, -92 },
18122  { 0xF8A95FCF88747D94, -343, -84 },
18123  { 0xB94470938FA89BCF, -316, -76 },
18124  { 0x8A08F0F8BF0F156B, -289, -68 },
18125  { 0xCDB02555653131B6, -263, -60 },
18126  { 0x993FE2C6D07B7FAC, -236, -52 },
18127  { 0xE45C10C42A2B3B06, -210, -44 },
18128  { 0xAA242499697392D3, -183, -36 },
18129  { 0xFD87B5F28300CA0E, -157, -28 },
18130  { 0xBCE5086492111AEB, -130, -20 },
18131  { 0x8CBCCC096F5088CC, -103, -12 },
18132  { 0xD1B71758E219652C, -77, -4 },
18133  { 0x9C40000000000000, -50, 4 },
18134  { 0xE8D4A51000000000, -24, 12 },
18135  { 0xAD78EBC5AC620000, 3, 20 },
18136  { 0x813F3978F8940984, 30, 28 },
18137  { 0xC097CE7BC90715B3, 56, 36 },
18138  { 0x8F7E32CE7BEA5C70, 83, 44 },
18139  { 0xD5D238A4ABE98068, 109, 52 },
18140  { 0x9F4F2726179A2245, 136, 60 },
18141  { 0xED63A231D4C4FB27, 162, 68 },
18142  { 0xB0DE65388CC8ADA8, 189, 76 },
18143  { 0x83C7088E1AAB65DB, 216, 84 },
18144  { 0xC45D1DF942711D9A, 242, 92 },
18145  { 0x924D692CA61BE758, 269, 100 },
18146  { 0xDA01EE641A708DEA, 295, 108 },
18147  { 0xA26DA3999AEF774A, 322, 116 },
18148  { 0xF209787BB47D6B85, 348, 124 },
18149  { 0xB454E4A179DD1877, 375, 132 },
18150  { 0x865B86925B9BC5C2, 402, 140 },
18151  { 0xC83553C5C8965D3D, 428, 148 },
18152  { 0x952AB45CFA97A0B3, 455, 156 },
18153  { 0xDE469FBD99A05FE3, 481, 164 },
18154  { 0xA59BC234DB398C25, 508, 172 },
18155  { 0xF6C69A72A3989F5C, 534, 180 },
18156  { 0xB7DCBF5354E9BECE, 561, 188 },
18157  { 0x88FCF317F22241E2, 588, 196 },
18158  { 0xCC20CE9BD35C78A5, 614, 204 },
18159  { 0x98165AF37B2153DF, 641, 212 },
18160  { 0xE2A0B5DC971F303A, 667, 220 },
18161  { 0xA8D9D1535CE3B396, 694, 228 },
18162  { 0xFB9B7CD9A4A7443C, 720, 236 },
18163  { 0xBB764C4CA7A44410, 747, 244 },
18164  { 0x8BAB8EEFB6409C1A, 774, 252 },
18165  { 0xD01FEF10A657842C, 800, 260 },
18166  { 0x9B10A4E5E9913129, 827, 268 },
18167  { 0xE7109BFBA19C0C9D, 853, 276 },
18168  { 0xAC2820D9623BF429, 880, 284 },
18169  { 0x80444B5E7AA7CF85, 907, 292 },
18170  { 0xBF21E44003ACDD2D, 933, 300 },
18171  { 0x8E679C2F5E44FF8F, 960, 308 },
18172  { 0xD433179D9C8CB841, 986, 316 },
18173  { 0x9E19DB92B4E31BA9, 1013, 324 },
18174  }
18175  };
18176 
18177  // This computation gives exactly the same results for k as
18178  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
18179  // for |e| <= 1500, but doesn't require floating-point operations.
18180  // NB: log_10(2) ~= 78913 / 2^18
18181  JSON_ASSERT(e >= -1500);
18182  JSON_ASSERT(e <= 1500);
18183  const int f = kAlpha - e - 1;
18184  const int k = ((f * 78913) / (1 << 18)) + static_cast<int>(f > 0);
18185 
18186  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
18187  JSON_ASSERT(index >= 0);
18188  JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
18189 
18190  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
18191  JSON_ASSERT(kAlpha <= cached.e + e + 64);
18192  JSON_ASSERT(kGamma >= cached.e + e + 64);
18193 
18194  return cached;
18195 }
18196 
18202 {
18203  // LCOV_EXCL_START
18204  if (n >= 1000000000)
18205  {
18206  pow10 = 1000000000;
18207  return 10;
18208  }
18209  // LCOV_EXCL_STOP
18210  if (n >= 100000000)
18211  {
18212  pow10 = 100000000;
18213  return 9;
18214  }
18215  if (n >= 10000000)
18216  {
18217  pow10 = 10000000;
18218  return 8;
18219  }
18220  if (n >= 1000000)
18221  {
18222  pow10 = 1000000;
18223  return 7;
18224  }
18225  if (n >= 100000)
18226  {
18227  pow10 = 100000;
18228  return 6;
18229  }
18230  if (n >= 10000)
18231  {
18232  pow10 = 10000;
18233  return 5;
18234  }
18235  if (n >= 1000)
18236  {
18237  pow10 = 1000;
18238  return 4;
18239  }
18240  if (n >= 100)
18241  {
18242  pow10 = 100;
18243  return 3;
18244  }
18245  if (n >= 10)
18246  {
18247  pow10 = 10;
18248  return 2;
18249  }
18250 
18251  pow10 = 1;
18252  return 1;
18253 }
18254 
18255 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
18256  std::uint64_t rest, std::uint64_t ten_k)
18257 {
18258  JSON_ASSERT(len >= 1);
18259  JSON_ASSERT(dist <= delta);
18260  JSON_ASSERT(rest <= delta);
18261  JSON_ASSERT(ten_k > 0);
18262 
18263  // <--------------------------- delta ---->
18264  // <---- dist --------->
18265  // --------------[------------------+-------------------]--------------
18266  // M- w M+
18267  //
18268  // ten_k
18269  // <------>
18270  // <---- rest ---->
18271  // --------------[------------------+----+--------------]--------------
18272  // w V
18273  // = buf * 10^k
18274  //
18275  // ten_k represents a unit-in-the-last-place in the decimal representation
18276  // stored in buf.
18277  // Decrement buf by ten_k while this takes buf closer to w.
18278 
18279  // The tests are written in this order to avoid overflow in unsigned
18280  // integer arithmetic.
18281 
18282  while (rest < dist
18283  && delta - rest >= ten_k
18284  && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
18285  {
18286  JSON_ASSERT(buf[len - 1] != '0');
18287  buf[len - 1]--;
18288  rest += ten_k;
18289  }
18290 }
18291 
18296 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
18297  diyfp M_minus, diyfp w, diyfp M_plus)
18298 {
18299  static_assert(kAlpha >= -60, "internal error");
18300  static_assert(kGamma <= -32, "internal error");
18301 
18302  // Generates the digits (and the exponent) of a decimal floating-point
18303  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
18304  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
18305  //
18306  // <--------------------------- delta ---->
18307  // <---- dist --------->
18308  // --------------[------------------+-------------------]--------------
18309  // M- w M+
18310  //
18311  // Grisu2 generates the digits of M+ from left to right and stops as soon as
18312  // V is in [M-,M+].
18313 
18314  JSON_ASSERT(M_plus.e >= kAlpha);
18315  JSON_ASSERT(M_plus.e <= kGamma);
18316 
18317  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
18318  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
18319 
18320  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
18321  //
18322  // M+ = f * 2^e
18323  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
18324  // = ((p1 ) * 2^-e + (p2 )) * 2^e
18325  // = p1 + p2 * 2^e
18326 
18327  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
18328 
18329  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.)
18330  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
18331 
18332  // 1)
18333  //
18334  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
18335 
18336  JSON_ASSERT(p1 > 0);
18337 
18338  std::uint32_t pow10{};
18339  const int k = find_largest_pow10(p1, pow10);
18340 
18341  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
18342  //
18343  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
18344  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
18345  //
18346  // M+ = p1 + p2 * 2^e
18347  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
18348  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
18349  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
18350  //
18351  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
18352  //
18353  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
18354  //
18355  // but stop as soon as
18356  //
18357  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
18358 
18359  int n = k;
18360  while (n > 0)
18361  {
18362  // Invariants:
18363  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
18364  // pow10 = 10^(n-1) <= p1 < 10^n
18365  //
18366  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
18367  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
18368  //
18369  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
18370  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
18371  //
18372  JSON_ASSERT(d <= 9);
18373  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
18374  //
18375  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
18376  //
18377  p1 = r;
18378  n--;
18379  //
18380  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
18381  // pow10 = 10^n
18382  //
18383 
18384  // Now check if enough digits have been generated.
18385  // Compute
18386  //
18387  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
18388  //
18389  // Note:
18390  // Since rest and delta share the same exponent e, it suffices to
18391  // compare the significands.
18392  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
18393  if (rest <= delta)
18394  {
18395  // V = buffer * 10^n, with M- <= V <= M+.
18396 
18397  decimal_exponent += n;
18398 
18399  // We may now just stop. But instead, it looks as if the buffer
18400  // could be decremented to bring V closer to w.
18401  //
18402  // pow10 = 10^n is now 1 ulp in the decimal representation V.
18403  // The rounding procedure works with diyfp's with an implicit
18404  // exponent of e.
18405  //
18406  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
18407  //
18408  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
18409  grisu2_round(buffer, length, dist, delta, rest, ten_n);
18410 
18411  return;
18412  }
18413 
18414  pow10 /= 10;
18415  //
18416  // pow10 = 10^(n-1) <= p1 < 10^n
18417  // Invariants restored.
18418  }
18419 
18420  // 2)
18421  //
18422  // The digits of the integral part have been generated:
18423  //
18424  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
18425  // = buffer + p2 * 2^e
18426  //
18427  // Now generate the digits of the fractional part p2 * 2^e.
18428  //
18429  // Note:
18430  // No decimal point is generated: the exponent is adjusted instead.
18431  //
18432  // p2 actually represents the fraction
18433  //
18434  // p2 * 2^e
18435  // = p2 / 2^-e
18436  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
18437  //
18438  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
18439  //
18440  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
18441  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
18442  //
18443  // using
18444  //
18445  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
18446  // = ( d) * 2^-e + ( r)
18447  //
18448  // or
18449  // 10^m * p2 * 2^e = d + r * 2^e
18450  //
18451  // i.e.
18452  //
18453  // M+ = buffer + p2 * 2^e
18454  // = buffer + 10^-m * (d + r * 2^e)
18455  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
18456  //
18457  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
18458 
18459  JSON_ASSERT(p2 > delta);
18460 
18461  int m = 0;
18462  for (;;)
18463  {
18464  // Invariant:
18465  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
18466  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
18467  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
18468  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
18469  //
18470  JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
18471  p2 *= 10;
18472  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
18473  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
18474  //
18475  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
18476  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
18477  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
18478  //
18479  JSON_ASSERT(d <= 9);
18480  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
18481  //
18482  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
18483  //
18484  p2 = r;
18485  m++;
18486  //
18487  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
18488  // Invariant restored.
18489 
18490  // Check if enough digits have been generated.
18491  //
18492  // 10^-m * p2 * 2^e <= delta * 2^e
18493  // p2 * 2^e <= 10^m * delta * 2^e
18494  // p2 <= 10^m * delta
18495  delta *= 10;
18496  dist *= 10;
18497  if (p2 <= delta)
18498  {
18499  break;
18500  }
18501  }
18502 
18503  // V = buffer * 10^-m, with M- <= V <= M+.
18504 
18505  decimal_exponent -= m;
18506 
18507  // 1 ulp in the decimal representation is now 10^-m.
18508  // Since delta and dist are now scaled by 10^m, we need to do the
18509  // same with ulp in order to keep the units in sync.
18510  //
18511  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
18512  //
18513  const std::uint64_t ten_m = one.f;
18514  grisu2_round(buffer, length, dist, delta, p2, ten_m);
18515 
18516  // By construction this algorithm generates the shortest possible decimal
18517  // number (Loitsch, Theorem 6.2) which rounds back to w.
18518  // For an input number of precision p, at least
18519  //
18520  // N = 1 + ceil(p * log_10(2))
18521  //
18522  // decimal digits are sufficient to identify all binary floating-point
18523  // numbers (Matula, "In-and-Out conversions").
18524  // This implies that the algorithm does not produce more than N decimal
18525  // digits.
18526  //
18527  // N = 17 for p = 53 (IEEE double precision)
18528  // N = 9 for p = 24 (IEEE single precision)
18529 }
18530 
18537 inline void grisu2(char* buf, int& len, int& decimal_exponent,
18538  diyfp m_minus, diyfp v, diyfp m_plus)
18539 {
18540  JSON_ASSERT(m_plus.e == m_minus.e);
18541  JSON_ASSERT(m_plus.e == v.e);
18542 
18543  // --------(-----------------------+-----------------------)-------- (A)
18544  // m- v m+
18545  //
18546  // --------------------(-----------+-----------------------)-------- (B)
18547  // m- v m+
18548  //
18549  // First scale v (and m- and m+) such that the exponent is in the range
18550  // [alpha, gamma].
18551 
18552  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
18553 
18554  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
18555 
18556  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
18557  const diyfp w = diyfp::mul(v, c_minus_k);
18558  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
18559  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
18560 
18561  // ----(---+---)---------------(---+---)---------------(---+---)----
18562  // w- w w+
18563  // = c*m- = c*v = c*m+
18564  //
18565  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
18566  // w+ are now off by a small amount.
18567  // In fact:
18568  //
18569  // w - v * 10^k < 1 ulp
18570  //
18571  // To account for this inaccuracy, add resp. subtract 1 ulp.
18572  //
18573  // --------+---[---------------(---+---)---------------]---+--------
18574  // w- M- w M+ w+
18575  //
18576  // Now any number in [M-, M+] (bounds included) will round to w when input,
18577  // regardless of how the input rounding algorithm breaks ties.
18578  //
18579  // And digit_gen generates the shortest possible such number in [M-, M+].
18580  // Note that this does not mean that Grisu2 always generates the shortest
18581  // possible number in the interval (m-, m+).
18582  const diyfp M_minus(w_minus.f + 1, w_minus.e);
18583  const diyfp M_plus (w_plus.f - 1, w_plus.e );
18584 
18585  decimal_exponent = -cached.k; // = -(-k) = k
18586 
18587  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
18588 }
18589 
18595 template<typename FloatType>
18597 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
18598 {
18599  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
18600  "internal error: not enough precision");
18601 
18602  JSON_ASSERT(std::isfinite(value));
18603  JSON_ASSERT(value > 0);
18604 
18605  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
18606  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
18607  // decimal representations are not exactly "short".
18608  //
18609  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
18610  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
18611  // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
18612  // does.
18613  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
18614  // representation using the corresponding std::from_chars function recovers value exactly". That
18615  // indicates that single precision floating-point numbers should be recovered using
18616  // 'std::strtof'.
18617  //
18618  // NB: If the neighbors are computed for single-precision numbers, there is a single float
18619  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
18620  // value is off by 1 ulp.
18621 #if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)
18622  const boundaries w = compute_boundaries(static_cast<double>(value));
18623 #else
18624  const boundaries w = compute_boundaries(value);
18625 #endif
18626 
18627  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
18628 }
18629 
18637 inline char* append_exponent(char* buf, int e)
18638 {
18639  JSON_ASSERT(e > -1000);
18640  JSON_ASSERT(e < 1000);
18641 
18642  if (e < 0)
18643  {
18644  e = -e;
18645  *buf++ = '-';
18646  }
18647  else
18648  {
18649  *buf++ = '+';
18650  }
18651 
18652  auto k = static_cast<std::uint32_t>(e);
18653  if (k < 10)
18654  {
18655  // Always print at least two digits in the exponent.
18656  // This is for compatibility with printf("%g").
18657  *buf++ = '0';
18658  *buf++ = static_cast<char>('0' + k);
18659  }
18660  else if (k < 100)
18661  {
18662  *buf++ = static_cast<char>('0' + (k / 10));
18663  k %= 10;
18664  *buf++ = static_cast<char>('0' + k);
18665  }
18666  else
18667  {
18668  *buf++ = static_cast<char>('0' + (k / 100));
18669  k %= 100;
18670  *buf++ = static_cast<char>('0' + (k / 10));
18671  k %= 10;
18672  *buf++ = static_cast<char>('0' + k);
18673  }
18674 
18675  return buf;
18676 }
18677 
18689 inline char* format_buffer(char* buf, int len, int decimal_exponent,
18690  int min_exp, int max_exp)
18691 {
18692  JSON_ASSERT(min_exp < 0);
18693  JSON_ASSERT(max_exp > 0);
18694 
18695  const int k = len;
18696  const int n = len + decimal_exponent;
18697 
18698  // v = buf * 10^(n-k)
18699  // k is the length of the buffer (number of decimal digits)
18700  // n is the position of the decimal point relative to the start of the buffer.
18701 
18702  if (k <= n && n <= max_exp)
18703  {
18704  // digits[000]
18705  // len <= max_exp + 2
18706 
18707  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
18708  // Make it look like a floating-point number (#362, #378)
18709  buf[n + 0] = '.';
18710  buf[n + 1] = '0';
18711  return buf + (static_cast<size_t>(n) + 2);
18712  }
18713 
18714  if (0 < n && n <= max_exp)
18715  {
18716  // dig.its
18717  // len <= max_digits10 + 1
18718 
18719  JSON_ASSERT(k > n);
18720 
18721  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
18722  buf[n] = '.';
18723  return buf + (static_cast<size_t>(k) + 1U);
18724  }
18725 
18726  if (min_exp < n && n <= 0)
18727  {
18728  // 0.[000]digits
18729  // len <= 2 + (-min_exp - 1) + max_digits10
18730 
18731  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
18732  buf[0] = '0';
18733  buf[1] = '.';
18734  std::memset(buf + 2, '0', static_cast<size_t>(-n));
18735  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
18736  }
18737 
18738  if (k == 1)
18739  {
18740  // dE+123
18741  // len <= 1 + 5
18742 
18743  buf += 1;
18744  }
18745  else
18746  {
18747  // d.igitsE+123
18748  // len <= max_digits10 + 1 + 5
18749 
18750  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
18751  buf[1] = '.';
18752  buf += 1 + static_cast<size_t>(k);
18753  }
18754 
18755  *buf++ = 'e';
18756  return append_exponent(buf, n - 1);
18757 }
18758 
18759 } // namespace dtoa_impl
18760 
18771 template<typename FloatType>
18774 char* to_chars(char* first, const char* last, FloatType value)
18775 {
18776  static_cast<void>(last); // maybe unused - fix warning
18777  JSON_ASSERT(std::isfinite(value));
18778 
18779  // Use signbit(value) instead of (value < 0) since signbit works for -0.
18780  if (std::signbit(value))
18781  {
18782  value = -value;
18783  *first++ = '-';
18784  }
18785 
18786 #ifdef __GNUC__
18787 #pragma GCC diagnostic push
18788 #pragma GCC diagnostic ignored "-Wfloat-equal"
18789 #endif
18790  if (value == 0) // +-0
18791  {
18792  *first++ = '0';
18793  // Make it look like a floating-point number (#362, #378)
18794  *first++ = '.';
18795  *first++ = '0';
18796  return first;
18797  }
18798 #ifdef __GNUC__
18799 #pragma GCC diagnostic pop
18800 #endif
18801 
18802  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
18803 
18804  // Compute v = buffer * 10^decimal_exponent.
18805  // The decimal digits are stored in the buffer, which needs to be interpreted
18806  // as an unsigned decimal integer.
18807  // len is the length of the buffer, i.e., the number of decimal digits.
18808  int len = 0;
18809  int decimal_exponent = 0;
18810  dtoa_impl::grisu2(first, len, decimal_exponent, value);
18811 
18812  JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
18813 
18814  // Format the buffer like printf("%.*g", prec, value)
18815  constexpr int kMinExp = -4;
18816  // Use digits10 here to increase compatibility with version 2.
18817  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
18818 
18819  JSON_ASSERT(last - first >= kMaxExp + 2);
18820  JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
18821  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
18822 
18823  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
18824 }
18825 
18826 } // namespace detail
18828 
18829 // #include <nlohmann/detail/exceptions.hpp>
18830 
18831 // #include <nlohmann/detail/macro_scope.hpp>
18832 
18833 // #include <nlohmann/detail/meta/cpp_future.hpp>
18834 
18835 // #include <nlohmann/detail/output/binary_writer.hpp>
18836 
18837 // #include <nlohmann/detail/output/output_adapters.hpp>
18838 
18839 // #include <nlohmann/detail/string_concat.hpp>
18840 
18841 // #include <nlohmann/detail/value_t.hpp>
18842 
18843 
18845 namespace detail
18846 {
18847 
18849 // serialization //
18851 
18854 {
18855  strict,
18856  replace,
18857  ignore
18858 };
18859 
18860 template<typename BasicJsonType>
18862 {
18864  using number_float_t = typename BasicJsonType::number_float_t;
18865  using number_integer_t = typename BasicJsonType::number_integer_t;
18866  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18867  using binary_char_t = typename BasicJsonType::binary_t::value_type;
18868  static constexpr std::uint8_t UTF8_ACCEPT = 0;
18869  static constexpr std::uint8_t UTF8_REJECT = 1;
18870 
18871  public:
18877  serializer(output_adapter_t<char> s, const char ichar,
18878  error_handler_t error_handler_ = error_handler_t::strict)
18879  : o(std::move(s))
18880  , loc(std::localeconv())
18881  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
18882  , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
18883  , indent_char(ichar)
18884  , indent_string(512, indent_char)
18885  , error_handler(error_handler_)
18886  {}
18887 
18888  // deleted because of pointer members
18889  serializer(const serializer&) = delete;
18890  serializer& operator=(const serializer&) = delete;
18891  serializer(serializer&&) = delete;
18893  ~serializer() = default;
18894 
18917  void dump(const BasicJsonType& val,
18918  const bool pretty_print,
18919  const bool ensure_ascii,
18920  const unsigned int indent_step,
18921  const unsigned int current_indent = 0)
18922  {
18923  switch (val.m_data.m_type)
18924  {
18925  case value_t::object:
18926  {
18927  if (val.m_data.m_value.object->empty())
18928  {
18929  o->write_characters("{}", 2);
18930  return;
18931  }
18932 
18933  if (pretty_print)
18934  {
18935  o->write_characters("{\n", 2);
18936 
18937  // variable to hold indentation for recursive calls
18938  const auto new_indent = current_indent + indent_step;
18939  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18940  {
18941  indent_string.resize(indent_string.size() * 2, ' ');
18942  }
18943 
18944  // first n-1 elements
18945  auto i = val.m_data.m_value.object->cbegin();
18946  for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18947  {
18948  o->write_characters(indent_string.c_str(), new_indent);
18949  o->write_character('\"');
18950  dump_escaped(i->first, ensure_ascii);
18951  o->write_characters("\": ", 3);
18952  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18953  o->write_characters(",\n", 2);
18954  }
18955 
18956  // last element
18957  JSON_ASSERT(i != val.m_data.m_value.object->cend());
18958  JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18959  o->write_characters(indent_string.c_str(), new_indent);
18960  o->write_character('\"');
18961  dump_escaped(i->first, ensure_ascii);
18962  o->write_characters("\": ", 3);
18963  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18964 
18965  o->write_character('\n');
18966  o->write_characters(indent_string.c_str(), current_indent);
18967  o->write_character('}');
18968  }
18969  else
18970  {
18971  o->write_character('{');
18972 
18973  // first n-1 elements
18974  auto i = val.m_data.m_value.object->cbegin();
18975  for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18976  {
18977  o->write_character('\"');
18978  dump_escaped(i->first, ensure_ascii);
18979  o->write_characters("\":", 2);
18980  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18981  o->write_character(',');
18982  }
18983 
18984  // last element
18985  JSON_ASSERT(i != val.m_data.m_value.object->cend());
18986  JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18987  o->write_character('\"');
18988  dump_escaped(i->first, ensure_ascii);
18989  o->write_characters("\":", 2);
18990  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18991 
18992  o->write_character('}');
18993  }
18994 
18995  return;
18996  }
18997 
18998  case value_t::array:
18999  {
19000  if (val.m_data.m_value.array->empty())
19001  {
19002  o->write_characters("[]", 2);
19003  return;
19004  }
19005 
19006  if (pretty_print)
19007  {
19008  o->write_characters("[\n", 2);
19009 
19010  // variable to hold indentation for recursive calls
19011  const auto new_indent = current_indent + indent_step;
19012  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
19013  {
19014  indent_string.resize(indent_string.size() * 2, ' ');
19015  }
19016 
19017  // first n-1 elements
19018  for (auto i = val.m_data.m_value.array->cbegin();
19019  i != val.m_data.m_value.array->cend() - 1; ++i)
19020  {
19021  o->write_characters(indent_string.c_str(), new_indent);
19022  dump(*i, true, ensure_ascii, indent_step, new_indent);
19023  o->write_characters(",\n", 2);
19024  }
19025 
19026  // last element
19027  JSON_ASSERT(!val.m_data.m_value.array->empty());
19028  o->write_characters(indent_string.c_str(), new_indent);
19029  dump(val.m_data.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
19030 
19031  o->write_character('\n');
19032  o->write_characters(indent_string.c_str(), current_indent);
19033  o->write_character(']');
19034  }
19035  else
19036  {
19037  o->write_character('[');
19038 
19039  // first n-1 elements
19040  for (auto i = val.m_data.m_value.array->cbegin();
19041  i != val.m_data.m_value.array->cend() - 1; ++i)
19042  {
19043  dump(*i, false, ensure_ascii, indent_step, current_indent);
19044  o->write_character(',');
19045  }
19046 
19047  // last element
19048  JSON_ASSERT(!val.m_data.m_value.array->empty());
19049  dump(val.m_data.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
19050 
19051  o->write_character(']');
19052  }
19053 
19054  return;
19055  }
19056 
19057  case value_t::string:
19058  {
19059  o->write_character('\"');
19060  dump_escaped(*val.m_data.m_value.string, ensure_ascii);
19061  o->write_character('\"');
19062  return;
19063  }
19064 
19065  case value_t::binary:
19066  {
19067  if (pretty_print)
19068  {
19069  o->write_characters("{\n", 2);
19070 
19071  // variable to hold indentation for recursive calls
19072  const auto new_indent = current_indent + indent_step;
19073  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
19074  {
19075  indent_string.resize(indent_string.size() * 2, ' ');
19076  }
19077 
19078  o->write_characters(indent_string.c_str(), new_indent);
19079 
19080  o->write_characters("\"bytes\": [", 10);
19081 
19082  if (!val.m_data.m_value.binary->empty())
19083  {
19084  for (auto i = val.m_data.m_value.binary->cbegin();
19085  i != val.m_data.m_value.binary->cend() - 1; ++i)
19086  {
19087  dump_integer(*i);
19088  o->write_characters(", ", 2);
19089  }
19090  dump_integer(val.m_data.m_value.binary->back());
19091  }
19092 
19093  o->write_characters("],\n", 3);
19094  o->write_characters(indent_string.c_str(), new_indent);
19095 
19096  o->write_characters("\"subtype\": ", 11);
19097  if (val.m_data.m_value.binary->has_subtype())
19098  {
19099  dump_integer(val.m_data.m_value.binary->subtype());
19100  }
19101  else
19102  {
19103  o->write_characters("null", 4);
19104  }
19105  o->write_character('\n');
19106  o->write_characters(indent_string.c_str(), current_indent);
19107  o->write_character('}');
19108  }
19109  else
19110  {
19111  o->write_characters("{\"bytes\":[", 10);
19112 
19113  if (!val.m_data.m_value.binary->empty())
19114  {
19115  for (auto i = val.m_data.m_value.binary->cbegin();
19116  i != val.m_data.m_value.binary->cend() - 1; ++i)
19117  {
19118  dump_integer(*i);
19119  o->write_character(',');
19120  }
19121  dump_integer(val.m_data.m_value.binary->back());
19122  }
19123 
19124  o->write_characters("],\"subtype\":", 12);
19125  if (val.m_data.m_value.binary->has_subtype())
19126  {
19127  dump_integer(val.m_data.m_value.binary->subtype());
19128  o->write_character('}');
19129  }
19130  else
19131  {
19132  o->write_characters("null}", 5);
19133  }
19134  }
19135  return;
19136  }
19137 
19138  case value_t::boolean:
19139  {
19140  if (val.m_data.m_value.boolean)
19141  {
19142  o->write_characters("true", 4);
19143  }
19144  else
19145  {
19146  o->write_characters("false", 5);
19147  }
19148  return;
19149  }
19150 
19151  case value_t::number_integer:
19152  {
19153  dump_integer(val.m_data.m_value.number_integer);
19154  return;
19155  }
19156 
19157  case value_t::number_unsigned:
19158  {
19159  dump_integer(val.m_data.m_value.number_unsigned);
19160  return;
19161  }
19162 
19163  case value_t::number_float:
19164  {
19165  dump_float(val.m_data.m_value.number_float);
19166  return;
19167  }
19168 
19169  case value_t::discarded:
19170  {
19171  o->write_characters("<discarded>", 11);
19172  return;
19173  }
19174 
19175  case value_t::null:
19176  {
19177  o->write_characters("null", 4);
19178  return;
19179  }
19180 
19181  default: // LCOV_EXCL_LINE
19182  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19183  }
19184  }
19185 
19201  void dump_escaped(const string_t& s, const bool ensure_ascii)
19202  {
19203  std::uint32_t codepoint{};
19204  std::uint8_t state = UTF8_ACCEPT;
19205  std::size_t bytes = 0; // number of bytes written to string_buffer
19206 
19207  // number of bytes written at the point of the last valid byte
19208  std::size_t bytes_after_last_accept = 0;
19209  std::size_t undumped_chars = 0;
19210 
19211  for (std::size_t i = 0; i < s.size(); ++i)
19212  {
19213  const auto byte = static_cast<std::uint8_t>(s[i]);
19214 
19215  switch (decode(state, codepoint, byte))
19216  {
19217  case UTF8_ACCEPT: // decode found a new code point
19218  {
19219  switch (codepoint)
19220  {
19221  case 0x08: // backspace
19222  {
19223  string_buffer[bytes++] = '\\';
19224  string_buffer[bytes++] = 'b';
19225  break;
19226  }
19227 
19228  case 0x09: // horizontal tab
19229  {
19230  string_buffer[bytes++] = '\\';
19231  string_buffer[bytes++] = 't';
19232  break;
19233  }
19234 
19235  case 0x0A: // newline
19236  {
19237  string_buffer[bytes++] = '\\';
19238  string_buffer[bytes++] = 'n';
19239  break;
19240  }
19241 
19242  case 0x0C: // formfeed
19243  {
19244  string_buffer[bytes++] = '\\';
19245  string_buffer[bytes++] = 'f';
19246  break;
19247  }
19248 
19249  case 0x0D: // carriage return
19250  {
19251  string_buffer[bytes++] = '\\';
19252  string_buffer[bytes++] = 'r';
19253  break;
19254  }
19255 
19256  case 0x22: // quotation mark
19257  {
19258  string_buffer[bytes++] = '\\';
19259  string_buffer[bytes++] = '\"';
19260  break;
19261  }
19262 
19263  case 0x5C: // reverse solidus
19264  {
19265  string_buffer[bytes++] = '\\';
19266  string_buffer[bytes++] = '\\';
19267  break;
19268  }
19269 
19270  default:
19271  {
19272  // escape control characters (0x00..0x1F) or, if
19273  // ensure_ascii parameter is used, non-ASCII characters
19274  if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
19275  {
19276  if (codepoint <= 0xFFFF)
19277  {
19278  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
19279  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
19280  static_cast<std::uint16_t>(codepoint)));
19281  bytes += 6;
19282  }
19283  else
19284  {
19285  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
19286  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
19287  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
19288  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
19289  bytes += 12;
19290  }
19291  }
19292  else
19293  {
19294  // copy byte to buffer (all previous bytes
19295  // been copied have in default case above)
19296  string_buffer[bytes++] = s[i];
19297  }
19298  break;
19299  }
19300  }
19301 
19302  // write buffer and reset index; there must be 13 bytes
19303  // left, as this is the maximal number of bytes to be
19304  // written ("\uxxxx\uxxxx\0") for one code point
19305  if (string_buffer.size() - bytes < 13)
19306  {
19307  o->write_characters(string_buffer.data(), bytes);
19308  bytes = 0;
19309  }
19310 
19311  // remember the byte position of this accept
19312  bytes_after_last_accept = bytes;
19313  undumped_chars = 0;
19314  break;
19315  }
19316 
19317  case UTF8_REJECT: // decode found invalid UTF-8 byte
19318  {
19319  switch (error_handler)
19320  {
19321  case error_handler_t::strict:
19322  {
19323  JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
19324  }
19325 
19326  case error_handler_t::ignore:
19327  case error_handler_t::replace:
19328  {
19329  // in case we saw this character the first time, we
19330  // would like to read it again, because the byte
19331  // may be OK for itself, but just not OK for the
19332  // previous sequence
19333  if (undumped_chars > 0)
19334  {
19335  --i;
19336  }
19337 
19338  // reset length buffer to the last accepted index;
19339  // thus removing/ignoring the invalid characters
19340  bytes = bytes_after_last_accept;
19341 
19342  if (error_handler == error_handler_t::replace)
19343  {
19344  // add a replacement character
19345  if (ensure_ascii)
19346  {
19347  string_buffer[bytes++] = '\\';
19348  string_buffer[bytes++] = 'u';
19349  string_buffer[bytes++] = 'f';
19350  string_buffer[bytes++] = 'f';
19351  string_buffer[bytes++] = 'f';
19352  string_buffer[bytes++] = 'd';
19353  }
19354  else
19355  {
19356  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
19357  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
19358  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
19359  }
19360 
19361  // write buffer and reset index; there must be 13 bytes
19362  // left, as this is the maximal number of bytes to be
19363  // written ("\uxxxx\uxxxx\0") for one code point
19364  if (string_buffer.size() - bytes < 13)
19365  {
19366  o->write_characters(string_buffer.data(), bytes);
19367  bytes = 0;
19368  }
19369 
19370  bytes_after_last_accept = bytes;
19371  }
19372 
19373  undumped_chars = 0;
19374 
19375  // continue processing the string
19376  state = UTF8_ACCEPT;
19377  break;
19378  }
19379 
19380  default: // LCOV_EXCL_LINE
19381  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19382  }
19383  break;
19384  }
19385 
19386  default: // decode found yet incomplete multibyte code point
19387  {
19388  if (!ensure_ascii)
19389  {
19390  // code point will not be escaped - copy byte to buffer
19391  string_buffer[bytes++] = s[i];
19392  }
19393  ++undumped_chars;
19394  break;
19395  }
19396  }
19397  }
19398 
19399  // we finished processing the string
19400  if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
19401  {
19402  // write buffer
19403  if (bytes > 0)
19404  {
19405  o->write_characters(string_buffer.data(), bytes);
19406  }
19407  }
19408  else
19409  {
19410  // we finish reading, but do not accept: string was incomplete
19411  switch (error_handler)
19412  {
19413  case error_handler_t::strict:
19414  {
19415  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));
19416  }
19417 
19418  case error_handler_t::ignore:
19419  {
19420  // write all accepted bytes
19421  o->write_characters(string_buffer.data(), bytes_after_last_accept);
19422  break;
19423  }
19424 
19425  case error_handler_t::replace:
19426  {
19427  // write all accepted bytes
19428  o->write_characters(string_buffer.data(), bytes_after_last_accept);
19429  // add a replacement character
19430  if (ensure_ascii)
19431  {
19432  o->write_characters("\\ufffd", 6);
19433  }
19434  else
19435  {
19436  o->write_characters("\xEF\xBF\xBD", 3);
19437  }
19438  break;
19439  }
19440 
19441  default: // LCOV_EXCL_LINE
19442  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19443  }
19444  }
19445  }
19446 
19447  private:
19456  unsigned int count_digits(number_unsigned_t x) noexcept
19457  {
19458  unsigned int n_digits = 1;
19459  for (;;)
19460  {
19461  if (x < 10)
19462  {
19463  return n_digits;
19464  }
19465  if (x < 100)
19466  {
19467  return n_digits + 1;
19468  }
19469  if (x < 1000)
19470  {
19471  return n_digits + 2;
19472  }
19473  if (x < 10000)
19474  {
19475  return n_digits + 3;
19476  }
19477  x = x / 10000u;
19478  n_digits += 4;
19479  }
19480  }
19481 
19487  static std::string hex_bytes(std::uint8_t byte)
19488  {
19489  std::string result = "FF";
19490  constexpr const char* nibble_to_hex = "0123456789ABCDEF";
19491  result[0] = nibble_to_hex[byte / 16];
19492  result[1] = nibble_to_hex[byte % 16];
19493  return result;
19494  }
19495 
19496  // templates to avoid warnings about useless casts
19498  bool is_negative_number(NumberType x)
19499  {
19500  return x < 0;
19501  }
19502 
19504  bool is_negative_number(NumberType /*unused*/)
19505  {
19506  return false;
19507  }
19508 
19518  template < typename NumberType, detail::enable_if_t <
19523  int > = 0 >
19524  void dump_integer(NumberType x)
19525  {
19526  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
19527  {
19528  {
19529  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
19530  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
19531  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
19532  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
19533  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
19534  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
19535  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
19536  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
19537  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
19538  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
19539  }
19540  };
19541 
19542  // special case for "0"
19543  if (x == 0)
19544  {
19545  o->write_character('0');
19546  return;
19547  }
19548 
19549  // use a pointer to fill the buffer
19550  auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
19551 
19552  number_unsigned_t abs_value;
19553 
19554  unsigned int n_chars{};
19555 
19556  if (is_negative_number(x))
19557  {
19558  *buffer_ptr = '-';
19559  abs_value = remove_sign(static_cast<number_integer_t>(x));
19560 
19561  // account one more byte for the minus sign
19562  n_chars = 1 + count_digits(abs_value);
19563  }
19564  else
19565  {
19566  abs_value = static_cast<number_unsigned_t>(x);
19567  n_chars = count_digits(abs_value);
19568  }
19569 
19570  // spare 1 byte for '\0'
19571  JSON_ASSERT(n_chars < number_buffer.size() - 1);
19572 
19573  // jump to the end to generate the string from backward,
19574  // so we later avoid reversing the result
19575  buffer_ptr += static_cast<typename decltype(number_buffer)::difference_type>(n_chars);
19576 
19577  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
19578  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
19579  while (abs_value >= 100)
19580  {
19581  const auto digits_index = static_cast<unsigned>((abs_value % 100));
19582  abs_value /= 100;
19583  *(--buffer_ptr) = digits_to_99[digits_index][1];
19584  *(--buffer_ptr) = digits_to_99[digits_index][0];
19585  }
19586 
19587  if (abs_value >= 10)
19588  {
19589  const auto digits_index = static_cast<unsigned>(abs_value);
19590  *(--buffer_ptr) = digits_to_99[digits_index][1];
19591  *(--buffer_ptr) = digits_to_99[digits_index][0];
19592  }
19593  else
19594  {
19595  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
19596  }
19597 
19598  o->write_characters(number_buffer.data(), n_chars);
19599  }
19600 
19609  void dump_float(number_float_t x)
19610  {
19611  // NaN / inf
19612  if (!std::isfinite(x))
19613  {
19614  o->write_characters("null", 4);
19615  return;
19616  }
19617 
19618  // If number_float_t is an IEEE-754 single or double precision number,
19619  // use the Grisu2 algorithm to produce short numbers which are
19620  // guaranteed to round-trip, using strtof and strtod, resp.
19621  //
19622  // NB: The test below works if <long double> == <double>.
19623  static constexpr bool is_ieee_single_or_double
19624  = (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) ||
19625  (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);
19626 
19627  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
19628  }
19629 
19630  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
19631  {
19632  auto* begin = number_buffer.data();
19633  auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
19634 
19635  o->write_characters(begin, static_cast<size_t>(end - begin));
19636  }
19637 
19638  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
19639  {
19640  // get the number of digits for a float -> text -> float round-trip
19641  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
19642 
19643  // the actual conversion
19644  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
19645  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
19646 
19647  // negative value indicates an error
19648  JSON_ASSERT(len > 0);
19649  // check if the buffer was large enough
19650  JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
19651 
19652  // erase thousands separators
19653  if (thousands_sep != '\0')
19654  {
19655  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
19656  const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
19657  std::fill(end, number_buffer.end(), '\0');
19658  JSON_ASSERT((end - number_buffer.begin()) <= len);
19659  len = (end - number_buffer.begin());
19660  }
19661 
19662  // convert decimal point to '.'
19663  if (decimal_point != '\0' && decimal_point != '.')
19664  {
19665  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
19666  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
19667  if (dec_pos != number_buffer.end())
19668  {
19669  *dec_pos = '.';
19670  }
19671  }
19672 
19673  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
19674 
19675  // determine if we need to append ".0"
19676  const bool value_is_int_like =
19677  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
19678  [](char c)
19679  {
19680  return c == '.' || c == 'e';
19681  });
19682 
19683  if (value_is_int_like)
19684  {
19685  o->write_characters(".0", 2);
19686  }
19687  }
19688 
19710  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
19711  {
19712  static const std::array<std::uint8_t, 400> utf8d =
19713  {
19714  {
19715  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
19716  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
19717  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
19718  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
19719  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
19720  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
19721  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
19722  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
19723  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
19724  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
19725  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
19726  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
19727  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
19728  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
19729  }
19730  };
19731 
19732  JSON_ASSERT(byte < utf8d.size());
19733  const std::uint8_t type = utf8d[byte];
19734 
19735  codep = (state != UTF8_ACCEPT)
19736  ? (byte & 0x3fu) | (codep << 6u)
19737  : (0xFFu >> type) & (byte);
19738 
19739  const std::size_t index = 256u + (static_cast<size_t>(state) * 16u) + static_cast<size_t>(type);
19740  JSON_ASSERT(index < utf8d.size());
19741  state = utf8d[index];
19742  return state;
19743  }
19744 
19745  /*
19746  * Overload to make the compiler happy while it is instantiating
19747  * dump_integer for number_unsigned_t.
19748  * Must never be called.
19749  */
19750  number_unsigned_t remove_sign(number_unsigned_t x)
19751  {
19752  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19753  return x; // LCOV_EXCL_LINE
19754  }
19755 
19756  /*
19757  * Helper function for dump_integer
19758  *
19759  * This function takes a negative signed integer and returns its absolute
19760  * value as an unsigned integer. The plus/minus shuffling is necessary as we
19761  * cannot directly remove the sign of an arbitrary signed integer as the
19762  * absolute values of INT_MIN and INT_MAX are usually not the same. See
19763  * #1708 for details.
19764  */
19765  number_unsigned_t remove_sign(number_integer_t x) noexcept
19766  {
19767  JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
19768  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
19769  }
19770 
19771  private:
19773  output_adapter_t<char> o = nullptr;
19774 
19776  std::array<char, 64> number_buffer{{}};
19777 
19779  const std::lconv* loc = nullptr;
19781  const char thousands_sep = '\0';
19783  const char decimal_point = '\0';
19784 
19786  std::array<char, 512> string_buffer{{}};
19787 
19789  const char indent_char;
19792 
19795 };
19796 
19797 } // namespace detail
19799 
19800 // #include <nlohmann/detail/value_t.hpp>
19801 
19802 // #include <nlohmann/json_fwd.hpp>
19803 
19804 // #include <nlohmann/ordered_map.hpp>
19805 // __ _____ _____ _____
19806 // __| | __| | | | JSON for Modern C++
19807 // | | |__ | | | | | | version 3.12.0
19808 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
19809 //
19810 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
19811 // SPDX-License-Identifier: MIT
19812 
19813 
19814 
19815 #include <functional> // equal_to, less
19816 #include <initializer_list> // initializer_list
19817 #include <iterator> // input_iterator_tag, iterator_traits
19818 #include <memory> // allocator
19819 #include <stdexcept> // for out_of_range
19820 #include <type_traits> // enable_if, is_convertible
19821 #include <utility> // pair
19822 #include <vector> // vector
19823 
19824 // #include <nlohmann/detail/macro_scope.hpp>
19825 
19826 // #include <nlohmann/detail/meta/type_traits.hpp>
19827 
19828 
19830 
19833 template <class Key, class T, class IgnoredLess = std::less<Key>,
19834  class Allocator = std::allocator<std::pair<const Key, T>>>
19835  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
19836 {
19837  using key_type = Key;
19838  using mapped_type = T;
19839  using Container = std::vector<std::pair<const Key, T>, Allocator>;
19840  using iterator = typename Container::iterator;
19841  using const_iterator = typename Container::const_iterator;
19843  using value_type = typename Container::value_type;
19844 #ifdef JSON_HAS_CPP_14
19845  using key_compare = std::equal_to<>;
19846 #else
19847  using key_compare = std::equal_to<Key>;
19848 #endif
19849 
19850  // Explicit constructors instead of `using Container::Container`
19851  // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
19852  ordered_map() noexcept(noexcept(Container())) : Container{} {}
19853  explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
19854  template <class It>
19855  ordered_map(It first, It last, const Allocator& alloc = Allocator())
19856  : Container{first, last, alloc} {}
19857  ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
19858  : Container{init, alloc} {}
19859 
19860  std::pair<iterator, bool> emplace(const key_type& key, T&& t)
19861  {
19862  for (auto it = this->begin(); it != this->end(); ++it)
19863  {
19864  if (m_compare(it->first, key))
19865  {
19866  return {it, false};
19867  }
19868  }
19869  Container::emplace_back(key, std::forward<T>(t));
19870  return {std::prev(this->end()), true};
19871  }
19872 
19873  template<class KeyType, detail::enable_if_t<
19875  std::pair<iterator, bool> emplace(KeyType && key, T && t)
19876  {
19877  for (auto it = this->begin(); it != this->end(); ++it)
19878  {
19879  if (m_compare(it->first, key))
19880  {
19881  return {it, false};
19882  }
19883  }
19884  Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
19885  return {std::prev(this->end()), true};
19886  }
19887 
19889  {
19890  return emplace(key, T{}).first->second;
19891  }
19892 
19893  template<class KeyType, detail::enable_if_t<
19895  T & operator[](KeyType && key)
19896  {
19897  return emplace(std::forward<KeyType>(key), T{}).first->second;
19898  }
19899 
19900  const T& operator[](const key_type& key) const
19901  {
19902  return at(key);
19903  }
19904 
19905  template<class KeyType, detail::enable_if_t<
19907  const T & operator[](KeyType && key) const
19908  {
19909  return at(std::forward<KeyType>(key));
19910  }
19911 
19912  T& at(const key_type& key)
19913  {
19914  for (auto it = this->begin(); it != this->end(); ++it)
19915  {
19916  if (m_compare(it->first, key))
19917  {
19918  return it->second;
19919  }
19920  }
19921 
19922  JSON_THROW(std::out_of_range("key not found"));
19923  }
19924 
19925  template<class KeyType, detail::enable_if_t<
19927  T & at(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
19928  {
19929  for (auto it = this->begin(); it != this->end(); ++it)
19930  {
19931  if (m_compare(it->first, key))
19932  {
19933  return it->second;
19934  }
19935  }
19936 
19937  JSON_THROW(std::out_of_range("key not found"));
19938  }
19939 
19940  const T& at(const key_type& key) const
19941  {
19942  for (auto it = this->begin(); it != this->end(); ++it)
19943  {
19944  if (m_compare(it->first, key))
19945  {
19946  return it->second;
19947  }
19948  }
19949 
19950  JSON_THROW(std::out_of_range("key not found"));
19951  }
19952 
19953  template<class KeyType, detail::enable_if_t<
19955  const T & at(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)
19956  {
19957  for (auto it = this->begin(); it != this->end(); ++it)
19958  {
19959  if (m_compare(it->first, key))
19960  {
19961  return it->second;
19962  }
19963  }
19964 
19965  JSON_THROW(std::out_of_range("key not found"));
19966  }
19967 
19969  {
19970  for (auto it = this->begin(); it != this->end(); ++it)
19971  {
19972  if (m_compare(it->first, key))
19973  {
19974  // Since we cannot move const Keys, re-construct them in place
19975  for (auto next = it; ++next != this->end(); ++it)
19976  {
19977  it->~value_type(); // Destroy but keep allocation
19978  new (&*it) value_type{std::move(*next)};
19979  }
19980  Container::pop_back();
19981  return 1;
19982  }
19983  }
19984  return 0;
19985  }
19986 
19987  template<class KeyType, detail::enable_if_t<
19989  size_type erase(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
19990  {
19991  for (auto it = this->begin(); it != this->end(); ++it)
19992  {
19993  if (m_compare(it->first, key))
19994  {
19995  // Since we cannot move const Keys, re-construct them in place
19996  for (auto next = it; ++next != this->end(); ++it)
19997  {
19998  it->~value_type(); // Destroy but keep allocation
19999  new (&*it) value_type{std::move(*next)};
20000  }
20001  Container::pop_back();
20002  return 1;
20003  }
20004  }
20005  return 0;
20006  }
20007 
20009  {
20010  return erase(pos, std::next(pos));
20011  }
20012 
20014  {
20015  if (first == last)
20016  {
20017  return first;
20018  }
20019 
20020  const auto elements_affected = std::distance(first, last);
20021  const auto offset = std::distance(Container::begin(), first);
20022 
20023  // This is the start situation. We need to delete elements_affected
20024  // elements (3 in this example: e, f, g), and need to return an
20025  // iterator past the last deleted element (h in this example).
20026  // Note that offset is the distance from the start of the vector
20027  // to first. We will need this later.
20028 
20029  // [ a, b, c, d, e, f, g, h, i, j ]
20030  // ^ ^
20031  // first last
20032 
20033  // Since we cannot move const Keys, we re-construct them in place.
20034  // We start at first and re-construct (viz. copy) the elements from
20035  // the back of the vector. Example for the first iteration:
20036 
20037  // ,--------.
20038  // v | destroy e and re-construct with h
20039  // [ a, b, c, d, e, f, g, h, i, j ]
20040  // ^ ^
20041  // it it + elements_affected
20042 
20043  for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
20044  {
20045  it->~value_type(); // destroy but keep allocation
20046  new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
20047  }
20048 
20049  // [ a, b, c, d, h, i, j, h, i, j ]
20050  // ^ ^
20051  // first last
20052 
20053  // remove the unneeded elements at the end of the vector
20054  Container::resize(this->size() - static_cast<size_type>(elements_affected));
20055 
20056  // [ a, b, c, d, h, i, j ]
20057  // ^ ^
20058  // first last
20059 
20060  // first is now pointing past the last deleted element, but we cannot
20061  // use this iterator, because it may have been invalidated by the
20062  // resize call. Instead, we can return begin() + offset.
20063  return Container::begin() + offset;
20064  }
20065 
20066  size_type count(const key_type& key) const
20067  {
20068  for (auto it = this->begin(); it != this->end(); ++it)
20069  {
20070  if (m_compare(it->first, key))
20071  {
20072  return 1;
20073  }
20074  }
20075  return 0;
20076  }
20077 
20078  template<class KeyType, detail::enable_if_t<
20080  size_type count(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)
20081  {
20082  for (auto it = this->begin(); it != this->end(); ++it)
20083  {
20084  if (m_compare(it->first, key))
20085  {
20086  return 1;
20087  }
20088  }
20089  return 0;
20090  }
20091 
20093  {
20094  for (auto it = this->begin(); it != this->end(); ++it)
20095  {
20096  if (m_compare(it->first, key))
20097  {
20098  return it;
20099  }
20100  }
20101  return Container::end();
20102  }
20103 
20104  template<class KeyType, detail::enable_if_t<
20106  iterator find(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
20107  {
20108  for (auto it = this->begin(); it != this->end(); ++it)
20109  {
20110  if (m_compare(it->first, key))
20111  {
20112  return it;
20113  }
20114  }
20115  return Container::end();
20116  }
20117 
20119  {
20120  for (auto it = this->begin(); it != this->end(); ++it)
20121  {
20122  if (m_compare(it->first, key))
20123  {
20124  return it;
20125  }
20126  }
20127  return Container::end();
20128  }
20129 
20130  std::pair<iterator, bool> insert( value_type&& value )
20131  {
20132  return emplace(value.first, std::move(value.second));
20133  }
20134 
20135  std::pair<iterator, bool> insert( const value_type& value )
20136  {
20137  for (auto it = this->begin(); it != this->end(); ++it)
20138  {
20139  if (m_compare(it->first, value.first))
20140  {
20141  return {it, false};
20142  }
20143  }
20144  Container::push_back(value);
20145  return {--this->end(), true};
20146  }
20147 
20148  template<typename InputIt>
20149  using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
20150  std::input_iterator_tag>::value>::type;
20151 
20152  template<typename InputIt, typename = require_input_iter<InputIt>>
20153  void insert(InputIt first, InputIt last)
20154  {
20155  for (auto it = first; it != last; ++it)
20156  {
20157  insert(*it);
20158  }
20159  }
20160 
20161 private:
20163 };
20164 
20166 
20167 
20168 #if defined(JSON_HAS_CPP_17)
20169  #if JSON_HAS_STATIC_RTTI
20170  #include <any>
20171  #endif
20172  #include <string_view>
20173 #endif
20174 
20181 
20201 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
20202  : public ::nlohmann::detail::json_base_class<CustomBaseClass>
20203 {
20204  private:
20205  template<detail::value_t> friend struct detail::external_constructor;
20206 
20207  template<typename>
20208  friend class ::nlohmann::json_pointer;
20209  // can be restored when json_pointer backwards compatibility is removed
20210  // friend ::nlohmann::json_pointer<StringType>;
20211 
20212  template<typename BasicJsonType, typename InputType>
20213  friend class ::nlohmann::detail::parser;
20214  friend ::nlohmann::detail::serializer<basic_json>;
20215  template<typename BasicJsonType>
20216  friend class ::nlohmann::detail::iter_impl;
20217  template<typename BasicJsonType, typename CharType>
20218  friend class ::nlohmann::detail::binary_writer;
20219  template<typename BasicJsonType, typename InputType, typename SAX>
20220  friend class ::nlohmann::detail::binary_reader;
20221  template<typename BasicJsonType, typename InputAdapterType>
20222  friend class ::nlohmann::detail::json_sax_dom_parser;
20223  template<typename BasicJsonType, typename InputAdapterType>
20224  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
20225  friend class ::nlohmann::detail::exception;
20226 
20229  using json_base_class_t = ::nlohmann::detail::json_base_class<CustomBaseClass>;
20230 
20232  // convenience aliases for types residing in namespace detail;
20234 
20235  template<typename InputAdapterType>
20236  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
20237  InputAdapterType adapter,
20239  const bool allow_exceptions = true,
20240  const bool ignore_comments = false,
20241  const bool ignore_trailing_commas = false
20242  )
20243  {
20244  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
20245  std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas);
20246  }
20247 
20248  private:
20250  template<typename BasicJsonType>
20252  template<typename BasicJsonType>
20254  template<typename Iterator>
20257 
20258  template<typename CharType>
20260 
20261  template<typename InputType>
20264 
20266  using serializer = ::nlohmann::detail::serializer<basic_json>;
20267 
20268  public:
20272  template<typename T, typename SFINAE>
20273  using json_serializer = JSONSerializer<T, SFINAE>;
20281  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
20282 
20286 
20288  // exceptions //
20290 
20294 
20301 
20303 
20305  // container types //
20307 
20312 
20315 
20319  using const_reference = const value_type&;
20320 
20322  using difference_type = std::ptrdiff_t;
20324  using size_type = std::size_t;
20325 
20327  using allocator_type = AllocatorType<basic_json>;
20328 
20332  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
20333 
20342 
20344 
20348  {
20349  return allocator_type();
20350  }
20351 
20355  static basic_json meta()
20356  {
20357  basic_json result;
20358 
20359  result["copyright"] = "(C) 2013-2025 Niels Lohmann";
20360  result["name"] = "JSON for Modern C++";
20361  result["url"] = "https://github.com/nlohmann/json";
20362  result["version"]["string"] =
20366  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
20367  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
20368  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
20369 
20370 #ifdef _WIN32
20371  result["platform"] = "win32";
20372 #elif defined __linux__
20373  result["platform"] = "linux";
20374 #elif defined __APPLE__
20375  result["platform"] = "apple";
20376 #elif defined __unix__
20377  result["platform"] = "unix";
20378 #else
20379  result["platform"] = "unknown";
20380 #endif
20381 
20382 #if defined(__ICC) || defined(__INTEL_COMPILER)
20383  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
20384 #elif defined(__clang__)
20385  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
20386 #elif defined(__GNUC__) || defined(__GNUG__)
20387  result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
20388  std::to_string(__GNUC__), '.',
20389  std::to_string(__GNUC_MINOR__), '.',
20390  std::to_string(__GNUC_PATCHLEVEL__))
20391  }
20392  };
20393 #elif defined(__HP_cc) || defined(__HP_aCC)
20394  result["compiler"] = "hp"
20395 #elif defined(__IBMCPP__)
20396  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
20397 #elif defined(_MSC_VER)
20398  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
20399 #elif defined(__PGI)
20400  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
20401 #elif defined(__SUNPRO_CC)
20402  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
20403 #else
20404  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
20405 #endif
20406 
20407 #if defined(_MSVC_LANG)
20408  result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
20409 #elif defined(__cplusplus)
20410  result["compiler"]["c++"] = std::to_string(__cplusplus);
20411 #else
20412  result["compiler"]["c++"] = "unknown";
20413 #endif
20414  return result;
20415  }
20416 
20418  // JSON value data types //
20420 
20425 
20430 #if defined(JSON_HAS_CPP_14)
20431  // use of transparent comparator avoids unnecessary repeated construction of temporaries
20432  // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
20433  using default_object_comparator_t = std::less<>;
20434 #else
20435  using default_object_comparator_t = std::less<StringType>;
20436 #endif
20437 
20440  using object_t = ObjectType<StringType,
20441  basic_json,
20443  AllocatorType<std::pair<const StringType,
20444  basic_json>>>;
20445 
20449 
20452  using string_t = StringType;
20453 
20456  using boolean_t = BooleanType;
20457 
20460  using number_integer_t = NumberIntegerType;
20461 
20464  using number_unsigned_t = NumberUnsignedType;
20465 
20468  using number_float_t = NumberFloatType;
20469 
20473 
20477 
20479 
20480  private:
20481 
20483  template<typename T, typename... Args>
20485  static T* create(Args&& ... args)
20486  {
20487  AllocatorType<T> alloc;
20488  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
20489 
20490  auto deleter = [&](T * obj)
20491  {
20492  AllocatorTraits::deallocate(alloc, obj, 1);
20493  };
20494  std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
20495  AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
20496  JSON_ASSERT(obj != nullptr);
20497  return obj.release();
20498  }
20499 
20501  // JSON value storage //
20503 
20530  union json_value
20531  {
20533  object_t* object;
20548 
20550  json_value() = default;
20552  json_value(boolean_t v) noexcept : boolean(v) {}
20561  {
20562  switch (t)
20563  {
20564  case value_t::object:
20565  {
20566  object = create<object_t>();
20567  break;
20568  }
20569 
20570  case value_t::array:
20571  {
20572  array = create<array_t>();
20573  break;
20574  }
20575 
20576  case value_t::string:
20577  {
20578  string = create<string_t>("");
20579  break;
20580  }
20581 
20582  case value_t::binary:
20583  {
20584  binary = create<binary_t>();
20585  break;
20586  }
20587 
20588  case value_t::boolean:
20589  {
20590  boolean = static_cast<boolean_t>(false);
20591  break;
20592  }
20593 
20594  case value_t::number_integer:
20595  {
20596  number_integer = static_cast<number_integer_t>(0);
20597  break;
20598  }
20599 
20600  case value_t::number_unsigned:
20601  {
20602  number_unsigned = static_cast<number_unsigned_t>(0);
20603  break;
20604  }
20605 
20606  case value_t::number_float:
20607  {
20608  number_float = static_cast<number_float_t>(0.0);
20609  break;
20610  }
20611 
20612  case value_t::null:
20613  {
20614  object = nullptr; // silence warning, see #821
20615  break;
20616  }
20617 
20618  case value_t::discarded:
20619  default:
20620  {
20621  object = nullptr; // silence warning, see #821
20622  if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
20623  {
20624  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.12.0", nullptr)); // LCOV_EXCL_LINE
20625  }
20626  break;
20627  }
20628  }
20629  }
20630 
20633 
20635  json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
20636 
20638  json_value(const object_t& value) : object(create<object_t>(value)) {}
20639 
20641  json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
20642 
20644  json_value(const array_t& value) : array(create<array_t>(value)) {}
20645 
20647  json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
20648 
20651 
20654 
20657 
20659  json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
20660 
20662  {
20663  if (
20664  (t == value_t::object && object == nullptr) ||
20665  (t == value_t::array && array == nullptr) ||
20666  (t == value_t::string && string == nullptr) ||
20667  (t == value_t::binary && binary == nullptr)
20668  )
20669  {
20670  // not initialized (e.g., due to exception in the ctor)
20671  return;
20672  }
20673  if (t == value_t::array || t == value_t::object)
20674  {
20675  // flatten the current json_value to a heap-allocated stack
20676  std::vector<basic_json> stack;
20677 
20678  // move the top-level items to stack
20679  if (t == value_t::array)
20680  {
20681  stack.reserve(array->size());
20682  std::move(array->begin(), array->end(), std::back_inserter(stack));
20683  }
20684  else
20685  {
20686  stack.reserve(object->size());
20687  for (auto&& it : *object)
20688  {
20689  stack.push_back(std::move(it.second));
20690  }
20691  }
20692 
20693  while (!stack.empty())
20694  {
20695  // move the last item to a local variable to be processed
20696  basic_json current_item(std::move(stack.back()));
20697  stack.pop_back();
20698 
20699  // if current_item is array/object, move
20700  // its children to the stack to be processed later
20701  if (current_item.is_array())
20702  {
20703  std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
20704 
20705  current_item.m_data.m_value.array->clear();
20706  }
20707  else if (current_item.is_object())
20708  {
20709  for (auto&& it : *current_item.m_data.m_value.object)
20710  {
20711  stack.push_back(std::move(it.second));
20712  }
20713 
20714  current_item.m_data.m_value.object->clear();
20715  }
20716 
20717  // it's now safe that current_item gets destructed
20718  // since it doesn't have any children
20719  }
20720  }
20721 
20722  switch (t)
20723  {
20724  case value_t::object:
20725  {
20726  AllocatorType<object_t> alloc;
20727  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
20728  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
20729  break;
20730  }
20731 
20732  case value_t::array:
20733  {
20734  AllocatorType<array_t> alloc;
20735  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
20736  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
20737  break;
20738  }
20739 
20740  case value_t::string:
20741  {
20742  AllocatorType<string_t> alloc;
20743  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
20744  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
20745  break;
20746  }
20747 
20748  case value_t::binary:
20749  {
20750  AllocatorType<binary_t> alloc;
20751  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
20752  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
20753  break;
20754  }
20755 
20756  case value_t::null:
20757  case value_t::boolean:
20758  case value_t::number_integer:
20759  case value_t::number_unsigned:
20760  case value_t::number_float:
20761  case value_t::discarded:
20762  default:
20763  {
20764  break;
20765  }
20766  }
20767  }
20768  };
20769 
20770  private:
20789  void assert_invariant(bool check_parents = true) const noexcept
20790  {
20791  JSON_ASSERT(m_data.m_type != value_t::object || m_data.m_value.object != nullptr);
20792  JSON_ASSERT(m_data.m_type != value_t::array || m_data.m_value.array != nullptr);
20793  JSON_ASSERT(m_data.m_type != value_t::string || m_data.m_value.string != nullptr);
20794  JSON_ASSERT(m_data.m_type != value_t::binary || m_data.m_value.binary != nullptr);
20795 
20796 #if JSON_DIAGNOSTICS
20797  JSON_TRY
20798  {
20799  // cppcheck-suppress assertWithSideEffect
20800  JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
20801  {
20802  return j.m_parent == this;
20803  }));
20804  }
20805  JSON_CATCH(...) {} // LCOV_EXCL_LINE
20806 #endif
20807  static_cast<void>(check_parents);
20808  }
20809 
20811  {
20812 #if JSON_DIAGNOSTICS
20813  switch (m_data.m_type)
20814  {
20815  case value_t::array:
20816  {
20817  for (auto& element : *m_data.m_value.array)
20818  {
20819  element.m_parent = this;
20820  }
20821  break;
20822  }
20823 
20824  case value_t::object:
20825  {
20826  for (auto& element : *m_data.m_value.object)
20827  {
20828  element.second.m_parent = this;
20829  }
20830  break;
20831  }
20832 
20833  case value_t::null:
20834  case value_t::string:
20835  case value_t::boolean:
20836  case value_t::number_integer:
20837  case value_t::number_unsigned:
20838  case value_t::number_float:
20839  case value_t::binary:
20840  case value_t::discarded:
20841  default:
20842  break;
20843  }
20844 #endif
20845  }
20846 
20847  iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
20848  {
20849 #if JSON_DIAGNOSTICS
20850  for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
20851  {
20852  (it + i)->m_parent = this;
20853  }
20854 #else
20855  static_cast<void>(count_set_parents);
20856 #endif
20857  return it;
20858  }
20859 
20860  reference set_parent(reference j, std::size_t old_capacity = detail::unknown_size())
20861  {
20862 #if JSON_DIAGNOSTICS
20863  if (old_capacity != detail::unknown_size())
20864  {
20865  // see https://github.com/nlohmann/json/issues/2838
20866  JSON_ASSERT(type() == value_t::array);
20867  if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
20868  {
20869  // capacity has changed: update all parents
20870  set_parents();
20871  return j;
20872  }
20873  }
20874 
20875  // ordered_json uses a vector internally, so pointers could have
20876  // been invalidated; see https://github.com/nlohmann/json/issues/2962
20877 #ifdef JSON_HEDLEY_MSVC_VERSION
20878 #pragma warning(push )
20879 #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
20880 #endif
20882  {
20883  set_parents();
20884  return j;
20885  }
20886 #ifdef JSON_HEDLEY_MSVC_VERSION
20887 #pragma warning( pop )
20888 #endif
20889 
20890  j.m_parent = this;
20891 #else
20892  static_cast<void>(j);
20893  static_cast<void>(old_capacity);
20894 #endif
20895  return j;
20896  }
20897 
20898  public:
20900  // JSON parser callback //
20902 
20906 
20910 
20912  // constructors //
20914 
20919 
20923  : m_data(v)
20924  {
20925  assert_invariant();
20926  }
20927 
20930  basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
20931  : basic_json(value_t::null)
20932  {
20933  assert_invariant();
20934  }
20935 
20938  template < typename CompatibleType,
20939  typename U = detail::uncvref_t<CompatibleType>,
20942  basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
20943  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
20944  std::forward<CompatibleType>(val))))
20945  {
20946  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
20947  set_parents();
20948  assert_invariant();
20949  }
20950 
20953  template < typename BasicJsonType,
20956  basic_json(const BasicJsonType& val)
20957 #if JSON_DIAGNOSTIC_POSITIONS
20958  : start_position(val.start_pos()),
20959  end_position(val.end_pos())
20960 #endif
20961  {
20962  using other_boolean_t = typename BasicJsonType::boolean_t;
20963  using other_number_float_t = typename BasicJsonType::number_float_t;
20964  using other_number_integer_t = typename BasicJsonType::number_integer_t;
20965  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
20966  using other_string_t = typename BasicJsonType::string_t;
20967  using other_object_t = typename BasicJsonType::object_t;
20968  using other_array_t = typename BasicJsonType::array_t;
20969  using other_binary_t = typename BasicJsonType::binary_t;
20970 
20971  switch (val.type())
20972  {
20973  case value_t::boolean:
20974  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
20975  break;
20976  case value_t::number_float:
20977  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
20978  break;
20979  case value_t::number_integer:
20980  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
20981  break;
20982  case value_t::number_unsigned:
20983  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
20984  break;
20985  case value_t::string:
20986  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
20987  break;
20988  case value_t::object:
20989  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
20990  break;
20991  case value_t::array:
20992  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
20993  break;
20994  case value_t::binary:
20995  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
20996  break;
20997  case value_t::null:
20998  *this = nullptr;
20999  break;
21000  case value_t::discarded:
21001  m_data.m_type = value_t::discarded;
21002  break;
21003  default: // LCOV_EXCL_LINE
21004  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
21005  }
21006  JSON_ASSERT(m_data.m_type == val.type());
21007 
21008  set_parents();
21009  assert_invariant();
21010  }
21011 
21015  bool type_deduction = true,
21016  value_t manual_type = value_t::array)
21017  {
21018  // check if each element is an array with two elements whose first
21019  // element is a string
21020  bool is_an_object = std::all_of(init.begin(), init.end(),
21021  [](const detail::json_ref<basic_json>& element_ref)
21022  {
21023  // The cast is to ensure op[size_type] is called, bearing in mind size_type may not be int;
21024  // (many string types can be constructed from 0 via its null-pointer guise, so we get a
21025  // broken call to op[key_type], the wrong semantics, and a 4804 warning on Windows)
21026  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[static_cast<size_type>(0)].is_string();
21027  });
21028 
21029  // adjust type if type deduction is not wanted
21030  if (!type_deduction)
21031  {
21032  // if an array is wanted, do not create an object though possible
21033  if (manual_type == value_t::array)
21034  {
21035  is_an_object = false;
21036  }
21037 
21038  // if an object is wanted but impossible, throw an exception
21039  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
21040  {
21041  JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
21042  }
21043  }
21044 
21045  if (is_an_object)
21046  {
21047  // the initializer list is a list of pairs -> create an object
21048  m_data.m_type = value_t::object;
21049  m_data.m_value = value_t::object;
21050 
21051  for (auto& element_ref : init)
21052  {
21053  auto element = element_ref.moved_or_copied();
21054  m_data.m_value.object->emplace(
21055  std::move(*((*element.m_data.m_value.array)[0].m_data.m_value.string)),
21056  std::move((*element.m_data.m_value.array)[1]));
21057  }
21058  }
21059  else
21060  {
21061  // the initializer list describes an array -> create an array
21062  m_data.m_type = value_t::array;
21063  m_data.m_value.array = create<array_t>(init.begin(), init.end());
21064  }
21065 
21066  set_parents();
21067  assert_invariant();
21068  }
21069 
21073  static basic_json binary(const typename binary_t::container_type& init)
21074  {
21075  auto res = basic_json();
21076  res.m_data.m_type = value_t::binary;
21077  res.m_data.m_value = init;
21078  return res;
21079  }
21080 
21084  static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
21085  {
21086  auto res = basic_json();
21087  res.m_data.m_type = value_t::binary;
21088  res.m_data.m_value = binary_t(init, subtype);
21089  return res;
21090  }
21091 
21096  {
21097  auto res = basic_json();
21098  res.m_data.m_type = value_t::binary;
21099  res.m_data.m_value = std::move(init);
21100  return res;
21101  }
21102 
21106  static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
21107  {
21108  auto res = basic_json();
21109  res.m_data.m_type = value_t::binary;
21110  res.m_data.m_value = binary_t(std::move(init), subtype);
21111  return res;
21112  }
21113 
21118  {
21119  return basic_json(init, false, value_t::array);
21120  }
21121 
21126  {
21127  return basic_json(init, false, value_t::object);
21128  }
21129 
21132  basic_json(size_type cnt, const basic_json& val):
21133  m_data{cnt, val}
21134  {
21135  set_parents();
21136  assert_invariant();
21137  }
21138 
21141  template < class InputIT, typename std::enable_if <
21144  basic_json(InputIT first, InputIT last) // NOLINT(performance-unnecessary-value-param)
21145  {
21146  JSON_ASSERT(first.m_object != nullptr);
21147  JSON_ASSERT(last.m_object != nullptr);
21148 
21149  // make sure the iterator fits the current value
21150  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21151  {
21152  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
21153  }
21154 
21155  // copy type from the first iterator
21156  m_data.m_type = first.m_object->m_data.m_type;
21157 
21158  // check if the iterator range is complete for primitive values
21159  switch (m_data.m_type)
21160  {
21161  case value_t::boolean:
21162  case value_t::number_float:
21163  case value_t::number_integer:
21164  case value_t::number_unsigned:
21165  case value_t::string:
21166  {
21167  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
21168  || !last.m_it.primitive_iterator.is_end()))
21169  {
21170  JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
21171  }
21172  break;
21173  }
21174 
21175  case value_t::null:
21176  case value_t::object:
21177  case value_t::array:
21178  case value_t::binary:
21179  case value_t::discarded:
21180  default:
21181  break;
21182  }
21183 
21184  switch (m_data.m_type)
21185  {
21186  case value_t::number_integer:
21187  {
21188  m_data.m_value.number_integer = first.m_object->m_data.m_value.number_integer;
21189  break;
21190  }
21191 
21192  case value_t::number_unsigned:
21193  {
21194  m_data.m_value.number_unsigned = first.m_object->m_data.m_value.number_unsigned;
21195  break;
21196  }
21197 
21198  case value_t::number_float:
21199  {
21200  m_data.m_value.number_float = first.m_object->m_data.m_value.number_float;
21201  break;
21202  }
21203 
21204  case value_t::boolean:
21205  {
21206  m_data.m_value.boolean = first.m_object->m_data.m_value.boolean;
21207  break;
21208  }
21209 
21210  case value_t::string:
21211  {
21212  m_data.m_value = *first.m_object->m_data.m_value.string;
21213  break;
21214  }
21215 
21216  case value_t::object:
21217  {
21218  m_data.m_value.object = create<object_t>(first.m_it.object_iterator,
21219  last.m_it.object_iterator);
21220  break;
21221  }
21222 
21223  case value_t::array:
21224  {
21225  m_data.m_value.array = create<array_t>(first.m_it.array_iterator,
21226  last.m_it.array_iterator);
21227  break;
21228  }
21229 
21230  case value_t::binary:
21231  {
21232  m_data.m_value = *first.m_object->m_data.m_value.binary;
21233  break;
21234  }
21235 
21236  case value_t::null:
21237  case value_t::discarded:
21238  default:
21239  JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
21240  }
21241 
21242  set_parents();
21243  assert_invariant();
21244  }
21245 
21247  // other constructors and destructor //
21249 
21250  template<typename JsonRef,
21252  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
21253  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
21254 
21257  basic_json(const basic_json& other)
21258  : json_base_class_t(other)
21260  , start_position(other.start_position)
21261  , end_position(other.end_position)
21262 #endif
21263  {
21264  m_data.m_type = other.m_data.m_type;
21265  // check of passed value is valid
21266  other.assert_invariant();
21267 
21268  switch (m_data.m_type)
21269  {
21270  case value_t::object:
21271  {
21272  m_data.m_value = *other.m_data.m_value.object;
21273  break;
21274  }
21275 
21276  case value_t::array:
21277  {
21278  m_data.m_value = *other.m_data.m_value.array;
21279  break;
21280  }
21281 
21282  case value_t::string:
21283  {
21284  m_data.m_value = *other.m_data.m_value.string;
21285  break;
21286  }
21287 
21288  case value_t::boolean:
21289  {
21290  m_data.m_value = other.m_data.m_value.boolean;
21291  break;
21292  }
21293 
21294  case value_t::number_integer:
21295  {
21296  m_data.m_value = other.m_data.m_value.number_integer;
21297  break;
21298  }
21299 
21300  case value_t::number_unsigned:
21301  {
21302  m_data.m_value = other.m_data.m_value.number_unsigned;
21303  break;
21304  }
21305 
21306  case value_t::number_float:
21307  {
21308  m_data.m_value = other.m_data.m_value.number_float;
21309  break;
21310  }
21311 
21312  case value_t::binary:
21313  {
21314  m_data.m_value = *other.m_data.m_value.binary;
21315  break;
21316  }
21317 
21318  case value_t::null:
21319  case value_t::discarded:
21320  default:
21321  break;
21322  }
21323 
21324  set_parents();
21325  assert_invariant();
21326  }
21327 
21330  basic_json(basic_json&& other) noexcept
21331  : json_base_class_t(std::forward<json_base_class_t>(other)),
21332  m_data(std::move(other.m_data)) // cppcheck-suppress[accessForwarded] TODO check
21333 #if JSON_DIAGNOSTIC_POSITIONS
21334  , start_position(other.start_position) // cppcheck-suppress[accessForwarded] TODO check
21335  , end_position(other.end_position) // cppcheck-suppress[accessForwarded] TODO check
21336 #endif
21337  {
21338  // check that the passed value is valid
21339  other.assert_invariant(false); // cppcheck-suppress[accessForwarded]
21340 
21341  // invalidate payload
21342  other.m_data.m_type = value_t::null;
21343  other.m_data.m_value = {};
21344 
21345 #if JSON_DIAGNOSTIC_POSITIONS
21346  other.start_position = std::string::npos;
21347  other.end_position = std::string::npos;
21348 #endif
21349 
21350  set_parents();
21351  assert_invariant();
21352  }
21353 
21356  basic_json& operator=(basic_json other) noexcept (
21362  )
21363  {
21364  // check that the passed value is valid
21365  other.assert_invariant();
21366 
21367  using std::swap;
21368  swap(m_data.m_type, other.m_data.m_type);
21369  swap(m_data.m_value, other.m_data.m_value);
21370 
21371 #if JSON_DIAGNOSTIC_POSITIONS
21372  swap(start_position, other.start_position);
21373  swap(end_position, other.end_position);
21374 #endif
21375 
21376  json_base_class_t::operator=(std::move(other));
21377 
21378  set_parents();
21379  assert_invariant();
21380  return *this;
21381  }
21382 
21385  ~basic_json() noexcept
21386  {
21387  assert_invariant(false);
21388  }
21389 
21391 
21392  public:
21394  // object inspection //
21396 
21400 
21403  string_t dump(const int indent = -1,
21404  const char indent_char = ' ',
21405  const bool ensure_ascii = false,
21406  const error_handler_t error_handler = error_handler_t::strict) const
21407  {
21408  string_t result;
21409  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
21410 
21411  if (indent >= 0)
21412  {
21413  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
21414  }
21415  else
21416  {
21417  s.dump(*this, false, ensure_ascii, 0);
21418  }
21419 
21420  return result;
21421  }
21422 
21425  constexpr value_t type() const noexcept
21426  {
21427  return m_data.m_type;
21428  }
21429 
21432  constexpr bool is_primitive() const noexcept
21433  {
21434  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
21435  }
21436 
21439  constexpr bool is_structured() const noexcept
21440  {
21441  return is_array() || is_object();
21442  }
21443 
21446  constexpr bool is_null() const noexcept
21447  {
21448  return m_data.m_type == value_t::null;
21449  }
21450 
21453  constexpr bool is_boolean() const noexcept
21454  {
21455  return m_data.m_type == value_t::boolean;
21456  }
21457 
21460  constexpr bool is_number() const noexcept
21461  {
21462  return is_number_integer() || is_number_float();
21463  }
21464 
21467  constexpr bool is_number_integer() const noexcept
21468  {
21469  return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
21470  }
21471 
21474  constexpr bool is_number_unsigned() const noexcept
21475  {
21476  return m_data.m_type == value_t::number_unsigned;
21477  }
21478 
21481  constexpr bool is_number_float() const noexcept
21482  {
21483  return m_data.m_type == value_t::number_float;
21484  }
21485 
21488  constexpr bool is_object() const noexcept
21489  {
21490  return m_data.m_type == value_t::object;
21491  }
21492 
21495  constexpr bool is_array() const noexcept
21496  {
21497  return m_data.m_type == value_t::array;
21498  }
21499 
21502  constexpr bool is_string() const noexcept
21503  {
21504  return m_data.m_type == value_t::string;
21505  }
21506 
21509  constexpr bool is_binary() const noexcept
21510  {
21511  return m_data.m_type == value_t::binary;
21512  }
21513 
21516  constexpr bool is_discarded() const noexcept
21517  {
21518  return m_data.m_type == value_t::discarded;
21519  }
21520 
21523  constexpr operator value_t() const noexcept
21524  {
21525  return m_data.m_type;
21526  }
21527 
21529 
21530  private:
21532  // value access //
21534 
21536  boolean_t get_impl(boolean_t* /*unused*/) const
21537  {
21538  if (JSON_HEDLEY_LIKELY(is_boolean()))
21539  {
21540  return m_data.m_value.boolean;
21541  }
21542 
21543  JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
21544  }
21545 
21547  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
21548  {
21549  return is_object() ? m_data.m_value.object : nullptr;
21550  }
21551 
21553  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
21554  {
21555  return is_object() ? m_data.m_value.object : nullptr;
21556  }
21557 
21559  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
21560  {
21561  return is_array() ? m_data.m_value.array : nullptr;
21562  }
21563 
21565  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
21566  {
21567  return is_array() ? m_data.m_value.array : nullptr;
21568  }
21569 
21571  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
21572  {
21573  return is_string() ? m_data.m_value.string : nullptr;
21574  }
21575 
21577  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
21578  {
21579  return is_string() ? m_data.m_value.string : nullptr;
21580  }
21581 
21583  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
21584  {
21585  return is_boolean() ? &m_data.m_value.boolean : nullptr;
21586  }
21587 
21589  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
21590  {
21591  return is_boolean() ? &m_data.m_value.boolean : nullptr;
21592  }
21593 
21596  {
21597  return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer : nullptr;
21598  }
21599 
21601  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
21602  {
21603  return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer : nullptr;
21604  }
21605 
21608  {
21609  return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
21610  }
21611 
21613  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
21614  {
21615  return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
21616  }
21617 
21620  {
21621  return is_number_float() ? &m_data.m_value.number_float : nullptr;
21622  }
21623 
21625  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
21626  {
21627  return is_number_float() ? &m_data.m_value.number_float : nullptr;
21628  }
21629 
21631  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
21632  {
21633  return is_binary() ? m_data.m_value.binary : nullptr;
21634  }
21635 
21637  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
21638  {
21639  return is_binary() ? m_data.m_value.binary : nullptr;
21640  }
21641 
21653  template<typename ReferenceType, typename ThisType>
21654  static ReferenceType get_ref_impl(ThisType& obj)
21655  {
21656  // delegate the call to get_ptr<>()
21657  auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
21658 
21659  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
21660  {
21661  return *ptr;
21662  }
21663 
21664  JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
21665  }
21666 
21667  public:
21671 
21674  template<typename PointerType, typename std::enable_if<
21676  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
21677  {
21678  // delegate the call to get_impl_ptr<>()
21679  return get_impl_ptr(static_cast<PointerType>(nullptr));
21680  }
21681 
21684  template < typename PointerType, typename std::enable_if <
21687  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
21688  {
21689  // delegate the call to get_impl_ptr<>() const
21690  return get_impl_ptr(static_cast<PointerType>(nullptr));
21691  }
21692 
21693  private:
21732  template < typename ValueType,
21736  int > = 0 >
21737  ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
21738  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
21739  {
21740  auto ret = ValueType();
21742  return ret;
21743  }
21744 
21775  template < typename ValueType,
21778  int > = 0 >
21779  ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
21780  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
21781  {
21783  }
21784 
21800  template < typename BasicJsonType,
21803  int > = 0 >
21804  BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
21805  {
21806  return *this;
21807  }
21808 
21823  template<typename BasicJsonType,
21826  int> = 0>
21828  {
21829  return *this;
21830  }
21831 
21836  template<typename PointerType,
21839  int> = 0>
21840  constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
21841  -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
21842  {
21843  // delegate the call to get_ptr
21844  return get_ptr<PointerType>();
21845  }
21846 
21847  public:
21871  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
21872 #if defined(JSON_HAS_CPP_14)
21873  constexpr
21874 #endif
21875  auto get() const noexcept(
21876  noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
21877  -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
21878  {
21879  // we cannot static_assert on ValueTypeCV being non-const, because
21880  // there is support for get<const basic_json_t>(), which is why we
21881  // still need the uncvref
21883  "get() cannot be used with reference types, you might want to use get_ref()");
21884  return get_impl<ValueType>(detail::priority_tag<4> {});
21885  }
21886 
21914  template<typename PointerType, typename std::enable_if<
21916  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
21917  {
21918  // delegate the call to get_ptr
21919  return get_ptr<PointerType>();
21920  }
21921 
21924  template < typename ValueType,
21928  int > = 0 >
21929  ValueType & get_to(ValueType& v) const noexcept(noexcept(
21930  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
21931  {
21933  return v;
21934  }
21935 
21936  // specialization to allow calling get_to with a basic_json value
21937  // see https://github.com/nlohmann/json/issues/2175
21938  template<typename ValueType,
21941  int> = 0>
21942  ValueType & get_to(ValueType& v) const
21943  {
21944  v = *this;
21945  return v;
21946  }
21947 
21948  template <
21949  typename T, std::size_t N,
21950  typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21953  Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21954  noexcept(noexcept(JSONSerializer<Array>::from_json(
21955  std::declval<const basic_json_t&>(), v)))
21956  {
21958  return v;
21959  }
21960 
21963  template<typename ReferenceType, typename std::enable_if<
21965  ReferenceType get_ref()
21966  {
21967  // delegate call to get_ref_impl
21968  return get_ref_impl<ReferenceType>(*this);
21969  }
21970 
21973  template < typename ReferenceType, typename std::enable_if <
21976  ReferenceType get_ref() const
21977  {
21978  // delegate call to get_ref_impl
21979  return get_ref_impl<ReferenceType>(*this);
21980  }
21981 
22011  template < typename ValueType, typename std::enable_if <
22019 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
22021 #endif
22022 #if defined(JSON_HAS_CPP_17) && JSON_HAS_STATIC_RTTI
22024 #endif
22026  >::value, int >::type = 0 >
22027  JSON_EXPLICIT operator ValueType() const
22028  {
22029  // delegate the call to get<>() const
22030  return get<ValueType>();
22031  }
22032 
22036  {
22037  if (!is_binary())
22038  {
22039  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
22040  }
22041 
22042  return *get_ptr<binary_t*>();
22043  }
22044 
22047  const binary_t& get_binary() const
22048  {
22049  if (!is_binary())
22050  {
22051  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
22052  }
22053 
22054  return *get_ptr<const binary_t*>();
22055  }
22056 
22058 
22060  // element access //
22062 
22066 
22070  {
22071  // at only works for arrays
22072  if (JSON_HEDLEY_LIKELY(is_array()))
22073  {
22074  JSON_TRY
22075  {
22076  return set_parent(m_data.m_value.array->at(idx));
22077  }
22078  JSON_CATCH (std::out_of_range&)
22079  {
22080  // create a better exception explanation
22081  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
22082  } // cppcheck-suppress[missingReturn]
22083  }
22084  else
22085  {
22086  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
22087  }
22088  }
22089 
22093  {
22094  // at only works for arrays
22095  if (JSON_HEDLEY_LIKELY(is_array()))
22096  {
22097  JSON_TRY
22098  {
22099  return m_data.m_value.array->at(idx);
22100  }
22101  JSON_CATCH (std::out_of_range&)
22102  {
22103  // create a better exception explanation
22104  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
22105  } // cppcheck-suppress[missingReturn]
22106  }
22107  else
22108  {
22109  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
22110  }
22111  }
22112 
22115  reference at(const typename object_t::key_type& key)
22116  {
22117  // at only works for objects
22118  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22119  {
22120  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
22121  }
22122 
22123  auto it = m_data.m_value.object->find(key);
22124  if (it == m_data.m_value.object->end())
22125  {
22126  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
22127  }
22128  return set_parent(it->second);
22129  }
22130 
22133  template<class KeyType, detail::enable_if_t<
22135  reference at(KeyType && key)
22136  {
22137  // at only works for objects
22138  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22139  {
22140  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
22141  }
22142 
22143  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
22144  if (it == m_data.m_value.object->end())
22145  {
22146  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
22147  }
22148  return set_parent(it->second);
22149  }
22150 
22153  const_reference at(const typename object_t::key_type& key) const
22154  {
22155  // at only works for objects
22156  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22157  {
22158  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
22159  }
22160 
22161  auto it = m_data.m_value.object->find(key);
22162  if (it == m_data.m_value.object->end())
22163  {
22164  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
22165  }
22166  return it->second;
22167  }
22168 
22171  template<class KeyType, detail::enable_if_t<
22173  const_reference at(KeyType && key) const
22174  {
22175  // at only works for objects
22176  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22177  {
22178  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
22179  }
22180 
22181  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
22182  if (it == m_data.m_value.object->end())
22183  {
22184  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
22185  }
22186  return it->second;
22187  }
22188 
22192  {
22193  // implicitly convert a null value to an empty array
22194  if (is_null())
22195  {
22196  m_data.m_type = value_t::array;
22197  m_data.m_value.array = create<array_t>();
22198  assert_invariant();
22199  }
22200 
22201  // operator[] only works for arrays
22202  if (JSON_HEDLEY_LIKELY(is_array()))
22203  {
22204  // fill up the array with null values if given idx is outside the range
22205  if (idx >= m_data.m_value.array->size())
22206  {
22207 #if JSON_DIAGNOSTICS
22208  // remember array size & capacity before resizing
22209  const auto old_size = m_data.m_value.array->size();
22210  const auto old_capacity = m_data.m_value.array->capacity();
22211 #endif
22212  m_data.m_value.array->resize(idx + 1);
22213 
22214 #if JSON_DIAGNOSTICS
22215  if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
22216  {
22217  // capacity has changed: update all parents
22218  set_parents();
22219  }
22220  else
22221  {
22222  // set parent for values added above
22223  set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
22224  }
22225 #endif
22226  assert_invariant();
22227  }
22228 
22229  return m_data.m_value.array->operator[](idx);
22230  }
22231 
22232  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
22233  }
22234 
22238  {
22239  // const operator[] only works for arrays
22240  if (JSON_HEDLEY_LIKELY(is_array()))
22241  {
22242  return m_data.m_value.array->operator[](idx);
22243  }
22244 
22245  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
22246  }
22247 
22250  reference operator[](typename object_t::key_type key) // NOLINT(performance-unnecessary-value-param)
22251  {
22252  // implicitly convert a null value to an empty object
22253  if (is_null())
22254  {
22255  m_data.m_type = value_t::object;
22256  m_data.m_value.object = create<object_t>();
22257  assert_invariant();
22258  }
22259 
22260  // operator[] only works for objects
22261  if (JSON_HEDLEY_LIKELY(is_object()))
22262  {
22263  auto result = m_data.m_value.object->emplace(std::move(key), nullptr);
22264  return set_parent(result.first->second);
22265  }
22266 
22267  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
22268  }
22269 
22272  const_reference operator[](const typename object_t::key_type& key) const
22273  {
22274  // const operator[] only works for objects
22275  if (JSON_HEDLEY_LIKELY(is_object()))
22276  {
22277  auto it = m_data.m_value.object->find(key);
22278  JSON_ASSERT(it != m_data.m_value.object->end());
22279  return it->second;
22280  }
22281 
22282  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
22283  }
22284 
22285  // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
22286  // (they seemingly cannot be constrained to resolve the ambiguity)
22287  template<typename T>
22289  {
22290  return operator[](typename object_t::key_type(key));
22291  }
22292 
22293  template<typename T>
22295  {
22296  return operator[](typename object_t::key_type(key));
22297  }
22298 
22301  template<class KeyType, detail::enable_if_t<
22304  {
22305  // implicitly convert a null value to an empty object
22306  if (is_null())
22307  {
22308  m_data.m_type = value_t::object;
22309  m_data.m_value.object = create<object_t>();
22310  assert_invariant();
22311  }
22312 
22313  // operator[] only works for objects
22314  if (JSON_HEDLEY_LIKELY(is_object()))
22315  {
22316  auto result = m_data.m_value.object->emplace(std::forward<KeyType>(key), nullptr);
22317  return set_parent(result.first->second);
22318  }
22319 
22320  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
22321  }
22322 
22325  template<class KeyType, detail::enable_if_t<
22327  const_reference operator[](KeyType && key) const
22328  {
22329  // const operator[] only works for objects
22330  if (JSON_HEDLEY_LIKELY(is_object()))
22331  {
22332  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
22333  JSON_ASSERT(it != m_data.m_value.object->end());
22334  return it->second;
22335  }
22336 
22337  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
22338  }
22339 
22340  private:
22341  template<typename KeyType>
22343  object_comparator_t, const typename object_t::key_type&, KeyType >;
22344 
22345  template<typename ValueType>
22346  using value_return_type = std::conditional <
22349 
22350  public:
22353  template < class ValueType, detail::enable_if_t <
22356  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22357  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
22358  {
22359  // value only works for objects
22360  if (JSON_HEDLEY_LIKELY(is_object()))
22361  {
22362  // If 'key' is found, return its value. Otherwise, return `default_value'.
22363  const auto it = find(key);
22364  if (it != end())
22365  {
22366  return it->template get<ValueType>();
22367  }
22368 
22369  return default_value;
22370  }
22371 
22372  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22373  }
22374 
22381  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22382  ReturnType value(const typename object_t::key_type& key, ValueType && default_value) const
22383  {
22384  // value only works for objects
22385  if (JSON_HEDLEY_LIKELY(is_object()))
22386  {
22387  // If 'key' is found, return its value. Otherwise, return `default_value'.
22388  const auto it = find(key);
22389  if (it != end())
22390  {
22391  return it->template get<ReturnType>();
22392  }
22393 
22394  return std::forward<ValueType>(default_value);
22395  }
22396 
22397  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22398  }
22399 
22402  template < class ValueType, class KeyType, detail::enable_if_t <
22407  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22408  ValueType value(KeyType && key, const ValueType& default_value) const
22409  {
22410  // value only works for objects
22411  if (JSON_HEDLEY_LIKELY(is_object()))
22412  {
22413  // If 'key' is found, return its value. Otherwise, return `default_value'.
22414  const auto it = find(std::forward<KeyType>(key));
22415  if (it != end())
22416  {
22417  return it->template get<ValueType>();
22418  }
22419 
22420  return default_value;
22421  }
22422 
22423  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22424  }
22425 
22434  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22435  ReturnType value(KeyType && key, ValueType && default_value) const
22436  {
22437  // value only works for objects
22438  if (JSON_HEDLEY_LIKELY(is_object()))
22439  {
22440  // If 'key' is found, return its value. Otherwise, return `default_value'.
22441  const auto it = find(std::forward<KeyType>(key));
22442  if (it != end())
22443  {
22444  return it->template get<ReturnType>();
22445  }
22446 
22447  return std::forward<ValueType>(default_value);
22448  }
22449 
22450  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22451  }
22452 
22455  template < class ValueType, detail::enable_if_t <
22457  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22458  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
22459  {
22460  // value only works for objects
22461  if (JSON_HEDLEY_LIKELY(is_object()))
22462  {
22463  // If the pointer resolves to a value, return it. Otherwise, return
22464  // 'default_value'.
22465  JSON_TRY
22466  {
22467  return ptr.get_checked(this).template get<ValueType>();
22468  }
22470  {
22471  return default_value;
22472  }
22473  }
22474 
22475  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22476  }
22477 
22483  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22484  ReturnType value(const json_pointer& ptr, ValueType && default_value) const
22485  {
22486  // value only works for objects
22487  if (JSON_HEDLEY_LIKELY(is_object()))
22488  {
22489  // If the pointer resolves to a value, return it. Otherwise, return
22490  // 'default_value'.
22491  JSON_TRY
22492  {
22493  return ptr.get_checked(this).template get<ReturnType>();
22494  }
22496  {
22497  return std::forward<ValueType>(default_value);
22498  }
22499  }
22500 
22501  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22502  }
22503 
22504  template < class ValueType, class BasicJsonType, detail::enable_if_t <
22507  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22509  ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
22510  {
22511  return value(ptr.convert(), default_value);
22512  }
22513 
22518  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22520  ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const
22521  {
22522  return value(ptr.convert(), std::forward<ValueType>(default_value));
22523  }
22524 
22527  reference front()
22528  {
22529  return *begin();
22530  }
22531 
22535  {
22536  return *cbegin();
22537  }
22538 
22542  {
22543  auto tmp = end();
22544  --tmp;
22545  return *tmp;
22546  }
22547 
22551  {
22552  auto tmp = cend();
22553  --tmp;
22554  return *tmp;
22555  }
22556 
22559  template < class IteratorType, detail::enable_if_t <
22562  IteratorType erase(IteratorType pos) // NOLINT(performance-unnecessary-value-param)
22563  {
22564  // make sure the iterator fits the current value
22565  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
22566  {
22567  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22568  }
22569 
22570  IteratorType result = end();
22571 
22572  switch (m_data.m_type)
22573  {
22574  case value_t::boolean:
22575  case value_t::number_float:
22576  case value_t::number_integer:
22577  case value_t::number_unsigned:
22578  case value_t::string:
22579  case value_t::binary:
22580  {
22581  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
22582  {
22583  JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
22584  }
22585 
22586  if (is_string())
22587  {
22588  AllocatorType<string_t> alloc;
22589  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
22590  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
22591  m_data.m_value.string = nullptr;
22592  }
22593  else if (is_binary())
22594  {
22595  AllocatorType<binary_t> alloc;
22596  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
22597  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
22598  m_data.m_value.binary = nullptr;
22599  }
22600 
22601  m_data.m_type = value_t::null;
22602  assert_invariant();
22603  break;
22604  }
22605 
22606  case value_t::object:
22607  {
22608  result.m_it.object_iterator = m_data.m_value.object->erase(pos.m_it.object_iterator);
22609  break;
22610  }
22611 
22612  case value_t::array:
22613  {
22614  result.m_it.array_iterator = m_data.m_value.array->erase(pos.m_it.array_iterator);
22615  break;
22616  }
22617 
22618  case value_t::null:
22619  case value_t::discarded:
22620  default:
22621  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
22622  }
22623 
22624  return result;
22625  }
22626 
22629  template < class IteratorType, detail::enable_if_t <
22632  IteratorType erase(IteratorType first, IteratorType last) // NOLINT(performance-unnecessary-value-param)
22633  {
22634  // make sure the iterator fits the current value
22635  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
22636  {
22637  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
22638  }
22639 
22640  IteratorType result = end();
22641 
22642  switch (m_data.m_type)
22643  {
22644  case value_t::boolean:
22645  case value_t::number_float:
22646  case value_t::number_integer:
22647  case value_t::number_unsigned:
22648  case value_t::string:
22649  case value_t::binary:
22650  {
22651  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
22652  || !last.m_it.primitive_iterator.is_end()))
22653  {
22654  JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
22655  }
22656 
22657  if (is_string())
22658  {
22659  AllocatorType<string_t> alloc;
22660  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
22661  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
22662  m_data.m_value.string = nullptr;
22663  }
22664  else if (is_binary())
22665  {
22666  AllocatorType<binary_t> alloc;
22667  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
22668  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
22669  m_data.m_value.binary = nullptr;
22670  }
22671 
22672  m_data.m_type = value_t::null;
22673  assert_invariant();
22674  break;
22675  }
22676 
22677  case value_t::object:
22678  {
22679  result.m_it.object_iterator = m_data.m_value.object->erase(first.m_it.object_iterator,
22680  last.m_it.object_iterator);
22681  break;
22682  }
22683 
22684  case value_t::array:
22685  {
22686  result.m_it.array_iterator = m_data.m_value.array->erase(first.m_it.array_iterator,
22687  last.m_it.array_iterator);
22688  break;
22689  }
22690 
22691  case value_t::null:
22692  case value_t::discarded:
22693  default:
22694  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
22695  }
22696 
22697  return result;
22698  }
22699 
22700  private:
22701  template < typename KeyType, detail::enable_if_t <
22704  {
22705  // this erase only works for objects
22706  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22707  {
22708  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
22709  }
22710 
22711  return m_data.m_value.object->erase(std::forward<KeyType>(key));
22712  }
22713 
22714  template < typename KeyType, detail::enable_if_t <
22717  {
22718  // this erase only works for objects
22719  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22720  {
22721  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
22722  }
22723 
22724  const auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
22725  if (it != m_data.m_value.object->end())
22726  {
22727  m_data.m_value.object->erase(it);
22728  return 1;
22729  }
22730  return 0;
22731  }
22732 
22733  public:
22734 
22737  size_type erase(const typename object_t::key_type& key)
22738  {
22739  // the indirection via erase_internal() is added to avoid making this
22740  // function a template and thus de-rank it during overload resolution
22741  return erase_internal(key);
22742  }
22743 
22746  template<class KeyType, detail::enable_if_t<
22748  size_type erase(KeyType && key)
22749  {
22750  return erase_internal(std::forward<KeyType>(key));
22751  }
22752 
22755  void erase(const size_type idx)
22756  {
22757  // this erase only works for arrays
22758  if (JSON_HEDLEY_LIKELY(is_array()))
22759  {
22760  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
22761  {
22762  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
22763  }
22764 
22765  m_data.m_value.array->erase(m_data.m_value.array->begin() + static_cast<difference_type>(idx));
22766  }
22767  else
22768  {
22769  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
22770  }
22771  }
22772 
22774 
22776  // lookup //
22778 
22781 
22784  iterator find(const typename object_t::key_type& key)
22785  {
22786  auto result = end();
22787 
22788  if (is_object())
22789  {
22790  result.m_it.object_iterator = m_data.m_value.object->find(key);
22791  }
22792 
22793  return result;
22794  }
22795 
22798  const_iterator find(const typename object_t::key_type& key) const
22799  {
22800  auto result = cend();
22801 
22802  if (is_object())
22803  {
22804  result.m_it.object_iterator = m_data.m_value.object->find(key);
22805  }
22806 
22807  return result;
22808  }
22809 
22812  template<class KeyType, detail::enable_if_t<
22814  iterator find(KeyType && key)
22815  {
22816  auto result = end();
22817 
22818  if (is_object())
22819  {
22820  result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
22821  }
22822 
22823  return result;
22824  }
22825 
22828  template<class KeyType, detail::enable_if_t<
22830  const_iterator find(KeyType && key) const
22831  {
22832  auto result = cend();
22833 
22834  if (is_object())
22835  {
22836  result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
22837  }
22838 
22839  return result;
22840  }
22841 
22844  size_type count(const typename object_t::key_type& key) const
22845  {
22846  // return 0 for all nonobject types
22847  return is_object() ? m_data.m_value.object->count(key) : 0;
22848  }
22849 
22852  template<class KeyType, detail::enable_if_t<
22854  size_type count(KeyType && key) const
22855  {
22856  // return 0 for all nonobject types
22857  return is_object() ? m_data.m_value.object->count(std::forward<KeyType>(key)) : 0;
22858  }
22859 
22862  bool contains(const typename object_t::key_type& key) const
22863  {
22864  return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
22865  }
22866 
22869  template<class KeyType, detail::enable_if_t<
22871  bool contains(KeyType && key) const
22872  {
22873  return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
22874  }
22875 
22878  bool contains(const json_pointer& ptr) const
22879  {
22880  return ptr.contains(this);
22881  }
22882 
22885  bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
22886  {
22887  return ptr.contains(this);
22888  }
22889 
22891 
22893  // iterators //
22895 
22898 
22901  iterator begin() noexcept
22902  {
22903  iterator result(this);
22904  result.set_begin();
22905  return result;
22906  }
22907 
22910  const_iterator begin() const noexcept
22911  {
22912  return cbegin();
22913  }
22914 
22917  const_iterator cbegin() const noexcept
22918  {
22919  const_iterator result(this);
22920  result.set_begin();
22921  return result;
22922  }
22923 
22926  iterator end() noexcept
22927  {
22928  iterator result(this);
22929  result.set_end();
22930  return result;
22931  }
22932 
22935  const_iterator end() const noexcept
22936  {
22937  return cend();
22938  }
22939 
22942  const_iterator cend() const noexcept
22943  {
22944  const_iterator result(this);
22945  result.set_end();
22946  return result;
22947  }
22948 
22951  reverse_iterator rbegin() noexcept
22952  {
22953  return reverse_iterator(end());
22954  }
22955 
22958  const_reverse_iterator rbegin() const noexcept
22959  {
22960  return crbegin();
22961  }
22962 
22965  reverse_iterator rend() noexcept
22966  {
22967  return reverse_iterator(begin());
22968  }
22969 
22972  const_reverse_iterator rend() const noexcept
22973  {
22974  return crend();
22975  }
22976 
22979  const_reverse_iterator crbegin() const noexcept
22980  {
22981  return const_reverse_iterator(cend());
22982  }
22983 
22986  const_reverse_iterator crend() const noexcept
22987  {
22988  return const_reverse_iterator(cbegin());
22989  }
22990 
22991  public:
22997  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22998  static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22999  {
23000  return ref.items();
23001  }
23002 
23008  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
23009  static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
23010  {
23011  return ref.items();
23012  }
23013 
23016  iteration_proxy<iterator> items() noexcept
23017  {
23018  return iteration_proxy<iterator>(*this);
23019  }
23020 
23023  iteration_proxy<const_iterator> items() const noexcept
23024  {
23025  return iteration_proxy<const_iterator>(*this);
23026  }
23027 
23029 
23031  // capacity //
23033 
23036 
23039  bool empty() const noexcept
23040  {
23041  switch (m_data.m_type)
23042  {
23043  case value_t::null:
23044  {
23045  // null values are empty
23046  return true;
23047  }
23048 
23049  case value_t::array:
23050  {
23051  // delegate call to array_t::empty()
23052  return m_data.m_value.array->empty();
23053  }
23054 
23055  case value_t::object:
23056  {
23057  // delegate call to object_t::empty()
23058  return m_data.m_value.object->empty();
23059  }
23060 
23061  case value_t::string:
23062  case value_t::boolean:
23063  case value_t::number_integer:
23064  case value_t::number_unsigned:
23065  case value_t::number_float:
23066  case value_t::binary:
23067  case value_t::discarded:
23068  default:
23069  {
23070  // all other types are nonempty
23071  return false;
23072  }
23073  }
23074  }
23075 
23078  size_type size() const noexcept
23079  {
23080  switch (m_data.m_type)
23081  {
23082  case value_t::null:
23083  {
23084  // null values are empty
23085  return 0;
23086  }
23087 
23088  case value_t::array:
23089  {
23090  // delegate call to array_t::size()
23091  return m_data.m_value.array->size();
23092  }
23093 
23094  case value_t::object:
23095  {
23096  // delegate call to object_t::size()
23097  return m_data.m_value.object->size();
23098  }
23099 
23100  case value_t::string:
23101  case value_t::boolean:
23102  case value_t::number_integer:
23103  case value_t::number_unsigned:
23104  case value_t::number_float:
23105  case value_t::binary:
23106  case value_t::discarded:
23107  default:
23108  {
23109  // all other types have size 1
23110  return 1;
23111  }
23112  }
23113  }
23114 
23117  size_type max_size() const noexcept
23118  {
23119  switch (m_data.m_type)
23120  {
23121  case value_t::array:
23122  {
23123  // delegate call to array_t::max_size()
23124  return m_data.m_value.array->max_size();
23125  }
23126 
23127  case value_t::object:
23128  {
23129  // delegate call to object_t::max_size()
23130  return m_data.m_value.object->max_size();
23131  }
23132 
23133  case value_t::null:
23134  case value_t::string:
23135  case value_t::boolean:
23136  case value_t::number_integer:
23137  case value_t::number_unsigned:
23138  case value_t::number_float:
23139  case value_t::binary:
23140  case value_t::discarded:
23141  default:
23142  {
23143  // all other types have max_size() == size()
23144  return size();
23145  }
23146  }
23147  }
23148 
23150 
23152  // modifiers //
23154 
23157 
23160  void clear() noexcept
23161  {
23162  switch (m_data.m_type)
23163  {
23164  case value_t::number_integer:
23165  {
23166  m_data.m_value.number_integer = 0;
23167  break;
23168  }
23169 
23170  case value_t::number_unsigned:
23171  {
23172  m_data.m_value.number_unsigned = 0;
23173  break;
23174  }
23175 
23176  case value_t::number_float:
23177  {
23178  m_data.m_value.number_float = 0.0;
23179  break;
23180  }
23181 
23182  case value_t::boolean:
23183  {
23184  m_data.m_value.boolean = false;
23185  break;
23186  }
23187 
23188  case value_t::string:
23189  {
23190  m_data.m_value.string->clear();
23191  break;
23192  }
23193 
23194  case value_t::binary:
23195  {
23196  m_data.m_value.binary->clear();
23197  break;
23198  }
23199 
23200  case value_t::array:
23201  {
23202  m_data.m_value.array->clear();
23203  break;
23204  }
23205 
23206  case value_t::object:
23207  {
23208  m_data.m_value.object->clear();
23209  break;
23210  }
23211 
23212  case value_t::null:
23213  case value_t::discarded:
23214  default:
23215  break;
23216  }
23217  }
23218 
23221  void push_back(basic_json&& val)
23222  {
23223  // push_back only works for null objects or arrays
23224  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23225  {
23226  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
23227  }
23228 
23229  // transform a null object into an array
23230  if (is_null())
23231  {
23232  m_data.m_type = value_t::array;
23233  m_data.m_value = value_t::array;
23234  assert_invariant();
23235  }
23236 
23237  // add the element to the array (move semantics)
23238  const auto old_capacity = m_data.m_value.array->capacity();
23239  m_data.m_value.array->push_back(std::move(val));
23240  set_parent(m_data.m_value.array->back(), old_capacity);
23241  // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
23242  }
23243 
23247  {
23248  push_back(std::move(val));
23249  return *this;
23250  }
23251 
23254  void push_back(const basic_json& val)
23255  {
23256  // push_back only works for null objects or arrays
23257  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23258  {
23259  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
23260  }
23261 
23262  // transform a null object into an array
23263  if (is_null())
23264  {
23265  m_data.m_type = value_t::array;
23266  m_data.m_value = value_t::array;
23267  assert_invariant();
23268  }
23269 
23270  // add the element to the array
23271  const auto old_capacity = m_data.m_value.array->capacity();
23272  m_data.m_value.array->push_back(val);
23273  set_parent(m_data.m_value.array->back(), old_capacity);
23274  }
23275 
23279  {
23280  push_back(val);
23281  return *this;
23282  }
23283 
23286  void push_back(const typename object_t::value_type& val)
23287  {
23288  // push_back only works for null objects or objects
23289  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23290  {
23291  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
23292  }
23293 
23294  // transform a null object into an object
23295  if (is_null())
23296  {
23297  m_data.m_type = value_t::object;
23298  m_data.m_value = value_t::object;
23299  assert_invariant();
23300  }
23301 
23302  // add the element to the object
23303  auto res = m_data.m_value.object->insert(val);
23304  set_parent(res.first->second);
23305  }
23306 
23309  reference operator+=(const typename object_t::value_type& val)
23310  {
23311  push_back(val);
23312  return *this;
23313  }
23314 
23318  {
23319  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
23320  {
23321  basic_json&& key = init.begin()->moved_or_copied();
23322  push_back(typename object_t::value_type(
23323  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
23324  }
23325  else
23326  {
23327  push_back(basic_json(init));
23328  }
23329  }
23330 
23334  {
23335  push_back(init);
23336  return *this;
23337  }
23338 
23341  template<class... Args>
23342  reference emplace_back(Args&& ... args)
23343  {
23344  // emplace_back only works for null objects or arrays
23345  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23346  {
23347  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
23348  }
23349 
23350  // transform a null object into an array
23351  if (is_null())
23352  {
23353  m_data.m_type = value_t::array;
23354  m_data.m_value = value_t::array;
23355  assert_invariant();
23356  }
23357 
23358  // add the element to the array (perfect forwarding)
23359  const auto old_capacity = m_data.m_value.array->capacity();
23360  m_data.m_value.array->emplace_back(std::forward<Args>(args)...);
23361  return set_parent(m_data.m_value.array->back(), old_capacity);
23362  }
23363 
23366  template<class... Args>
23367  std::pair<iterator, bool> emplace(Args&& ... args)
23368  {
23369  // emplace only works for null objects or arrays
23370  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23371  {
23372  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
23373  }
23374 
23375  // transform a null object into an object
23376  if (is_null())
23377  {
23378  m_data.m_type = value_t::object;
23379  m_data.m_value = value_t::object;
23380  assert_invariant();
23381  }
23382 
23383  // add the element to the array (perfect forwarding)
23384  auto res = m_data.m_value.object->emplace(std::forward<Args>(args)...);
23385  set_parent(res.first->second);
23386 
23387  // create a result iterator and set iterator to the result of emplace
23388  auto it = begin();
23389  it.m_it.object_iterator = res.first;
23390 
23391  // return pair of iterator and boolean
23392  return {it, res.second};
23393  }
23394 
23398  template<typename... Args>
23399  iterator insert_iterator(const_iterator pos, Args&& ... args) // NOLINT(performance-unnecessary-value-param)
23400  {
23401  iterator result(this);
23402  JSON_ASSERT(m_data.m_value.array != nullptr);
23403 
23404  auto insert_pos = std::distance(m_data.m_value.array->begin(), pos.m_it.array_iterator);
23405  m_data.m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23406  result.m_it.array_iterator = m_data.m_value.array->begin() + insert_pos;
23407 
23408  // This could have been written as:
23409  // result.m_it.array_iterator = m_data.m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23410  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23411 
23412  set_parents();
23413  return result;
23414  }
23415 
23418  iterator insert(const_iterator pos, const basic_json& val) // NOLINT(performance-unnecessary-value-param)
23419  {
23420  // insert only works for arrays
23421  if (JSON_HEDLEY_LIKELY(is_array()))
23422  {
23423  // check if iterator pos fits to this JSON value
23424  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23425  {
23426  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
23427  }
23428 
23429  // insert to array and return iterator
23430  return insert_iterator(pos, val);
23431  }
23432 
23433  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
23434  }
23435 
23438  iterator insert(const_iterator pos, basic_json&& val) // NOLINT(performance-unnecessary-value-param)
23439  {
23440  return insert(pos, val);
23441  }
23442 
23445  iterator insert(const_iterator pos, size_type cnt, const basic_json& val) // NOLINT(performance-unnecessary-value-param)
23446  {
23447  // insert only works for arrays
23448  if (JSON_HEDLEY_LIKELY(is_array()))
23449  {
23450  // check if iterator pos fits to this JSON value
23451  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23452  {
23453  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
23454  }
23455 
23456  // insert to array and return iterator
23457  return insert_iterator(pos, cnt, val);
23458  }
23459 
23460  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
23461  }
23462 
23465  iterator insert(const_iterator pos, const_iterator first, const_iterator last) // NOLINT(performance-unnecessary-value-param)
23466  {
23467  // insert only works for arrays
23468  if (JSON_HEDLEY_UNLIKELY(!is_array()))
23469  {
23470  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
23471  }
23472 
23473  // check if iterator pos fits to this JSON value
23474  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23475  {
23476  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
23477  }
23478 
23479  // check if range iterators belong to the same JSON object
23480  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23481  {
23482  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
23483  }
23484 
23485  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23486  {
23487  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
23488  }
23489 
23490  // insert to array and return iterator
23491  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23492  }
23493 
23496  iterator insert(const_iterator pos, initializer_list_t ilist) // NOLINT(performance-unnecessary-value-param)
23497  {
23498  // insert only works for arrays
23499  if (JSON_HEDLEY_UNLIKELY(!is_array()))
23500  {
23501  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
23502  }
23503 
23504  // check if iterator pos fits to this JSON value
23505  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23506  {
23507  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
23508  }
23509 
23510  // insert to array and return iterator
23511  return insert_iterator(pos, ilist.begin(), ilist.end());
23512  }
23513 
23516  void insert(const_iterator first, const_iterator last) // NOLINT(performance-unnecessary-value-param)
23517  {
23518  // insert only works for objects
23519  if (JSON_HEDLEY_UNLIKELY(!is_object()))
23520  {
23521  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
23522  }
23523 
23524  // check if range iterators belong to the same JSON object
23525  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23526  {
23527  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
23528  }
23529 
23530  // passed iterators must belong to objects
23531  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23532  {
23533  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
23534  }
23535 
23536  m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23537  set_parents();
23538  }
23539 
23542  void update(const_reference j, bool merge_objects = false)
23543  {
23544  update(j.begin(), j.end(), merge_objects);
23545  }
23546 
23549  void update(const_iterator first, const_iterator last, bool merge_objects = false) // NOLINT(performance-unnecessary-value-param)
23550  {
23551  // implicitly convert a null value to an empty object
23552  if (is_null())
23553  {
23554  m_data.m_type = value_t::object;
23555  m_data.m_value.object = create<object_t>();
23556  assert_invariant();
23557  }
23558 
23559  if (JSON_HEDLEY_UNLIKELY(!is_object()))
23560  {
23561  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
23562  }
23563 
23564  // check if range iterators belong to the same JSON object
23565  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23566  {
23567  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
23568  }
23569 
23570  // passed iterators must belong to objects
23571  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23572  {
23573  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
23574  }
23575 
23576  for (auto it = first; it != last; ++it)
23577  {
23578  if (merge_objects && it.value().is_object())
23579  {
23580  auto it2 = m_data.m_value.object->find(it.key());
23581  if (it2 != m_data.m_value.object->end())
23582  {
23583  it2->second.update(it.value(), true);
23584  continue;
23585  }
23586  }
23587  m_data.m_value.object->operator[](it.key()) = it.value();
23588 #if JSON_DIAGNOSTICS
23589  m_data.m_value.object->operator[](it.key()).m_parent = this;
23590 #endif
23591  }
23592  }
23593 
23596  void swap(reference other) noexcept (
23599  std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23601  )
23602  {
23603  std::swap(m_data.m_type, other.m_data.m_type);
23604  std::swap(m_data.m_value, other.m_data.m_value);
23605 
23606  set_parents();
23607  other.set_parents();
23608  assert_invariant();
23609  }
23610 
23613  friend void swap(reference left, reference right) noexcept (
23616  std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23618  )
23619  {
23620  left.swap(right);
23621  }
23622 
23625  void swap(array_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23626  {
23627  // swap only works for arrays
23628  if (JSON_HEDLEY_LIKELY(is_array()))
23629  {
23630  using std::swap;
23631  swap(*(m_data.m_value.array), other);
23632  }
23633  else
23634  {
23635  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
23636  }
23637  }
23638 
23641  void swap(object_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23642  {
23643  // swap only works for objects
23644  if (JSON_HEDLEY_LIKELY(is_object()))
23645  {
23646  using std::swap;
23647  swap(*(m_data.m_value.object), other);
23648  }
23649  else
23650  {
23651  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
23652  }
23653  }
23654 
23657  void swap(string_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23658  {
23659  // swap only works for strings
23660  if (JSON_HEDLEY_LIKELY(is_string()))
23661  {
23662  using std::swap;
23663  swap(*(m_data.m_value.string), other);
23664  }
23665  else
23666  {
23667  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
23668  }
23669  }
23670 
23673  void swap(binary_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23674  {
23675  // swap only works for strings
23676  if (JSON_HEDLEY_LIKELY(is_binary()))
23677  {
23678  using std::swap;
23679  swap(*(m_data.m_value.binary), other);
23680  }
23681  else
23682  {
23683  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
23684  }
23685  }
23686 
23689  void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23690  {
23691  // swap only works for strings
23692  if (JSON_HEDLEY_LIKELY(is_binary()))
23693  {
23694  using std::swap;
23695  swap(*(m_data.m_value.binary), other);
23696  }
23697  else
23698  {
23699  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
23700  }
23701  }
23702 
23704 
23706  // lexicographical comparison operators //
23708 
23711 
23712  // note parentheses around operands are necessary; see
23713  // https://github.com/nlohmann/json/issues/1530
23714 #define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
23715  const auto lhs_type = lhs.type(); \
23716  const auto rhs_type = rhs.type(); \
23717  \
23718  if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
23719  { \
23720  switch (lhs_type) \
23721  { \
23722  case value_t::array: \
23723  return (*lhs.m_data.m_value.array) op (*rhs.m_data.m_value.array); \
23724  \
23725  case value_t::object: \
23726  return (*lhs.m_data.m_value.object) op (*rhs.m_data.m_value.object); \
23727  \
23728  case value_t::null: \
23729  return (null_result); \
23730  \
23731  case value_t::string: \
23732  return (*lhs.m_data.m_value.string) op (*rhs.m_data.m_value.string); \
23733  \
23734  case value_t::boolean: \
23735  return (lhs.m_data.m_value.boolean) op (rhs.m_data.m_value.boolean); \
23736  \
23737  case value_t::number_integer: \
23738  return (lhs.m_data.m_value.number_integer) op (rhs.m_data.m_value.number_integer); \
23739  \
23740  case value_t::number_unsigned: \
23741  return (lhs.m_data.m_value.number_unsigned) op (rhs.m_data.m_value.number_unsigned); \
23742  \
23743  case value_t::number_float: \
23744  return (lhs.m_data.m_value.number_float) op (rhs.m_data.m_value.number_float); \
23745  \
23746  case value_t::binary: \
23747  return (*lhs.m_data.m_value.binary) op (*rhs.m_data.m_value.binary); \
23748  \
23749  case value_t::discarded: \
23750  default: \
23751  return (unordered_result); \
23752  } \
23753  } \
23754  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
23755  { \
23756  return static_cast<number_float_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_float; \
23757  } \
23758  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
23759  { \
23760  return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_integer); \
23761  } \
23762  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
23763  { \
23764  return static_cast<number_float_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_float; \
23765  } \
23766  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
23767  { \
23768  return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_unsigned); \
23769  } \
23770  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
23771  { \
23772  return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \
23773  } \
23774  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
23775  { \
23776  return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \
23777  } \
23778  else if(compares_unordered(lhs, rhs))\
23779  {\
23780  return (unordered_result);\
23781  }\
23782  \
23783  return (default_result);
23784 
23786  // returns true if:
23787  // - any operand is NaN and the other operand is of number type
23788  // - any operand is discarded
23789  // in legacy mode, discarded values are considered ordered if
23790  // an operation is computed as an odd number of inverses of others
23791  static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
23792  {
23793  if ((lhs.is_number_float() && std::isnan(lhs.m_data.m_value.number_float) && rhs.is_number())
23794  || (rhs.is_number_float() && std::isnan(rhs.m_data.m_value.number_float) && lhs.is_number()))
23795  {
23796  return true;
23797  }
23798 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
23799  return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
23800 #else
23801  static_cast<void>(inverse);
23802  return lhs.is_discarded() || rhs.is_discarded();
23803 #endif
23804  }
23805 
23806  private:
23807  bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
23808  {
23809  return compares_unordered(*this, rhs, inverse);
23810  }
23811 
23812  public:
23813 #if JSON_HAS_THREE_WAY_COMPARISON
23816  bool operator==(const_reference rhs) const noexcept
23817  {
23818 #ifdef __GNUC__
23819 #pragma GCC diagnostic push
23820 #pragma GCC diagnostic ignored "-Wfloat-equal"
23821 #endif
23822  const_reference lhs = *this;
23823  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
23824 #ifdef __GNUC__
23825 #pragma GCC diagnostic pop
23826 #endif
23827  }
23828 
23831  template<typename ScalarType>
23832  requires std::is_scalar_v<ScalarType>
23833  bool operator==(ScalarType rhs) const noexcept
23834  {
23835  return *this == basic_json(rhs);
23836  }
23837 
23840  bool operator!=(const_reference rhs) const noexcept
23841  {
23842  if (compares_unordered(rhs, true))
23843  {
23844  return false;
23845  }
23846  return !operator==(rhs);
23847  }
23848 
23851  std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
23852  {
23853  const_reference lhs = *this;
23854  // default_result is used if we cannot compare values. In that case,
23855  // we compare types.
23856  JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD*
23857  std::partial_ordering::equivalent,
23858  std::partial_ordering::unordered,
23859  lhs_type <=> rhs_type) // *NOPAD*
23860  }
23861 
23864  template<typename ScalarType>
23865  requires std::is_scalar_v<ScalarType>
23866  std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
23867  {
23868  return *this <=> basic_json(rhs); // *NOPAD*
23869  }
23870 
23871 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
23872  // all operators that are computed as an odd number of inverses of others
23873  // need to be overloaded to emulate the legacy comparison behavior
23874 
23878  bool operator<=(const_reference rhs) const noexcept
23879  {
23880  if (compares_unordered(rhs, true))
23881  {
23882  return false;
23883  }
23884  return !(rhs < *this);
23885  }
23886 
23889  template<typename ScalarType>
23890  requires std::is_scalar_v<ScalarType>
23891  bool operator<=(ScalarType rhs) const noexcept
23892  {
23893  return *this <= basic_json(rhs);
23894  }
23895 
23899  bool operator>=(const_reference rhs) const noexcept
23900  {
23901  if (compares_unordered(rhs, true))
23902  {
23903  return false;
23904  }
23905  return !(*this < rhs);
23906  }
23907 
23910  template<typename ScalarType>
23911  requires std::is_scalar_v<ScalarType>
23912  bool operator>=(ScalarType rhs) const noexcept
23913  {
23914  return *this >= basic_json(rhs);
23915  }
23916 #endif
23917 #else
23920  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23921  {
23922 #ifdef __GNUC__
23923 #pragma GCC diagnostic push
23924 #pragma GCC diagnostic ignored "-Wfloat-equal"
23925 #endif
23926  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
23927 #ifdef __GNUC__
23928 #pragma GCC diagnostic pop
23929 #endif
23930  }
23931 
23934  template<typename ScalarType, typename std::enable_if<
23936  friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23937  {
23938  return lhs == basic_json(rhs);
23939  }
23940 
23943  template<typename ScalarType, typename std::enable_if<
23945  friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23946  {
23947  return basic_json(lhs) == rhs;
23948  }
23949 
23952  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23953  {
23954  if (compares_unordered(lhs, rhs, true))
23955  {
23956  return false;
23957  }
23958  return !(lhs == rhs);
23959  }
23960 
23963  template<typename ScalarType, typename std::enable_if<
23965  friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23966  {
23967  return lhs != basic_json(rhs);
23968  }
23969 
23972  template<typename ScalarType, typename std::enable_if<
23974  friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23975  {
23976  return basic_json(lhs) != rhs;
23977  }
23978 
23981  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23982  {
23983  // default_result is used if we cannot compare values. In that case,
23984  // we compare types. Note we have to call the operator explicitly,
23985  // because MSVC has problems otherwise.
23986  JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))
23987  }
23988 
23991  template<typename ScalarType, typename std::enable_if<
23993  friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23994  {
23995  return lhs < basic_json(rhs);
23996  }
23997 
24000  template<typename ScalarType, typename std::enable_if<
24002  friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
24003  {
24004  return basic_json(lhs) < rhs;
24005  }
24006 
24009  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
24010  {
24011  if (compares_unordered(lhs, rhs, true))
24012  {
24013  return false;
24014  }
24015  return !(rhs < lhs);
24016  }
24017 
24020  template<typename ScalarType, typename std::enable_if<
24022  friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24023  {
24024  return lhs <= basic_json(rhs);
24025  }
24026 
24029  template<typename ScalarType, typename std::enable_if<
24031  friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24032  {
24033  return basic_json(lhs) <= rhs;
24034  }
24035 
24038  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24039  {
24040  // double inverse
24041  if (compares_unordered(lhs, rhs))
24042  {
24043  return false;
24044  }
24045  return !(lhs <= rhs);
24046  }
24047 
24050  template<typename ScalarType, typename std::enable_if<
24052  friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24053  {
24054  return lhs > basic_json(rhs);
24055  }
24056 
24059  template<typename ScalarType, typename std::enable_if<
24061  friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24062  {
24063  return basic_json(lhs) > rhs;
24064  }
24065 
24068  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24069  {
24070  if (compares_unordered(lhs, rhs, true))
24071  {
24072  return false;
24073  }
24074  return !(lhs < rhs);
24075  }
24076 
24079  template<typename ScalarType, typename std::enable_if<
24081  friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24082  {
24083  return lhs >= basic_json(rhs);
24084  }
24085 
24088  template<typename ScalarType, typename std::enable_if<
24090  friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24091  {
24092  return basic_json(lhs) >= rhs;
24093  }
24094 #endif
24095 
24096 #undef JSON_IMPLEMENT_OPERATOR
24097 
24099 
24101  // serialization //
24103 
24106 #ifndef JSON_NO_IO
24109  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24110  {
24111  // read width member and use it as the indentation parameter if nonzero
24112  const bool pretty_print = o.width() > 0;
24113  const auto indentation = pretty_print ? o.width() : 0;
24114 
24115  // reset width to 0 for subsequent calls to this stream
24116  o.width(0);
24117 
24118  // do the actual serialization
24119  serializer s(detail::output_adapter<char>(o), o.fill());
24120  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24121  return o;
24122  }
24123 
24130  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
24131  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24132  {
24133  return o << j;
24134  }
24135 #endif // JSON_NO_IO
24137 
24139  // deserialization //
24141 
24144 
24147  template<typename InputType>
24149  static basic_json parse(InputType&& i,
24150  parser_callback_t cb = nullptr,
24151  const bool allow_exceptions = true,
24152  const bool ignore_comments = false,
24153  const bool ignore_trailing_commas = false)
24154  {
24155  basic_json result;
24156  parser(detail::input_adapter(std::forward<InputType>(i)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(true, result); // cppcheck-suppress[accessMoved,accessForwarded]
24157  return result;
24158  }
24159 
24162  template<typename IteratorType>
24164  static basic_json parse(IteratorType first,
24165  IteratorType last,
24166  parser_callback_t cb = nullptr,
24167  const bool allow_exceptions = true,
24168  const bool ignore_comments = false,
24169  const bool ignore_trailing_commas = false)
24170  {
24171  basic_json result;
24172  parser(detail::input_adapter(std::move(first), std::move(last)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(true, result); // cppcheck-suppress[accessMoved]
24173  return result;
24174  }
24175 
24177  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
24178  static basic_json parse(detail::span_input_adapter&& i,
24179  parser_callback_t cb = nullptr,
24180  const bool allow_exceptions = true,
24181  const bool ignore_comments = false,
24182  const bool ignore_trailing_commas = false)
24183  {
24184  basic_json result;
24185  parser(i.get(), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(true, result); // cppcheck-suppress[accessMoved]
24186  return result;
24187  }
24188 
24191  template<typename InputType>
24192  static bool accept(InputType&& i,
24193  const bool ignore_comments = false,
24194  const bool ignore_trailing_commas = false)
24195  {
24196  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments, ignore_trailing_commas).accept(true);
24197  }
24198 
24201  template<typename IteratorType>
24202  static bool accept(IteratorType first, IteratorType last,
24203  const bool ignore_comments = false,
24204  const bool ignore_trailing_commas = false)
24205  {
24206  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments, ignore_trailing_commas).accept(true);
24207  }
24208 
24210  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
24211  static bool accept(detail::span_input_adapter&& i,
24212  const bool ignore_comments = false,
24213  const bool ignore_trailing_commas = false)
24214  {
24215  return parser(i.get(), nullptr, false, ignore_comments, ignore_trailing_commas).accept(true);
24216  }
24217 
24220  template <typename InputType, typename SAX>
24222  static bool sax_parse(InputType&& i, SAX* sax,
24224  const bool strict = true,
24225  const bool ignore_comments = false,
24226  const bool ignore_trailing_commas = false)
24227  {
24228  auto ia = detail::input_adapter(std::forward<InputType>(i));
24229  return format == input_format_t::json
24230  ? parser(std::move(ia), nullptr, true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict)
24231  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
24232  }
24233 
24236  template<class IteratorType, class SAX>
24238  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24240  const bool strict = true,
24241  const bool ignore_comments = false,
24242  const bool ignore_trailing_commas = false)
24243  {
24244  auto ia = detail::input_adapter(std::move(first), std::move(last));
24245  return format == input_format_t::json
24246  ? parser(std::move(ia), nullptr, true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict)
24247  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
24248  }
24249 
24255  template <typename SAX>
24256  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24258  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24260  const bool strict = true,
24261  const bool ignore_comments = false,
24262  const bool ignore_trailing_commas = false)
24263  {
24264  auto ia = i.get();
24265  return format == input_format_t::json
24266  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24267  ? parser(std::move(ia), nullptr, true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict)
24268  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24269  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
24270  }
24271 #ifndef JSON_NO_IO
24278  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24279  friend std::istream& operator<<(basic_json& j, std::istream& i)
24280  {
24281  return operator>>(i, j);
24282  }
24283 
24286  friend std::istream& operator>>(std::istream& i, basic_json& j)
24287  {
24288  parser(detail::input_adapter(i)).parse(false, j);
24289  return i;
24290  }
24291 #endif // JSON_NO_IO
24293 
24295  // convenience functions //
24297 
24301  const char* type_name() const noexcept
24302  {
24303  switch (m_data.m_type)
24304  {
24305  case value_t::null:
24306  return "null";
24307  case value_t::object:
24308  return "object";
24309  case value_t::array:
24310  return "array";
24311  case value_t::string:
24312  return "string";
24313  case value_t::boolean:
24314  return "boolean";
24315  case value_t::binary:
24316  return "binary";
24317  case value_t::discarded:
24318  return "discarded";
24319  case value_t::number_integer:
24320  case value_t::number_unsigned:
24321  case value_t::number_float:
24322  return "number";
24323  default:
24324  return "invalid";
24325  }
24326  }
24327 
24330  // member variables //
24332 
24333  struct data
24334  {
24336  value_t m_type = value_t::null;
24337 
24339  json_value m_value = {};
24340 
24341  data(const value_t v)
24342  : m_type(v), m_value(v)
24343  {
24344  }
24345 
24346  data(size_type cnt, const basic_json& val)
24347  : m_type(value_t::array)
24348  {
24349  m_value.array = create<array_t>(cnt, val);
24350  }
24351 
24352  data() noexcept = default;
24353  data(data&&) noexcept = default;
24354  data(const data&) noexcept = delete;
24355  data& operator=(data&&) noexcept = delete;
24356  data& operator=(const data&) noexcept = delete;
24357 
24358  ~data() noexcept
24359  {
24360  m_value.destroy(m_type);
24361  }
24362  };
24363 
24364  data m_data = {};
24365 
24366 #if JSON_DIAGNOSTICS
24368  basic_json* m_parent = nullptr;
24369 #endif
24370 
24371 #if JSON_DIAGNOSTIC_POSITIONS
24373  std::size_t start_position = std::string::npos;
24375  std::size_t end_position = std::string::npos;
24376  public:
24377  constexpr std::size_t start_pos() const noexcept
24378  {
24379  return start_position;
24380  }
24381 
24382  constexpr std::size_t end_pos() const noexcept
24383  {
24384  return end_position;
24385  }
24386 #endif
24387 
24389  // binary serialization/deserialization //
24391 
24394 
24395  public:
24398  static std::vector<std::uint8_t> to_cbor(const basic_json& j)
24399  {
24400  std::vector<std::uint8_t> result;
24401  to_cbor(j, result);
24402  return result;
24403  }
24404 
24408  {
24410  }
24411 
24415  {
24417  }
24418 
24421  static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
24422  {
24423  std::vector<std::uint8_t> result;
24424  to_msgpack(j, result);
24425  return result;
24426  }
24427 
24431  {
24433  }
24434 
24438  {
24440  }
24441 
24444  static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
24445  const bool use_size = false,
24446  const bool use_type = false)
24447  {
24448  std::vector<std::uint8_t> result;
24449  to_ubjson(j, result, use_size, use_type);
24450  return result;
24451  }
24452 
24456  const bool use_size = false, const bool use_type = false)
24457  {
24458  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
24459  }
24460 
24464  const bool use_size = false, const bool use_type = false)
24465  {
24466  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
24467  }
24468 
24471  static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
24472  const bool use_size = false,
24473  const bool use_type = false,
24474  const bjdata_version_t version = bjdata_version_t::draft2)
24475  {
24476  std::vector<std::uint8_t> result;
24477  to_bjdata(j, result, use_size, use_type, version);
24478  return result;
24479  }
24480 
24484  const bool use_size = false, const bool use_type = false,
24485  const bjdata_version_t version = bjdata_version_t::draft2)
24486  {
24487  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true, version);
24488  }
24489 
24493  const bool use_size = false, const bool use_type = false,
24494  const bjdata_version_t version = bjdata_version_t::draft2)
24495  {
24496  binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true, version);
24497  }
24498 
24501  static std::vector<std::uint8_t> to_bson(const basic_json& j)
24502  {
24503  std::vector<std::uint8_t> result;
24504  to_bson(j, result);
24505  return result;
24506  }
24507 
24511  {
24513  }
24514 
24518  {
24520  }
24521 
24524  template<typename InputType>
24526  static basic_json from_cbor(InputType&& i,
24527  const bool strict = true,
24528  const bool allow_exceptions = true,
24529  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24530  {
24531  basic_json result;
24532  auto ia = detail::input_adapter(std::forward<InputType>(i));
24533  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24534  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); // cppcheck-suppress[accessMoved]
24535  return res ? result : basic_json(value_t::discarded);
24536  }
24537 
24540  template<typename IteratorType>
24542  static basic_json from_cbor(IteratorType first, IteratorType last,
24543  const bool strict = true,
24544  const bool allow_exceptions = true,
24545  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24546  {
24547  basic_json result;
24548  auto ia = detail::input_adapter(std::move(first), std::move(last));
24549  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24550  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); // cppcheck-suppress[accessMoved]
24551  return res ? result : basic_json(value_t::discarded);
24552  }
24553 
24554  template<typename T>
24556  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24557  static basic_json from_cbor(const T* ptr, std::size_t len,
24558  const bool strict = true,
24559  const bool allow_exceptions = true,
24560  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24561  {
24562  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
24563  }
24564 
24566  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24567  static basic_json from_cbor(detail::span_input_adapter&& i,
24568  const bool strict = true,
24569  const bool allow_exceptions = true,
24570  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24571  {
24572  basic_json result;
24573  auto ia = i.get();
24574  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24575  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24576  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); // cppcheck-suppress[accessMoved]
24577  return res ? result : basic_json(value_t::discarded);
24578  }
24579 
24582  template<typename InputType>
24584  static basic_json from_msgpack(InputType&& i,
24585  const bool strict = true,
24586  const bool allow_exceptions = true)
24587  {
24588  basic_json result;
24589  auto ia = detail::input_adapter(std::forward<InputType>(i));
24590  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24591  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); // cppcheck-suppress[accessMoved]
24592  return res ? result : basic_json(value_t::discarded);
24593  }
24594 
24597  template<typename IteratorType>
24599  static basic_json from_msgpack(IteratorType first, IteratorType last,
24600  const bool strict = true,
24601  const bool allow_exceptions = true)
24602  {
24603  basic_json result;
24604  auto ia = detail::input_adapter(std::move(first), std::move(last));
24605  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24606  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); // cppcheck-suppress[accessMoved]
24607  return res ? result : basic_json(value_t::discarded);
24608  }
24609 
24610  template<typename T>
24612  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24613  static basic_json from_msgpack(const T* ptr, std::size_t len,
24614  const bool strict = true,
24615  const bool allow_exceptions = true)
24616  {
24617  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24618  }
24619 
24621  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24622  static basic_json from_msgpack(detail::span_input_adapter&& i,
24623  const bool strict = true,
24624  const bool allow_exceptions = true)
24625  {
24626  basic_json result;
24627  auto ia = i.get();
24628  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24629  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24630  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); // cppcheck-suppress[accessMoved]
24631  return res ? result : basic_json(value_t::discarded);
24632  }
24633 
24636  template<typename InputType>
24638  static basic_json from_ubjson(InputType&& i,
24639  const bool strict = true,
24640  const bool allow_exceptions = true)
24641  {
24642  basic_json result;
24643  auto ia = detail::input_adapter(std::forward<InputType>(i));
24644  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24645  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); // cppcheck-suppress[accessMoved]
24646  return res ? result : basic_json(value_t::discarded);
24647  }
24648 
24651  template<typename IteratorType>
24653  static basic_json from_ubjson(IteratorType first, IteratorType last,
24654  const bool strict = true,
24655  const bool allow_exceptions = true)
24656  {
24657  basic_json result;
24658  auto ia = detail::input_adapter(std::move(first), std::move(last));
24659  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24660  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); // cppcheck-suppress[accessMoved]
24661  return res ? result : basic_json(value_t::discarded);
24662  }
24663 
24664  template<typename T>
24666  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24667  static basic_json from_ubjson(const T* ptr, std::size_t len,
24668  const bool strict = true,
24669  const bool allow_exceptions = true)
24670  {
24671  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24672  }
24673 
24675  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24676  static basic_json from_ubjson(detail::span_input_adapter&& i,
24677  const bool strict = true,
24678  const bool allow_exceptions = true)
24679  {
24680  basic_json result;
24681  auto ia = i.get();
24682  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24683  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24684  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); // cppcheck-suppress[accessMoved]
24685  return res ? result : basic_json(value_t::discarded);
24686  }
24687 
24690  template<typename InputType>
24692  static basic_json from_bjdata(InputType&& i,
24693  const bool strict = true,
24694  const bool allow_exceptions = true)
24695  {
24696  basic_json result;
24697  auto ia = detail::input_adapter(std::forward<InputType>(i));
24698  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24699  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); // cppcheck-suppress[accessMoved]
24700  return res ? result : basic_json(value_t::discarded);
24701  }
24702 
24705  template<typename IteratorType>
24707  static basic_json from_bjdata(IteratorType first, IteratorType last,
24708  const bool strict = true,
24709  const bool allow_exceptions = true)
24710  {
24711  basic_json result;
24712  auto ia = detail::input_adapter(std::move(first), std::move(last));
24713  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24714  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); // cppcheck-suppress[accessMoved]
24715  return res ? result : basic_json(value_t::discarded);
24716  }
24717 
24720  template<typename InputType>
24722  static basic_json from_bson(InputType&& i,
24723  const bool strict = true,
24724  const bool allow_exceptions = true)
24725  {
24726  basic_json result;
24727  auto ia = detail::input_adapter(std::forward<InputType>(i));
24728  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24729  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); // cppcheck-suppress[accessMoved]
24730  return res ? result : basic_json(value_t::discarded);
24731  }
24732 
24735  template<typename IteratorType>
24737  static basic_json from_bson(IteratorType first, IteratorType last,
24738  const bool strict = true,
24739  const bool allow_exceptions = true)
24740  {
24741  basic_json result;
24742  auto ia = detail::input_adapter(std::move(first), std::move(last));
24743  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24744  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); // cppcheck-suppress[accessMoved]
24745  return res ? result : basic_json(value_t::discarded);
24746  }
24747 
24748  template<typename T>
24750  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24751  static basic_json from_bson(const T* ptr, std::size_t len,
24752  const bool strict = true,
24753  const bool allow_exceptions = true)
24754  {
24755  return from_bson(ptr, ptr + len, strict, allow_exceptions);
24756  }
24757 
24759  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24760  static basic_json from_bson(detail::span_input_adapter&& i,
24761  const bool strict = true,
24762  const bool allow_exceptions = true)
24763  {
24764  basic_json result;
24765  auto ia = i.get();
24766  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24767  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24768  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); // cppcheck-suppress[accessMoved]
24769  return res ? result : basic_json(value_t::discarded);
24770  }
24772 
24774  // JSON Pointer support //
24776 
24779 
24783  {
24784  return ptr.get_unchecked(this);
24785  }
24786 
24789  reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
24790  {
24791  return ptr.get_unchecked(this);
24792  }
24793 
24797  {
24798  return ptr.get_unchecked(this);
24799  }
24800 
24803  const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
24804  {
24805  return ptr.get_unchecked(this);
24806  }
24807 
24810  reference at(const json_pointer& ptr)
24811  {
24812  return ptr.get_checked(this);
24813  }
24814 
24817  reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
24818  {
24819  return ptr.get_checked(this);
24820  }
24821 
24824  const_reference at(const json_pointer& ptr) const
24825  {
24826  return ptr.get_checked(this);
24827  }
24828 
24831  const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
24832  {
24833  return ptr.get_checked(this);
24834  }
24835 
24838  basic_json flatten() const
24839  {
24840  basic_json result(value_t::object);
24841  json_pointer::flatten("", *this, result);
24842  return result;
24843  }
24844 
24847  basic_json unflatten() const
24848  {
24849  return json_pointer::unflatten(*this);
24850  }
24851 
24853 
24855  // JSON Patch functions //
24857 
24860 
24863  void patch_inplace(const basic_json& json_patch)
24864  {
24865  basic_json& result = *this;
24866  // the valid JSON Patch operations
24867  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24868 
24869  const auto get_op = [](const string_t& op)
24870  {
24871  if (op == "add")
24872  {
24873  return patch_operations::add;
24874  }
24875  if (op == "remove")
24876  {
24877  return patch_operations::remove;
24878  }
24879  if (op == "replace")
24880  {
24881  return patch_operations::replace;
24882  }
24883  if (op == "move")
24884  {
24885  return patch_operations::move;
24886  }
24887  if (op == "copy")
24888  {
24889  return patch_operations::copy;
24890  }
24891  if (op == "test")
24892  {
24893  return patch_operations::test;
24894  }
24895 
24896  return patch_operations::invalid;
24897  };
24898 
24899  // wrapper for "add" operation; add value at ptr
24900  const auto operation_add = [&result](json_pointer & ptr, const basic_json & val)
24901  {
24902  // adding to the root of the target document means replacing it
24903  if (ptr.empty())
24904  {
24905  result = val;
24906  return;
24907  }
24908 
24909  // make sure the top element of the pointer exists
24910  json_pointer const top_pointer = ptr.top();
24911  if (top_pointer != ptr)
24912  {
24913  result.at(top_pointer);
24914  }
24915 
24916  // get reference to the parent of the JSON pointer ptr
24917  const auto last_path = ptr.back();
24918  ptr.pop_back();
24919  // parent must exist when performing patch add per RFC6902 specs
24920  basic_json& parent = result.at(ptr);
24921 
24922  switch (parent.m_data.m_type)
24923  {
24924  case value_t::null:
24925  case value_t::object:
24926  {
24927  // use operator[] to add value
24928  parent[last_path] = val;
24929  break;
24930  }
24931 
24932  case value_t::array:
24933  {
24934  if (last_path == "-")
24935  {
24936  // special case: append to back
24937  parent.push_back(val);
24938  }
24939  else
24940  {
24941  const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
24942  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24943  {
24944  // avoid undefined behavior
24945  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
24946  }
24947 
24948  // default case: insert add offset
24949  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24950  }
24951  break;
24952  }
24953 
24954  // if there exists a parent, it cannot be primitive
24955  case value_t::string: // LCOV_EXCL_LINE
24956  case value_t::boolean: // LCOV_EXCL_LINE
24957  case value_t::number_integer: // LCOV_EXCL_LINE
24958  case value_t::number_unsigned: // LCOV_EXCL_LINE
24959  case value_t::number_float: // LCOV_EXCL_LINE
24960  case value_t::binary: // LCOV_EXCL_LINE
24961  case value_t::discarded: // LCOV_EXCL_LINE
24962  default: // LCOV_EXCL_LINE
24963  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
24964  }
24965  };
24966 
24967  // wrapper for "remove" operation; remove value at ptr
24968  const auto operation_remove = [this, & result](json_pointer & ptr)
24969  {
24970  // get reference to the parent of the JSON pointer ptr
24971  const auto last_path = ptr.back();
24972  ptr.pop_back();
24973  basic_json& parent = result.at(ptr);
24974 
24975  // remove child
24976  if (parent.is_object())
24977  {
24978  // perform range check
24979  auto it = parent.find(last_path);
24980  if (JSON_HEDLEY_LIKELY(it != parent.end()))
24981  {
24982  parent.erase(it);
24983  }
24984  else
24985  {
24986  JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
24987  }
24988  }
24989  else if (parent.is_array())
24990  {
24991  // note erase performs range check
24992  parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
24993  }
24994  };
24995 
24996  // type check: top level value must be an array
24997  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24998  {
24999  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
25000  }
25001 
25002  // iterate and apply the operations
25003  for (const auto& val : json_patch)
25004  {
25005  // wrapper to get a value for an operation
25006  const auto get_value = [&val](const string_t& op,
25007  const string_t& member,
25008  bool string_type) -> basic_json &
25009  {
25010  // find value
25011  auto it = val.m_data.m_value.object->find(member);
25012 
25013  // context-sensitive error message
25014  const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\''); // NOLINT(bugprone-unused-local-non-trivial-variable)
25015 
25016  // check if the desired value is present
25017  if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))
25018  {
25019  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25020  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
25021  }
25022 
25023  // check if the result is of type string
25024  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
25025  {
25026  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25027  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
25028  }
25029 
25030  // no error: return value
25031  return it->second;
25032  };
25033 
25034  // type check: every element of the array must be an object
25035  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
25036  {
25037  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
25038  }
25039 
25040  // collect mandatory members
25041  const auto op = get_value("op", "op", true).template get<string_t>();
25042  const auto path = get_value(op, "path", true).template get<string_t>();
25043  json_pointer ptr(path);
25044 
25045  switch (get_op(op))
25046  {
25047  case patch_operations::add:
25048  {
25049  operation_add(ptr, get_value("add", "value", false));
25050  break;
25051  }
25052 
25053  case patch_operations::remove:
25054  {
25055  operation_remove(ptr);
25056  break;
25057  }
25058 
25059  case patch_operations::replace:
25060  {
25061  // the "path" location must exist - use at()
25062  result.at(ptr) = get_value("replace", "value", false);
25063  break;
25064  }
25065 
25066  case patch_operations::move:
25067  {
25068  const auto from_path = get_value("move", "from", true).template get<string_t>();
25069  json_pointer from_ptr(from_path);
25070 
25071  // the "from" location must exist - use at()
25072  basic_json const v = result.at(from_ptr);
25073 
25074  // The move operation is functionally identical to a
25075  // "remove" operation on the "from" location, followed
25076  // immediately by an "add" operation at the target
25077  // location with the value that was just removed.
25078  operation_remove(from_ptr);
25079  operation_add(ptr, v);
25080  break;
25081  }
25082 
25083  case patch_operations::copy:
25084  {
25085  const auto from_path = get_value("copy", "from", true).template get<string_t>();
25086  const json_pointer from_ptr(from_path);
25087 
25088  // the "from" location must exist - use at()
25089  basic_json const v = result.at(from_ptr);
25090 
25091  // The copy is functionally identical to an "add"
25092  // operation at the target location using the value
25093  // specified in the "from" member.
25094  operation_add(ptr, v);
25095  break;
25096  }
25097 
25098  case patch_operations::test:
25099  {
25100  bool success = false;
25101  JSON_TRY
25102  {
25103  // check if "value" matches the one at "path"
25104  // the "path" location must exist - use at()
25105  success = (result.at(ptr) == get_value("test", "value", false));
25106  }
25107  JSON_INTERNAL_CATCH (out_of_range&)
25108  {
25109  // ignore out of range errors: success remains false
25110  }
25111 
25112  // throw an exception if the test fails
25113  if (JSON_HEDLEY_UNLIKELY(!success))
25114  {
25115  JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
25116  }
25117 
25118  break;
25119  }
25120 
25121  case patch_operations::invalid:
25122  default:
25123  {
25124  // op must be "add", "remove", "replace", "move", "copy", or
25125  // "test"
25126  JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
25127  }
25128  }
25129  }
25130  }
25131 
25134  basic_json patch(const basic_json& json_patch) const
25135  {
25136  basic_json result = *this;
25137  result.patch_inplace(json_patch);
25138  return result;
25139  }
25140 
25144  static basic_json diff(const basic_json& source, const basic_json& target,
25145  const string_t& path = "")
25146  {
25147  // the patch
25148  basic_json result(value_t::array);
25149 
25150  // if the values are the same, return an empty patch
25151  if (source == target)
25152  {
25153  return result;
25154  }
25155 
25156  if (source.type() != target.type())
25157  {
25158  // different types: replace value
25159  result.push_back(
25160  {
25161  {"op", "replace"}, {"path", path}, {"value", target}
25162  });
25163  return result;
25164  }
25165 
25166  switch (source.type())
25167  {
25168  case value_t::array:
25169  {
25170  // first pass: traverse common elements
25171  std::size_t i = 0;
25172  while (i < source.size() && i < target.size())
25173  {
25174  // recursive call to compare array values at index i
25175  auto temp_diff = diff(source[i], target[i], detail::concat<string_t>(path, '/', detail::to_string<string_t>(i)));
25176  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25177  ++i;
25178  }
25179 
25180  // We now reached the end of at least one array
25181  // in a second pass, traverse the remaining elements
25182 
25183  // remove my remaining elements
25184  const auto end_index = static_cast<difference_type>(result.size());
25185  while (i < source.size())
25186  {
25187  // add operations in reverse order to avoid invalid
25188  // indices
25189  result.insert(result.begin() + end_index, object(
25190  {
25191  {"op", "remove"},
25192  {"path", detail::concat<string_t>(path, '/', detail::to_string<string_t>(i))}
25193  }));
25194  ++i;
25195  }
25196 
25197  // add other remaining elements
25198  while (i < target.size())
25199  {
25200  result.push_back(
25201  {
25202  {"op", "add"},
25203  {"path", detail::concat<string_t>(path, "/-")},
25204  {"value", target[i]}
25205  });
25206  ++i;
25207  }
25208 
25209  break;
25210  }
25211 
25212  case value_t::object:
25213  {
25214  // first pass: traverse this object's elements
25215  for (auto it = source.cbegin(); it != source.cend(); ++it)
25216  {
25217  // escape the key name to be used in a JSON patch
25218  const auto path_key = detail::concat<string_t>(path, '/', detail::escape(it.key()));
25219 
25220  if (target.find(it.key()) != target.end())
25221  {
25222  // recursive call to compare object values at key it
25223  auto temp_diff = diff(it.value(), target[it.key()], path_key);
25224  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25225  }
25226  else
25227  {
25228  // found a key that is not in o -> remove it
25229  result.push_back(object(
25230  {
25231  {"op", "remove"}, {"path", path_key}
25232  }));
25233  }
25234  }
25235 
25236  // second pass: traverse other object's elements
25237  for (auto it = target.cbegin(); it != target.cend(); ++it)
25238  {
25239  if (source.find(it.key()) == source.end())
25240  {
25241  // found a key that is not in this -> add it
25242  const auto path_key = detail::concat<string_t>(path, '/', detail::escape(it.key()));
25243  result.push_back(
25244  {
25245  {"op", "add"}, {"path", path_key},
25246  {"value", it.value()}
25247  });
25248  }
25249  }
25250 
25251  break;
25252  }
25253 
25254  case value_t::null:
25255  case value_t::string:
25256  case value_t::boolean:
25257  case value_t::number_integer:
25258  case value_t::number_unsigned:
25259  case value_t::number_float:
25260  case value_t::binary:
25261  case value_t::discarded:
25262  default:
25263  {
25264  // both primitive types: replace value
25265  result.push_back(
25266  {
25267  {"op", "replace"}, {"path", path}, {"value", target}
25268  });
25269  break;
25270  }
25271  }
25272 
25273  return result;
25274  }
25276 
25278  // JSON Merge Patch functions //
25280 
25283 
25286  void merge_patch(const basic_json& apply_patch)
25287  {
25288  if (apply_patch.is_object())
25289  {
25290  if (!is_object())
25291  {
25292  *this = object();
25293  }
25294  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25295  {
25296  if (it.value().is_null())
25297  {
25298  erase(it.key());
25299  }
25300  else
25301  {
25302  operator[](it.key()).merge_patch(it.value());
25303  }
25304  }
25305  }
25306  else
25307  {
25308  *this = apply_patch;
25309  }
25310  }
25311 
25313 };
25314 
25318 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25319 {
25320  return j.dump();
25321 }
25322 
25323 inline namespace literals
25324 {
25325 inline namespace json_literals
25326 {
25327 
25331 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
25332  inline nlohmann::json operator ""_json(const char* s, std::size_t n)
25333 #else
25334  inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25335 #endif
25336 {
25337  return nlohmann::json::parse(s, s + n);
25338 }
25339 
25343 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
25344  inline nlohmann::json::json_pointer operator ""_json_pointer(const char* s, std::size_t n)
25345 #else
25346  inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25347 #endif
25348 {
25349  return nlohmann::json::json_pointer(std::string(s, n));
25350 }
25351 
25352 } // namespace json_literals
25353 } // namespace literals
25355 
25357 // nonmember support //
25359 
25360 namespace std // NOLINT(cert-dcl58-cpp)
25361 {
25362 
25366 struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp)
25367 {
25368  std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
25369  {
25370  return nlohmann::detail::hash(j);
25371  }
25372 };
25373 
25374 // specialization for std::less<value_t>
25375 template<>
25376 struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
25377 {
25383  ::nlohmann::detail::value_t rhs) const noexcept
25384  {
25385 #if JSON_HAS_THREE_WAY_COMPARISON
25386  return std::is_lt(lhs <=> rhs); // *NOPAD*
25387 #else
25389 #endif
25390  }
25391 };
25392 
25393 // C++20 prohibit function specialization in the std namespace.
25394 #ifndef JSON_HAS_CPP_20
25395 
25399 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)
25400  is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
25402 {
25403  j1.swap(j2);
25404 }
25405 
25406 #endif
25407 
25408 } // namespace std
25409 
25410 #if JSON_USE_GLOBAL_UDLS
25411  #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
25412  using nlohmann::literals::json_literals::operator ""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
25413  using nlohmann::literals::json_literals::operator ""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
25414  #else
25415  using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
25416  using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
25417  #endif
25418 #endif
25419 
25420 // #include <nlohmann/detail/macro_unscope.hpp>
25421 // __ _____ _____ _____
25422 // __| | __| | | | JSON for Modern C++
25423 // | | |__ | | | | | | version 3.12.0
25424 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
25425 //
25426 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
25427 // SPDX-License-Identifier: MIT
25428 
25429 
25430 
25431 // restore clang diagnostic settings
25432 #if defined(__clang__)
25433  #pragma clang diagnostic pop
25434 #endif
25435 
25436 // clean up
25437 #undef JSON_ASSERT
25438 #undef JSON_INTERNAL_CATCH
25439 #undef JSON_THROW
25440 #undef JSON_PRIVATE_UNLESS_TESTED
25441 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25442 #undef NLOHMANN_BASIC_JSON_TPL
25443 #undef JSON_EXPLICIT
25444 #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
25445 #undef JSON_INLINE_VARIABLE
25446 #undef JSON_NO_UNIQUE_ADDRESS
25447 #undef JSON_DISABLE_ENUM_SERIALIZATION
25448 #undef JSON_USE_GLOBAL_UDLS
25449 
25450 #ifndef JSON_TEST_KEEP_MACROS
25451  #undef JSON_CATCH
25452  #undef JSON_TRY
25453  #undef JSON_HAS_CPP_11
25454  #undef JSON_HAS_CPP_14
25455  #undef JSON_HAS_CPP_17
25456  #undef JSON_HAS_CPP_20
25457  #undef JSON_HAS_CPP_23
25458  #undef JSON_HAS_CPP_26
25459  #undef JSON_HAS_FILESYSTEM
25460  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
25461  #undef JSON_HAS_THREE_WAY_COMPARISON
25462  #undef JSON_HAS_RANGES
25463  #undef JSON_HAS_STATIC_RTTI
25464  #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
25465 #endif
25466 
25467 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25468 // __ _____ _____ _____
25469 // __| | __| | | | JSON for Modern C++
25470 // | | |__ | | | | | | version 3.12.0
25471 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
25472 //
25473 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
25474 // SPDX-License-Identifier: MIT
25475 
25476 
25477 
25478 #undef JSON_HEDLEY_ALWAYS_INLINE
25479 #undef JSON_HEDLEY_ARM_VERSION
25480 #undef JSON_HEDLEY_ARM_VERSION_CHECK
25481 #undef JSON_HEDLEY_ARRAY_PARAM
25482 #undef JSON_HEDLEY_ASSUME
25483 #undef JSON_HEDLEY_BEGIN_C_DECLS
25484 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25485 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25486 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25487 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25488 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25489 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
25490 #undef JSON_HEDLEY_CLANG_HAS_WARNING
25491 #undef JSON_HEDLEY_COMPCERT_VERSION
25492 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25493 #undef JSON_HEDLEY_CONCAT
25494 #undef JSON_HEDLEY_CONCAT3
25495 #undef JSON_HEDLEY_CONCAT3_EX
25496 #undef JSON_HEDLEY_CONCAT_EX
25497 #undef JSON_HEDLEY_CONST
25498 #undef JSON_HEDLEY_CONSTEXPR
25499 #undef JSON_HEDLEY_CONST_CAST
25500 #undef JSON_HEDLEY_CPP_CAST
25501 #undef JSON_HEDLEY_CRAY_VERSION
25502 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
25503 #undef JSON_HEDLEY_C_DECL
25504 #undef JSON_HEDLEY_DEPRECATED
25505 #undef JSON_HEDLEY_DEPRECATED_FOR
25506 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
25507 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
25508 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
25509 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
25510 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
25511 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
25512 #undef JSON_HEDLEY_DIAGNOSTIC_POP
25513 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
25514 #undef JSON_HEDLEY_DMC_VERSION
25515 #undef JSON_HEDLEY_DMC_VERSION_CHECK
25516 #undef JSON_HEDLEY_EMPTY_BASES
25517 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
25518 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
25519 #undef JSON_HEDLEY_END_C_DECLS
25520 #undef JSON_HEDLEY_FLAGS
25521 #undef JSON_HEDLEY_FLAGS_CAST
25522 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
25523 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
25524 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
25525 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
25526 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
25527 #undef JSON_HEDLEY_GCC_HAS_FEATURE
25528 #undef JSON_HEDLEY_GCC_HAS_WARNING
25529 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
25530 #undef JSON_HEDLEY_GCC_VERSION
25531 #undef JSON_HEDLEY_GCC_VERSION_CHECK
25532 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
25533 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
25534 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
25535 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
25536 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
25537 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
25538 #undef JSON_HEDLEY_GNUC_HAS_WARNING
25539 #undef JSON_HEDLEY_GNUC_VERSION
25540 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
25541 #undef JSON_HEDLEY_HAS_ATTRIBUTE
25542 #undef JSON_HEDLEY_HAS_BUILTIN
25543 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
25544 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
25545 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
25546 #undef JSON_HEDLEY_HAS_EXTENSION
25547 #undef JSON_HEDLEY_HAS_FEATURE
25548 #undef JSON_HEDLEY_HAS_WARNING
25549 #undef JSON_HEDLEY_IAR_VERSION
25550 #undef JSON_HEDLEY_IAR_VERSION_CHECK
25551 #undef JSON_HEDLEY_IBM_VERSION
25552 #undef JSON_HEDLEY_IBM_VERSION_CHECK
25553 #undef JSON_HEDLEY_IMPORT
25554 #undef JSON_HEDLEY_INLINE
25555 #undef JSON_HEDLEY_INTEL_CL_VERSION
25556 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
25557 #undef JSON_HEDLEY_INTEL_VERSION
25558 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
25559 #undef JSON_HEDLEY_IS_CONSTANT
25560 #undef JSON_HEDLEY_IS_CONSTEXPR_
25561 #undef JSON_HEDLEY_LIKELY
25562 #undef JSON_HEDLEY_MALLOC
25563 #undef JSON_HEDLEY_MCST_LCC_VERSION
25564 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
25565 #undef JSON_HEDLEY_MESSAGE
25566 #undef JSON_HEDLEY_MSVC_VERSION
25567 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
25568 #undef JSON_HEDLEY_NEVER_INLINE
25569 #undef JSON_HEDLEY_NON_NULL
25570 #undef JSON_HEDLEY_NO_ESCAPE
25571 #undef JSON_HEDLEY_NO_RETURN
25572 #undef JSON_HEDLEY_NO_THROW
25573 #undef JSON_HEDLEY_NULL
25574 #undef JSON_HEDLEY_PELLES_VERSION
25575 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
25576 #undef JSON_HEDLEY_PGI_VERSION
25577 #undef JSON_HEDLEY_PGI_VERSION_CHECK
25578 #undef JSON_HEDLEY_PREDICT
25579 #undef JSON_HEDLEY_PRINTF_FORMAT
25580 #undef JSON_HEDLEY_PRIVATE
25581 #undef JSON_HEDLEY_PUBLIC
25582 #undef JSON_HEDLEY_PURE
25583 #undef JSON_HEDLEY_REINTERPRET_CAST
25584 #undef JSON_HEDLEY_REQUIRE
25585 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
25586 #undef JSON_HEDLEY_REQUIRE_MSG
25587 #undef JSON_HEDLEY_RESTRICT
25588 #undef JSON_HEDLEY_RETURNS_NON_NULL
25589 #undef JSON_HEDLEY_SENTINEL
25590 #undef JSON_HEDLEY_STATIC_ASSERT
25591 #undef JSON_HEDLEY_STATIC_CAST
25592 #undef JSON_HEDLEY_STRINGIFY
25593 #undef JSON_HEDLEY_STRINGIFY_EX
25594 #undef JSON_HEDLEY_SUNPRO_VERSION
25595 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
25596 #undef JSON_HEDLEY_TINYC_VERSION
25597 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
25598 #undef JSON_HEDLEY_TI_ARMCL_VERSION
25599 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
25600 #undef JSON_HEDLEY_TI_CL2000_VERSION
25601 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
25602 #undef JSON_HEDLEY_TI_CL430_VERSION
25603 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
25604 #undef JSON_HEDLEY_TI_CL6X_VERSION
25605 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
25606 #undef JSON_HEDLEY_TI_CL7X_VERSION
25607 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
25608 #undef JSON_HEDLEY_TI_CLPRU_VERSION
25609 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
25610 #undef JSON_HEDLEY_TI_VERSION
25611 #undef JSON_HEDLEY_TI_VERSION_CHECK
25612 #undef JSON_HEDLEY_UNAVAILABLE
25613 #undef JSON_HEDLEY_UNLIKELY
25614 #undef JSON_HEDLEY_UNPREDICTABLE
25615 #undef JSON_HEDLEY_UNREACHABLE
25616 #undef JSON_HEDLEY_UNREACHABLE_RETURN
25617 #undef JSON_HEDLEY_VERSION
25618 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
25619 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
25620 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
25621 #undef JSON_HEDLEY_VERSION_ENCODE
25622 #undef JSON_HEDLEY_WARNING
25623 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
25624 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
25625 #undef JSON_HEDLEY_FALL_THROUGH
25626 
25627 
25628 
25629 #endif // INCLUDE_NLOHMANN_JSON_HPP_
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2622
#define JSON_HEDLEY_CONST
Definition: json.hpp:1829
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:1113
#define JSON_INLINE_VARIABLE
Definition: json.hpp:2521
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1459
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2581
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:70
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1724
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1617
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2548
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:25318
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:2058
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:15511
#define JSON_CATCH(exception)
Definition: json.hpp:2547
#define JSON_ASSERT(x)
Definition: json.hpp:2574
#define JSON_THROW(exception)
Definition: json.hpp:2545
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition: json.hpp:81
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:68
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2632
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1725
#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
Definition: json.hpp:12867
#define JSON_TRY
Definition: json.hpp:2546
#define NLOHMANN_JSON_NAMESPACE_END
Definition: json.hpp:155
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.hpp:2527
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:15536
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:69
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition: json.hpp:2916
#define NLOHMANN_JSON_NAMESPACE_BEGIN
Definition: json.hpp:145
#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
Definition: json.hpp:12864
basic_json<> json
default specialization
Definition: json.hpp:3554
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:1114
#define JSON_EXPLICIT
Definition: json.hpp:2953
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.hpp:1407
#define JSON_HEDLEY_PURE
Definition: json.hpp:1798
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:15561
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition: json.hpp:23714
#define JSON_DIAGNOSTIC_POSITIONS
Definition: json.hpp:77
ArrayType
Definition: Xml.h:25
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:585
namespace for Niels Lohmann
Definition: json.hpp:20203
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition: json.hpp:21637
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:21502
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:21929
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:22737
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition: json.hpp:20485
reference operator[](KeyType &&key)
access specified object element
Definition: json.hpp:22303
json_value(object_t &&value)
constructor for rvalue objects
Definition: json.hpp:20641
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:24542
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition: json.hpp:20653
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.hpp:20545
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition: json.hpp:21875
reference back()
access the last element
Definition: json.hpp:22541
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:20942
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.hpp:21547
number_float_t number_float
number (floating-point)
Definition: json.hpp:20547
basic_json patch(const basic_json &json_patch) const
applies a JSON patch to a copy of the current object
Definition: json.hpp:25134
json_value(const array_t &value)
constructor for arrays
Definition: json.hpp:20644
const_reference front() const
access the first element
Definition: json.hpp:22534
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) const _reference operator[](const
access specified element via JSON Pointer
Definition: json.hpp:24802
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:21495
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)
exchanges the values
Definition: json.hpp:23596
ReturnType value(const json_pointer &ptr, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:22484
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:22854
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:21613
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:20281
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:21467
data(size_type cnt, const basic_json &val)
Definition: json.hpp:24346
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:24737
::nlohmann::detail::json_base_class< CustomBaseClass > json_base_class_t
Definition: json.hpp:20229
basic_json get_impl(detail::priority_tag< 3 >) const
get special-case overload
Definition: json.hpp:21827
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:24782
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:20332
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference at(const
Definition: json.hpp:24816
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:20324
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:21439
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.hpp:20552
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.hpp:22327
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:21536
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:23673
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:21965
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:23542
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:21976
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:21516
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:23333
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) ValueType value(const
access the first element
Definition: json.hpp:22508
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition: json.hpp:20259
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.hpp:22272
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.hpp:20554
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.hpp:21654
const_reference back() const
access the last element
Definition: json.hpp:22550
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:22632
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:23278
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:23613
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:24638
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:21084
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.hpp:23445
const binary_t & get_binary() const
get a binary value
Definition: json.hpp:22047
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:24722
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:20347
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.hpp:22135
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:21474
json_value(array_t &&value)
constructor for rvalue arrays
Definition: json.hpp:20647
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:23549
data m_data
Definition: json.hpp:24364
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:23317
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:20909
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:21125
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:24437
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:20535
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition: json.hpp:20789
ReturnType value(const typename object_t::key_type &key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:22382
void destroy(value_t t)
Definition: json.hpp:20661
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:21737
json_value(string_t &&value)
constructor for rvalue strings
Definition: json.hpp:20635
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:24692
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.hpp:21595
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:24824
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition: json.hpp:21095
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:20930
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:24526
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:24653
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.hpp:20556
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition: json.hpp:22748
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.hpp:21553
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.hpp:21577
json_value(const string_t &value)
constructor for strings
Definition: json.hpp:20632
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.hpp:23465
ReturnType value(KeyType &&key, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:22435
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:24796
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.hpp:20558
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:20448
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:22871
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:24407
static std::vector< std::uint8_t > to_bjdata(const basic_json &j, const bool use_size=false, const bool use_type=false, const bjdata_version_t version=bjdata_version_t::draft2)
create a BJData serialization of a given JSON value
Definition: json.hpp:24471
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:24517
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.hpp:22784
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:21073
BasicJsonType get_impl(detail::priority_tag< 2 >) const
get special-case overload
Definition: json.hpp:21804
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:21601
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.hpp:22173
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:20355
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:21132
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.hpp:22798
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:22562
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.hpp:23418
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:20468
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:22357
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:21625
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:20537
ValueType & get_to(ValueType &v) const
Definition: json.hpp:21942
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:20327
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:20330
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:21619
reference set_parent(reference j, std::size_t old_capacity=detail::unknown_size())
Definition: json.hpp:20860
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:21403
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:25286
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, const bjdata_version_t version=bjdata_version_t::draft2)
create a BJData serialization of a given JSON value
Definition: json.hpp:24483
reference operator[](T *key)
Definition: json.hpp:22288
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:22069
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.hpp:22814
binary_t * binary
binary (stored with pointer to save storage)
Definition: json.hpp:20539
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:21481
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.hpp:21559
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:20456
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const string_t &path="")
creates a diff as a JSON patch
Definition: json.hpp:25144
void set_parents()
Definition: json.hpp:20810
std::conditional< detail::is_c_string_uncvref< ValueType >::value, string_t, typename std::decay< ValueType >::type > value_return_type
Definition: json.hpp:22348
size_type erase_internal(KeyType &&key)
Definition: json.hpp:22703
std::less< StringType > default_object_comparator_t
default object key comparator type The actual object key comparator type (object_comparator_t) may be...
Definition: json.hpp:20435
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:23309
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:21607
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:24398
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.hpp:22250
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:21687
~basic_json() noexcept
destructor
Definition: json.hpp:21385
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition: json.hpp:20659
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:21014
json_value(const object_t &value)
constructor for objects
Definition: json.hpp:20638
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:23689
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:21460
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:24286
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.hpp:23516
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:21356
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:24584
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:21916
const_reference operator[](T *key) const
Definition: json.hpp:22294
data(const value_t v)
Definition: json.hpp:24341
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:22191
basic_json(const JsonRef &ref)
Definition: json.hpp:21253
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:20273
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:24463
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:21953
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:20460
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:21676
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:22153
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:21509
void swap(object_t &other)
exchanges the values
Definition: json.hpp:23641
iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
Definition: json.hpp:20847
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:21840
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.hpp:23496
static void to_bjdata(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false, const bjdata_version_t version=bjdata_version_t::draft2)
create a BJData serialization of a given JSON value
Definition: json.hpp:24492
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:21106
void swap(array_t &other)
exchanges the values
Definition: json.hpp:23625
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:22755
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:23367
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:23246
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:22878
binary_t & get_binary()
get a binary value
Definition: json.hpp:22035
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:21779
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:21425
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:23342
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:22458
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:21117
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.hpp:21589
data() noexcept=default
StringType string_t
a type for a string
Definition: json.hpp:20452
ObjectType< StringType, basic_json, default_object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.hpp:20444
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:23254
ValueType value(KeyType &&key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:22408
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:22115
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:24707
json_value m_value
the value of the current element
Definition: json.hpp:24339
number_integer_t number_integer
number (integer)
Definition: json.hpp:20543
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:21453
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:22844
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:24421
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:21432
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:21446
json_value(value_t t)
constructor for empty values of a given type
Definition: json.hpp:20560
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:24455
json_value()=default
default constructor (for null values)
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition: json.hpp:24501
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.hpp:21571
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:21330
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:20922
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:22237
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:20322
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.hpp:23438
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:20464
void swap(string_t &other)
exchanges the values
Definition: json.hpp:23657
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:20956
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition: json.hpp:20228
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.hpp:21583
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition: json.hpp:20656
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.hpp:21565
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:22092
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.hpp:20476
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:21257
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:23286
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:24414
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:21488
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition: json.hpp:21631
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:24430
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, const bool ignore_trailing_commas=false)
Definition: json.hpp:20236
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:24599
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:23399
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:21144
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference operator[](const
Definition: json.hpp:24788
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:24444
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:24301
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition: json.hpp:22862
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:24510
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.hpp:22830
boolean_t boolean
boolean
Definition: json.hpp:20541
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition: json.hpp:20650
an internal type for a backed binary type
Definition: json.hpp:6239
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:6279
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:6245
std::uint64_t subtype_type
Definition: json.hpp:6242
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:6273
BinaryType container_type
Definition: json.hpp:6241
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:6267
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:6255
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:6294
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:6260
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:6301
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:6250
subtype_type m_subtype
Definition: json.hpp:6315
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:6286
bool m_has_subtype
Definition: json.hpp:6316
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:6308
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:9892
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:12723
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:12070
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:10220
typename BasicJsonType::string_t string_t
Definition: json.hpp:9896
std::pair< char_int_type, string_t > bjd_type
Definition: json.hpp:12888
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition: json.hpp:10182
typename InputAdapterType::char_type char_type
Definition: json.hpp:9899
bool parse_msgpack_internal()
Definition: json.hpp:11026
std::string get_token_string() const
Definition: json.hpp:12793
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9894
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition: json.hpp:11407
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition: json.hpp:12806
InputAdapterType ia
input adapter
Definition: json.hpp:12846
bool get_ubjson_high_precision_number()
Definition: json.hpp:12528
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:12756
binary_reader(binary_reader &&)=default
static void byte_swap(NumberType &number)
Definition: json.hpp:12651
char_int_type get_ignore_noop()
Definition: json.hpp:12639
bool get_ubjson_value(const char_int_type prefix)
Definition: json.hpp:12137
bool get_ubjson_ndarray_size(std::vector< size_t > &dim)
Definition: json.hpp:11774
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:10096
bool get_msgpack_object(const std::size_t len)
Definition: json.hpp:11623
typename char_traits< char_type >::int_type char_int_type
Definition: json.hpp:9900
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition: json.hpp:9908
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9897
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition: json.hpp:9992
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:10970
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition: json.hpp:10837
bool get_number(const input_format_t format, NumberType &result)
Definition: json.hpp:12693
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9893
bool get_ubjson_array()
Definition: json.hpp:12330
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition: json.hpp:10017
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:9929
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:10932
bool get_msgpack_array(const std::size_t len)
Definition: json.hpp:11601
char_int_type get()
get next character from the input
Definition: json.hpp:12607
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9895
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition: json.hpp:11490
bool parse_ubjson_internal(const bool get_char=true)
Definition: json.hpp:11660
SAX json_sax_t
Definition: json.hpp:9898
bool get_ubjson_size_value(std::size_t &result, bool &is_ndarray, char_int_type prefix=0)
Definition: json.hpp:11839
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:10250
binary_reader & operator=(binary_reader &&)=default
binary_reader & operator=(const binary_reader &)=delete
bool get_ubjson_object()
Definition: json.hpp:12445
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:10047
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition: json.hpp:11679
bool get_to(T &dest, const input_format_t format, const char *context)
get_to read into a primitive type
Definition: json.hpp:12622
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition: json.hpp:10741
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:10069
serialization to CBOR and MessagePack values
Definition: json.hpp:15863
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:16976
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:16813
void write_bson(const BasicJsonType &j)
Definition: json.hpp:15883
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:15865
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:16873
typename BasicJsonType::string_t string_t
Definition: json.hpp:15864
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:17623
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition: json.hpp:16891
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true, const bool use_bjdata=false, const bjdata_version_t bjdata_version=bjdata_version_t::draft2)
Definition: json.hpp:16563
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:16957
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:17630
static constexpr CharType get_cbor_float_prefix(double)
Definition: json.hpp:17122
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:16841
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:15874
static constexpr CharType get_ubjson_float_prefix(double)
Definition: json.hpp:17437
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix, const bool use_bjdata)
Definition: json.hpp:17148
static constexpr CharType get_msgpack_float_prefix(double)
Definition: json.hpp:17136
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:17039
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:17665
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition: json.hpp:17101
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:16823
static std::size_t calc_bson_string_size(const string_t &value)
Definition: json.hpp:16833
void write_number(const NumberType n, const bool OutputIsLittleEndian=false)
Definition: json.hpp:17573
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition: json.hpp:16786
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition: json.hpp:16855
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:15866
CharType ubjson_prefix(const BasicJsonType &j, const bool use_bjdata) const noexcept
determine the type prefix of container values
Definition: json.hpp:17331
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition: json.hpp:16901
static constexpr CharType get_ubjson_float_prefix(float)
Definition: json.hpp:17432
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition: json.hpp:16949
bool write_bjdata_ndarray(const typename BasicJsonType::object_t &value, const bool use_count, const bool use_type, const bjdata_version_t bjdata_version)
Definition: json.hpp:17445
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:16991
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:16236
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:17086
void write_compact_float(const number_float_t n, detail::input_format_t format)
Definition: json.hpp:17589
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:15912
static constexpr CharType get_cbor_float_prefix(float)
Definition: json.hpp:17117
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:16801
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:16924
static constexpr CharType get_msgpack_float_prefix(float)
Definition: json.hpp:17131
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition: json.hpp:16934
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition: json.hpp:16863
general exception of the basic_json class
Definition: json.hpp:4540
static std::string get_byte_positions(const BasicJsonType *leaf_element)
Definition: json.hpp:4645
const int id
the id of the exception
Definition: json.hpp:4549
static std::string diagnostics(std::nullptr_t)
Definition: json.hpp:4560
std::runtime_error m
an exception object as storage for error messages
Definition: json.hpp:4632
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:4543
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:4555
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.hpp:4566
Definition: json.hpp:6542
char char_type
Definition: json.hpp:6544
file_input_adapter(const file_input_adapter &)=delete
std::FILE * m_file
the file pointer to read from
Definition: json.hpp:6574
file_input_adapter(file_input_adapter &&) noexcept=default
std::size_t get_elements(T *dest, std::size_t count=1)
Definition: json.hpp:6567
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6560
Definition: json.hpp:6587
std::istream * is
the associated input stream
Definition: json.hpp:6644
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:6610
~input_stream_adapter()
Definition: json.hpp:6591
std::size_t get_elements(T *dest, std::size_t count=1)
Definition: json.hpp:6632
char char_type
Definition: json.hpp:6589
input_stream_adapter(const input_stream_adapter &)=delete
input_stream_adapter & operator=(input_stream_adapter &)=delete
std::streambuf * sb
Definition: json.hpp:6645
input_stream_adapter & operator=(input_stream_adapter &&)=delete
std::char_traits< char >::int_type get_character()
Definition: json.hpp:6620
input_stream_adapter(std::istream &i)
Definition: json.hpp:6601
exception indicating errors with iterators
Definition: json.hpp:4709
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4712
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:13682
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:13794
~iter_impl()=default
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:14265
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:14256
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:14219
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:14210
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:13809
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:14152
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:14192
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:14011
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:14103
iter_impl operator++(int) &
post-increment (it++)
Definition: json.hpp:14000
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:14062
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:14327
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:14365
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:13712
pointer operator->() const
dereference the iterator
Definition: json.hpp:13958
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:13819
friend other_iter_impl
allow basic_json to access private members
Definition: json.hpp:13686
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:14390
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:14298
iter_impl(iter_impl &&) noexcept=default
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:13707
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:14276
reference value() const
return the value of an iterator
Definition: json.hpp:14381
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:14201
typename BasicJsonType::array_t array_t
Definition: json.hpp:13692
typename BasicJsonType::object_t object_t
Definition: json.hpp:13691
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:13716
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:13710
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:13914
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:14287
iter_impl()=default
friend BasicJsonType
Definition: json.hpp:13687
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:14143
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.hpp:14051
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:13721
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:13784
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:13875
Definition: json.hpp:5501
iteration_proxy_value operator++(int) &
Definition: json.hpp:5557
iteration_proxy_value(iteration_proxy_value const &)=default
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:5566
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:5572
std::ptrdiff_t difference_type
Definition: json.hpp:5503
string_type empty_str
an empty string (to return a reference for primitive values)
Definition: json.hpp:5520
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:5524
std::forward_iterator_tag iterator_category
Definition: json.hpp:5507
std::size_t array_index_last
last stringified array index
Definition: json.hpp:5516
std::size_t array_index
an index for arrays (used to create key names)
Definition: json.hpp:5514
const string_type & key() const
return key of the iterator
Definition: json.hpp:5578
iteration_proxy_value(iteration_proxy_value &&) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_move_constructible< string_type >::value)=default
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:5614
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:5549
iteration_proxy_value & operator=(iteration_proxy_value const &)=default
string_type array_index_str
a string representation of the array index
Definition: json.hpp:5518
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:5508
IteratorType anchor
the iterator
Definition: json.hpp:5512
proxy class for the items() function
Definition: json.hpp:5622
IteratorType::pointer container
the container to iterate
Definition: json.hpp:5625
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:5647
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:5641
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:5631
iteration_proxy & operator=(iteration_proxy const &)=default
Definition: json.hpp:6653
IteratorType end
Definition: json.hpp:6695
bool empty() const
Definition: json.hpp:6700
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6657
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:6655
std::size_t get_elements(T *dest, std::size_t count=1)
Definition: json.hpp:6675
IteratorType current
Definition: json.hpp:6694
char_traits< char_type >::int_type get_character()
Definition: json.hpp:6661
Definition: json.hpp:15595
json_ref(json_ref &&) noexcept=default
json_ref(const value_type &value)
Definition: json.hpp:15603
json_ref(value_type &&value)
Definition: json.hpp:15599
value_type const & operator*() const
Definition: json.hpp:15634
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:15607
json_ref(Args &&... args)
Definition: json.hpp:15614
value_type moved_or_copied() const
Definition: json.hpp:15625
BasicJsonType value_type
Definition: json.hpp:15597
value_type const * operator->() const
Definition: json.hpp:15639
a template for a reverse iterator class
Definition: json.hpp:14444
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.hpp:14460
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:14466
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.hpp:14472
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:14478
std::ptrdiff_t difference_type
Definition: json.hpp:14446
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:14508
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:14514
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:14502
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:14484
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:14450
reference value() const
return the value of an iterator
Definition: json.hpp:14521
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:14457
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:14448
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:14496
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:14453
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:14490
Definition: json.hpp:9607
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9610
bool end_object()
Definition: json.hpp:9660
bool binary(binary_t &)
Definition: json.hpp:9645
bool number_integer(number_integer_t)
Definition: json.hpp:9625
bool start_array(std::size_t=detail::unknown_size())
Definition: json.hpp:9665
bool boolean(bool)
Definition: json.hpp:9620
bool end_array()
Definition: json.hpp:9670
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:9630
bool start_object(std::size_t=detail::unknown_size())
Definition: json.hpp:9650
bool string(string_t &)
Definition: json.hpp:9640
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9613
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:9635
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:9675
bool key(string_t &)
Definition: json.hpp:9655
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9609
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9611
typename BasicJsonType::string_t string_t
Definition: json.hpp:9612
Definition: json.hpp:9170
bool start_array(std::size_t len)
Definition: json.hpp:9338
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:9177
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:9178
bool number_integer(number_integer_t val)
Definition: json.hpp:9209
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:9417
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9174
bool end_object()
Definition: json.hpp:9288
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:9215
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:9221
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
constexpr bool is_errored() const
Definition: json.hpp:9429
json_sax_dom_callback_parser(BasicJsonType &r, parser_callback_t cb, const bool allow_exceptions_=true, lexer_t *lexer_=nullptr)
Definition: json.hpp:9181
bool binary(binary_t &val)
Definition: json.hpp:9233
typename BasicJsonType::string_t string_t
Definition: json.hpp:9175
bool boolean(bool val)
Definition: json.hpp:9203
bool key(string_t &val)
Definition: json.hpp:9271
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition: json.hpp:9516
bool string(string_t &val)
Definition: json.hpp:9227
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:9584
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9173
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9172
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9176
bool end_array()
Definition: json.hpp:9370
bool start_object(std::size_t len)
Definition: json.hpp:9239
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:8864
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition: json.hpp:9117
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:8913
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:8907
json_sax_dom_parser(const json_sax_dom_parser &)=delete
bool binary(binary_t &val)
Definition: json.hpp:8925
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8870
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true, lexer_t *lexer_=nullptr)
Definition: json.hpp:8878
bool start_object(std::size_t len)
Definition: json.hpp:8931
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8866
bool key(string_t &val)
Definition: json.hpp:8954
bool end_object()
Definition: json.hpp:8964
typename BasicJsonType::string_t string_t
Definition: json.hpp:8869
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8867
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:9022
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool boolean(bool val)
Definition: json.hpp:8895
bool start_array(std::size_t len)
Definition: json.hpp:8982
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8868
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:9155
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool end_array()
Definition: json.hpp:9003
json_sax_dom_parser(json_sax_dom_parser &&)=default
constexpr bool is_errored() const
Definition: json.hpp:9034
bool string(string_t &val)
Definition: json.hpp:8919
bool number_integer(number_integer_t val)
Definition: json.hpp:8901
Definition: json.hpp:7104
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:7131
token_type
token types for the parser
Definition: json.hpp:7108
@ value_float
an floating point number – use get_number_float() for actual value
@ begin_array
the character for array begin [
@ value_string
a string – use get_string() for actual value
@ end_array
the character for array end ]
@ uninitialized
indicating the scanner is uninitialized
@ parse_error
indicating a parse error
@ value_integer
a signed integer – use get_number_integer() for actual value
@ value_separator
the value separator ,
@ end_object
the character for object end }
@ literal_true
the true literal
@ begin_object
the character for object begin {
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
@ literal_null
the null literal
@ end_of_input
indicating the end of the input buffer
@ name_separator
the name separator :
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
@ literal_false
the false literal
lexical analysis
Definition: json.hpp:7181
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: json.hpp:8391
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8563
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition: json.hpp:8694
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: json.hpp:7238
token_type scan_string()
scan a string literal
Definition: json.hpp:7323
number_integer_t value_integer
Definition: json.hpp:8700
void skip_whitespace()
Definition: json.hpp:8577
lexer & operator=(lexer &&)=default
const bool ignore_comments
whether comments should be ignored (true) or signaled as errors (false)
Definition: json.hpp:8679
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:7192
char_int_type current
the current character
Definition: json.hpp:8682
std::string get_token_string() const
Definition: json.hpp:8525
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:7184
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8484
typename BasicJsonType::string_t string_t
Definition: json.hpp:7185
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:7183
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:7286
char_int_type get()
Definition: json.hpp:8409
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8517
static void strtof(float &f, const char *str, char **endptr) noexcept
Definition: json.hpp:7981
const char_int_type decimal_point_char
the decimal point
Definition: json.hpp:8705
number_unsigned_t value_unsigned
Definition: json.hpp:8701
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:7182
token_type scan()
Definition: json.hpp:8586
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8490
typename char_traits< char_type >::int_type char_int_type
Definition: json.hpp:7187
bool scan_comment()
scan a comment
Definition: json.hpp:7913
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:7190
lexer(lexer &&)=default
~lexer()=default
const char * error_message
a description of occurred lexer errors
Definition: json.hpp:8697
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8502
lexer & operator=(lexer &)=delete
bool next_unget
whether the next get() call should just return current
Definition: json.hpp:8685
lexer(const lexer &)=delete
constexpr JSON_HEDLEY_RETURNS_NON_NULL const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8550
std::size_t decimal_point_position
the position of the decimal point in the input
Definition: json.hpp:8707
typename InputAdapterType::char_type char_type
Definition: json.hpp:7186
InputAdapterType ia
input adapter
Definition: json.hpp:8676
token_type scan_number()
scan a number literal
Definition: json.hpp:8038
number_float_t value_float
Definition: json.hpp:8702
token_type scan_literal(const char_type *literal_text, const std::size_t length, token_type return_type)
Definition: json.hpp:8371
std::vector< char_type > token_string
raw input token string (for error messages)
Definition: json.hpp:8691
void add(char_int_type c)
add a character to token_buffer
Definition: json.hpp:8473
position_t position
the start position of the current token
Definition: json.hpp:8688
void unget()
unget current character (read it again on next get)
Definition: json.hpp:8446
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8496
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.hpp:7212
exception indicating other library errors
Definition: json.hpp:4761
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4764
exception indicating access out of the defined range
Definition: json.hpp:4744
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4747
Definition: json.hpp:15814
output_adapter(StringType &s)
Definition: json.hpp:15825
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:15821
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:15817
output adapter for output streams
Definition: json.hpp:15766
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:15768
void write_character(CharType c) override
Definition: json.hpp:15772
std::basic_ostream< CharType > & stream
Definition: json.hpp:15784
output adapter for basic_string
Definition: json.hpp:15791
void write_character(CharType c) override
Definition: json.hpp:15797
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:15793
StringType & str
Definition: json.hpp:15809
output adapter for byte vectors
Definition: json.hpp:15741
std::vector< CharType, AllocatorType > & v
Definition: json.hpp:15759
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:15743
void write_character(CharType c) override
Definition: json.hpp:15747
exception indicating a parse error
Definition: json.hpp:4656
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:4668
static std::string position_string(const position_t &pos)
Definition: json.hpp:4699
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4676
const std::size_t byte
byte index of the parse error
Definition: json.hpp:4693
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition: json.hpp:4696
syntax analysis
Definition: json.hpp:12978
std::string exception_message(const token_type expected, const std::string &context)
Definition: json.hpp:13410
typename lexer_t::token_type token_type
Definition: json.hpp:12984
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:13012
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:12980
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:12979
typename BasicJsonType::string_t string_t
Definition: json.hpp:12982
lexer_t m_lexer
the lexer
Definition: json.hpp:13445
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:13072
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:12981
token_type get_token()
get next token from lexer
Definition: json.hpp:13405
parser(InputAdapterType &&adapter, parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool ignore_comments=false, const bool ignore_trailing_commas_=false)
a parser reading from an input adapter
Definition: json.hpp:12988
Definition: json.hpp:13499
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:13587
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:13574
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:13528
constexpr friend bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:13544
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:13561
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:13522
constexpr friend difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:13556
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:13534
primitive_iterator_t operator++(int) &noexcept
Definition: json.hpp:13567
constexpr difference_type get_value() const noexcept
Definition: json.hpp:13510
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:13549
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:13593
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:13516
primitive_iterator_t operator--(int) &noexcept
Definition: json.hpp:13580
std::ptrdiff_t difference_type
Definition: json.hpp:13501
constexpr friend bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:13539
Definition: json.hpp:18862
serializer & operator=(serializer &&)=delete
typename BasicJsonType::binary_t::value_type binary_char_t
Definition: json.hpp:18867
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:18866
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:18877
~serializer()=default
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:19794
string_t indent_string
the indentation string
Definition: json.hpp:19791
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:18865
serializer & operator=(const serializer &)=delete
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:18864
typename BasicJsonType::string_t string_t
Definition: json.hpp:18863
const char indent_char
the indentation character
Definition: json.hpp:19789
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:18917
serializer(const serializer &)=delete
serializer(serializer &&)=delete
Definition: json.hpp:7015
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:7023
contiguous_bytes_input_adapter ia
Definition: json.hpp:7039
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:7030
contiguous_bytes_input_adapter && get()
Definition: json.hpp:7033
exception indicating executing a member function with a wrong type
Definition: json.hpp:4727
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4730
Definition: json.hpp:6832
std::size_t get_elements(T *, std::size_t=1)
Definition: json.hpp:6858
std::array< std::char_traits< char >::int_type, 4 > utf8_bytes
a buffer for UTF-8 bytes
Definition: json.hpp:6873
std::size_t utf8_bytes_filled
number of valid bytes in the utf8_codes array
Definition: json.hpp:6878
BaseInputAdapter base_adapter
Definition: json.hpp:6864
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:6836
char char_type
Definition: json.hpp:6834
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6839
std::size_t utf8_bytes_index
index to the utf8_codes array for the next valid byte
Definition: json.hpp:6876
void fill_buffer()
Definition: json.hpp:6867
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition: json.hpp:14616
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition: json.hpp:15060
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:14711
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: json.hpp:15002
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:14688
static BasicJsonType::size_type array_index(const string_t &s)
Definition: json.hpp:14794
typename string_t_helper< RefStringType >::type string_t
Definition: json.hpp:14638
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:14718
result reference_tokens
Definition: json.hpp:14840
static std::vector< string_t > split(const string_t &reference_string)
split the string input to reference tokens
Definition: json.hpp:15246
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:14678
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.hpp:14642
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:14777
friend std::ostream & operator<<(std::ostream &o, const json_pointer &ptr)
write string representation of the JSON pointer to stream
Definition: json.hpp:14669
void pop_back()
remove last reference token
Definition: json.hpp:14739
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:14648
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:14770
std::vector< string_t > reference_tokens
the reference tokens
Definition: json.hpp:15505
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: json.hpp:14934
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition: json.hpp:15109
return result
Definition: json.hpp:14841
static void flatten(const string_t &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition: json.hpp:15315
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition: json.hpp:14854
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:14703
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:14725
static BasicJsonType unflatten(const BasicJsonType &value)
Definition: json.hpp:15387
const string_t & back() const
return last reference token
Definition: json.hpp:14751
json_pointer< string_t > convert() &&
Definition: json.hpp:15422
json_pointer< string_t > convert() const &
Definition: json.hpp:15415
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:14763
bool contains(const BasicJsonType *ptr) const
Definition: json.hpp:15158
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:14696
a class to store JSON values
Definition: json.hpp:17064
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: json.hpp:23644
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:17126
an internal type for a backed binary type
Definition: json.hpp:4803
BinaryType container_type
the type of the underlying container
Definition: json.hpp:4806
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:8109
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:8146
serialization to CBOR and MessagePack values
Definition: json.hpp:13132
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: json.hpp:13801
void write_bson(const BasicJsonType &j)
Definition: json.hpp:13152
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:13172
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:13477
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:11218
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:11245
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:11821
proxy class for the items() function
Definition: json.hpp:4291
a template for a reverse iterator class
Definition: json.hpp:11863
Definition: json.hpp:6319
Definition: json.hpp:11045
Definition: json.hpp:15853
JSON Pointer.
Definition: json.hpp:11975
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: json.hpp:12485
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: json.hpp:12426
bool contains(const BasicJsonType *ptr) const
Definition: json.hpp:12614
Concept for allocating, resizing and freeing memory block.
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:5695
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:2117
v1d & operator+=(v1d &a, cv1d &b)
Definition: Tools.cpp:29
v1d operator-(v1d a, double &b)
Definition: Tools.cpp:17
@ pos
Definition: Typedefs.h:19
v1d operator*(v1d a, double b)
Definition: Tools.cpp:9
v1d operator+(v1d a, double b)
Definition: Tools.cpp:13
uint d
int N
std::string decode(std::string const &encoded_string)
Definition: base64.hpp:89
type
The type the bitset is encoded with.
Definition: bitset.hpp:44
C const & container(std::queue< T, C > const &queue)
Allows access to the protected container in queue.
Definition: queue.hpp:48
std::basic_ostream< Ch > & operator<<(std::basic_ostream< Ch > &out, const xml_node< Ch > &node)
Definition: rapidxml_print.hpp:418
CEREAL_SIZE_TYPE size_type
The size type used by cereal.
Definition: helpers.hpp:61
constexpr bool is_transparent()
Definition: json.hpp:4350
constexpr bool is_c_string()
Definition: json.hpp:4322
detail namespace with internal helper functions
Definition: json.hpp:260
input_format_t
the supported input formats
Definition: json.hpp:6530
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:6110
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:320
typename make_void< Ts... >::type void_t
Definition: json.hpp:266
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:9754
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:15736
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition: json.hpp:4431
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:9762
constexpr std::array< T, sizeof...(Args)> make_array(Args &&... args)
Definition: json.hpp:3352
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:12969
OutStringType concat(Args &&... args)
Definition: json.hpp:4505
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.hpp:4440
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 >>, priority_tag< 0 >)
Definition: json.hpp:5278
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3649
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3655
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:4172
typename T::pointer pointer_t
Definition: json.hpp:3640
parse_event_t
Definition: json.hpp:12952
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.hpp:4434
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:5083
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3313
typename T::value_type value_type_t
Definition: json.hpp:3634
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:324
void int_to_string(StringType &target, std::size_t value)
Definition: json.hpp:5475
T conditional_static_cast(U value)
Definition: json.hpp:4206
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.hpp:4446
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3225
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:9723
typename T::mapped_type mapped_type_t
Definition: json.hpp:3628
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition: json.hpp:3101
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:9731
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3900
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:5657
bool little_endianness(int num=1) noexcept
determine system byte order
Definition: json.hpp:9878
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:9865
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:317
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3652
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:6984
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3321
std::integral_constant< bool, Value > bool_constant
Definition: json.hpp:4312
void concat_into(OutStringType &)
Definition: json.hpp:4421
typename T::key_type key_type_t
Definition: json.hpp:3631
constexpr bool value_in_range_of(T val)
Definition: json.hpp:4306
value_t
the JSON type enumeration
Definition: json.hpp:3003
@ null
null value
@ number_integer
number value (signed integer)
@ boolean
boolean value
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ string
string value
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
std::integral_constant< bool, all_signed< Types... >::value||all_unsigned< Types... >::value > same_sign
Definition: json.hpp:4229
constexpr std::size_t unknown_size()
Definition: json.hpp:8844
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6920
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:5266
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:9739
StringType to_string(std::size_t value)
Definition: json.hpp:5483
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:311
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:4156
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:6370
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition: json.hpp:4437
typename T::iterator_category iterator_category_t
Definition: json.hpp:3646
void unescape(StringType &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:3135
decltype(input_adapter(std::declval< std::string >())) string_input_adapter_type
Definition: json.hpp:6960
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:6352
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:3032
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:9757
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:4184
error_handler_t
how to treat decoding errors
Definition: json.hpp:18854
@ strict
throw a type_error exception in case of invalid UTF-8
@ replace
replace invalid UTF-8 sequences with U+FFFD
std::size_t concat_length()
Definition: json.hpp:4390
value_type_t< iterator_traits< iterator_t< T > >> range_value_t
Definition: json.hpp:3903
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:4863
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.hpp:3728
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition: json.hpp:4425
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5971
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:4892
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:9715
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3329
typename T::difference_type difference_type_t
Definition: json.hpp:3637
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:3211
typename T::is_transparent detect_is_transparent
Definition: json.hpp:4142
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:9735
typename std::conditional< std::is_same< T, void >::value, json_default_base, T >::type json_base_class
Definition: json.hpp:14570
typename T::reference reference_t
Definition: json.hpp:3643
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:9719
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:9750
bjdata_version_t
how to encode BJData
Definition: json.hpp:15849
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.hpp:4175
typename T::key_compare detect_key_compare
Definition: json.hpp:3712
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:9743
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition: json.hpp:4443
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:9727
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:305
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:3120
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:4234
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.hpp:4428
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:5166
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:9747
Definition: json.hpp:25324
std::istream & operator>>(std::istream &in, JsonValue &value)
Definition: json_parser.h:246
Target reinterpret_bits(const Source source)
Definition: json.hpp:14757
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:14898
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:15201
constexpr int kGamma
Definition: json.hpp:15021
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:15255
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:15296
void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
Definition: json.hpp:15597
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:15689
constexpr int kAlpha
Definition: json.hpp:15020
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:15637
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:15037
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3042
value_t
the JSON type enumeration
Definition: json.hpp:118
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3146
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:10569
parse_event_t
Definition: json.hpp:10552
integer_sequence< size_t, Ints... > index_sequence
Definition: json.hpp:3084
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:4986
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:15774
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3138
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:13020
void to_json(BasicJsonType &j, const T &b)
Definition: json.hpp:4697
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:4317
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.hpp:4125
namespace for Niels Lohmann
Definition: json.hpp:86
std::basic_string< PUGIXML_CHAR, std::char_traits< PUGIXML_CHAR >, std::allocator< PUGIXML_CHAR > > string_t
Definition: pugixml.hpp:141
Definition: json.hpp:5678
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression, cppcoreguidelines-noexcept-swap, performance-noexcept-swap) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:25399
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1282
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1181
const CharType(& source)[N]
Definition: pointer.h:1204
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1181
PUGI_IMPL_FN void reverse(I begin, I end)
Definition: pugixml.cpp:7615
void swap(T &lhs, T &rhs)
Definition: pugixml.cpp:7597
PUGI_IMPL_FN bool is_little_endian()
Definition: pugixml.cpp:1931
signed short int16_t
Definition: stdint.h:122
unsigned short uint16_t
Definition: stdint.h:125
signed __int64 int64_t
Definition: stdint.h:135
unsigned int uint32_t
Definition: stdint.h:126
signed int int32_t
Definition: stdint.h:123
unsigned char uint8_t
Definition: stdint.h:124
unsigned __int64 uint64_t
Definition: stdint.h:136
signed char int8_t
Definition: stdint.h:121
namespace for Niels Lohmann
Definition: json.hpp:6181
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:6205
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:6195
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:6185
Definition: json.hpp:3720
typename BasicJsonType::object_t object_t
Definition: json.hpp:3721
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.hpp:3722
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition: json.hpp:3724
signed char char_type
Definition: json.hpp:3767
static constexpr int_type eof() noexcept
Definition: json.hpp:3781
uint64_t int_type
Definition: json.hpp:3768
static char_type to_char_type(int_type i) noexcept
Definition: json.hpp:3776
static int_type to_int_type(char_type c) noexcept
Definition: json.hpp:3771
static char_type to_char_type(int_type i) noexcept
Definition: json.hpp:3752
static constexpr int_type eof() noexcept
Definition: json.hpp:3757
unsigned char char_type
Definition: json.hpp:3743
uint64_t int_type
Definition: json.hpp:3744
static int_type to_int_type(char_type c) noexcept
Definition: json.hpp:3747
Definition: json.hpp:3737
Definition: json.hpp:3817
Definition: json.hpp:3816
decltype(input_adapter(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))) adapter_type
Definition: json.hpp:6943
Definition: json.hpp:292
std::false_type value_t
Definition: json.hpp:293
Default type
Definition: json.hpp:294
Definition: json.hpp:17885
diyfp w
Definition: json.hpp:17886
diyfp minus
Definition: json.hpp:17887
diyfp plus
Definition: json.hpp:17888
Definition: json.hpp:18024
std::uint64_t f
Definition: json.hpp:18025
int e
Definition: json.hpp:18026
int k
Definition: json.hpp:18027
Definition: json.hpp:17767
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:17791
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:17873
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:17856
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:17779
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:17773
std::uint64_t f
Definition: json.hpp:17770
int e
Definition: json.hpp:17771
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:5880
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:5855
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:5845
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:5867
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:5896
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:5784
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:5793
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:5738
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:5806
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:5832
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:5819
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:5915
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:5936
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:5925
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:5760
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:5771
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:5751
Definition: json.hpp:5732
Definition: json.hpp:5375
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:5377
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3674
Definition: json.hpp:3659
Definition: json.hpp:3715
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3689
Definition: json.hpp:3684
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3704
Definition: json.hpp:3699
Definition: json.hpp:4805
Definition: json.hpp:3253
T value_type
Definition: json.hpp:3254
static constexpr std::size_t size() noexcept
Definition: json.hpp:3255
an iterator value
Definition: json.hpp:13615
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:13619
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:13621
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:13617
Definition: json.hpp:3608
Definition: json.hpp:3595
Definition: json.hpp:4337
Definition: json.hpp:4133
Definition: json.hpp:3997
Definition: json.hpp:4016
Definition: json.hpp:4087
Definition: json.hpp:3937
Definition: json.hpp:3974
static constexpr auto value
Definition: json.hpp:3975
Definition: json.hpp:4090
Definition: json.hpp:4103
Definition: json.hpp:3910
Definition: json.hpp:4060
Definition: json.hpp:3970
Definition: json.hpp:3981
ConstructibleStringType laundered_type
Definition: json.hpp:3986
static constexpr auto value
Definition: json.hpp:3989
Definition: json.hpp:4106
Definition: json.hpp:3848
Definition: json.hpp:3829
Definition: json.hpp:308
Definition: json.hpp:3667
static constexpr bool value
Definition: json.hpp:3668
Definition: json.hpp:6896
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:6897
Definition: json.hpp:3863
Definition: json.hpp:4112
Definition: json.hpp:3618
Definition: json.hpp:4194
char x[2]
Definition: json.hpp:4195
Definition: json.hpp:4190
static one test(decltype(&C::capacity))
char one
Definition: json.hpp:4191
@ value
Definition: json.hpp:4201
static two test(...)
Definition: json.hpp:3882
detected_t< result_of_end, t_ref > sentinel
Definition: json.hpp:3887
detected_t< result_of_begin, t_ref > iterator
Definition: json.hpp:3886
typename std::add_lvalue_reference< T >::type t_ref
Definition: json.hpp:3884
static constexpr bool value
Definition: json.hpp:3896
static constexpr auto is_iterator_begin
Definition: json.hpp:3892
Definition: json.hpp:9797
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9802
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9803
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9806
typename BasicJsonType::exception exception_t
Definition: json.hpp:9807
typename BasicJsonType::string_t string_t
Definition: json.hpp:9805
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9804
Definition: json.hpp:9766
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9775
typename BasicJsonType::exception exception_t
Definition: json.hpp:9776
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9773
typename BasicJsonType::string_t string_t
Definition: json.hpp:9774
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9772
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9771
Definition: json.hpp:4123
Definition: json.hpp:4359
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6908
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6912
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:6886
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6885
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6888
IteratorType iterator_type
Definition: json.hpp:6884
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3435
Definition: json.hpp:3423
Definition: json.hpp:3404
Default base class of the basic_json class.
Definition: json.hpp:14563
Definition: json.hpp:263
void type
Definition: json.hpp:264
Definition: json.hpp:3823
Definition: json.hpp:278
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:15722
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:3166
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:3170
std::size_t lines_read
the number of lines read
Definition: json.hpp:3172
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:3168
Definition: json.hpp:3337
Definition: json.hpp:3336
Definition: json.hpp:3342
static constexpr JSON_INLINE_VARIABLE T value
Definition: json.hpp:3343
Definition: json.hpp:6148
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:6150
Definition: json.hpp:3273
Definition: json.hpp:3292
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:3294
static constexpr bool test(T val)
Definition: json.hpp:4290
static constexpr bool test(T)
Definition: json.hpp:4299
Definition: json.hpp:4285
static constexpr bool test(T val)
Definition: json.hpp:4244
static constexpr bool test(T val)
Definition: json.hpp:4264
static constexpr bool test(T val)
Definition: json.hpp:4254
static constexpr bool test(T val)
Definition: json.hpp:4274
Definition: json.hpp:4239
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:6771
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:6713
Definition: json.hpp:6707
Definition: json.hpp:14626
T type
Definition: json.hpp:14627
SAX interface.
Definition: json.hpp:8729
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:8730
typename BasicJsonType::string_t string_t
Definition: json.hpp:8733
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:8732
virtual bool null()=0
a null value was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8731
json_sax(json_sax &&) noexcept=default
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8734
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
Definition: pugixml.cpp:7582
an iterator value
Definition: json.hpp:11160
a minimal map-like container that preserves insertion order
Definition: json.hpp:19836
const T & at(const key_type &key) const
Definition: json.hpp:19940
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:19839
const T & operator[](const key_type &key) const
Definition: json.hpp:19900
std::pair< iterator, bool > emplace(KeyType &&key, T &&t)
Definition: json.hpp:19875
typename Container::value_type value_type
Definition: json.hpp:19843
std::equal_to< Key > key_compare
Definition: json.hpp:19847
iterator erase(iterator pos)
Definition: json.hpp:20008
T mapped_type
Definition: json.hpp:19838
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.hpp:19853
typename Container::iterator iterator
Definition: json.hpp:19840
T & operator[](KeyType &&key)
Definition: json.hpp:19895
iterator find(const key_type &key)
Definition: json.hpp:20092
T & at(const key_type &key)
Definition: json.hpp:19912
iterator erase(iterator first, iterator last)
Definition: json.hpp:20013
const_iterator find(const key_type &key) const
Definition: json.hpp:20118
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:20135
size_type erase(KeyType &&key)
Definition: json.hpp:19989
typename Container::size_type size_type
Definition: json.hpp:19842
const T & at(KeyType &&key) const
Definition: json.hpp:19955
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:19860
ordered_map() noexcept(noexcept(Container()))
Definition: json.hpp:19852
void insert(InputIt first, InputIt last)
Definition: json.hpp:20153
T & operator[](const key_type &key)
Definition: json.hpp:19888
size_type count(const key_type &key) const
Definition: json.hpp:20066
size_type erase(const key_type &key)
Definition: json.hpp:19968
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:20130
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.hpp:19857
size_type count(KeyType &&key) const
Definition: json.hpp:20080
Key key_type
Definition: json.hpp:19837
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:19855
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:20150
iterator find(KeyType &&key)
Definition: json.hpp:20106
T & at(KeyType &&key)
Definition: json.hpp:19927
typename Container::const_iterator const_iterator
Definition: json.hpp:19841
const T & operator[](KeyType &&key) const
Definition: json.hpp:19907
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.hpp:25368
bool operator()(::nlohmann::detail::value_t lhs, ::nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:25382
#define const
Definition: zconf.h:233