Orderbook Simulation
OrderbookSim is a C++ application simulating a financial market order book. It efficiently manages and matches buy and sell orders while calculating the Volume-Weighted Average Price (VWAP).
json.hpp
Go to the documentation of this file.
1 // __ _____ _____ _____
2 // __| | __| | | | JSON for Modern C++
3 // | | |__ | | | | | | version 3.11.3
4 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5 //
6 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
7 // SPDX-License-Identifier: MIT
8 
9 /****************************************************************************\
10  * Note on documentation: The source files contain links to the online *
11  * documentation of the public API at https://json.nlohmann.me. This URL *
12  * contains the most recent documentation and should also be applicable to *
13  * previous versions; documentation for deprecated functions is not *
14  * removed, but marked deprecated. See "Generate documentation" section in *
15  * file docs/README.md. *
16 \****************************************************************************/
17 
18 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
19 #define INCLUDE_NLOHMANN_JSON_HPP_
20 
21 #include <algorithm> // all_of, find, for_each
22 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
23 #include <functional> // hash, less
24 #include <initializer_list> // initializer_list
25 #ifndef JSON_NO_IO
26 #include <iosfwd> // istream, ostream
27 #endif // JSON_NO_IO
28 #include <iterator> // random_access_iterator_tag
29 #include <memory> // unique_ptr
30 #include <string> // string, stoi, to_string
31 #include <utility> // declval, forward, move, pair, swap
32 #include <vector> // vector
33 
34 // #include <nlohmann/adl_serializer.hpp>
35 // __ _____ _____ _____
36 // __| | __| | | | JSON for Modern C++
37 // | | |__ | | | | | | version 3.11.3
38 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
39 //
40 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
41 // SPDX-License-Identifier: MIT
42 
43 
44 
45 #include <utility>
46 
47 // #include <nlohmann/detail/abi_macros.hpp>
48 // __ _____ _____ _____
49 // __| | __| | | | JSON for Modern C++
50 // | | |__ | | | | | | version 3.11.3
51 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
52 //
53 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
54 // SPDX-License-Identifier: MIT
55 
56 
57 
58 // This file contains all macro definitions affecting or depending on the ABI
59 
60 #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
61 #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
62 #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 3
63 #warning "Already included a different version of the library!"
64 #endif
65 #endif
66 #endif
67 
68 #define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
69 #define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum)
70 #define NLOHMANN_JSON_VERSION_PATCH 3 // NOLINT(modernize-macro-to-enum)
71 
72 #ifndef JSON_DIAGNOSTICS
73 #define JSON_DIAGNOSTICS 0
74 #endif
75 
76 #ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
77 #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
78 #endif
79 
80 #if JSON_DIAGNOSTICS
81 #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
82 #else
83 #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
84 #endif
85 
86 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
87 #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
88 #else
89 #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
90 #endif
91 
92 #ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
93 #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
94 #endif
95 
96 // Construct the namespace ABI tags component
97 #define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
98 #define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
99  NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
100 
101 #define NLOHMANN_JSON_ABI_TAGS \
102  NLOHMANN_JSON_ABI_TAGS_CONCAT( \
103  NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
104  NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
105 
106 // Construct the namespace version component
107 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
108  _v ## major ## _ ## minor ## _ ## patch
109 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
110  NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
111 
112 #if NLOHMANN_JSON_NAMESPACE_NO_VERSION
113 #define NLOHMANN_JSON_NAMESPACE_VERSION
114 #else
115 #define NLOHMANN_JSON_NAMESPACE_VERSION \
116  NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
117  NLOHMANN_JSON_VERSION_MINOR, \
118  NLOHMANN_JSON_VERSION_PATCH)
119 #endif
120 
121 // Combine namespace components
122 #define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
123 #define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
124  NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
125 
126 #ifndef NLOHMANN_JSON_NAMESPACE
127 #define NLOHMANN_JSON_NAMESPACE \
128  nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
129  NLOHMANN_JSON_ABI_TAGS, \
130  NLOHMANN_JSON_NAMESPACE_VERSION)
131 #endif
132 
133 #ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
134 #define NLOHMANN_JSON_NAMESPACE_BEGIN \
135  namespace nlohmann \
136  { \
137  inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
138  NLOHMANN_JSON_ABI_TAGS, \
139  NLOHMANN_JSON_NAMESPACE_VERSION) \
140  {
141 #endif
142 
143 #ifndef NLOHMANN_JSON_NAMESPACE_END
144 #define NLOHMANN_JSON_NAMESPACE_END \
145  } /* namespace (inline namespace) NOLINT(readability/namespace) */ \
146  } // namespace nlohmann
147 #endif
148 
149 // #include <nlohmann/detail/conversions/from_json.hpp>
150 // __ _____ _____ _____
151 // __| | __| | | | JSON for Modern C++
152 // | | |__ | | | | | | version 3.11.3
153 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
154 //
155 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
156 // SPDX-License-Identifier: MIT
157 
158 
159 
160 #include <algorithm> // transform
161 #include <array> // array
162 #include <forward_list> // forward_list
163 #include <iterator> // inserter, front_inserter, end
164 #include <map> // map
165 #include <string> // string
166 #include <tuple> // tuple, make_tuple
167 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
168 #include <unordered_map> // unordered_map
169 #include <utility> // pair, declval
170 #include <valarray> // valarray
171 
172 // #include <nlohmann/detail/exceptions.hpp>
173 // __ _____ _____ _____
174 // __| | __| | | | JSON for Modern C++
175 // | | |__ | | | | | | version 3.11.3
176 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
177 //
178 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
179 // SPDX-License-Identifier: MIT
180 
181 
182 
183 #include <cstddef> // nullptr_t
184 #include <exception> // exception
185 #if JSON_DIAGNOSTICS
186 #include <numeric> // accumulate
187 #endif
188 #include <stdexcept> // runtime_error
189 #include <string> // to_string
190 #include <vector> // vector
191 
192 // #include <nlohmann/detail/value_t.hpp>
193 // __ _____ _____ _____
194 // __| | __| | | | JSON for Modern C++
195 // | | |__ | | | | | | version 3.11.3
196 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
197 //
198 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
199 // SPDX-License-Identifier: MIT
200 
201 
202 
203 #include <array> // array
204 #include <cstddef> // size_t
205 #include <cstdint> // uint8_t
206 #include <string> // string
207 
208 // #include <nlohmann/detail/macro_scope.hpp>
209 // __ _____ _____ _____
210 // __| | __| | | | JSON for Modern C++
211 // | | |__ | | | | | | version 3.11.3
212 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
213 //
214 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
215 // SPDX-License-Identifier: MIT
216 
217 
218 
219 #include <utility> // declval, pair
220 // #include <nlohmann/detail/meta/detected.hpp>
221 // __ _____ _____ _____
222 // __| | __| | | | JSON for Modern C++
223 // | | |__ | | | | | | version 3.11.3
224 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
225 //
226 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
227 // SPDX-License-Identifier: MIT
228 
229 
230 
231 #include <type_traits>
232 
233 // #include <nlohmann/detail/meta/void_t.hpp>
234 // __ _____ _____ _____
235 // __| | __| | | | JSON for Modern C++
236 // | | |__ | | | | | | version 3.11.3
237 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
238 //
239 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
240 // SPDX-License-Identifier: MIT
241 
242 
243 
244 // #include <nlohmann/detail/abi_macros.hpp>
245 
246 
248 namespace detail
249 {
250 
251  template<typename ...Ts> struct make_void
252  {
253  using type = void;
254  };
255  template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
256 
257 } // namespace detail
259 
260 
262 namespace detail
263 {
264 
265  // https://en.cppreference.com/w/cpp/experimental/is_detected
266  struct nonesuch
267  {
268  nonesuch() = delete;
269  ~nonesuch() = delete;
270  nonesuch(nonesuch const&) = delete;
271  nonesuch(nonesuch const&&) = delete;
272  void operator=(nonesuch const&) = delete;
273  void operator=(nonesuch&&) = delete;
274  };
275 
276  template<class Default,
277  class AlwaysVoid,
278  template<class...> class Op,
279  class... Args>
280  struct detector
281  {
282  using value_t = std::false_type;
283  using type = Default;
284  };
285 
286  template<class Default, template<class...> class Op, class... Args>
287  struct detector<Default, void_t<Op<Args...>>, Op, Args...>
288  {
289  using value_t = std::true_type;
290  using type = Op<Args...>;
291  };
292 
293  template<template<class...> class Op, class... Args>
294  using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
295 
296  template<template<class...> class Op, class... Args>
297  struct is_detected_lazy : is_detected<Op, Args...> { };
298 
299  template<template<class...> class Op, class... Args>
300  using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
301 
302  template<class Default, template<class...> class Op, class... Args>
303  using detected_or = detector<Default, void, Op, Args...>;
304 
305  template<class Default, template<class...> class Op, class... Args>
306  using detected_or_t = typename detected_or<Default, Op, Args...>::type;
307 
308  template<class Expected, template<class...> class Op, class... Args>
309  using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
310 
311  template<class To, template<class...> class Op, class... Args>
313  std::is_convertible<detected_t<Op, Args...>, To>;
314 
315 } // namespace detail
317 
318 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
319 
320 
321 // __ _____ _____ _____
322 // __| | __| | | | JSON for Modern C++
323 // | | |__ | | | | | | version 3.11.3
324 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
325 //
326 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
327 // SPDX-FileCopyrightText: 2016-2021 Evan Nemerson <evan@nemerson.com>
328 // SPDX-License-Identifier: MIT
329 
330 /* Hedley - https://nemequ.github.io/hedley
331  * Created by Evan Nemerson <evan@nemerson.com>
332  */
333 
334 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
335 #if defined(JSON_HEDLEY_VERSION)
336 #undef JSON_HEDLEY_VERSION
337 #endif
338 #define JSON_HEDLEY_VERSION 15
339 
340 #if defined(JSON_HEDLEY_STRINGIFY_EX)
341 #undef JSON_HEDLEY_STRINGIFY_EX
342 #endif
343 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
344 
345 #if defined(JSON_HEDLEY_STRINGIFY)
346 #undef JSON_HEDLEY_STRINGIFY
347 #endif
348 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
349 
350 #if defined(JSON_HEDLEY_CONCAT_EX)
351 #undef JSON_HEDLEY_CONCAT_EX
352 #endif
353 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
354 
355 #if defined(JSON_HEDLEY_CONCAT)
356 #undef JSON_HEDLEY_CONCAT
357 #endif
358 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
359 
360 #if defined(JSON_HEDLEY_CONCAT3_EX)
361 #undef JSON_HEDLEY_CONCAT3_EX
362 #endif
363 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
364 
365 #if defined(JSON_HEDLEY_CONCAT3)
366 #undef JSON_HEDLEY_CONCAT3
367 #endif
368 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
369 
370 #if defined(JSON_HEDLEY_VERSION_ENCODE)
371 #undef JSON_HEDLEY_VERSION_ENCODE
372 #endif
373 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
374 
375 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
376 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
377 #endif
378 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
379 
380 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
381 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
382 #endif
383 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
384 
385 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
386 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
387 #endif
388 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
389 
390 #if defined(JSON_HEDLEY_GNUC_VERSION)
391 #undef JSON_HEDLEY_GNUC_VERSION
392 #endif
393 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
394 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
395 #elif defined(__GNUC__)
396 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
397 #endif
398 
399 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
400 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
401 #endif
402 #if defined(JSON_HEDLEY_GNUC_VERSION)
403 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
404 #else
405 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
406 #endif
407 
408 #if defined(JSON_HEDLEY_MSVC_VERSION)
409 #undef JSON_HEDLEY_MSVC_VERSION
410 #endif
411 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
412 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
413 #elif defined(_MSC_FULL_VER) && !defined(__ICL)
414 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
415 #elif defined(_MSC_VER) && !defined(__ICL)
416 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
417 #endif
418 
419 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
420 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
421 #endif
422 #if !defined(JSON_HEDLEY_MSVC_VERSION)
423 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
424 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
425 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
426 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
427 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
428 #else
429 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
430 #endif
431 
432 #if defined(JSON_HEDLEY_INTEL_VERSION)
433 #undef JSON_HEDLEY_INTEL_VERSION
434 #endif
435 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
436 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
437 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
438 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
439 #endif
440 
441 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
442 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
443 #endif
444 #if defined(JSON_HEDLEY_INTEL_VERSION)
445 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446 #else
447 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
448 #endif
449 
450 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
451 #undef JSON_HEDLEY_INTEL_CL_VERSION
452 #endif
453 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
454 #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
455 #endif
456 
457 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
458 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
459 #endif
460 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
461 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462 #else
463 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
464 #endif
465 
466 #if defined(JSON_HEDLEY_PGI_VERSION)
467 #undef JSON_HEDLEY_PGI_VERSION
468 #endif
469 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
470 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
471 #endif
472 
473 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
474 #undef JSON_HEDLEY_PGI_VERSION_CHECK
475 #endif
476 #if defined(JSON_HEDLEY_PGI_VERSION)
477 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
478 #else
479 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
480 #endif
481 
482 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
483 #undef JSON_HEDLEY_SUNPRO_VERSION
484 #endif
485 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
486 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
487 #elif defined(__SUNPRO_C)
488 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
489 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
490 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
491 #elif defined(__SUNPRO_CC)
492 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
493 #endif
494 
495 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
496 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
497 #endif
498 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
499 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
500 #else
501 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
502 #endif
503 
504 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
505 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
506 #endif
507 #if defined(__EMSCRIPTEN__)
508 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
509 #endif
510 
511 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
512 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
513 #endif
514 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
515 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
516 #else
517 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
518 #endif
519 
520 #if defined(JSON_HEDLEY_ARM_VERSION)
521 #undef JSON_HEDLEY_ARM_VERSION
522 #endif
523 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
524 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
525 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
526 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
527 #endif
528 
529 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
530 #undef JSON_HEDLEY_ARM_VERSION_CHECK
531 #endif
532 #if defined(JSON_HEDLEY_ARM_VERSION)
533 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
534 #else
535 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
536 #endif
537 
538 #if defined(JSON_HEDLEY_IBM_VERSION)
539 #undef JSON_HEDLEY_IBM_VERSION
540 #endif
541 #if defined(__ibmxl__)
542 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
543 #elif defined(__xlC__) && defined(__xlC_ver__)
544 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
545 #elif defined(__xlC__)
546 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
547 #endif
548 
549 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
550 #undef JSON_HEDLEY_IBM_VERSION_CHECK
551 #endif
552 #if defined(JSON_HEDLEY_IBM_VERSION)
553 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
554 #else
555 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
556 #endif
557 
558 #if defined(JSON_HEDLEY_TI_VERSION)
559 #undef JSON_HEDLEY_TI_VERSION
560 #endif
561 #if \
562  defined(__TI_COMPILER_VERSION__) && \
563  ( \
564  defined(__TMS470__) || defined(__TI_ARM__) || \
565  defined(__MSP430__) || \
566  defined(__TMS320C2000__) \
567  )
568 #if (__TI_COMPILER_VERSION__ >= 16000000)
569 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
570 #endif
571 #endif
572 
573 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
574 #undef JSON_HEDLEY_TI_VERSION_CHECK
575 #endif
576 #if defined(JSON_HEDLEY_TI_VERSION)
577 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
578 #else
579 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
580 #endif
581 
582 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
583 #undef JSON_HEDLEY_TI_CL2000_VERSION
584 #endif
585 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
586 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
587 #endif
588 
589 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
590 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
591 #endif
592 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
593 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
594 #else
595 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
596 #endif
597 
598 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
599 #undef JSON_HEDLEY_TI_CL430_VERSION
600 #endif
601 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
602 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
603 #endif
604 
605 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
606 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
607 #endif
608 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
609 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
610 #else
611 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
612 #endif
613 
614 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
615 #undef JSON_HEDLEY_TI_ARMCL_VERSION
616 #endif
617 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
618 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
619 #endif
620 
621 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
622 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
623 #endif
624 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
625 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
626 #else
627 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
628 #endif
629 
630 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
631 #undef JSON_HEDLEY_TI_CL6X_VERSION
632 #endif
633 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
634 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
635 #endif
636 
637 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
638 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
639 #endif
640 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
641 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
642 #else
643 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
644 #endif
645 
646 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
647 #undef JSON_HEDLEY_TI_CL7X_VERSION
648 #endif
649 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
650 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
651 #endif
652 
653 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
654 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
655 #endif
656 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
657 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
658 #else
659 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
660 #endif
661 
662 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
663 #undef JSON_HEDLEY_TI_CLPRU_VERSION
664 #endif
665 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
666 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
667 #endif
668 
669 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
670 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
671 #endif
672 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
673 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
674 #else
675 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
676 #endif
677 
678 #if defined(JSON_HEDLEY_CRAY_VERSION)
679 #undef JSON_HEDLEY_CRAY_VERSION
680 #endif
681 #if defined(_CRAYC)
682 #if defined(_RELEASE_PATCHLEVEL)
683 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
684 #else
685 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
686 #endif
687 #endif
688 
689 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
690 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
691 #endif
692 #if defined(JSON_HEDLEY_CRAY_VERSION)
693 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
694 #else
695 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
696 #endif
697 
698 #if defined(JSON_HEDLEY_IAR_VERSION)
699 #undef JSON_HEDLEY_IAR_VERSION
700 #endif
701 #if defined(__IAR_SYSTEMS_ICC__)
702 #if __VER__ > 1000
703 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
704 #else
705 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
706 #endif
707 #endif
708 
709 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
710 #undef JSON_HEDLEY_IAR_VERSION_CHECK
711 #endif
712 #if defined(JSON_HEDLEY_IAR_VERSION)
713 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
714 #else
715 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
716 #endif
717 
718 #if defined(JSON_HEDLEY_TINYC_VERSION)
719 #undef JSON_HEDLEY_TINYC_VERSION
720 #endif
721 #if defined(__TINYC__)
722 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
723 #endif
724 
725 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
726 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
727 #endif
728 #if defined(JSON_HEDLEY_TINYC_VERSION)
729 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
730 #else
731 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
732 #endif
733 
734 #if defined(JSON_HEDLEY_DMC_VERSION)
735 #undef JSON_HEDLEY_DMC_VERSION
736 #endif
737 #if defined(__DMC__)
738 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
739 #endif
740 
741 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
742 #undef JSON_HEDLEY_DMC_VERSION_CHECK
743 #endif
744 #if defined(JSON_HEDLEY_DMC_VERSION)
745 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
746 #else
747 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
748 #endif
749 
750 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
751 #undef JSON_HEDLEY_COMPCERT_VERSION
752 #endif
753 #if defined(__COMPCERT_VERSION__)
754 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
755 #endif
756 
757 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
758 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
759 #endif
760 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
761 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
762 #else
763 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
764 #endif
765 
766 #if defined(JSON_HEDLEY_PELLES_VERSION)
767 #undef JSON_HEDLEY_PELLES_VERSION
768 #endif
769 #if defined(__POCC__)
770 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
771 #endif
772 
773 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
774 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
775 #endif
776 #if defined(JSON_HEDLEY_PELLES_VERSION)
777 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
778 #else
779 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
780 #endif
781 
782 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
783 #undef JSON_HEDLEY_MCST_LCC_VERSION
784 #endif
785 #if defined(__LCC__) && defined(__LCC_MINOR__)
786 #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
787 #endif
788 
789 #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
790 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
791 #endif
792 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
793 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
794 #else
795 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
796 #endif
797 
798 #if defined(JSON_HEDLEY_GCC_VERSION)
799 #undef JSON_HEDLEY_GCC_VERSION
800 #endif
801 #if \
802  defined(JSON_HEDLEY_GNUC_VERSION) && \
803  !defined(__clang__) && \
804  !defined(JSON_HEDLEY_INTEL_VERSION) && \
805  !defined(JSON_HEDLEY_PGI_VERSION) && \
806  !defined(JSON_HEDLEY_ARM_VERSION) && \
807  !defined(JSON_HEDLEY_CRAY_VERSION) && \
808  !defined(JSON_HEDLEY_TI_VERSION) && \
809  !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
810  !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
811  !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
812  !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
813  !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
814  !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
815  !defined(__COMPCERT__) && \
816  !defined(JSON_HEDLEY_MCST_LCC_VERSION)
817 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
818 #endif
819 
820 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
821 #undef JSON_HEDLEY_GCC_VERSION_CHECK
822 #endif
823 #if defined(JSON_HEDLEY_GCC_VERSION)
824 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
825 #else
826 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
827 #endif
828 
829 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
830 #undef JSON_HEDLEY_HAS_ATTRIBUTE
831 #endif
832 #if \
833  defined(__has_attribute) && \
834  ( \
835  (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
836  )
837 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
838 #else
839 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
840 #endif
841 
842 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
843 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
844 #endif
845 #if defined(__has_attribute)
846 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
847 #else
848 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
849 #endif
850 
851 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
852 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
853 #endif
854 #if defined(__has_attribute)
855 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
856 #else
857 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
858 #endif
859 
860 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
861 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
862 #endif
863 #if \
864  defined(__has_cpp_attribute) && \
865  defined(__cplusplus) && \
866  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
867 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
868 #else
869 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
870 #endif
871 
872 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
873 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
874 #endif
875 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
876 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
877 #elif \
878  !defined(JSON_HEDLEY_PGI_VERSION) && \
879  !defined(JSON_HEDLEY_IAR_VERSION) && \
880  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
881  (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
882 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
883 #else
884 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
885 #endif
886 
887 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
888 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
889 #endif
890 #if defined(__has_cpp_attribute) && defined(__cplusplus)
891 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
892 #else
893 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
894 #endif
895 
896 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
897 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
898 #endif
899 #if defined(__has_cpp_attribute) && defined(__cplusplus)
900 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
901 #else
902 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
903 #endif
904 
905 #if defined(JSON_HEDLEY_HAS_BUILTIN)
906 #undef JSON_HEDLEY_HAS_BUILTIN
907 #endif
908 #if defined(__has_builtin)
909 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
910 #else
911 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
912 #endif
913 
914 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
915 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
916 #endif
917 #if defined(__has_builtin)
918 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
919 #else
920 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
921 #endif
922 
923 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
924 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
925 #endif
926 #if defined(__has_builtin)
927 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
928 #else
929 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
930 #endif
931 
932 #if defined(JSON_HEDLEY_HAS_FEATURE)
933 #undef JSON_HEDLEY_HAS_FEATURE
934 #endif
935 #if defined(__has_feature)
936 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
937 #else
938 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
939 #endif
940 
941 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
942 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
943 #endif
944 #if defined(__has_feature)
945 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
946 #else
947 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
948 #endif
949 
950 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
951 #undef JSON_HEDLEY_GCC_HAS_FEATURE
952 #endif
953 #if defined(__has_feature)
954 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
955 #else
956 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
957 #endif
958 
959 #if defined(JSON_HEDLEY_HAS_EXTENSION)
960 #undef JSON_HEDLEY_HAS_EXTENSION
961 #endif
962 #if defined(__has_extension)
963 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
964 #else
965 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
966 #endif
967 
968 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
969 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
970 #endif
971 #if defined(__has_extension)
972 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
973 #else
974 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
975 #endif
976 
977 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
978 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
979 #endif
980 #if defined(__has_extension)
981 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
982 #else
983 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
984 #endif
985 
986 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
987 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
988 #endif
989 #if defined(__has_declspec_attribute)
990 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
991 #else
992 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
993 #endif
994 
995 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
996 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
997 #endif
998 #if defined(__has_declspec_attribute)
999 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1000 #else
1001 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1002 #endif
1003 
1004 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
1005 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
1006 #endif
1007 #if defined(__has_declspec_attribute)
1008 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1009 #else
1010 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1011 #endif
1012 
1013 #if defined(JSON_HEDLEY_HAS_WARNING)
1014 #undef JSON_HEDLEY_HAS_WARNING
1015 #endif
1016 #if defined(__has_warning)
1017 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
1018 #else
1019 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
1020 #endif
1021 
1022 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
1023 #undef JSON_HEDLEY_GNUC_HAS_WARNING
1024 #endif
1025 #if defined(__has_warning)
1026 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1027 #else
1028 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1029 #endif
1030 
1031 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
1032 #undef JSON_HEDLEY_GCC_HAS_WARNING
1033 #endif
1034 #if defined(__has_warning)
1035 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1036 #else
1037 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1038 #endif
1039 
1040 #if \
1041  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1042  defined(__clang__) || \
1043  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1044  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1045  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1046  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1047  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1048  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1049  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1050  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1051  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1052  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
1053  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1054  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1055  JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
1056  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
1057  JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
1058  (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
1059 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
1060 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1061 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
1062 #else
1063 #define JSON_HEDLEY_PRAGMA(value)
1064 #endif
1065 
1066 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
1067 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
1068 #endif
1069 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
1070 #undef JSON_HEDLEY_DIAGNOSTIC_POP
1071 #endif
1072 #if defined(__clang__)
1073 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
1074 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
1075 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1076 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1077 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1078 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1079 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
1080 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
1081 #elif \
1082  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1083  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1084 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
1085 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
1086 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
1087 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
1088 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
1089 #elif \
1090  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1091  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1092  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
1093  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1094  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1095  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1096 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
1097 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
1098 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1099 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1100 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1101 #else
1102 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
1103 #define JSON_HEDLEY_DIAGNOSTIC_POP
1104 #endif
1105 
1106  /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
1107  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1108 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1109 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
1110 #endif
1111 #if defined(__cplusplus)
1112 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
1113 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
1114 # if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
1115 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1116  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1117  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1118  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1119  _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
1120  xpr \
1121  JSON_HEDLEY_DIAGNOSTIC_POP
1122 # else
1123 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1124  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1125  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1126  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1127  xpr \
1128  JSON_HEDLEY_DIAGNOSTIC_POP
1129 # endif
1130 # else
1131 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1132  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1133  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1134  xpr \
1135  JSON_HEDLEY_DIAGNOSTIC_POP
1136 # endif
1137 # endif
1138 #endif
1139 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1140 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1141 #endif
1142 
1143 #if defined(JSON_HEDLEY_CONST_CAST)
1144 #undef JSON_HEDLEY_CONST_CAST
1145 #endif
1146 #if defined(__cplusplus)
1147 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1148 #elif \
1149  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1150  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1151  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1152 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1153  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1154  JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1155  ((T) (expr)); \
1156  JSON_HEDLEY_DIAGNOSTIC_POP \
1157  }))
1158 #else
1159 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1160 #endif
1161 
1162 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
1163 #undef JSON_HEDLEY_REINTERPRET_CAST
1164 #endif
1165 #if defined(__cplusplus)
1166 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1167 #else
1168 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1169 #endif
1170 
1171 #if defined(JSON_HEDLEY_STATIC_CAST)
1172 #undef JSON_HEDLEY_STATIC_CAST
1173 #endif
1174 #if defined(__cplusplus)
1175 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1176 #else
1177 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1178 #endif
1179 
1180 #if defined(JSON_HEDLEY_CPP_CAST)
1181 #undef JSON_HEDLEY_CPP_CAST
1182 #endif
1183 #if defined(__cplusplus)
1184 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1185 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1186  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1187  _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1188  ((T) (expr)) \
1189  JSON_HEDLEY_DIAGNOSTIC_POP
1190 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1191 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1192  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1193  _Pragma("diag_suppress=Pe137") \
1194  JSON_HEDLEY_DIAGNOSTIC_POP
1195 # else
1196 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1197 # endif
1198 #else
1199 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1200 #endif
1201 
1202 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1203 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1204 #endif
1205 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1206 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1207 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1208 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1209 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1210 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1211 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1212 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1213 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1214 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1215 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1216 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1217 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1218 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1219 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1220 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1221 #elif \
1222  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1233 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1234 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1235 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1236 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1237 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1238 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1239 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1240 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1241 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1242 #else
1243 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1244 #endif
1245 
1246 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1247 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1248 #endif
1249 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1250 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1251 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1252 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1253 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1254 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1255 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1256 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1257 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1258 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1259 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1260 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1261 #elif \
1262  JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1263  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1264  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1265  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1266 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1267 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1268 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1269 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1270 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1271 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1272 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1273 #else
1274 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1275 #endif
1276 
1277 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1278 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1279 #endif
1280 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1281 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1282 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1283 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1284 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1285 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1286 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1287 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1288 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1289 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1290 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1291 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1292 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1293 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1294 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1295 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1296 #elif \
1297  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1298  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1299  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1300 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1301 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1302 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1303 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1304 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1305 #else
1306 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1307 #endif
1308 
1309 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1310 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1311 #endif
1312 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1313 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1314 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1315 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1316 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1317 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1318 #else
1319 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1320 #endif
1321 
1322 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1323 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1324 #endif
1325 #if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1326 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1327 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1328 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1329 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1330 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1331 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1332 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1333 #else
1334 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1335 #endif
1336 
1337 #if defined(JSON_HEDLEY_DEPRECATED)
1338 #undef JSON_HEDLEY_DEPRECATED
1339 #endif
1340 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1341 #undef JSON_HEDLEY_DEPRECATED_FOR
1342 #endif
1343 #if \
1344  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1345  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1346 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1347 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1348 #elif \
1349  (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1350  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1351  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1352  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1353  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1354  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1355  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1356  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1357  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1358  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1359  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1360  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1361 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1362 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1363 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1364 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1365 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1366 #elif \
1367  JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1368  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1369  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1370  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1371  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1372  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1373  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1374  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1375  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1376  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1377  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1378  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1379  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1380  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1381  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1382  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1383 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1384 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1385 #elif \
1386  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1387  JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1388  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1389 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1390 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1391 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1392 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1393 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1394 #else
1395 #define JSON_HEDLEY_DEPRECATED(since)
1396 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1397 #endif
1398 
1399 #if defined(JSON_HEDLEY_UNAVAILABLE)
1400 #undef JSON_HEDLEY_UNAVAILABLE
1401 #endif
1402 #if \
1403  JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1404  JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1405  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1406  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1407 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1408 #else
1409 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1410 #endif
1411 
1412 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1413 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1414 #endif
1415 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1416 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1417 #endif
1418 #if \
1419  JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1420  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1421  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1422  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1423  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1424  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1425  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1426  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1427  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1428  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1429  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1430  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1431  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1432  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1433  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1434  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1435  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1436 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1437 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1438 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1439 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1440 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1441 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1442 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1443 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1444 #elif defined(_Check_return_) /* SAL */
1445 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1446 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1447 #else
1448 #define JSON_HEDLEY_WARN_UNUSED_RESULT
1449 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1450 #endif
1451 
1452 #if defined(JSON_HEDLEY_SENTINEL)
1453 #undef JSON_HEDLEY_SENTINEL
1454 #endif
1455 #if \
1456  JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1457  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1458  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1459  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1460  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1461 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1462 #else
1463 #define JSON_HEDLEY_SENTINEL(position)
1464 #endif
1465 
1466 #if defined(JSON_HEDLEY_NO_RETURN)
1467 #undef JSON_HEDLEY_NO_RETURN
1468 #endif
1469 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1470 #define JSON_HEDLEY_NO_RETURN __noreturn
1471 #elif \
1472  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1474 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1475 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1476 #define JSON_HEDLEY_NO_RETURN _Noreturn
1477 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1478 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1479 #elif \
1480  JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1481  JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1482  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1483  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1484  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1485  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1486  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1487  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1488  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1489  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1490  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1491  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1492  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1493  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1494  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1495  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1496  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1497 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1498 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1499 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1500 #elif \
1501  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1502  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1503 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1504 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1505 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1506 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1507 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1508 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1509 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1510 #else
1511 #define JSON_HEDLEY_NO_RETURN
1512 #endif
1513 
1514 #if defined(JSON_HEDLEY_NO_ESCAPE)
1515 #undef JSON_HEDLEY_NO_ESCAPE
1516 #endif
1517 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1518 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1519 #else
1520 #define JSON_HEDLEY_NO_ESCAPE
1521 #endif
1522 
1523 #if defined(JSON_HEDLEY_UNREACHABLE)
1524 #undef JSON_HEDLEY_UNREACHABLE
1525 #endif
1526 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1527 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1528 #endif
1529 #if defined(JSON_HEDLEY_ASSUME)
1530 #undef JSON_HEDLEY_ASSUME
1531 #endif
1532 #if \
1533  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1534  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1535  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1536 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1537 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1538 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1539 #elif \
1540  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1541  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1542 #if defined(__cplusplus)
1543 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1544 #else
1545 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1546 #endif
1547 #endif
1548 #if \
1549  (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1550  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1551  JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1552  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1553  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1554  JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1555  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1556 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1557 #elif defined(JSON_HEDLEY_ASSUME)
1558 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1559 #endif
1560 #if !defined(JSON_HEDLEY_ASSUME)
1561 #if defined(JSON_HEDLEY_UNREACHABLE)
1562 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1563 #else
1564 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1565 #endif
1566 #endif
1567 #if defined(JSON_HEDLEY_UNREACHABLE)
1568 #if \
1569  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1570  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1571 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1572 #else
1573 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1574 #endif
1575 #else
1576 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1577 #endif
1578 #if !defined(JSON_HEDLEY_UNREACHABLE)
1579 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1580 #endif
1581 
1583 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1584 #pragma clang diagnostic ignored "-Wpedantic"
1585 #endif
1586 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1587 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1588 #endif
1589 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1590 #if defined(__clang__)
1591 #pragma clang diagnostic ignored "-Wvariadic-macros"
1592 #elif defined(JSON_HEDLEY_GCC_VERSION)
1593 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1594 #endif
1595 #endif
1596 #if defined(JSON_HEDLEY_NON_NULL)
1597 #undef JSON_HEDLEY_NON_NULL
1598 #endif
1599 #if \
1600  JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1601  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1602  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1603  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1604 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1605 #else
1606 #define JSON_HEDLEY_NON_NULL(...)
1607 #endif
1609 
1610 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1611 #undef JSON_HEDLEY_PRINTF_FORMAT
1612 #endif
1613 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1614 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1615 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1616 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1617 #elif \
1618  JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1619  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1620  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1621  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1622  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1623  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1624  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1625  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1626  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1627  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1628  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1629  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1630  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1631  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1632  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1633  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1634  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1635 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1636 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1637 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1638 #else
1639 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1640 #endif
1641 
1642 #if defined(JSON_HEDLEY_CONSTEXPR)
1643 #undef JSON_HEDLEY_CONSTEXPR
1644 #endif
1645 #if defined(__cplusplus)
1646 #if __cplusplus >= 201103L
1647 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1648 #endif
1649 #endif
1650 #if !defined(JSON_HEDLEY_CONSTEXPR)
1651 #define JSON_HEDLEY_CONSTEXPR
1652 #endif
1653 
1654 #if defined(JSON_HEDLEY_PREDICT)
1655 #undef JSON_HEDLEY_PREDICT
1656 #endif
1657 #if defined(JSON_HEDLEY_LIKELY)
1658 #undef JSON_HEDLEY_LIKELY
1659 #endif
1660 #if defined(JSON_HEDLEY_UNLIKELY)
1661 #undef JSON_HEDLEY_UNLIKELY
1662 #endif
1663 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1664 #undef JSON_HEDLEY_UNPREDICTABLE
1665 #endif
1666 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1667 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1668 #endif
1669 #if \
1670  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1671  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1672  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1673 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1674 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1675 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1676 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1677 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1678 #elif \
1679  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1680  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1681  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1682  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1683  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1684  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1685  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1686  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1687  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1688  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1689  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1690  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1691  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1692  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1693  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1694  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1695 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1696  (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1697 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1698  (__extension__ ({ \
1699  double hedley_probability_ = (probability); \
1700  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1701  }))
1702 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1703  (__extension__ ({ \
1704  double hedley_probability_ = (probability); \
1705  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1706  }))
1707 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1708 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1709 #else
1710 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1711 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1712 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1713 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1714 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1715 #endif
1716 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1717 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1718 #endif
1719 
1720 #if defined(JSON_HEDLEY_MALLOC)
1721 #undef JSON_HEDLEY_MALLOC
1722 #endif
1723 #if \
1724  JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1725  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1726  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1727  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1728  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1729  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1730  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1731  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1732  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1733  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1734  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1735  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1736  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1737  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1738  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1739  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1740  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1741  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1742 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1743 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1744 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1745 #elif \
1746  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1747  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1748 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1749 #else
1750 #define JSON_HEDLEY_MALLOC
1751 #endif
1752 
1753 #if defined(JSON_HEDLEY_PURE)
1754 #undef JSON_HEDLEY_PURE
1755 #endif
1756 #if \
1757  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1758  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1759  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1760  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1761  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1762  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1763  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1764  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1765  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1766  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1767  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1768  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1769  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1770  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1771  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1772  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1773  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1774  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1775  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1776 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1777 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1778 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1779 #elif defined(__cplusplus) && \
1780  ( \
1781  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1782  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1783  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1784  )
1785 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1786 #else
1787 # define JSON_HEDLEY_PURE
1788 #endif
1789 
1790 #if defined(JSON_HEDLEY_CONST)
1791 #undef JSON_HEDLEY_CONST
1792 #endif
1793 #if \
1794  JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1795  JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1796  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1797  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1798  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1799  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1800  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1801  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1802  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1803  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1804  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1805  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1806  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1807  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1808  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1809  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1810  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1811  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1812  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1813 #define JSON_HEDLEY_CONST __attribute__((__const__))
1814 #elif \
1815  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1816 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1817 #else
1818 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1819 #endif
1820 
1821 #if defined(JSON_HEDLEY_RESTRICT)
1822 #undef JSON_HEDLEY_RESTRICT
1823 #endif
1824 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1825 #define JSON_HEDLEY_RESTRICT restrict
1826 #elif \
1827  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1828  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1829  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1830  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1831  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1832  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1833  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1834  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1835  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1836  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1837  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1838  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1839  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1840  defined(__clang__) || \
1841  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1842 #define JSON_HEDLEY_RESTRICT __restrict
1843 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1844 #define JSON_HEDLEY_RESTRICT _Restrict
1845 #else
1846 #define JSON_HEDLEY_RESTRICT
1847 #endif
1848 
1849 #if defined(JSON_HEDLEY_INLINE)
1850 #undef JSON_HEDLEY_INLINE
1851 #endif
1852 #if \
1853  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1854  (defined(__cplusplus) && (__cplusplus >= 199711L))
1855 #define JSON_HEDLEY_INLINE inline
1856 #elif \
1857  defined(JSON_HEDLEY_GCC_VERSION) || \
1858  JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1859 #define JSON_HEDLEY_INLINE __inline__
1860 #elif \
1861  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1862  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1863  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1864  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1865  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1866  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1867  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1868  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1869  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1870  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1871 #define JSON_HEDLEY_INLINE __inline
1872 #else
1873 #define JSON_HEDLEY_INLINE
1874 #endif
1875 
1876 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1877 #undef JSON_HEDLEY_ALWAYS_INLINE
1878 #endif
1879 #if \
1880  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1881  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1882  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1883  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1884  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1885  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1886  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1887  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1888  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1889  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1890  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1891  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1892  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1893  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1894  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1895  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1896  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1897  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1898  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1899 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1900 #elif \
1901  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1902  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1903 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1904 #elif defined(__cplusplus) && \
1905  ( \
1906  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1907  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1908  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1909  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1910  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1911  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1912  )
1913 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1914 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1915 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1916 #else
1917 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1918 #endif
1919 
1920 #if defined(JSON_HEDLEY_NEVER_INLINE)
1921 #undef JSON_HEDLEY_NEVER_INLINE
1922 #endif
1923 #if \
1924  JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1925  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1926  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1927  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1928  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1929  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1930  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1931  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1932  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1933  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1934  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1935  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1936  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1937  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1938  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1939  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1940  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1941  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1942  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1943 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1944 #elif \
1945  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1946  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1947 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1948 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1949 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1950 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1951 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1952 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1953 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1954 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1955 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1956 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1957 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1958 #else
1959 #define JSON_HEDLEY_NEVER_INLINE
1960 #endif
1961 
1962 #if defined(JSON_HEDLEY_PRIVATE)
1963 #undef JSON_HEDLEY_PRIVATE
1964 #endif
1965 #if defined(JSON_HEDLEY_PUBLIC)
1966 #undef JSON_HEDLEY_PUBLIC
1967 #endif
1968 #if defined(JSON_HEDLEY_IMPORT)
1969 #undef JSON_HEDLEY_IMPORT
1970 #endif
1971 #if defined(_WIN32) || defined(__CYGWIN__)
1972 # define JSON_HEDLEY_PRIVATE
1973 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1974 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1975 #else
1976 # if \
1977  JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1978  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1979  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1980  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1981  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1982  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1983  ( \
1984  defined(__TI_EABI__) && \
1985  ( \
1986  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1987  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1988  ) \
1989  ) || \
1990  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1991 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1992 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1993 # else
1994 # define JSON_HEDLEY_PRIVATE
1995 # define JSON_HEDLEY_PUBLIC
1996 # endif
1997 # define JSON_HEDLEY_IMPORT extern
1998 #endif
1999 
2000 #if defined(JSON_HEDLEY_NO_THROW)
2001 #undef JSON_HEDLEY_NO_THROW
2002 #endif
2003 #if \
2004  JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
2005  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
2006  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2007  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2008 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
2009 #elif \
2010  JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
2011  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
2012  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
2013 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
2014 #else
2015 #define JSON_HEDLEY_NO_THROW
2016 #endif
2017 
2018 #if defined(JSON_HEDLEY_FALL_THROUGH)
2019 #undef JSON_HEDLEY_FALL_THROUGH
2020 #endif
2021 #if \
2022  JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
2023  JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
2024  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2025 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
2026 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
2027 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
2028 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
2029 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
2030 #elif defined(__fallthrough) /* SAL */
2031 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
2032 #else
2033 #define JSON_HEDLEY_FALL_THROUGH
2034 #endif
2035 
2036 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
2037 #undef JSON_HEDLEY_RETURNS_NON_NULL
2038 #endif
2039 #if \
2040  JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
2041  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2042  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2043 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
2044 #elif defined(_Ret_notnull_) /* SAL */
2045 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
2046 #else
2047 #define JSON_HEDLEY_RETURNS_NON_NULL
2048 #endif
2049 
2050 #if defined(JSON_HEDLEY_ARRAY_PARAM)
2051 #undef JSON_HEDLEY_ARRAY_PARAM
2052 #endif
2053 #if \
2054  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
2055  !defined(__STDC_NO_VLA__) && \
2056  !defined(__cplusplus) && \
2057  !defined(JSON_HEDLEY_PGI_VERSION) && \
2058  !defined(JSON_HEDLEY_TINYC_VERSION)
2059 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
2060 #else
2061 #define JSON_HEDLEY_ARRAY_PARAM(name)
2062 #endif
2063 
2064 #if defined(JSON_HEDLEY_IS_CONSTANT)
2065 #undef JSON_HEDLEY_IS_CONSTANT
2066 #endif
2067 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
2068 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
2069 #endif
2070  /* JSON_HEDLEY_IS_CONSTEXPR_ is for
2071  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
2072 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2073 #undef JSON_HEDLEY_IS_CONSTEXPR_
2074 #endif
2075 #if \
2076  JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
2077  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2078  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2079  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
2080  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2081  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2082  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
2083  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
2084  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2085  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2086 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
2087 #endif
2088 #if !defined(__cplusplus)
2089 # if \
2090  JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
2091  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2092  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2093  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2094  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2095  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
2096  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
2097 #if defined(__INTPTR_TYPE__)
2098 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
2099 #else
2100 #include <stdint.h>
2101 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
2102 #endif
2103 # elif \
2104  ( \
2105  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
2106  !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
2107  !defined(JSON_HEDLEY_PGI_VERSION) && \
2108  !defined(JSON_HEDLEY_IAR_VERSION)) || \
2109  (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
2110  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2111  JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
2112  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
2113  JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
2114 #if defined(__INTPTR_TYPE__)
2115 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
2116 #else
2117 #include <stdint.h>
2118 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
2119 #endif
2120 # elif \
2121  defined(JSON_HEDLEY_GCC_VERSION) || \
2122  defined(JSON_HEDLEY_INTEL_VERSION) || \
2123  defined(JSON_HEDLEY_TINYC_VERSION) || \
2124  defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
2125  JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
2126  defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
2127  defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
2128  defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
2129  defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
2130  defined(__clang__)
2131 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2132  sizeof(void) != \
2133  sizeof(*( \
2134  1 ? \
2135  ((void*) ((expr) * 0L) ) : \
2136 ((struct { char v[sizeof(void) * 2]; } *) 1) \
2137  ) \
2138  ) \
2139  )
2140 # endif
2141 #endif
2142 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2143 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2144 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2145 #endif
2146 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2147 #else
2148 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2149 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2150 #endif
2151 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2152 #endif
2153 
2154 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2155 #undef JSON_HEDLEY_BEGIN_C_DECLS
2156 #endif
2157 #if defined(JSON_HEDLEY_END_C_DECLS)
2158 #undef JSON_HEDLEY_END_C_DECLS
2159 #endif
2160 #if defined(JSON_HEDLEY_C_DECL)
2161 #undef JSON_HEDLEY_C_DECL
2162 #endif
2163 #if defined(__cplusplus)
2164 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2165 #define JSON_HEDLEY_END_C_DECLS }
2166 #define JSON_HEDLEY_C_DECL extern "C"
2167 #else
2168 #define JSON_HEDLEY_BEGIN_C_DECLS
2169 #define JSON_HEDLEY_END_C_DECLS
2170 #define JSON_HEDLEY_C_DECL
2171 #endif
2172 
2173 #if defined(JSON_HEDLEY_STATIC_ASSERT)
2174 #undef JSON_HEDLEY_STATIC_ASSERT
2175 #endif
2176 #if \
2177  !defined(__cplusplus) && ( \
2178  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2179  (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2180  JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2181  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2182  defined(_Static_assert) \
2183  )
2184 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2185 #elif \
2186  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2187  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2188  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2189 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2190 #else
2191 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2192 #endif
2193 
2194 #if defined(JSON_HEDLEY_NULL)
2195 #undef JSON_HEDLEY_NULL
2196 #endif
2197 #if defined(__cplusplus)
2198 #if __cplusplus >= 201103L
2199 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2200 #elif defined(NULL)
2201 #define JSON_HEDLEY_NULL NULL
2202 #else
2203 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2204 #endif
2205 #elif defined(NULL)
2206 #define JSON_HEDLEY_NULL NULL
2207 #else
2208 #define JSON_HEDLEY_NULL ((void*) 0)
2209 #endif
2210 
2211 #if defined(JSON_HEDLEY_MESSAGE)
2212 #undef JSON_HEDLEY_MESSAGE
2213 #endif
2214 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2215 # define JSON_HEDLEY_MESSAGE(msg) \
2216  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2217  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2218  JSON_HEDLEY_PRAGMA(message msg) \
2219  JSON_HEDLEY_DIAGNOSTIC_POP
2220 #elif \
2221  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2222  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2223 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2224 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2225 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2226 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2227 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2228 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2229 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2230 #else
2231 # define JSON_HEDLEY_MESSAGE(msg)
2232 #endif
2233 
2234 #if defined(JSON_HEDLEY_WARNING)
2235 #undef JSON_HEDLEY_WARNING
2236 #endif
2237 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2238 # define JSON_HEDLEY_WARNING(msg) \
2239  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2240  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2241  JSON_HEDLEY_PRAGMA(clang warning msg) \
2242  JSON_HEDLEY_DIAGNOSTIC_POP
2243 #elif \
2244  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2245  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2246  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2247 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2248 #elif \
2249  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2250  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2251 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2252 #else
2253 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2254 #endif
2255 
2256 #if defined(JSON_HEDLEY_REQUIRE)
2257 #undef JSON_HEDLEY_REQUIRE
2258 #endif
2259 #if defined(JSON_HEDLEY_REQUIRE_MSG)
2260 #undef JSON_HEDLEY_REQUIRE_MSG
2261 #endif
2262 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2263 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2264 # define JSON_HEDLEY_REQUIRE(expr) \
2265  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2266  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2267  __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2268  JSON_HEDLEY_DIAGNOSTIC_POP
2269 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2270  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2271  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2272  __attribute__((diagnose_if(!(expr), msg, "error"))) \
2273  JSON_HEDLEY_DIAGNOSTIC_POP
2274 # else
2275 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2276 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2277 # endif
2278 #else
2279 # define JSON_HEDLEY_REQUIRE(expr)
2280 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2281 #endif
2282 
2283 #if defined(JSON_HEDLEY_FLAGS)
2284 #undef JSON_HEDLEY_FLAGS
2285 #endif
2286 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2287 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2288 #else
2289 #define JSON_HEDLEY_FLAGS
2290 #endif
2291 
2292 #if defined(JSON_HEDLEY_FLAGS_CAST)
2293 #undef JSON_HEDLEY_FLAGS_CAST
2294 #endif
2295 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2296 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2297  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2298  _Pragma("warning(disable:188)") \
2299  ((T) (expr)); \
2300  JSON_HEDLEY_DIAGNOSTIC_POP \
2301  }))
2302 #else
2303 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2304 #endif
2305 
2306 #if defined(JSON_HEDLEY_EMPTY_BASES)
2307 #undef JSON_HEDLEY_EMPTY_BASES
2308 #endif
2309 #if \
2310  (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2311  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2312 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2313 #else
2314 #define JSON_HEDLEY_EMPTY_BASES
2315 #endif
2316 
2317  /* Remaining macros are deprecated. */
2318 
2319 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2320 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2321 #endif
2322 #if defined(__clang__)
2323 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2324 #else
2325 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2326 #endif
2327 
2328 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2329 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2330 #endif
2331 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2332 
2333 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2334 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2335 #endif
2336 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2337 
2338 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2339 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2340 #endif
2341 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2342 
2343 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2344 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2345 #endif
2346 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2347 
2348 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2349 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2350 #endif
2351 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2352 
2353 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2354 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2355 #endif
2356 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2357 
2358 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2359 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2360 #endif
2361 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2362 
2363 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2364 
2365 
2366 // This file contains all internal macro definitions (except those affecting ABI)
2367 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2368 
2369 // #include <nlohmann/detail/abi_macros.hpp>
2370 
2371 
2372 // exclude unsupported compilers
2373 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2374 #if defined(__clang__)
2375 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2376 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2377 #endif
2378 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2379 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2380 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2381 #endif
2382 #endif
2383 #endif
2384 
2385 // C++ language standard detection
2386 // if the user manually specified the used c++ version this is skipped
2387 #if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2388 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2389 #define JSON_HAS_CPP_20
2390 #define JSON_HAS_CPP_17
2391 #define JSON_HAS_CPP_14
2392 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2393 #define JSON_HAS_CPP_17
2394 #define JSON_HAS_CPP_14
2395 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2396 #define JSON_HAS_CPP_14
2397 #endif
2398 // the cpp 11 flag is always specified because it is the minimal required version
2399 #define JSON_HAS_CPP_11
2400 #endif
2401 
2402 #ifdef __has_include
2403 #if __has_include(<version>)
2404 #include <version>
2405 #endif
2406 #endif
2407 
2408 #if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2409 #ifdef JSON_HAS_CPP_17
2410 #if defined(__cpp_lib_filesystem)
2411 #define JSON_HAS_FILESYSTEM 1
2412 #elif defined(__cpp_lib_experimental_filesystem)
2413 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2414 #elif !defined(__has_include)
2415 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2416 #elif __has_include(<filesystem>)
2417 #define JSON_HAS_FILESYSTEM 1
2418 #elif __has_include(<experimental/filesystem>)
2419 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2420 #endif
2421 
2422 // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2423 #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2424 #undef JSON_HAS_FILESYSTEM
2425 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2426 #endif
2427 
2428 // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2429 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2430 #undef JSON_HAS_FILESYSTEM
2431 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2432 #endif
2433 
2434 // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2435 #if defined(__clang_major__) && __clang_major__ < 7
2436 #undef JSON_HAS_FILESYSTEM
2437 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2438 #endif
2439 
2440 // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2441 #if defined(_MSC_VER) && _MSC_VER < 1914
2442 #undef JSON_HAS_FILESYSTEM
2443 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2444 #endif
2445 
2446 // no filesystem support before iOS 13
2447 #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2448 #undef JSON_HAS_FILESYSTEM
2449 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2450 #endif
2451 
2452 // no filesystem support before macOS Catalina
2453 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2454 #undef JSON_HAS_FILESYSTEM
2455 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2456 #endif
2457 #endif
2458 #endif
2459 
2460 #ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2461 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2462 #endif
2463 
2464 #ifndef JSON_HAS_FILESYSTEM
2465 #define JSON_HAS_FILESYSTEM 0
2466 #endif
2467 
2468 #ifndef JSON_HAS_THREE_WAY_COMPARISON
2469 #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
2470  && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
2471 #define JSON_HAS_THREE_WAY_COMPARISON 1
2472 #else
2473 #define JSON_HAS_THREE_WAY_COMPARISON 0
2474 #endif
2475 #endif
2476 
2477 #ifndef JSON_HAS_RANGES
2478  // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error
2479 #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427
2480 #define JSON_HAS_RANGES 0
2481 #elif defined(__cpp_lib_ranges)
2482 #define JSON_HAS_RANGES 1
2483 #else
2484 #define JSON_HAS_RANGES 0
2485 #endif
2486 #endif
2487 
2488 #ifndef JSON_HAS_STATIC_RTTI
2489 #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0
2490 #define JSON_HAS_STATIC_RTTI 1
2491 #else
2492 #define JSON_HAS_STATIC_RTTI 0
2493 #endif
2494 #endif
2495 
2496 #ifdef JSON_HAS_CPP_17
2497 #define JSON_INLINE_VARIABLE inline
2498 #else
2499 #define JSON_INLINE_VARIABLE
2500 #endif
2501 
2502 #if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2503 #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2504 #else
2505 #define JSON_NO_UNIQUE_ADDRESS
2506 #endif
2507 
2508 // disable documentation warnings on clang
2509 #if defined(__clang__)
2510 #pragma clang diagnostic push
2511 #pragma clang diagnostic ignored "-Wdocumentation"
2512 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2513 #endif
2514 
2515 // allow disabling exceptions
2516 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2517 #define JSON_THROW(exception) throw exception
2518 #define JSON_TRY try
2519 #define JSON_CATCH(exception) catch(exception)
2520 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2521 #else
2522 #include <cstdlib>
2523 #define JSON_THROW(exception) std::abort()
2524 #define JSON_TRY if(true)
2525 #define JSON_CATCH(exception) if(false)
2526 #define JSON_INTERNAL_CATCH(exception) if(false)
2527 #endif
2528 
2529 // override exception macros
2530 #if defined(JSON_THROW_USER)
2531 #undef JSON_THROW
2532 #define JSON_THROW JSON_THROW_USER
2533 #endif
2534 #if defined(JSON_TRY_USER)
2535 #undef JSON_TRY
2536 #define JSON_TRY JSON_TRY_USER
2537 #endif
2538 #if defined(JSON_CATCH_USER)
2539 #undef JSON_CATCH
2540 #define JSON_CATCH JSON_CATCH_USER
2541 #undef JSON_INTERNAL_CATCH
2542 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2543 #endif
2544 #if defined(JSON_INTERNAL_CATCH_USER)
2545 #undef JSON_INTERNAL_CATCH
2546 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2547 #endif
2548 
2549 // allow overriding assert
2550 #if !defined(JSON_ASSERT)
2551 #include <cassert> // assert
2552 #define JSON_ASSERT(x) assert(x)
2553 #endif
2554 
2555 // allow to access some private functions (needed by the test suite)
2556 #if defined(JSON_TESTS_PRIVATE)
2557 #define JSON_PRIVATE_UNLESS_TESTED public
2558 #else
2559 #define JSON_PRIVATE_UNLESS_TESTED private
2560 #endif
2561 
2567 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2568  template<typename BasicJsonType> \
2569  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2570  { \
2571  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2572  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2573  auto it = std::find_if(std::begin(m), std::end(m), \
2574  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2575  { \
2576  return ej_pair.first == e; \
2577  }); \
2578  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2579  } \
2580  template<typename BasicJsonType> \
2581  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2582  { \
2583  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2584  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2585  auto it = std::find_if(std::begin(m), std::end(m), \
2586  [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2587  { \
2588  return ej_pair.second == j; \
2589  }); \
2590  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2591  }
2592 
2593 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2594 // may be removed in the future once the class is split.
2595 
2596 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2597  template<template<typename, typename, typename...> class ObjectType, \
2598  template<typename, typename...> class ArrayType, \
2599  class StringType, class BooleanType, class NumberIntegerType, \
2600  class NumberUnsignedType, class NumberFloatType, \
2601  template<typename> class AllocatorType, \
2602  template<typename, typename = void> class JSONSerializer, \
2603  class BinaryType, \
2604  class CustomBaseClass>
2605 
2606 #define NLOHMANN_BASIC_JSON_TPL \
2607  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2608  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2609  AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>
2610 
2611 // Macros to simplify conversion from/to types
2612 
2613 #define NLOHMANN_JSON_EXPAND( x ) x
2614 #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2615 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2616  NLOHMANN_JSON_PASTE64, \
2617  NLOHMANN_JSON_PASTE63, \
2618  NLOHMANN_JSON_PASTE62, \
2619  NLOHMANN_JSON_PASTE61, \
2620  NLOHMANN_JSON_PASTE60, \
2621  NLOHMANN_JSON_PASTE59, \
2622  NLOHMANN_JSON_PASTE58, \
2623  NLOHMANN_JSON_PASTE57, \
2624  NLOHMANN_JSON_PASTE56, \
2625  NLOHMANN_JSON_PASTE55, \
2626  NLOHMANN_JSON_PASTE54, \
2627  NLOHMANN_JSON_PASTE53, \
2628  NLOHMANN_JSON_PASTE52, \
2629  NLOHMANN_JSON_PASTE51, \
2630  NLOHMANN_JSON_PASTE50, \
2631  NLOHMANN_JSON_PASTE49, \
2632  NLOHMANN_JSON_PASTE48, \
2633  NLOHMANN_JSON_PASTE47, \
2634  NLOHMANN_JSON_PASTE46, \
2635  NLOHMANN_JSON_PASTE45, \
2636  NLOHMANN_JSON_PASTE44, \
2637  NLOHMANN_JSON_PASTE43, \
2638  NLOHMANN_JSON_PASTE42, \
2639  NLOHMANN_JSON_PASTE41, \
2640  NLOHMANN_JSON_PASTE40, \
2641  NLOHMANN_JSON_PASTE39, \
2642  NLOHMANN_JSON_PASTE38, \
2643  NLOHMANN_JSON_PASTE37, \
2644  NLOHMANN_JSON_PASTE36, \
2645  NLOHMANN_JSON_PASTE35, \
2646  NLOHMANN_JSON_PASTE34, \
2647  NLOHMANN_JSON_PASTE33, \
2648  NLOHMANN_JSON_PASTE32, \
2649  NLOHMANN_JSON_PASTE31, \
2650  NLOHMANN_JSON_PASTE30, \
2651  NLOHMANN_JSON_PASTE29, \
2652  NLOHMANN_JSON_PASTE28, \
2653  NLOHMANN_JSON_PASTE27, \
2654  NLOHMANN_JSON_PASTE26, \
2655  NLOHMANN_JSON_PASTE25, \
2656  NLOHMANN_JSON_PASTE24, \
2657  NLOHMANN_JSON_PASTE23, \
2658  NLOHMANN_JSON_PASTE22, \
2659  NLOHMANN_JSON_PASTE21, \
2660  NLOHMANN_JSON_PASTE20, \
2661  NLOHMANN_JSON_PASTE19, \
2662  NLOHMANN_JSON_PASTE18, \
2663  NLOHMANN_JSON_PASTE17, \
2664  NLOHMANN_JSON_PASTE16, \
2665  NLOHMANN_JSON_PASTE15, \
2666  NLOHMANN_JSON_PASTE14, \
2667  NLOHMANN_JSON_PASTE13, \
2668  NLOHMANN_JSON_PASTE12, \
2669  NLOHMANN_JSON_PASTE11, \
2670  NLOHMANN_JSON_PASTE10, \
2671  NLOHMANN_JSON_PASTE9, \
2672  NLOHMANN_JSON_PASTE8, \
2673  NLOHMANN_JSON_PASTE7, \
2674  NLOHMANN_JSON_PASTE6, \
2675  NLOHMANN_JSON_PASTE5, \
2676  NLOHMANN_JSON_PASTE4, \
2677  NLOHMANN_JSON_PASTE3, \
2678  NLOHMANN_JSON_PASTE2, \
2679  NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2680 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2681 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2682 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2683 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2684 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2685 #define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2686 #define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2687 #define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2688 #define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2689 #define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2690 #define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2691 #define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2692 #define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2693 #define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2694 #define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2695 #define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2696 #define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2697 #define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2698 #define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2699 #define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2700 #define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2701 #define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2702 #define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2703 #define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2704 #define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2705 #define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2706 #define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2707 #define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2708 #define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2709 #define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2710 #define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2711 #define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2712 #define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2713 #define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2714 #define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2715 #define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2716 #define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2717 #define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2718 #define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2719 #define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2720 #define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2721 #define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2722 #define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2723 #define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2724 #define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2725 #define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2726 #define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2727 #define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2728 #define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2729 #define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2730 #define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2731 #define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2732 #define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2733 #define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2734 #define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2735 #define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2736 #define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2737 #define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2738 #define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2739 #define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2740 #define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2741 #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2742 #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2743 
2744 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2745 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2746 #define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2747 
2753 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2754  friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2755  friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2756 
2757 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2758  friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2759  friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2760 
2761 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
2762  friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2763 
2769 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2770  inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2771  inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2772 
2773 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
2774  inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2775 
2776 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2777  inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2778  inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2779 
2780 // inspired from https://stackoverflow.com/a/26745591
2781 // allows to call any std function as if (e.g. with begin):
2782 // using std::begin; begin(x);
2783 //
2784 // it allows using the detected idiom to retrieve the return type
2785 // of such an expression
2786 #define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2787  namespace detail { \
2788  using std::std_name; \
2789  \
2790  template<typename... T> \
2791  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2792  } \
2793  \
2794  namespace detail2 { \
2795  struct std_name##_tag \
2796  { \
2797  }; \
2798  \
2799  template<typename... T> \
2800  std_name##_tag std_name(T&&...); \
2801  \
2802  template<typename... T> \
2803  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2804  \
2805  template<typename... T> \
2806  struct would_call_std_##std_name \
2807  { \
2808  static constexpr auto const value = ::nlohmann::detail:: \
2809  is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2810  }; \
2811  } /* namespace detail2 */ \
2812  \
2813  template<typename... T> \
2814  struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2815  { \
2816  }
2817 
2818 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2819 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2820 #endif
2821 
2822 #if JSON_USE_IMPLICIT_CONVERSIONS
2823 #define JSON_EXPLICIT
2824 #else
2825 #define JSON_EXPLICIT explicit
2826 #endif
2827 
2828 #ifndef JSON_DISABLE_ENUM_SERIALIZATION
2829 #define JSON_DISABLE_ENUM_SERIALIZATION 0
2830 #endif
2831 
2832 #ifndef JSON_USE_GLOBAL_UDLS
2833 #define JSON_USE_GLOBAL_UDLS 1
2834 #endif
2835 
2836 #if JSON_HAS_THREE_WAY_COMPARISON
2837 #include <compare> // partial_ordering
2838 #endif
2839 
2841 namespace detail
2842 {
2843 
2845  // JSON type enumeration //
2847 
2872  enum class value_t : std::uint8_t
2873  {
2874  null,
2875  object,
2876  array,
2877  string,
2878  boolean,
2879  number_integer,
2880  number_unsigned,
2881  number_float,
2882  binary,
2883  discarded
2884  };
2885 
2899 #if JSON_HAS_THREE_WAY_COMPARISON
2900  inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
2901 #else
2902  inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2903 #endif
2904  {
2905  static constexpr std::array<std::uint8_t, 9> order = { {
2906  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2907  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
2908  6 /* binary */
2909  }
2910  };
2911 
2912  const auto l_index = static_cast<std::size_t>(lhs);
2913  const auto r_index = static_cast<std::size_t>(rhs);
2914 #if JSON_HAS_THREE_WAY_COMPARISON
2915  if (l_index < order.size() && r_index < order.size())
2916  {
2917  return order[l_index] <=> order[r_index]; // *NOPAD*
2918  }
2919  return std::partial_ordering::unordered;
2920 #else
2921  return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
2922 #endif
2923  }
2924 
2925  // GCC selects the built-in operator< over an operator rewritten from
2926  // a user-defined spaceship operator
2927  // Clang, MSVC, and ICC select the rewritten candidate
2928  // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
2929 #if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
2930  inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2931  {
2932  return std::is_lt(lhs <=> rhs); // *NOPAD*
2933  }
2934 #endif
2935 
2936 } // namespace detail
2938 
2939 // #include <nlohmann/detail/string_escape.hpp>
2940 // __ _____ _____ _____
2941 // __| | __| | | | JSON for Modern C++
2942 // | | |__ | | | | | | version 3.11.3
2943 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
2944 //
2945 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
2946 // SPDX-License-Identifier: MIT
2947 
2948 
2949 
2950 // #include <nlohmann/detail/abi_macros.hpp>
2951 
2952 
2954 namespace detail
2955 {
2956 
2970  template<typename StringType>
2971  inline void replace_substring(StringType& s, const StringType& f,
2972  const StringType& t)
2973  {
2974  JSON_ASSERT(!f.empty());
2975  for (auto pos = s.find(f); // find first occurrence of f
2976  pos != StringType::npos; // make sure f was found
2977  s.replace(pos, f.size(), t), // replace with t, and
2978  pos = s.find(f, pos + t.size())) // find next occurrence of f
2979  {
2980  }
2981  }
2982 
2990  template<typename StringType>
2991  inline StringType escape(StringType s)
2992  {
2993  replace_substring(s, StringType{ "~" }, StringType{ "~0" });
2994  replace_substring(s, StringType{ "/" }, StringType{ "~1" });
2995  return s;
2996  }
2997 
3005  template<typename StringType>
3006  static void unescape(StringType& s)
3007  {
3008  replace_substring(s, StringType{ "~1" }, StringType{ "/" });
3009  replace_substring(s, StringType{ "~0" }, StringType{ "~" });
3010  }
3011 
3012 } // namespace detail
3014 
3015 // #include <nlohmann/detail/input/position_t.hpp>
3016 // __ _____ _____ _____
3017 // __| | __| | | | JSON for Modern C++
3018 // | | |__ | | | | | | version 3.11.3
3019 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3020 //
3021 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3022 // SPDX-License-Identifier: MIT
3023 
3024 
3025 
3026 #include <cstddef> // size_t
3027 
3028 // #include <nlohmann/detail/abi_macros.hpp>
3029 
3030 
3032 namespace detail
3033 {
3034 
3036  struct position_t
3037  {
3039  std::size_t chars_read_total = 0;
3041  std::size_t chars_read_current_line = 0;
3043  std::size_t lines_read = 0;
3044 
3046  constexpr operator size_t() const
3047  {
3048  return chars_read_total;
3049  }
3050  };
3051 
3052 } // namespace detail
3054 
3055 // #include <nlohmann/detail/macro_scope.hpp>
3056 
3057 // #include <nlohmann/detail/meta/cpp_future.hpp>
3058 // __ _____ _____ _____
3059 // __| | __| | | | JSON for Modern C++
3060 // | | |__ | | | | | | version 3.11.3
3061 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3062 //
3063 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3064 // SPDX-FileCopyrightText: 2018 The Abseil Authors
3065 // SPDX-License-Identifier: MIT
3066 
3067 
3068 
3069 #include <array> // array
3070 #include <cstddef> // size_t
3071 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3072 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3073 
3074 // #include <nlohmann/detail/macro_scope.hpp>
3075 
3076 
3078 namespace detail
3079 {
3080 
3081  template<typename T>
3082  using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3083 
3084 #ifdef JSON_HAS_CPP_14
3085 
3086  // the following utilities are natively available in C++14
3087  using std::enable_if_t;
3088  using std::index_sequence;
3091 
3092 #else
3093 
3094  // alias templates to reduce boilerplate
3095  template<bool B, typename T = void>
3096  using enable_if_t = typename std::enable_if<B, T>::type;
3097 
3098  // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3099  // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3100 
3102 
3103  // integer_sequence
3104  //
3105  // Class template representing a compile-time integer sequence. An instantiation
3106  // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3107  // type through its template arguments (which is a common need when
3108  // working with C++11 variadic templates). `absl::integer_sequence` is designed
3109  // to be a drop-in replacement for C++14's `std::integer_sequence`.
3110  //
3111  // Example:
3112  //
3113  // template< class T, T... Ints >
3114  // void user_function(integer_sequence<T, Ints...>);
3115  //
3116  // int main()
3117  // {
3118  // // user_function's `T` will be deduced to `int` and `Ints...`
3119  // // will be deduced to `0, 1, 2, 3, 4`.
3120  // user_function(make_integer_sequence<int, 5>());
3121  // }
3122  template <typename T, T... Ints>
3124  {
3125  using value_type = T;
3126  static constexpr std::size_t size() noexcept
3127  {
3128  return sizeof...(Ints);
3129  }
3130  };
3131 
3132  // index_sequence
3133  //
3134  // A helper template for an `integer_sequence` of `size_t`,
3135  // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3136  // `std::index_sequence`.
3137  template <size_t... Ints>
3138  using index_sequence = integer_sequence<size_t, Ints...>;
3139 
3140  namespace utility_internal
3141  {
3142 
3143  template <typename Seq, size_t SeqSize, size_t Rem>
3144  struct Extend;
3145 
3146  // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3147  template <typename T, T... Ints, size_t SeqSize>
3148  struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3149  {
3150  using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3151  };
3152 
3153  template <typename T, T... Ints, size_t SeqSize>
3154  struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3155  {
3156  using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3157  };
3158 
3159  // Recursion helper for 'make_integer_sequence<T, N>'.
3160  // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3161  template <typename T, size_t N>
3162  struct Gen
3163  {
3164  using type =
3165  typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3166  };
3167 
3168  template <typename T>
3169  struct Gen<T, 0>
3170  {
3172  };
3173 
3174  } // namespace utility_internal
3175 
3176  // Compile-time sequences of integers
3177 
3178  // make_integer_sequence
3179  //
3180  // This template alias is equivalent to
3181  // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3182  // replacement for C++14's `std::make_integer_sequence`.
3183  template <typename T, T N>
3185 
3186  // make_index_sequence
3187  //
3188  // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3189  // and is designed to be a drop-in replacement for C++14's
3190  // `std::make_index_sequence`.
3191  template <size_t N>
3193 
3194  // index_sequence_for
3195  //
3196  // Converts a typename pack into an index sequence of the same length, and
3197  // is designed to be a drop-in replacement for C++14's
3198  // `std::index_sequence_for()`
3199  template <typename... Ts>
3200  using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
3201 
3203 
3204 #endif
3205 
3206 // dispatch utility (taken from ranges-v3)
3207  template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3208  template<> struct priority_tag<0> {};
3209 
3210  // taken from ranges-v3
3211  template<typename T>
3213  {
3214  static JSON_INLINE_VARIABLE constexpr T value{};
3215  };
3216 
3217 #ifndef JSON_HAS_CPP_17
3218  template<typename T>
3219  constexpr T static_const<T>::value;
3220 #endif
3221 
3222  template<typename T, typename... Args>
3223  inline constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args)
3224  {
3225  return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}};
3226  }
3227 
3228 } // namespace detail
3230 
3231 // #include <nlohmann/detail/meta/type_traits.hpp>
3232 // __ _____ _____ _____
3233 // __| | __| | | | JSON for Modern C++
3234 // | | |__ | | | | | | version 3.11.3
3235 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3236 //
3237 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3238 // SPDX-License-Identifier: MIT
3239 
3240 
3241 
3242 #include <limits> // numeric_limits
3243 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3244 #include <utility> // declval
3245 #include <tuple> // tuple
3246 #include <string> // char_traits
3247 
3248 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3249 // __ _____ _____ _____
3250 // __| | __| | | | JSON for Modern C++
3251 // | | |__ | | | | | | version 3.11.3
3252 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3253 //
3254 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3255 // SPDX-License-Identifier: MIT
3256 
3257 
3258 
3259 #include <iterator> // random_access_iterator_tag
3260 
3261 // #include <nlohmann/detail/abi_macros.hpp>
3262 
3263 // #include <nlohmann/detail/meta/void_t.hpp>
3264 
3265 // #include <nlohmann/detail/meta/cpp_future.hpp>
3266 
3267 
3269 namespace detail
3270 {
3271 
3272  template<typename It, typename = void>
3273  struct iterator_types {};
3274 
3275  template<typename It>
3277  It,
3278  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3279  typename It::reference, typename It::iterator_category >>
3280  {
3281  using difference_type = typename It::difference_type;
3282  using value_type = typename It::value_type;
3283  using pointer = typename It::pointer;
3284  using reference = typename It::reference;
3285  using iterator_category = typename It::iterator_category;
3286  };
3287 
3288  // This is required as some compilers implement std::iterator_traits in a way that
3289  // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3290  template<typename T, typename = void>
3292  {
3293  };
3294 
3295  template<typename T>
3296  struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3297  : iterator_types<T>
3298  {
3299  };
3300 
3301  template<typename T>
3303  {
3304  using iterator_category = std::random_access_iterator_tag;
3305  using value_type = T;
3306  using difference_type = ptrdiff_t;
3307  using pointer = T*;
3308  using reference = T&;
3309  };
3310 
3311 } // namespace detail
3313 
3314 // #include <nlohmann/detail/macro_scope.hpp>
3315 
3316 // #include <nlohmann/detail/meta/call_std/begin.hpp>
3317 // __ _____ _____ _____
3318 // __| | __| | | | JSON for Modern C++
3319 // | | |__ | | | | | | version 3.11.3
3320 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3321 //
3322 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3323 // SPDX-License-Identifier: MIT
3324 
3325 
3326 
3327 // #include <nlohmann/detail/macro_scope.hpp>
3328 
3329 
3331 
3333 
3335 
3336 // #include <nlohmann/detail/meta/call_std/end.hpp>
3337 // __ _____ _____ _____
3338 // __| | __| | | | JSON for Modern C++
3339 // | | |__ | | | | | | version 3.11.3
3340 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3341 //
3342 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3343 // SPDX-License-Identifier: MIT
3344 
3345 
3346 
3347 // #include <nlohmann/detail/macro_scope.hpp>
3348 
3349 
3351 
3353 
3355 
3356 // #include <nlohmann/detail/meta/cpp_future.hpp>
3357 
3358 // #include <nlohmann/detail/meta/detected.hpp>
3359 
3360 // #include <nlohmann/json_fwd.hpp>
3361 // __ _____ _____ _____
3362 // __| | __| | | | JSON for Modern C++
3363 // | | |__ | | | | | | version 3.11.3
3364 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3365 //
3366 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3367 // SPDX-License-Identifier: MIT
3368 
3369 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3370 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3371 
3372 #include <cstdint> // int64_t, uint64_t
3373 #include <map> // map
3374 #include <memory> // allocator
3375 #include <string> // string
3376 #include <vector> // vector
3377 
3378 // #include <nlohmann/detail/abi_macros.hpp>
3379 
3380 
3387 
3395 template<typename T = void, typename SFINAE = void>
3396 struct adl_serializer;
3397 
3400 template<template<typename U, typename V, typename... Args> class ObjectType =
3401  std::map,
3402  template<typename U, typename... Args> class ArrayType = std::vector,
3403  class StringType = std::string, class BooleanType = bool,
3404  class NumberIntegerType = std::int64_t,
3405  class NumberUnsignedType = std::uint64_t,
3406  class NumberFloatType = double,
3407  template<typename U> class AllocatorType = std::allocator,
3408  template<typename T, typename SFINAE = void> class JSONSerializer =
3410  class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
3411  class CustomBaseClass = void>
3412 class basic_json;
3413 
3416 template<typename RefStringType>
3417 class json_pointer;
3418 
3424 
3427 template<class Key, class T, class IgnoredLess, class Allocator>
3428 struct ordered_map;
3429 
3433 
3435 
3436 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3437 
3438 
3448 namespace detail
3449 {
3450 
3452  // helpers //
3454 
3455  // Note to maintainers:
3456  //
3457  // Every trait in this file expects a non CV-qualified type.
3458  // The only exceptions are in the 'aliases for detected' section
3459  // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3460  //
3461  // In this case, T has to be properly CV-qualified to constraint the function arguments
3462  // (e.g. to_json(BasicJsonType&, const T&))
3463 
3464  template<typename> struct is_basic_json : std::false_type {};
3465 
3467  struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3468 
3469  // used by exceptions create() member functions
3470  // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3471  // false_type otherwise
3472  template<typename BasicJsonContext>
3474  std::integral_constant < bool,
3475  is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3476  || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3477  {};
3478 
3480  // json_ref helpers //
3482 
3483  template<typename>
3484  class json_ref;
3485 
3486  template<typename>
3487  struct is_json_ref : std::false_type {};
3488 
3489  template<typename T>
3490  struct is_json_ref<json_ref<T>> : std::true_type {};
3491 
3493  // aliases for detected //
3495 
3496  template<typename T>
3497  using mapped_type_t = typename T::mapped_type;
3498 
3499  template<typename T>
3500  using key_type_t = typename T::key_type;
3501 
3502  template<typename T>
3503  using value_type_t = typename T::value_type;
3504 
3505  template<typename T>
3506  using difference_type_t = typename T::difference_type;
3507 
3508  template<typename T>
3509  using pointer_t = typename T::pointer;
3510 
3511  template<typename T>
3512  using reference_t = typename T::reference;
3513 
3514  template<typename T>
3515  using iterator_category_t = typename T::iterator_category;
3516 
3517  template<typename T, typename... Args>
3518  using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3519 
3520  template<typename T, typename... Args>
3521  using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3522 
3523  template<typename T, typename U>
3524  using get_template_function = decltype(std::declval<T>().template get<U>());
3525 
3526  // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3527  template<typename BasicJsonType, typename T, typename = void>
3528  struct has_from_json : std::false_type {};
3529 
3530  // trait checking if j.get<T> is valid
3531  // use this trait instead of std::is_constructible or std::is_convertible,
3532  // both rely on, or make use of implicit conversions, and thus fail when T
3533  // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3534  template <typename BasicJsonType, typename T>
3535  struct is_getable
3536  {
3538  };
3539 
3540  template<typename BasicJsonType, typename T>
3541  struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3542  {
3543  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3544 
3545  static constexpr bool value =
3547  const BasicJsonType&, T&>::value;
3548  };
3549 
3550  // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3551  // this overload is used for non-default-constructible user-defined-types
3552  template<typename BasicJsonType, typename T, typename = void>
3553  struct has_non_default_from_json : std::false_type {};
3554 
3555  template<typename BasicJsonType, typename T>
3556  struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3557  {
3558  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3559 
3560  static constexpr bool value =
3562  const BasicJsonType&>::value;
3563  };
3564 
3565  // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3566  // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3567  template<typename BasicJsonType, typename T, typename = void>
3568  struct has_to_json : std::false_type {};
3569 
3570  template<typename BasicJsonType, typename T>
3571  struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3572  {
3573  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3574 
3575  static constexpr bool value =
3576  is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3577  T>::value;
3578  };
3579 
3580  template<typename T>
3581  using detect_key_compare = typename T::key_compare;
3582 
3583  template<typename T>
3584  struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3585 
3586  // obtains the actual object key comparator
3587  template<typename BasicJsonType>
3589  {
3590  using object_t = typename BasicJsonType::object_t;
3591  using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3592  using type = typename std::conditional < has_key_compare<object_t>::value,
3593  typename object_t::key_compare, object_comparator_t>::type;
3594  };
3595 
3596  template<typename BasicJsonType>
3598 
3600  // char_traits //
3602 
3603  // Primary template of char_traits calls std char_traits
3604  template<typename T>
3605  struct char_traits : std::char_traits<T>
3606  {};
3607 
3608  // Explicitly define char traits for unsigned char since it is not standard
3609  template<>
3610  struct char_traits<unsigned char> : std::char_traits<char>
3611  {
3612  using char_type = unsigned char;
3613  using int_type = uint64_t;
3614 
3615  // Redefine to_int_type function
3616  static int_type to_int_type(char_type c) noexcept
3617  {
3618  return static_cast<int_type>(c);
3619  }
3620 
3621  static char_type to_char_type(int_type i) noexcept
3622  {
3623  return static_cast<char_type>(i);
3624  }
3625 
3626  static constexpr int_type eof() noexcept
3627  {
3628  return static_cast<int_type>(EOF);
3629  }
3630  };
3631 
3632  // Explicitly define char traits for signed char since it is not standard
3633  template<>
3634  struct char_traits<signed char> : std::char_traits<char>
3635  {
3636  using char_type = signed char;
3637  using int_type = uint64_t;
3638 
3639  // Redefine to_int_type function
3640  static int_type to_int_type(char_type c) noexcept
3641  {
3642  return static_cast<int_type>(c);
3643  }
3644 
3645  static char_type to_char_type(int_type i) noexcept
3646  {
3647  return static_cast<char_type>(i);
3648  }
3649 
3650  static constexpr int_type eof() noexcept
3651  {
3652  return static_cast<int_type>(EOF);
3653  }
3654  };
3655 
3657  // is_ functions //
3659 
3660  // https://en.cppreference.com/w/cpp/types/conjunction
3661  template<class...> struct conjunction : std::true_type { };
3662  template<class B> struct conjunction<B> : B { };
3663  template<class B, class... Bn>
3664  struct conjunction<B, Bn...>
3665  : std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
3666 
3667  // https://en.cppreference.com/w/cpp/types/negation
3668  template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3669 
3670  // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3671  // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3672  // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3673  template <typename T>
3674  struct is_default_constructible : std::is_default_constructible<T> {};
3675 
3676  template <typename T1, typename T2>
3677  struct is_default_constructible<std::pair<T1, T2>>
3678  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3679 
3680  template <typename T1, typename T2>
3681  struct is_default_constructible<const std::pair<T1, T2>>
3682  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3683 
3684  template <typename... Ts>
3685  struct is_default_constructible<std::tuple<Ts...>>
3686  : conjunction<is_default_constructible<Ts>...> {};
3687 
3688  template <typename... Ts>
3689  struct is_default_constructible<const std::tuple<Ts...>>
3690  : conjunction<is_default_constructible<Ts>...> {};
3691 
3692  template <typename T, typename... Args>
3693  struct is_constructible : std::is_constructible<T, Args...> {};
3694 
3695  template <typename T1, typename T2>
3696  struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3697 
3698  template <typename T1, typename T2>
3699  struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3700 
3701  template <typename... Ts>
3702  struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3703 
3704  template <typename... Ts>
3705  struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3706 
3707  template<typename T, typename = void>
3708  struct is_iterator_traits : std::false_type {};
3709 
3710  template<typename T>
3712  {
3713  private:
3714  using traits = iterator_traits<T>;
3715 
3716  public:
3717  static constexpr auto value =
3723  };
3724 
3725  template<typename T>
3726  struct is_range
3727  {
3728  private:
3729  using t_ref = typename std::add_lvalue_reference<T>::type;
3730 
3731  using iterator = detected_t<result_of_begin, t_ref>;
3732  using sentinel = detected_t<result_of_end, t_ref>;
3733 
3734  // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3735  // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3736  // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3737  static constexpr auto is_iterator_begin =
3739 
3740  public:
3741  static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value&& is_iterator_begin;
3742  };
3743 
3744  template<typename R>
3745  using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3746 
3747  template<typename T>
3749 
3750  // The following implementation of is_complete_type is taken from
3751  // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3752  // and is written by Xiang Fan who agreed to using it in this library.
3753 
3754  template<typename T, typename = void>
3755  struct is_complete_type : std::false_type {};
3756 
3757  template<typename T>
3758  struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3759 
3760  template<typename BasicJsonType, typename CompatibleObjectType,
3761  typename = void>
3762  struct is_compatible_object_type_impl : std::false_type {};
3763 
3764  template<typename BasicJsonType, typename CompatibleObjectType>
3766  BasicJsonType, CompatibleObjectType,
3767  enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3768  is_detected<key_type_t, CompatibleObjectType>::value >>
3769  {
3770  using object_t = typename BasicJsonType::object_t;
3771 
3772  // macOS's is_constructible does not play well with nonesuch...
3773  static constexpr bool value =
3774  is_constructible<typename object_t::key_type,
3775  typename CompatibleObjectType::key_type>::value&&
3776  is_constructible<typename object_t::mapped_type,
3777  typename CompatibleObjectType::mapped_type>::value;
3778  };
3779 
3780  template<typename BasicJsonType, typename CompatibleObjectType>
3782  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3783 
3784  template<typename BasicJsonType, typename ConstructibleObjectType,
3785  typename = void>
3786  struct is_constructible_object_type_impl : std::false_type {};
3787 
3788  template<typename BasicJsonType, typename ConstructibleObjectType>
3790  BasicJsonType, ConstructibleObjectType,
3791  enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3792  is_detected<key_type_t, ConstructibleObjectType>::value >>
3793  {
3794  using object_t = typename BasicJsonType::object_t;
3795 
3796  static constexpr bool value =
3798  (std::is_move_assignable<ConstructibleObjectType>::value ||
3799  std::is_copy_assignable<ConstructibleObjectType>::value) &&
3800  (is_constructible<typename ConstructibleObjectType::key_type,
3801  typename object_t::key_type>::value &&
3802  std::is_same <
3803  typename object_t::mapped_type,
3804  typename ConstructibleObjectType::mapped_type >::value)) ||
3805  (has_from_json<BasicJsonType,
3806  typename ConstructibleObjectType::mapped_type>::value ||
3808  BasicJsonType,
3809  typename ConstructibleObjectType::mapped_type >::value);
3810  };
3811 
3812  template<typename BasicJsonType, typename ConstructibleObjectType>
3814  : is_constructible_object_type_impl<BasicJsonType,
3815  ConstructibleObjectType> {};
3816 
3817  template<typename BasicJsonType, typename CompatibleStringType>
3819  {
3820  static constexpr auto value =
3822  };
3823 
3824  template<typename BasicJsonType, typename ConstructibleStringType>
3826  {
3827  // launder type through decltype() to fix compilation failure on ICPC
3828 #ifdef __INTEL_COMPILER
3829  using laundered_type = decltype(std::declval<ConstructibleStringType>());
3830 #else
3831  using laundered_type = ConstructibleStringType;
3832 #endif
3833 
3834  static constexpr auto value =
3835  conjunction <
3837  is_detected_exact<typename BasicJsonType::string_t::value_type,
3839  };
3840 
3841  template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3842  struct is_compatible_array_type_impl : std::false_type {};
3843 
3844  template<typename BasicJsonType, typename CompatibleArrayType>
3846  BasicJsonType, CompatibleArrayType,
3847  enable_if_t <
3848  is_detected<iterator_t, CompatibleArrayType>::value&&
3849  is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value &&
3850  // special case for types like std::filesystem::path whose iterator's value_type are themselves
3851  // c.f. https://github.com/nlohmann/json/pull/3073
3852  !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3853  {
3854  static constexpr bool value =
3855  is_constructible<BasicJsonType,
3857  };
3858 
3859  template<typename BasicJsonType, typename CompatibleArrayType>
3861  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3862 
3863  template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3864  struct is_constructible_array_type_impl : std::false_type {};
3865 
3866  template<typename BasicJsonType, typename ConstructibleArrayType>
3868  BasicJsonType, ConstructibleArrayType,
3869  enable_if_t<std::is_same<ConstructibleArrayType,
3870  typename BasicJsonType::value_type>::value >>
3871  : std::true_type {};
3872 
3873  template<typename BasicJsonType, typename ConstructibleArrayType>
3875  BasicJsonType, ConstructibleArrayType,
3876  enable_if_t < !std::is_same<ConstructibleArrayType,
3877  typename BasicJsonType::value_type>::value &&
3878  !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3879  is_default_constructible<ConstructibleArrayType>::value &&
3880  (std::is_move_assignable<ConstructibleArrayType>::value ||
3881  std::is_copy_assignable<ConstructibleArrayType>::value) &&
3882  is_detected<iterator_t, ConstructibleArrayType>::value&&
3883  is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3884  is_detected<range_value_t, ConstructibleArrayType>::value &&
3885  // special case for types like std::filesystem::path whose iterator's value_type are themselves
3886  // c.f. https://github.com/nlohmann/json/pull/3073
3887  !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3889  detected_t<range_value_t, ConstructibleArrayType >>::value >>
3890  {
3892 
3893  static constexpr bool value =
3894  std::is_same<value_type,
3895  typename BasicJsonType::array_t::value_type>::value ||
3896  has_from_json<BasicJsonType,
3897  value_type>::value ||
3899  BasicJsonType,
3900  value_type >::value;
3901  };
3902 
3903  template<typename BasicJsonType, typename ConstructibleArrayType>
3905  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3906 
3907  template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3908  typename = void>
3909  struct is_compatible_integer_type_impl : std::false_type {};
3910 
3911  template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3913  RealIntegerType, CompatibleNumberIntegerType,
3914  enable_if_t < std::is_integral<RealIntegerType>::value&&
3915  std::is_integral<CompatibleNumberIntegerType>::value &&
3916  !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3917  {
3918  // is there an assert somewhere on overflows?
3919  using RealLimits = std::numeric_limits<RealIntegerType>;
3920  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3921 
3922  static constexpr auto value =
3923  is_constructible<RealIntegerType,
3924  CompatibleNumberIntegerType>::value&&
3925  CompatibleLimits::is_integer&&
3926  RealLimits::is_signed == CompatibleLimits::is_signed;
3927  };
3928 
3929  template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3931  : is_compatible_integer_type_impl<RealIntegerType,
3932  CompatibleNumberIntegerType> {};
3933 
3934  template<typename BasicJsonType, typename CompatibleType, typename = void>
3935  struct is_compatible_type_impl : std::false_type {};
3936 
3937  template<typename BasicJsonType, typename CompatibleType>
3939  BasicJsonType, CompatibleType,
3940  enable_if_t<is_complete_type<CompatibleType>::value >>
3941  {
3942  static constexpr bool value =
3944  };
3945 
3946  template<typename BasicJsonType, typename CompatibleType>
3948  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3949 
3950  template<typename T1, typename T2>
3951  struct is_constructible_tuple : std::false_type {};
3952 
3953  template<typename T1, typename... Args>
3954  struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3955 
3956  template<typename BasicJsonType, typename T>
3957  struct is_json_iterator_of : std::false_type {};
3958 
3959  template<typename BasicJsonType>
3960  struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3961 
3962  template<typename BasicJsonType>
3963  struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3964  {};
3965 
3966  // checks if a given type T is a template specialization of Primary
3967  template<template <typename...> class Primary, typename T>
3968  struct is_specialization_of : std::false_type {};
3969 
3970  template<template <typename...> class Primary, typename... Args>
3971  struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3972 
3973  template<typename T>
3975 
3976  // checks if A and B are comparable using Compare functor
3977  template<typename Compare, typename A, typename B, typename = void>
3978  struct is_comparable : std::false_type {};
3979 
3980  template<typename Compare, typename A, typename B>
3981  struct is_comparable<Compare, A, B, void_t<
3982  decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3983  decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3984  >> : std::true_type {};
3985 
3986  template<typename T>
3988 
3989  // type trait to check if KeyType can be used as object key (without a BasicJsonType)
3990  // see is_usable_as_basic_json_key_type below
3991  template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3992  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3993  using is_usable_as_key_type = typename std::conditional <
3995  && !(ExcludeObjectKeyType&& std::is_same<KeyType,
3996  ObjectKeyType>::value)
3997  && (!RequireTransparentComparator
4000  std::true_type,
4001  std::false_type >::type;
4002 
4003  // type trait to check if KeyType can be used as object key
4004  // true if:
4005  // - KeyType is comparable with BasicJsonType::object_t::key_type
4006  // - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
4007  // - the comparator is transparent or RequireTransparentComparator is false
4008  // - KeyType is not a JSON iterator or json_pointer
4009  template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
4010  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
4011  using is_usable_as_basic_json_key_type = typename std::conditional <
4012  is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
4013  typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
4014  RequireTransparentComparator, ExcludeObjectKeyType>::value
4016  std::true_type,
4017  std::false_type >::type;
4018 
4019  template<typename ObjectType, typename KeyType>
4020  using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
4021 
4022  // type trait to check if object_t has an erase() member functions accepting KeyType
4023  template<typename BasicJsonType, typename KeyType>
4024  using has_erase_with_key_type = typename std::conditional <
4025  is_detected <
4027  typename BasicJsonType::object_t, KeyType >::value,
4028  std::true_type,
4029  std::false_type >::type;
4030 
4031  // a naive helper to check if a type is an ordered_map (exploits the fact that
4032  // ordered_map inherits capacity() from std::vector)
4033  template <typename T>
4035  {
4036  using one = char;
4037 
4038  struct two
4039  {
4040  char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4041  };
4042 
4043  template <typename C> static one test(decltype(&C::capacity));
4044  template <typename C> static two test(...);
4045 
4046  enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
4047  };
4048 
4049  // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
4050  template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
4052  {
4053  return static_cast<T>(value);
4054  }
4055 
4056  template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
4057  T conditional_static_cast(U value)
4058  {
4059  return value;
4060  }
4061 
4062  template<typename... Types>
4064 
4065  template<typename... Types>
4067 
4068  template<typename... Types>
4070 
4071  // there's a disjunction trait in another PR; replace when merged
4072  template<typename... Types>
4073  using same_sign = std::integral_constant < bool,
4074  all_signed<Types...>::value || all_unsigned<Types...>::value >;
4075 
4076  template<typename OfType, typename T>
4077  using never_out_of_range = std::integral_constant < bool,
4078  (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
4079  || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
4080 
4081  template<typename OfType, typename T,
4082  bool OfTypeSigned = std::is_signed<OfType>::value,
4083  bool TSigned = std::is_signed<T>::value>
4085 
4086  template<typename OfType, typename T>
4087  struct value_in_range_of_impl2<OfType, T, false, false>
4088  {
4089  static constexpr bool test(T val)
4090  {
4091  using CommonType = typename std::common_type<OfType, T>::type;
4092  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4093  }
4094  };
4095 
4096  template<typename OfType, typename T>
4097  struct value_in_range_of_impl2<OfType, T, true, false>
4098  {
4099  static constexpr bool test(T val)
4100  {
4101  using CommonType = typename std::common_type<OfType, T>::type;
4102  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4103  }
4104  };
4105 
4106  template<typename OfType, typename T>
4107  struct value_in_range_of_impl2<OfType, T, false, true>
4108  {
4109  static constexpr bool test(T val)
4110  {
4111  using CommonType = typename std::common_type<OfType, T>::type;
4112  return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4113  }
4114  };
4115 
4116  template<typename OfType, typename T>
4117  struct value_in_range_of_impl2<OfType, T, true, true>
4118  {
4119  static constexpr bool test(T val)
4120  {
4121  using CommonType = typename std::common_type<OfType, T>::type;
4122  return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
4123  && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4124  }
4125  };
4126 
4127  template<typename OfType, typename T,
4128  bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
4131 
4132  template<typename OfType, typename T>
4133  struct value_in_range_of_impl1<OfType, T, false>
4134  {
4135  static constexpr bool test(T val)
4136  {
4138  }
4139  };
4140 
4141  template<typename OfType, typename T>
4142  struct value_in_range_of_impl1<OfType, T, true>
4143  {
4144  static constexpr bool test(T /*val*/)
4145  {
4146  return true;
4147  }
4148  };
4149 
4150  template<typename OfType, typename T>
4151  inline constexpr bool value_in_range_of(T val)
4152  {
4154  }
4155 
4156  template<bool Value>
4157  using bool_constant = std::integral_constant<bool, Value>;
4158 
4160  // is_c_string
4162 
4163  namespace impl
4164  {
4165 
4166  template<typename T>
4167  inline constexpr bool is_c_string()
4168  {
4169  using TUnExt = typename std::remove_extent<T>::type;
4170  using TUnCVExt = typename std::remove_cv<TUnExt>::type;
4171  using TUnPtr = typename std::remove_pointer<T>::type;
4172  using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
4173  return
4174  (std::is_array<T>::value && std::is_same<TUnCVExt, char>::value)
4175  || (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
4176  }
4177 
4178  } // namespace impl
4179 
4180  // checks whether T is a [cv] char */[cv] char[] C string
4181  template<typename T>
4182  struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
4183 
4184  template<typename T>
4186 
4188  // is_transparent
4190 
4191  namespace impl
4192  {
4193 
4194  template<typename T>
4195  inline constexpr bool is_transparent()
4196  {
4198  }
4199 
4200  } // namespace impl
4201 
4202  // checks whether T has a member named is_transparent
4203  template<typename T>
4204  struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
4205 
4207 
4208 } // namespace detail
4210 
4211 // #include <nlohmann/detail/string_concat.hpp>
4212 // __ _____ _____ _____
4213 // __| | __| | | | JSON for Modern C++
4214 // | | |__ | | | | | | version 3.11.3
4215 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4216 //
4217 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
4218 // SPDX-License-Identifier: MIT
4219 
4220 
4221 
4222 #include <cstring> // strlen
4223 #include <string> // string
4224 #include <utility> // forward
4225 
4226 // #include <nlohmann/detail/meta/cpp_future.hpp>
4227 
4228 // #include <nlohmann/detail/meta/detected.hpp>
4229 
4230 
4232 namespace detail
4233 {
4234 
4235  inline std::size_t concat_length()
4236  {
4237  return 0;
4238  }
4239 
4240  template<typename... Args>
4241  inline std::size_t concat_length(const char* cstr, const Args& ... rest);
4242 
4243  template<typename StringType, typename... Args>
4244  inline std::size_t concat_length(const StringType& str, const Args& ... rest);
4245 
4246  template<typename... Args>
4247  inline std::size_t concat_length(const char /*c*/, const Args& ... rest)
4248  {
4249  return 1 + concat_length(rest...);
4250  }
4251 
4252  template<typename... Args>
4253  inline std::size_t concat_length(const char* cstr, const Args& ... rest)
4254  {
4255  // cppcheck-suppress ignoredReturnValue
4256  return ::strlen(cstr) + concat_length(rest...);
4257  }
4258 
4259  template<typename StringType, typename... Args>
4260  inline std::size_t concat_length(const StringType& str, const Args& ... rest)
4261  {
4262  return str.size() + concat_length(rest...);
4263  }
4264 
4265  template<typename OutStringType>
4266  inline void concat_into(OutStringType& /*out*/)
4267  {}
4268 
4269  template<typename StringType, typename Arg>
4270  using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg&& >()));
4271 
4272  template<typename StringType, typename Arg>
4274 
4275  template<typename StringType, typename Arg>
4276  using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg&& >());
4277 
4278  template<typename StringType, typename Arg>
4280 
4281  template<typename StringType, typename Arg>
4282  using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
4283 
4284  template<typename StringType, typename Arg>
4286 
4287  template<typename StringType, typename Arg>
4288  using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
4289 
4290  template<typename StringType, typename Arg>
4292 
4293  template < typename OutStringType, typename Arg, typename... Args,
4296  inline void concat_into(OutStringType& out, Arg&& arg, Args && ... rest);
4297 
4298  template < typename OutStringType, typename Arg, typename... Args,
4302  inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4303 
4304  template < typename OutStringType, typename Arg, typename... Args,
4309  inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4310 
4311  template<typename OutStringType, typename Arg, typename... Args,
4313  inline void concat_into(OutStringType& out, Arg&& arg, Args && ... rest)
4314  {
4315  out.append(std::forward<Arg>(arg));
4316  concat_into(out, std::forward<Args>(rest)...);
4317  }
4318 
4319  template < typename OutStringType, typename Arg, typename... Args,
4320  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4321  && detect_string_can_append_op<OutStringType, Arg>::value, int > >
4322  inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
4323  {
4324  out += std::forward<Arg>(arg);
4325  concat_into(out, std::forward<Args>(rest)...);
4326  }
4327 
4328  template < typename OutStringType, typename Arg, typename... Args,
4329  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4330  && !detect_string_can_append_op<OutStringType, Arg>::value
4331  && detect_string_can_append_iter<OutStringType, Arg>::value, int > >
4332  inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4333  {
4334  out.append(arg.begin(), arg.end());
4335  concat_into(out, std::forward<Args>(rest)...);
4336  }
4337 
4338  template < typename OutStringType, typename Arg, typename... Args,
4339  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4340  && !detect_string_can_append_op<OutStringType, Arg>::value
4341  && !detect_string_can_append_iter<OutStringType, Arg>::value
4342  && detect_string_can_append_data<OutStringType, Arg>::value, int > >
4343  inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4344  {
4345  out.append(arg.data(), arg.size());
4346  concat_into(out, std::forward<Args>(rest)...);
4347  }
4348 
4349  template<typename OutStringType = std::string, typename... Args>
4350  inline OutStringType concat(Args && ... args)
4351  {
4352  OutStringType str;
4353  str.reserve(concat_length(args...));
4354  concat_into(str, std::forward<Args>(args)...);
4355  return str;
4356  }
4357 
4358 } // namespace detail
4360 
4361 
4363 namespace detail
4364 {
4365 
4367  // exceptions //
4369 
4372  class exception : public std::exception
4373  {
4374  public:
4376  const char* what() const noexcept override
4377  {
4378  return m.what();
4379  }
4380 
4382  const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4383 
4384  protected:
4386  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
4387 
4388  static std::string name(const std::string& ename, int id_)
4389  {
4390  return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
4391  }
4392 
4393  static std::string diagnostics(std::nullptr_t /*leaf_element*/)
4394  {
4395  return "";
4396  }
4397 
4398  template<typename BasicJsonType>
4399  static std::string diagnostics(const BasicJsonType* leaf_element)
4400  {
4401 #if JSON_DIAGNOSTICS
4402  std::vector<std::string> tokens;
4403  for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
4404  {
4405  switch (current->m_parent->type())
4406  {
4407  case value_t::array:
4408  {
4409  for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i)
4410  {
4411  if (&current->m_parent->m_data.m_value.array->operator[](i) == current)
4412  {
4413  tokens.emplace_back(std::to_string(i));
4414  break;
4415  }
4416  }
4417  break;
4418  }
4419 
4420  case value_t::object:
4421  {
4422  for (const auto& element : *current->m_parent->m_data.m_value.object)
4423  {
4424  if (&element.second == current)
4425  {
4426  tokens.emplace_back(element.first.c_str());
4427  break;
4428  }
4429  }
4430  break;
4431  }
4432 
4433  case value_t::null: // LCOV_EXCL_LINE
4434  case value_t::string: // LCOV_EXCL_LINE
4435  case value_t::boolean: // LCOV_EXCL_LINE
4436  case value_t::number_integer: // LCOV_EXCL_LINE
4437  case value_t::number_unsigned: // LCOV_EXCL_LINE
4438  case value_t::number_float: // LCOV_EXCL_LINE
4439  case value_t::binary: // LCOV_EXCL_LINE
4440  case value_t::discarded: // LCOV_EXCL_LINE
4441  default: // LCOV_EXCL_LINE
4442  break; // LCOV_EXCL_LINE
4443  }
4444  }
4445 
4446  if (tokens.empty())
4447  {
4448  return "";
4449  }
4450 
4451  auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4452  [](const std::string& a, const std::string& b)
4453  {
4454  return concat(a, '/', detail::escape(b));
4455  });
4456  return concat('(', str, ") ");
4457 #else
4458  static_cast<void>(leaf_element);
4459  return "";
4460 #endif
4461  }
4462 
4463  private:
4465  std::runtime_error m;
4466  };
4467 
4470  class parse_error : public exception
4471  {
4472  public:
4482  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4483  static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4484  {
4485  const std::string w = concat(exception::name("parse_error", id_), "parse error",
4486  position_string(pos), ": ", exception::diagnostics(context), what_arg);
4487  return { id_, pos.chars_read_total, w.c_str() };
4488  }
4489 
4490  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4491  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4492  {
4493  const std::string w = concat(exception::name("parse_error", id_), "parse error",
4494  (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4495  ": ", exception::diagnostics(context), what_arg);
4496  return { id_, byte_, w.c_str() };
4497  }
4498 
4508  const std::size_t byte;
4509 
4510  private:
4511  parse_error(int id_, std::size_t byte_, const char* what_arg)
4512  : exception(id_, what_arg), byte(byte_) {}
4513 
4514  static std::string position_string(const position_t& pos)
4515  {
4516  return concat(" at line ", std::to_string(pos.lines_read + 1),
4517  ", column ", std::to_string(pos.chars_read_current_line));
4518  }
4519  };
4520 
4524  {
4525  public:
4526  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4527  static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4528  {
4529  const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4530  return { id_, w.c_str() };
4531  }
4532 
4533  private:
4535  invalid_iterator(int id_, const char* what_arg)
4536  : exception(id_, what_arg) {}
4537  };
4538 
4541  class type_error : public exception
4542  {
4543  public:
4544  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4545  static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4546  {
4547  const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4548  return { id_, w.c_str() };
4549  }
4550 
4551  private:
4553  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4554  };
4555 
4558  class out_of_range : public exception
4559  {
4560  public:
4561  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4562  static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4563  {
4564  const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4565  return { id_, w.c_str() };
4566  }
4567 
4568  private:
4570  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4571  };
4572 
4575  class other_error : public exception
4576  {
4577  public:
4578  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4579  static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4580  {
4581  const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4582  return { id_, w.c_str() };
4583  }
4584 
4585  private:
4587  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4588  };
4589 
4590 } // namespace detail
4592 
4593 // #include <nlohmann/detail/macro_scope.hpp>
4594 
4595 // #include <nlohmann/detail/meta/cpp_future.hpp>
4596 
4597 // #include <nlohmann/detail/meta/identity_tag.hpp>
4598 // __ _____ _____ _____
4599 // __| | __| | | | JSON for Modern C++
4600 // | | |__ | | | | | | version 3.11.3
4601 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4602 //
4603 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
4604 // SPDX-License-Identifier: MIT
4605 
4606 
4607 
4608 // #include <nlohmann/detail/abi_macros.hpp>
4609 
4610 
4612 namespace detail
4613 {
4614 
4615  // dispatching helper struct
4616  template <class T> struct identity_tag {};
4617 
4618 } // namespace detail
4620 
4621 // #include <nlohmann/detail/meta/std_fs.hpp>
4622 // __ _____ _____ _____
4623 // __| | __| | | | JSON for Modern C++
4624 // | | |__ | | | | | | version 3.11.3
4625 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4626 //
4627 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
4628 // SPDX-License-Identifier: MIT
4629 
4630 
4631 
4632 // #include <nlohmann/detail/macro_scope.hpp>
4633 
4634 
4635 #if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4636 #include <experimental/filesystem>
4638 namespace detail
4639 {
4640  namespace std_fs = std::experimental::filesystem;
4641 } // namespace detail
4643 #elif JSON_HAS_FILESYSTEM
4644 #include <filesystem>
4646 namespace detail
4647 {
4648  namespace std_fs = std::filesystem;
4649 } // namespace detail
4651 #endif
4652 
4653 // #include <nlohmann/detail/meta/type_traits.hpp>
4654 
4655 // #include <nlohmann/detail/string_concat.hpp>
4656 
4657 // #include <nlohmann/detail/value_t.hpp>
4658 
4659 
4661 namespace detail
4662 {
4663 
4664  template<typename BasicJsonType>
4665  inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4666  {
4667  if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4668  {
4669  JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4670  }
4671  n = nullptr;
4672  }
4673 
4674  // overloads for basic_json template parameters
4675  template < typename BasicJsonType, typename ArithmeticType,
4676  enable_if_t < std::is_arithmetic<ArithmeticType>::value &&
4677  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4678  int > = 0 >
4679  void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4680  {
4681  switch (static_cast<value_t>(j))
4682  {
4684  {
4685  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4686  break;
4687  }
4689  {
4690  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4691  break;
4692  }
4693  case value_t::number_float:
4694  {
4695  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4696  break;
4697  }
4698 
4699  case value_t::null:
4700  case value_t::object:
4701  case value_t::array:
4702  case value_t::string:
4703  case value_t::boolean:
4704  case value_t::binary:
4705  case value_t::discarded:
4706  default:
4707  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4708  }
4709  }
4710 
4711  template<typename BasicJsonType>
4712  inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4713  {
4714  if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4715  {
4716  JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4717  }
4718  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4719  }
4720 
4721  template<typename BasicJsonType>
4722  inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4723  {
4724  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4725  {
4726  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4727  }
4728  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4729  }
4730 
4731  template <
4732  typename BasicJsonType, typename StringType,
4733  enable_if_t <
4734  std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4735  && is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value
4736  && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4737  && !is_json_ref<StringType>::value, int > = 0 >
4738  inline void from_json(const BasicJsonType& j, StringType& s)
4739  {
4740  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4741  {
4742  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4743  }
4744 
4745  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4746  }
4747 
4748  template<typename BasicJsonType>
4749  inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4750  {
4751  get_arithmetic_value(j, val);
4752  }
4753 
4754  template<typename BasicJsonType>
4755  inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4756  {
4757  get_arithmetic_value(j, val);
4758  }
4759 
4760  template<typename BasicJsonType>
4761  inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4762  {
4763  get_arithmetic_value(j, val);
4764  }
4765 
4766 #if !JSON_DISABLE_ENUM_SERIALIZATION
4767  template<typename BasicJsonType, typename EnumType,
4768  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4769  inline void from_json(const BasicJsonType& j, EnumType& e)
4770  {
4771  typename std::underlying_type<EnumType>::type val;
4772  get_arithmetic_value(j, val);
4773  e = static_cast<EnumType>(val);
4774  }
4775 #endif // JSON_DISABLE_ENUM_SERIALIZATION
4776 
4777  // forward_list doesn't have an insert method
4778  template<typename BasicJsonType, typename T, typename Allocator,
4779  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4780  inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4781  {
4782  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4783  {
4784  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4785  }
4786  l.clear();
4787  std::transform(j.rbegin(), j.rend(),
4788  std::front_inserter(l), [](const BasicJsonType& i)
4789  {
4790  return i.template get<T>();
4791  });
4792  }
4793 
4794  // valarray doesn't have an insert method
4795  template<typename BasicJsonType, typename T,
4796  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4797  inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
4798  {
4799  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4800  {
4801  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4802  }
4803  l.resize(j.size());
4804  std::transform(j.begin(), j.end(), std::begin(l),
4805  [](const BasicJsonType& elem)
4806  {
4807  return elem.template get<T>();
4808  });
4809  }
4810 
4811  template<typename BasicJsonType, typename T, std::size_t N>
4812  auto from_json(const BasicJsonType& j, T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4813  -> decltype(j.template get<T>(), void())
4814  {
4815  for (std::size_t i = 0; i < N; ++i)
4816  {
4817  arr[i] = j.at(i).template get<T>();
4818  }
4819  }
4820 
4821  template<typename BasicJsonType>
4822  inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4823  {
4824  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4825  }
4826 
4827  template<typename BasicJsonType, typename T, std::size_t N>
4828  auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4829  priority_tag<2> /*unused*/)
4830  -> decltype(j.template get<T>(), void())
4831  {
4832  for (std::size_t i = 0; i < N; ++i)
4833  {
4834  arr[i] = j.at(i).template get<T>();
4835  }
4836  }
4837 
4838  template<typename BasicJsonType, typename ConstructibleArrayType,
4839  enable_if_t<
4840  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4841  int> = 0>
4842  auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4843  -> decltype(
4844  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4845  j.template get<typename ConstructibleArrayType::value_type>(),
4846  void())
4847  {
4848  using std::end;
4849 
4850  ConstructibleArrayType ret;
4851  ret.reserve(j.size());
4852  std::transform(j.begin(), j.end(),
4853  std::inserter(ret, end(ret)), [](const BasicJsonType& i)
4854  {
4855  // get<BasicJsonType>() returns *this, this won't call a from_json
4856  // method when value_type is BasicJsonType
4857  return i.template get<typename ConstructibleArrayType::value_type>();
4858  });
4859  arr = std::move(ret);
4860  }
4861 
4862  template<typename BasicJsonType, typename ConstructibleArrayType,
4863  enable_if_t<
4864  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4865  int> = 0>
4866  inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4867  priority_tag<0> /*unused*/)
4868  {
4869  using std::end;
4870 
4871  ConstructibleArrayType ret;
4872  std::transform(
4873  j.begin(), j.end(), std::inserter(ret, end(ret)),
4874  [](const BasicJsonType& i)
4875  {
4876  // get<BasicJsonType>() returns *this, this won't call a from_json
4877  // method when value_type is BasicJsonType
4878  return i.template get<typename ConstructibleArrayType::value_type>();
4879  });
4880  arr = std::move(ret);
4881  }
4882 
4883  template < typename BasicJsonType, typename ConstructibleArrayType,
4884  enable_if_t <
4885  is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value &&
4886  !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value &&
4888  !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value &&
4889  !is_basic_json<ConstructibleArrayType>::value,
4890  int > = 0 >
4891  auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4892  -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4893  j.template get<typename ConstructibleArrayType::value_type>(),
4894  void())
4895  {
4896  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4897  {
4898  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4899  }
4900 
4901  from_json_array_impl(j, arr, priority_tag<3> {});
4902  }
4903 
4904  template < typename BasicJsonType, typename T, std::size_t... Idx >
4905  std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4906  identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4907  {
4908  return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4909  }
4910 
4911  template < typename BasicJsonType, typename T, std::size_t N >
4912  auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4913  -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4914  {
4915  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4916  {
4917  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4918  }
4919 
4920  return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4921  }
4922 
4923  template<typename BasicJsonType>
4924  inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4925  {
4926  if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4927  {
4928  JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4929  }
4930 
4931  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4932  }
4933 
4934  template<typename BasicJsonType, typename ConstructibleObjectType,
4935  enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4936  inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4937  {
4938  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4939  {
4940  JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4941  }
4942 
4943  ConstructibleObjectType ret;
4944  const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4945  using value_type = typename ConstructibleObjectType::value_type;
4946  std::transform(
4947  inner_object->begin(), inner_object->end(),
4948  std::inserter(ret, ret.begin()),
4949  [](typename BasicJsonType::object_t::value_type const& p)
4950  {
4951  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4952  });
4953  obj = std::move(ret);
4954  }
4955 
4956  // overload for arithmetic types, not chosen for basic_json template arguments
4957  // (BooleanType, etc..); note: Is it really necessary to provide explicit
4958  // overloads for boolean_t etc. in case of a custom BooleanType which is not
4959  // an arithmetic type?
4960  template < typename BasicJsonType, typename ArithmeticType,
4961  enable_if_t <
4962  std::is_arithmetic<ArithmeticType>::value &&
4963  !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value &&
4964  !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value &&
4965  !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value &&
4966  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4967  int > = 0 >
4968  inline void from_json(const BasicJsonType& j, ArithmeticType& val)
4969  {
4970  switch (static_cast<value_t>(j))
4971  {
4973  {
4974  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4975  break;
4976  }
4978  {
4979  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4980  break;
4981  }
4982  case value_t::number_float:
4983  {
4984  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4985  break;
4986  }
4987  case value_t::boolean:
4988  {
4989  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4990  break;
4991  }
4992 
4993  case value_t::null:
4994  case value_t::object:
4995  case value_t::array:
4996  case value_t::string:
4997  case value_t::binary:
4998  case value_t::discarded:
4999  default:
5000  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
5001  }
5002  }
5003 
5004  template<typename BasicJsonType, typename... Args, std::size_t... Idx>
5005  std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
5006  {
5007  return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
5008  }
5009 
5010  template < typename BasicJsonType, class A1, class A2 >
5011  std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
5012  {
5013  return { std::forward<BasicJsonType>(j).at(0).template get<A1>(),
5014  std::forward<BasicJsonType>(j).at(1).template get<A2>() };
5015  }
5016 
5017  template<typename BasicJsonType, typename A1, typename A2>
5018  inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
5019  {
5020  p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
5021  }
5022 
5023  template<typename BasicJsonType, typename... Args>
5024  std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
5025  {
5026  return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
5027  }
5028 
5029  template<typename BasicJsonType, typename... Args>
5030  inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
5031  {
5032  t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
5033  }
5034 
5035  template<typename BasicJsonType, typename TupleRelated>
5036  auto from_json(BasicJsonType&& j, TupleRelated&& t)
5037  -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
5038  {
5039  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5040  {
5041  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5042  }
5043 
5044  return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
5045  }
5046 
5047  template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
5048  typename = enable_if_t < !std::is_constructible <
5049  typename BasicJsonType::string_t, Key >::value >>
5050  inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
5051  {
5052  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5053  {
5054  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5055  }
5056  m.clear();
5057  for (const auto& p : j)
5058  {
5059  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5060  {
5061  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5062  }
5063  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5064  }
5065  }
5066 
5067  template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
5068  typename = enable_if_t < !std::is_constructible <
5069  typename BasicJsonType::string_t, Key >::value >>
5070  inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
5071  {
5072  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5073  {
5074  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5075  }
5076  m.clear();
5077  for (const auto& p : j)
5078  {
5079  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5080  {
5081  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5082  }
5083  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5084  }
5085  }
5086 
5087 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5088  template<typename BasicJsonType>
5089  inline void from_json(const BasicJsonType& j, std_fs::path& p)
5090  {
5091  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
5092  {
5093  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
5094  }
5095  p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
5096  }
5097 #endif
5098 
5100  {
5101  template<typename BasicJsonType, typename T>
5102  auto operator()(const BasicJsonType& j, T&& val) const
5103  noexcept(noexcept(from_json(j, std::forward<T>(val))))
5104  -> decltype(from_json(j, std::forward<T>(val)))
5105  {
5106  return from_json(j, std::forward<T>(val));
5107  }
5108  };
5109 
5110 } // namespace detail
5111 
5112 #ifndef JSON_HAS_CPP_17
5116 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5117 {
5118 #endif
5119  JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
5121 #ifndef JSON_HAS_CPP_17
5122 } // namespace
5123 #endif
5124 
5126 
5127 // #include <nlohmann/detail/conversions/to_json.hpp>
5128 // __ _____ _____ _____
5129 // __| | __| | | | JSON for Modern C++
5130 // | | |__ | | | | | | version 3.11.3
5131 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5132 //
5133 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5134 // SPDX-License-Identifier: MIT
5135 
5136 
5137 
5138 #include <algorithm> // copy
5139 #include <iterator> // begin, end
5140 #include <string> // string
5141 #include <tuple> // tuple, get
5142 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
5143 #include <utility> // move, forward, declval, pair
5144 #include <valarray> // valarray
5145 #include <vector> // vector
5146 
5147 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5148 // __ _____ _____ _____
5149 // __| | __| | | | JSON for Modern C++
5150 // | | |__ | | | | | | version 3.11.3
5151 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5152 //
5153 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5154 // SPDX-License-Identifier: MIT
5155 
5156 
5157 
5158 #include <cstddef> // size_t
5159 #include <iterator> // input_iterator_tag
5160 #include <string> // string, to_string
5161 #include <tuple> // tuple_size, get, tuple_element
5162 #include <utility> // move
5163 
5164 #if JSON_HAS_RANGES
5165 #include <ranges> // enable_borrowed_range
5166 #endif
5167 
5168 // #include <nlohmann/detail/abi_macros.hpp>
5169 
5170 // #include <nlohmann/detail/meta/type_traits.hpp>
5171 
5172 // #include <nlohmann/detail/value_t.hpp>
5173 
5174 
5176 namespace detail
5177 {
5178 
5179  template<typename string_type>
5180  void int_to_string(string_type& target, std::size_t value)
5181  {
5182  // For ADL
5183  using std::to_string;
5184  target = to_string(value);
5185  }
5186  template<typename IteratorType> class iteration_proxy_value
5187  {
5188  public:
5189  using difference_type = std::ptrdiff_t;
5193  using iterator_category = std::input_iterator_tag;
5194  using string_type = typename std::remove_cv< typename std::remove_reference<decltype(std::declval<IteratorType>().key()) >::type >::type;
5195 
5196  private:
5198  IteratorType anchor{};
5200  std::size_t array_index = 0;
5202  mutable std::size_t array_index_last = 0;
5204  mutable string_type array_index_str = "0";
5206  string_type empty_str{};
5207 
5208  public:
5209  explicit iteration_proxy_value() = default;
5210  explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
5211  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5212  && std::is_nothrow_default_constructible<string_type>::value)
5213  : anchor(std::move(it))
5214  , array_index(array_index_)
5215  {}
5216 
5219  // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
5221  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5222  && std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
5224  noexcept(std::is_nothrow_move_assignable<IteratorType>::value
5225  && std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
5227 
5229  const iteration_proxy_value& operator*() const
5230  {
5231  return *this;
5232  }
5233 
5236  {
5237  ++anchor;
5238  ++array_index;
5239 
5240  return *this;
5241  }
5242 
5243  iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
5244  {
5245  auto tmp = iteration_proxy_value(anchor, array_index);
5246  ++anchor;
5247  ++array_index;
5248  return tmp;
5249  }
5250 
5252  bool operator==(const iteration_proxy_value& o) const
5253  {
5254  return anchor == o.anchor;
5255  }
5256 
5258  bool operator!=(const iteration_proxy_value& o) const
5259  {
5260  return anchor != o.anchor;
5261  }
5262 
5264  const string_type& key() const
5265  {
5266  JSON_ASSERT(anchor.m_object != nullptr);
5267 
5268  switch (anchor.m_object->type())
5269  {
5270  // use integer array index as key
5271  case value_t::array:
5272  {
5273  if (array_index != array_index_last)
5274  {
5275  int_to_string(array_index_str, array_index);
5276  array_index_last = array_index;
5277  }
5278  return array_index_str;
5279  }
5280 
5281  // use key from the object
5282  case value_t::object:
5283  return anchor.key();
5284 
5285  // use an empty key for all primitive types
5286  case value_t::null:
5287  case value_t::string:
5288  case value_t::boolean:
5291  case value_t::number_float:
5292  case value_t::binary:
5293  case value_t::discarded:
5294  default:
5295  return empty_str;
5296  }
5297  }
5298 
5300  typename IteratorType::reference value() const
5301  {
5302  return anchor.value();
5303  }
5304  };
5305 
5307  template<typename IteratorType> class iteration_proxy
5308  {
5309  private:
5311  typename IteratorType::pointer container = nullptr;
5312 
5313  public:
5314  explicit iteration_proxy() = default;
5315 
5317  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
5318  : container(&cont) {}
5319 
5322  iteration_proxy(iteration_proxy&&) noexcept = default;
5323  iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
5324  ~iteration_proxy() = default;
5325 
5327  iteration_proxy_value<IteratorType> begin() const noexcept
5328  {
5329  return iteration_proxy_value<IteratorType>(container->begin());
5330  }
5331 
5334  {
5335  return iteration_proxy_value<IteratorType>(container->end());
5336  }
5337  };
5338 
5339  // Structured Bindings Support
5340  // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5341  // And see https://github.com/nlohmann/json/pull/1391
5342  template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
5343  auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
5344  {
5345  return i.key();
5346  }
5347  // Structured Bindings Support
5348  // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5349  // And see https://github.com/nlohmann/json/pull/1391
5350  template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
5351  auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
5352  {
5353  return i.value();
5354  }
5355 
5356 } // namespace detail
5358 
5359 // The Addition to the STD Namespace is required to add
5360 // Structured Bindings Support to the iteration_proxy_value class
5361 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5362 // And see https://github.com/nlohmann/json/pull/1391
5363 namespace std
5364 {
5365 
5366 #if defined(__clang__)
5367  // Fix: https://github.com/nlohmann/json/issues/1401
5368 #pragma clang diagnostic push
5369 #pragma clang diagnostic ignored "-Wmismatched-tags"
5370 #endif
5371  template<typename IteratorType>
5372  class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
5373  : public std::integral_constant<std::size_t, 2> {};
5374 
5375  template<std::size_t N, typename IteratorType>
5376  class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)
5377  {
5378  public:
5379  using type = decltype(
5380  get<N>(std::declval <
5381  ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
5382  };
5383 #if defined(__clang__)
5384 #pragma clang diagnostic pop
5385 #endif
5386 
5387 } // namespace std
5388 
5389 #if JSON_HAS_RANGES
5390 template <typename IteratorType>
5391 inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
5392 #endif
5393 
5394 // #include <nlohmann/detail/macro_scope.hpp>
5395 
5396 // #include <nlohmann/detail/meta/cpp_future.hpp>
5397 
5398 // #include <nlohmann/detail/meta/std_fs.hpp>
5399 
5400 // #include <nlohmann/detail/meta/type_traits.hpp>
5401 
5402 // #include <nlohmann/detail/value_t.hpp>
5403 
5404 
5406 namespace detail
5407 {
5408 
5410  // constructors //
5412 
5413  /*
5414  * Note all external_constructor<>::construct functions need to call
5415  * j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an
5416  * allocated value (e.g., a string). See bug issue
5417  * https://github.com/nlohmann/json/issues/2865 for more information.
5418  */
5419 
5420  template<value_t> struct external_constructor;
5421 
5422  template<>
5424  {
5425  template<typename BasicJsonType>
5426  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
5427  {
5428  j.m_data.m_value.destroy(j.m_data.m_type);
5429  j.m_data.m_type = value_t::boolean;
5430  j.m_data.m_value = b;
5431  j.assert_invariant();
5432  }
5433  };
5434 
5435  template<>
5437  {
5438  template<typename BasicJsonType>
5439  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
5440  {
5441  j.m_data.m_value.destroy(j.m_data.m_type);
5442  j.m_data.m_type = value_t::string;
5443  j.m_data.m_value = s;
5444  j.assert_invariant();
5445  }
5446 
5447  template<typename BasicJsonType>
5448  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5449  {
5450  j.m_data.m_value.destroy(j.m_data.m_type);
5451  j.m_data.m_type = value_t::string;
5452  j.m_data.m_value = std::move(s);
5453  j.assert_invariant();
5454  }
5455 
5456  template < typename BasicJsonType, typename CompatibleStringType,
5458  int > = 0 >
5459  static void construct(BasicJsonType& j, const CompatibleStringType& str)
5460  {
5461  j.m_data.m_value.destroy(j.m_data.m_type);
5462  j.m_data.m_type = value_t::string;
5463  j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
5464  j.assert_invariant();
5465  }
5466  };
5467 
5468  template<>
5470  {
5471  template<typename BasicJsonType>
5472  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
5473  {
5474  j.m_data.m_value.destroy(j.m_data.m_type);
5475  j.m_data.m_type = value_t::binary;
5476  j.m_data.m_value = typename BasicJsonType::binary_t(b);
5477  j.assert_invariant();
5478  }
5479 
5480  template<typename BasicJsonType>
5481  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
5482  {
5483  j.m_data.m_value.destroy(j.m_data.m_type);
5484  j.m_data.m_type = value_t::binary;
5485  j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
5486  j.assert_invariant();
5487  }
5488  };
5489 
5490  template<>
5492  {
5493  template<typename BasicJsonType>
5494  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5495  {
5496  j.m_data.m_value.destroy(j.m_data.m_type);
5497  j.m_data.m_type = value_t::number_float;
5498  j.m_data.m_value = val;
5499  j.assert_invariant();
5500  }
5501  };
5502 
5503  template<>
5505  {
5506  template<typename BasicJsonType>
5507  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5508  {
5509  j.m_data.m_value.destroy(j.m_data.m_type);
5510  j.m_data.m_type = value_t::number_unsigned;
5511  j.m_data.m_value = val;
5512  j.assert_invariant();
5513  }
5514  };
5515 
5516  template<>
5518  {
5519  template<typename BasicJsonType>
5520  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5521  {
5522  j.m_data.m_value.destroy(j.m_data.m_type);
5523  j.m_data.m_type = value_t::number_integer;
5524  j.m_data.m_value = val;
5525  j.assert_invariant();
5526  }
5527  };
5528 
5529  template<>
5531  {
5532  template<typename BasicJsonType>
5533  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5534  {
5535  j.m_data.m_value.destroy(j.m_data.m_type);
5536  j.m_data.m_type = value_t::array;
5537  j.m_data.m_value = arr;
5538  j.set_parents();
5539  j.assert_invariant();
5540  }
5541 
5542  template<typename BasicJsonType>
5543  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5544  {
5545  j.m_data.m_value.destroy(j.m_data.m_type);
5546  j.m_data.m_type = value_t::array;
5547  j.m_data.m_value = std::move(arr);
5548  j.set_parents();
5549  j.assert_invariant();
5550  }
5551 
5552  template < typename BasicJsonType, typename CompatibleArrayType,
5554  int > = 0 >
5555  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5556  {
5557  using std::begin;
5558  using std::end;
5559 
5560  j.m_data.m_value.destroy(j.m_data.m_type);
5561  j.m_data.m_type = value_t::array;
5562  j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5563  j.set_parents();
5564  j.assert_invariant();
5565  }
5566 
5567  template<typename BasicJsonType>
5568  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5569  {
5570  j.m_data.m_value.destroy(j.m_data.m_type);
5571  j.m_data.m_type = value_t::array;
5572  j.m_data.m_value = value_t::array;
5573  j.m_data.m_value.array->reserve(arr.size());
5574  for (const bool x : arr)
5575  {
5576  j.m_data.m_value.array->push_back(x);
5577  j.set_parent(j.m_data.m_value.array->back());
5578  }
5579  j.assert_invariant();
5580  }
5581 
5582  template<typename BasicJsonType, typename T,
5584  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5585  {
5586  j.m_data.m_value.destroy(j.m_data.m_type);
5587  j.m_data.m_type = value_t::array;
5588  j.m_data.m_value = value_t::array;
5589  j.m_data.m_value.array->resize(arr.size());
5590  if (arr.size() > 0)
5591  {
5592  std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());
5593  }
5594  j.set_parents();
5595  j.assert_invariant();
5596  }
5597  };
5598 
5599  template<>
5601  {
5602  template<typename BasicJsonType>
5603  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5604  {
5605  j.m_data.m_value.destroy(j.m_data.m_type);
5606  j.m_data.m_type = value_t::object;
5607  j.m_data.m_value = obj;
5608  j.set_parents();
5609  j.assert_invariant();
5610  }
5611 
5612  template<typename BasicJsonType>
5613  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5614  {
5615  j.m_data.m_value.destroy(j.m_data.m_type);
5616  j.m_data.m_type = value_t::object;
5617  j.m_data.m_value = std::move(obj);
5618  j.set_parents();
5619  j.assert_invariant();
5620  }
5621 
5622  template < typename BasicJsonType, typename CompatibleObjectType,
5624  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5625  {
5626  using std::begin;
5627  using std::end;
5628 
5629  j.m_data.m_value.destroy(j.m_data.m_type);
5630  j.m_data.m_type = value_t::object;
5631  j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5632  j.set_parents();
5633  j.assert_invariant();
5634  }
5635  };
5636 
5638  // to_json //
5640 
5641  template<typename BasicJsonType, typename T,
5642  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5643  inline void to_json(BasicJsonType& j, T b) noexcept
5644  {
5646  }
5647 
5648  template < typename BasicJsonType, typename BoolRef,
5649  enable_if_t <
5650  ((std::is_same<std::vector<bool>::reference, BoolRef>::value
5651  && !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
5652  || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
5653  && !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
5654  typename BasicJsonType::boolean_t >::value))
5655  && std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 >
5656  inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
5657  {
5658  external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
5659  }
5660 
5661  template<typename BasicJsonType, typename CompatibleString,
5662  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5663  inline void to_json(BasicJsonType& j, const CompatibleString& s)
5664  {
5666  }
5667 
5668  template<typename BasicJsonType>
5669  inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5670  {
5672  }
5673 
5674  template<typename BasicJsonType, typename FloatType,
5675  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5676  inline void to_json(BasicJsonType& j, FloatType val) noexcept
5677  {
5678  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5679  }
5680 
5681  template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5682  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5683  inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5684  {
5685  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5686  }
5687 
5688  template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5689  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5690  inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5691  {
5692  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5693  }
5694 
5695 #if !JSON_DISABLE_ENUM_SERIALIZATION
5696  template<typename BasicJsonType, typename EnumType,
5697  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5698  inline void to_json(BasicJsonType& j, EnumType e) noexcept
5699  {
5700  using underlying_type = typename std::underlying_type<EnumType>::type;
5701  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5702  }
5703 #endif // JSON_DISABLE_ENUM_SERIALIZATION
5704 
5705  template<typename BasicJsonType>
5706  inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
5707  {
5709  }
5710 
5711  template < typename BasicJsonType, typename CompatibleArrayType,
5712  enable_if_t < is_compatible_array_type<BasicJsonType,
5713  CompatibleArrayType>::value &&
5714  !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value &&
5716  !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value &&
5717  !is_basic_json<CompatibleArrayType>::value,
5718  int > = 0 >
5719  inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5720  {
5722  }
5723 
5724  template<typename BasicJsonType>
5725  inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5726  {
5728  }
5729 
5730  template<typename BasicJsonType, typename T,
5731  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
5732  inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5733  {
5735  }
5736 
5737  template<typename BasicJsonType>
5738  inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5739  {
5741  }
5742 
5743  template < typename BasicJsonType, typename CompatibleObjectType,
5744  enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value && !is_basic_json<CompatibleObjectType>::value, int > = 0 >
5745  inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5746  {
5748  }
5749 
5750  template<typename BasicJsonType>
5751  inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5752  {
5754  }
5755 
5756  template <
5757  typename BasicJsonType, typename T, std::size_t N,
5758  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5759  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5760  int > = 0 >
5761  inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5762  {
5764  }
5765 
5766  template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
5767  inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5768  {
5769  j = { p.first, p.second };
5770  }
5771 
5772  // for https://github.com/nlohmann/json/pull/1134
5773  template<typename BasicJsonType, typename T,
5774  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
5775  inline void to_json(BasicJsonType& j, const T& b)
5776  {
5777  j = { {b.key(), b.value()} };
5778  }
5779 
5780  template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5781  inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5782  {
5783  j = { std::get<Idx>(t)... };
5784  }
5785 
5786  template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5787  inline void to_json(BasicJsonType& j, const T& t)
5788  {
5789  to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5790  }
5791 
5792 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5793  template<typename BasicJsonType>
5794  inline void to_json(BasicJsonType& j, const std_fs::path& p)
5795  {
5796  j = p.string();
5797  }
5798 #endif
5799 
5800  struct to_json_fn
5801  {
5802  template<typename BasicJsonType, typename T>
5803  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5804  -> decltype(to_json(j, std::forward<T>(val)), void())
5805  {
5806  return to_json(j, std::forward<T>(val));
5807  }
5808  };
5809 } // namespace detail
5810 
5811 #ifndef JSON_HAS_CPP_17
5815 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5816 {
5817 #endif
5818  JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
5820 #ifndef JSON_HAS_CPP_17
5821 } // namespace
5822 #endif
5823 
5825 
5826 // #include <nlohmann/detail/meta/identity_tag.hpp>
5827 
5828 
5830 
5832 template<typename ValueType, typename>
5834 {
5837  template<typename BasicJsonType, typename TargetType = ValueType>
5838  static auto from_json(BasicJsonType&& j, TargetType& val) noexcept(
5839  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5840  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5841  {
5842  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5843  }
5844 
5847  template<typename BasicJsonType, typename TargetType = ValueType>
5848  static auto from_json(BasicJsonType&& j) noexcept(
5849  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5850  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5851  {
5852  return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5853  }
5854 
5857  template<typename BasicJsonType, typename TargetType = ValueType>
5858  static auto to_json(BasicJsonType& j, TargetType&& val) noexcept(
5859  noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5860  -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5861  {
5862  ::nlohmann::to_json(j, std::forward<TargetType>(val));
5863  }
5864 };
5865 
5867 
5868 // #include <nlohmann/byte_container_with_subtype.hpp>
5869 // __ _____ _____ _____
5870 // __| | __| | | | JSON for Modern C++
5871 // | | |__ | | | | | | version 3.11.3
5872 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5873 //
5874 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5875 // SPDX-License-Identifier: MIT
5876 
5877 
5878 
5879 #include <cstdint> // uint8_t, uint64_t
5880 #include <tuple> // tie
5881 #include <utility> // move
5882 
5883 // #include <nlohmann/detail/abi_macros.hpp>
5884 
5885 
5887 
5890 template<typename BinaryType>
5891 class byte_container_with_subtype : public BinaryType
5892 {
5893 public:
5894  using container_type = BinaryType;
5895  using subtype_type = std::uint64_t;
5896 
5899  : container_type()
5900  {}
5901 
5904  : container_type(b)
5905  {}
5906 
5908  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5909  : container_type(std::move(b))
5910  {}
5911 
5913  byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5914  : container_type(b)
5915  , m_subtype(subtype_)
5916  , m_has_subtype(true)
5917  {}
5918 
5920  byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5921  : container_type(std::move(b))
5922  , m_subtype(subtype_)
5923  , m_has_subtype(true)
5924  {}
5925 
5927  {
5928  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5929  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5930  }
5931 
5933  {
5934  return !(rhs == *this);
5935  }
5936 
5939  void set_subtype(subtype_type subtype_) noexcept
5940  {
5941  m_subtype = subtype_;
5942  m_has_subtype = true;
5943  }
5944 
5947  constexpr subtype_type subtype() const noexcept
5948  {
5949  return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5950  }
5951 
5954  constexpr bool has_subtype() const noexcept
5955  {
5956  return m_has_subtype;
5957  }
5958 
5961  void clear_subtype() noexcept
5962  {
5963  m_subtype = 0;
5964  m_has_subtype = false;
5965  }
5966 
5967 private:
5968  subtype_type m_subtype = 0;
5969  bool m_has_subtype = false;
5970 };
5971 
5973 
5974 // #include <nlohmann/detail/conversions/from_json.hpp>
5975 
5976 // #include <nlohmann/detail/conversions/to_json.hpp>
5977 
5978 // #include <nlohmann/detail/exceptions.hpp>
5979 
5980 // #include <nlohmann/detail/hash.hpp>
5981 // __ _____ _____ _____
5982 // __| | __| | | | JSON for Modern C++
5983 // | | |__ | | | | | | version 3.11.3
5984 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5985 //
5986 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5987 // SPDX-License-Identifier: MIT
5988 
5989 
5990 
5991 #include <cstdint> // uint8_t
5992 #include <cstddef> // size_t
5993 #include <functional> // hash
5994 
5995 // #include <nlohmann/detail/abi_macros.hpp>
5996 
5997 // #include <nlohmann/detail/value_t.hpp>
5998 
5999 
6001 namespace detail
6002 {
6003 
6004  // boost::hash_combine
6005  inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
6006  {
6007  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
6008  return seed;
6009  }
6010 
6022  template<typename BasicJsonType>
6023  std::size_t hash(const BasicJsonType& j)
6024  {
6025  using string_t = typename BasicJsonType::string_t;
6026  using number_integer_t = typename BasicJsonType::number_integer_t;
6027  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6028  using number_float_t = typename BasicJsonType::number_float_t;
6029 
6030  const auto type = static_cast<std::size_t>(j.type());
6031  switch (j.type())
6032  {
6033  case BasicJsonType::value_t::null:
6034  case BasicJsonType::value_t::discarded:
6035  {
6036  return combine(type, 0);
6037  }
6038 
6039  case BasicJsonType::value_t::object:
6040  {
6041  auto seed = combine(type, j.size());
6042  for (const auto& element : j.items())
6043  {
6044  const auto h = std::hash<string_t>{}(element.key());
6045  seed = combine(seed, h);
6046  seed = combine(seed, hash(element.value()));
6047  }
6048  return seed;
6049  }
6050 
6051  case BasicJsonType::value_t::array:
6052  {
6053  auto seed = combine(type, j.size());
6054  for (const auto& element : j)
6055  {
6056  seed = combine(seed, hash(element));
6057  }
6058  return seed;
6059  }
6060 
6061  case BasicJsonType::value_t::string:
6062  {
6063  const auto h = std::hash<string_t>{}(j.template get_ref<const string_t&>());
6064  return combine(type, h);
6065  }
6066 
6067  case BasicJsonType::value_t::boolean:
6068  {
6069  const auto h = std::hash<bool>{}(j.template get<bool>());
6070  return combine(type, h);
6071  }
6072 
6073  case BasicJsonType::value_t::number_integer:
6074  {
6075  const auto h = std::hash<number_integer_t>{}(j.template get<number_integer_t>());
6076  return combine(type, h);
6077  }
6078 
6079  case BasicJsonType::value_t::number_unsigned:
6080  {
6081  const auto h = std::hash<number_unsigned_t>{}(j.template get<number_unsigned_t>());
6082  return combine(type, h);
6083  }
6084 
6085  case BasicJsonType::value_t::number_float:
6086  {
6087  const auto h = std::hash<number_float_t>{}(j.template get<number_float_t>());
6088  return combine(type, h);
6089  }
6090 
6091  case BasicJsonType::value_t::binary:
6092  {
6093  auto seed = combine(type, j.get_binary().size());
6094  const auto h = std::hash<bool>{}(j.get_binary().has_subtype());
6095  seed = combine(seed, h);
6096  seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
6097  for (const auto byte : j.get_binary())
6098  {
6099  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
6100  }
6101  return seed;
6102  }
6103 
6104  default: // LCOV_EXCL_LINE
6105  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
6106  return 0; // LCOV_EXCL_LINE
6107  }
6108  }
6109 
6110 } // namespace detail
6112 
6113 // #include <nlohmann/detail/input/binary_reader.hpp>
6114 // __ _____ _____ _____
6115 // __| | __| | | | JSON for Modern C++
6116 // | | |__ | | | | | | version 3.11.3
6117 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6118 //
6119 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
6120 // SPDX-License-Identifier: MIT
6121 
6122 
6123 
6124 #include <algorithm> // generate_n
6125 #include <array> // array
6126 #include <cmath> // ldexp
6127 #include <cstddef> // size_t
6128 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6129 #include <cstdio> // snprintf
6130 #include <cstring> // memcpy
6131 #include <iterator> // back_inserter
6132 #include <limits> // numeric_limits
6133 #include <string> // char_traits, string
6134 #include <utility> // make_pair, move
6135 #include <vector> // vector
6136 
6137 // #include <nlohmann/detail/exceptions.hpp>
6138 
6139 // #include <nlohmann/detail/input/input_adapters.hpp>
6140 // __ _____ _____ _____
6141 // __| | __| | | | JSON for Modern C++
6142 // | | |__ | | | | | | version 3.11.3
6143 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6144 //
6145 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
6146 // SPDX-License-Identifier: MIT
6147 
6148 
6149 
6150 #include <array> // array
6151 #include <cstddef> // size_t
6152 #include <cstring> // strlen
6153 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
6154 #include <memory> // shared_ptr, make_shared, addressof
6155 #include <numeric> // accumulate
6156 #include <string> // string, char_traits
6157 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
6158 #include <utility> // pair, declval
6159 
6160 #ifndef JSON_NO_IO
6161 #include <cstdio> // FILE *
6162 #include <istream> // istream
6163 #endif // JSON_NO_IO
6164 
6165 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
6166 
6167 // #include <nlohmann/detail/macro_scope.hpp>
6168 
6169 // #include <nlohmann/detail/meta/type_traits.hpp>
6170 
6171 
6173 namespace detail
6174 {
6175 
6178 
6180  // input adapters //
6182 
6183 #ifndef JSON_NO_IO
6189  {
6190  public:
6191  using char_type = char;
6192 
6194  explicit file_input_adapter(std::FILE* f) noexcept
6195  : m_file(f)
6196  {
6197  JSON_ASSERT(m_file != nullptr);
6198  }
6199 
6200  // make class move-only
6203  file_input_adapter& operator=(const file_input_adapter&) = delete;
6204  file_input_adapter& operator=(file_input_adapter&&) = delete;
6205  ~file_input_adapter() = default;
6206 
6207  std::char_traits<char>::int_type get_character() noexcept
6208  {
6209  return std::fgetc(m_file);
6210  }
6211 
6212  private:
6214  std::FILE* m_file;
6215  };
6216 
6227  {
6228  public:
6229  using char_type = char;
6230 
6232  {
6233  // clear stream flags; we use underlying streambuf I/O, do not
6234  // maintain ifstream flags, except eof
6235  if (is != nullptr)
6236  {
6237  is->clear(is->rdstate() & std::ios::eofbit);
6238  }
6239  }
6240 
6241  explicit input_stream_adapter(std::istream& i)
6242  : is(&i), sb(i.rdbuf())
6243  {}
6244 
6245  // delete because of pointer members
6249 
6251  : is(rhs.is), sb(rhs.sb)
6252  {
6253  rhs.is = nullptr;
6254  rhs.sb = nullptr;
6255  }
6256 
6257  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
6258  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
6259  // end up as the same value, e.g. 0xFFFFFFFF.
6260  std::char_traits<char>::int_type get_character()
6261  {
6262  auto res = sb->sbumpc();
6263  // set eof manually, as we don't use the istream interface.
6264  if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
6265  {
6266  is->clear(is->rdstate() | std::ios::eofbit);
6267  }
6268  return res;
6269  }
6270 
6271  private:
6273  std::istream* is = nullptr;
6274  std::streambuf* sb = nullptr;
6275  };
6276 #endif // JSON_NO_IO
6277 
6278  // General-purpose iterator-based adapter. It might not be as fast as
6279  // theoretically possible for some containers, but it is extremely versatile.
6280  template<typename IteratorType>
6282  {
6283  public:
6284  using char_type = typename std::iterator_traits<IteratorType>::value_type;
6285 
6286  iterator_input_adapter(IteratorType first, IteratorType last)
6287  : current(std::move(first)), end(std::move(last))
6288  {}
6289 
6291  {
6292  if (JSON_HEDLEY_LIKELY(current != end))
6293  {
6294  auto result = char_traits<char_type>::to_int_type(*current);
6295  std::advance(current, 1);
6296  return result;
6297  }
6298 
6299  return char_traits<char_type>::eof();
6300  }
6301 
6302  private:
6303  IteratorType current;
6304  IteratorType end;
6305 
6306  template<typename BaseInputAdapter, size_t T>
6308 
6309  bool empty() const
6310  {
6311  return current == end;
6312  }
6313  };
6314 
6315  template<typename BaseInputAdapter, size_t T>
6317 
6318  template<typename BaseInputAdapter>
6319  struct wide_string_input_helper<BaseInputAdapter, 4>
6320  {
6321  // UTF-32
6322  static void fill_buffer(BaseInputAdapter& input,
6323  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6324  size_t& utf8_bytes_index,
6325  size_t& utf8_bytes_filled)
6326  {
6327  utf8_bytes_index = 0;
6328 
6329  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6330  {
6331  utf8_bytes[0] = std::char_traits<char>::eof();
6332  utf8_bytes_filled = 1;
6333  }
6334  else
6335  {
6336  // get the current character
6337  const auto wc = input.get_character();
6338 
6339  // UTF-32 to UTF-8 encoding
6340  if (wc < 0x80)
6341  {
6342  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6343  utf8_bytes_filled = 1;
6344  }
6345  else if (wc <= 0x7FF)
6346  {
6347  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
6348  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6349  utf8_bytes_filled = 2;
6350  }
6351  else if (wc <= 0xFFFF)
6352  {
6353  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
6354  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6355  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6356  utf8_bytes_filled = 3;
6357  }
6358  else if (wc <= 0x10FFFF)
6359  {
6360  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
6361  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
6362  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6363  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6364  utf8_bytes_filled = 4;
6365  }
6366  else
6367  {
6368  // unknown character
6369  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6370  utf8_bytes_filled = 1;
6371  }
6372  }
6373  }
6374  };
6375 
6376  template<typename BaseInputAdapter>
6377  struct wide_string_input_helper<BaseInputAdapter, 2>
6378  {
6379  // UTF-16
6380  static void fill_buffer(BaseInputAdapter& input,
6381  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6382  size_t& utf8_bytes_index,
6383  size_t& utf8_bytes_filled)
6384  {
6385  utf8_bytes_index = 0;
6386 
6387  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6388  {
6389  utf8_bytes[0] = std::char_traits<char>::eof();
6390  utf8_bytes_filled = 1;
6391  }
6392  else
6393  {
6394  // get the current character
6395  const auto wc = input.get_character();
6396 
6397  // UTF-16 to UTF-8 encoding
6398  if (wc < 0x80)
6399  {
6400  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6401  utf8_bytes_filled = 1;
6402  }
6403  else if (wc <= 0x7FF)
6404  {
6405  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
6406  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6407  utf8_bytes_filled = 2;
6408  }
6409  else if (0xD800 > wc || wc >= 0xE000)
6410  {
6411  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
6412  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6413  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6414  utf8_bytes_filled = 3;
6415  }
6416  else
6417  {
6418  if (JSON_HEDLEY_UNLIKELY(!input.empty()))
6419  {
6420  const auto wc2 = static_cast<unsigned int>(input.get_character());
6421  const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
6422  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
6423  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
6424  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
6425  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
6426  utf8_bytes_filled = 4;
6427  }
6428  else
6429  {
6430  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6431  utf8_bytes_filled = 1;
6432  }
6433  }
6434  }
6435  }
6436  };
6437 
6438  // Wraps another input adapter to convert wide character types into individual bytes.
6439  template<typename BaseInputAdapter, typename WideCharType>
6441  {
6442  public:
6443  using char_type = char;
6444 
6445  wide_string_input_adapter(BaseInputAdapter base)
6446  : base_adapter(base) {}
6447 
6448  typename std::char_traits<char>::int_type get_character() noexcept
6449  {
6450  // check if buffer needs to be filled
6451  if (utf8_bytes_index == utf8_bytes_filled)
6452  {
6453  fill_buffer<sizeof(WideCharType)>();
6454 
6455  JSON_ASSERT(utf8_bytes_filled > 0);
6456  JSON_ASSERT(utf8_bytes_index == 0);
6457  }
6458 
6459  // use buffer
6460  JSON_ASSERT(utf8_bytes_filled > 0);
6461  JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
6462  return utf8_bytes[utf8_bytes_index++];
6463  }
6464 
6465  private:
6466  BaseInputAdapter base_adapter;
6467 
6468  template<size_t T>
6469  void fill_buffer()
6470  {
6471  wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
6472  }
6473 
6475  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = { {0, 0, 0, 0} };
6476 
6478  std::size_t utf8_bytes_index = 0;
6480  std::size_t utf8_bytes_filled = 0;
6481  };
6482 
6483  template<typename IteratorType, typename Enable = void>
6485  {
6486  using iterator_type = IteratorType;
6487  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6489 
6490  static adapter_type create(IteratorType first, IteratorType last)
6491  {
6492  return adapter_type(std::move(first), std::move(last));
6493  }
6494  };
6495 
6496  template<typename T>
6498  {
6499  using value_type = typename std::iterator_traits<T>::value_type;
6500  enum
6501  {
6502  value = sizeof(value_type) > 1
6503  };
6504  };
6505 
6506  template<typename IteratorType>
6508  {
6509  using iterator_type = IteratorType;
6510  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6513 
6514  static adapter_type create(IteratorType first, IteratorType last)
6515  {
6516  return adapter_type(base_adapter_type(std::move(first), std::move(last)));
6517  }
6518  };
6519 
6520  // General purpose iterator-based input
6521  template<typename IteratorType>
6522  typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
6523  {
6524  using factory_type = iterator_input_adapter_factory<IteratorType>;
6525  return factory_type::create(first, last);
6526  }
6527 
6528  // Convenience shorthand from container to iterator
6529  // Enables ADL on begin(container) and end(container)
6530  // Encloses the using declarations in namespace for not to leak them to outside scope
6531 
6532  namespace container_input_adapter_factory_impl
6533  {
6534 
6535  using std::begin;
6536  using std::end;
6537 
6538  template<typename ContainerType, typename Enable = void>
6540 
6541  template<typename ContainerType>
6542  struct container_input_adapter_factory< ContainerType,
6543  void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6544  {
6545  using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6546 
6547  static adapter_type create(const ContainerType& container)
6548  {
6549  return input_adapter(begin(container), end(container));
6550  }
6551  };
6552 
6553  } // namespace container_input_adapter_factory_impl
6554 
6555  template<typename ContainerType>
6557  {
6559  }
6560 
6561 #ifndef JSON_NO_IO
6562  // Special cases with fast paths
6563  inline file_input_adapter input_adapter(std::FILE* file)
6564  {
6565  return file_input_adapter(file);
6566  }
6567 
6568  inline input_stream_adapter input_adapter(std::istream& stream)
6569  {
6570  return input_stream_adapter(stream);
6571  }
6572 
6573  inline input_stream_adapter input_adapter(std::istream&& stream)
6574  {
6575  return input_stream_adapter(stream);
6576  }
6577 #endif // JSON_NO_IO
6578 
6579  using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6580 
6581  // Null-delimited strings, and the like.
6582  template < typename CharT,
6583  typename std::enable_if <
6584  std::is_pointer<CharT>::value &&
6585  !std::is_array<CharT>::value&&
6586  std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
6587  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6588  int >::type = 0 >
6590  {
6591  auto length = std::strlen(reinterpret_cast<const char*>(b));
6592  const auto* ptr = reinterpret_cast<const char*>(b);
6593  return input_adapter(ptr, ptr + length);
6594  }
6595 
6596  template<typename T, std::size_t N>
6597  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)
6598  {
6599  return input_adapter(array, array + N);
6600  }
6601 
6602  // This class only handles inputs of input_buffer_adapter type.
6603  // It's required so that expressions like {ptr, len} can be implicitly cast
6604  // to the correct adapter.
6606  {
6607  public:
6608  template < typename CharT,
6609  typename std::enable_if <
6610  std::is_pointer<CharT>::value&&
6611  std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
6612  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6613  int >::type = 0 >
6614  span_input_adapter(CharT b, std::size_t l)
6615  : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
6616 
6617  template<class IteratorType,
6618  typename std::enable_if<
6619  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
6620  int>::type = 0>
6621  span_input_adapter(IteratorType first, IteratorType last)
6622  : ia(input_adapter(first, last)) {}
6623 
6625  {
6626  return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6627  }
6628 
6629  private:
6631  };
6632 
6633 } // namespace detail
6635 
6636 // #include <nlohmann/detail/input/json_sax.hpp>
6637 // __ _____ _____ _____
6638 // __| | __| | | | JSON for Modern C++
6639 // | | |__ | | | | | | version 3.11.3
6640 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6641 //
6642 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
6643 // SPDX-License-Identifier: MIT
6644 
6645 
6646 
6647 #include <cstddef>
6648 #include <string> // string
6649 #include <utility> // move
6650 #include <vector> // vector
6651 
6652 // #include <nlohmann/detail/exceptions.hpp>
6653 
6654 // #include <nlohmann/detail/macro_scope.hpp>
6655 
6656 // #include <nlohmann/detail/string_concat.hpp>
6657 
6658 
6660 
6669 template<typename BasicJsonType>
6670 struct json_sax
6671 {
6672  using number_integer_t = typename BasicJsonType::number_integer_t;
6673  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6674  using number_float_t = typename BasicJsonType::number_float_t;
6675  using string_t = typename BasicJsonType::string_t;
6676  using binary_t = typename BasicJsonType::binary_t;
6677 
6682  virtual bool null() = 0;
6683 
6689  virtual bool boolean(bool val) = 0;
6690 
6696  virtual bool number_integer(number_integer_t val) = 0;
6697 
6703  virtual bool number_unsigned(number_unsigned_t val) = 0;
6704 
6711  virtual bool number_float(number_float_t val, const string_t& s) = 0;
6712 
6719  virtual bool string(string_t& val) = 0;
6720 
6727  virtual bool binary(binary_t& val) = 0;
6728 
6735  virtual bool start_object(std::size_t elements) = 0;
6736 
6743  virtual bool key(string_t& val) = 0;
6744 
6749  virtual bool end_object() = 0;
6750 
6757  virtual bool start_array(std::size_t elements) = 0;
6758 
6763  virtual bool end_array() = 0;
6764 
6772  virtual bool parse_error(std::size_t position,
6773  const std::string& last_token,
6774  const detail::exception& ex) = 0;
6775 
6776  json_sax() = default;
6777  json_sax(const json_sax&) = default;
6778  json_sax(json_sax&&) noexcept = default;
6779  json_sax& operator=(const json_sax&) = default;
6780  json_sax& operator=(json_sax&&) noexcept = default;
6781  virtual ~json_sax() = default;
6782 };
6783 
6784 namespace detail
6785 {
6799  template<typename BasicJsonType>
6801  {
6802  public:
6803  using number_integer_t = typename BasicJsonType::number_integer_t;
6804  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6805  using number_float_t = typename BasicJsonType::number_float_t;
6806  using string_t = typename BasicJsonType::string_t;
6807  using binary_t = typename BasicJsonType::binary_t;
6808 
6814  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6815  : root(r), allow_exceptions(allow_exceptions_)
6816  {}
6817 
6818  // make class move-only
6820  json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6822  json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6824 
6825  bool null()
6826  {
6827  handle_value(nullptr);
6828  return true;
6829  }
6830 
6831  bool boolean(bool val)
6832  {
6833  handle_value(val);
6834  return true;
6835  }
6836 
6838  {
6839  handle_value(val);
6840  return true;
6841  }
6842 
6844  {
6845  handle_value(val);
6846  return true;
6847  }
6848 
6849  bool number_float(number_float_t val, const string_t& /*unused*/)
6850  {
6851  handle_value(val);
6852  return true;
6853  }
6854 
6855  bool string(string_t& val)
6856  {
6857  handle_value(val);
6858  return true;
6859  }
6860 
6861  bool binary(binary_t& val)
6862  {
6863  handle_value(std::move(val));
6864  return true;
6865  }
6866 
6867  bool start_object(std::size_t len)
6868  {
6869  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6870 
6871  if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6872  {
6873  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6874  }
6875 
6876  return true;
6877  }
6878 
6879  bool key(string_t& val)
6880  {
6881  JSON_ASSERT(!ref_stack.empty());
6882  JSON_ASSERT(ref_stack.back()->is_object());
6883 
6884  // add null at given key and store the reference for later
6885  object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val));
6886  return true;
6887  }
6888 
6889  bool end_object()
6890  {
6891  JSON_ASSERT(!ref_stack.empty());
6892  JSON_ASSERT(ref_stack.back()->is_object());
6893 
6894  ref_stack.back()->set_parents();
6895  ref_stack.pop_back();
6896  return true;
6897  }
6898 
6899  bool start_array(std::size_t len)
6900  {
6901  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6902 
6903  if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6904  {
6905  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6906  }
6907 
6908  return true;
6909  }
6910 
6911  bool end_array()
6912  {
6913  JSON_ASSERT(!ref_stack.empty());
6914  JSON_ASSERT(ref_stack.back()->is_array());
6915 
6916  ref_stack.back()->set_parents();
6917  ref_stack.pop_back();
6918  return true;
6919  }
6920 
6921  template<class Exception>
6922  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6923  const Exception& ex)
6924  {
6925  errored = true;
6926  static_cast<void>(ex);
6927  if (allow_exceptions)
6928  {
6929  JSON_THROW(ex);
6930  }
6931  return false;
6932  }
6933 
6934  constexpr bool is_errored() const
6935  {
6936  return errored;
6937  }
6938 
6939  private:
6946  template<typename Value>
6948  BasicJsonType* handle_value(Value&& v)
6949  {
6950  if (ref_stack.empty())
6951  {
6952  root = BasicJsonType(std::forward<Value>(v));
6953  return &root;
6954  }
6955 
6956  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6957 
6958  if (ref_stack.back()->is_array())
6959  {
6960  ref_stack.back()->m_data.m_value.array->emplace_back(std::forward<Value>(v));
6961  return &(ref_stack.back()->m_data.m_value.array->back());
6962  }
6963 
6964  JSON_ASSERT(ref_stack.back()->is_object());
6965  JSON_ASSERT(object_element);
6966  *object_element = BasicJsonType(std::forward<Value>(v));
6967  return object_element;
6968  }
6969 
6971  BasicJsonType& root;
6973  std::vector<BasicJsonType*> ref_stack{};
6975  BasicJsonType* object_element = nullptr;
6977  bool errored = false;
6979  const bool allow_exceptions = true;
6980  };
6981 
6982  template<typename BasicJsonType>
6984  {
6985  public:
6986  using number_integer_t = typename BasicJsonType::number_integer_t;
6987  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6988  using number_float_t = typename BasicJsonType::number_float_t;
6989  using string_t = typename BasicJsonType::string_t;
6990  using binary_t = typename BasicJsonType::binary_t;
6993 
6995  const parser_callback_t cb,
6996  const bool allow_exceptions_ = true)
6997  : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6998  {
6999  keep_stack.push_back(true);
7000  }
7001 
7002  // make class move-only
7004  json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7006  json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7008 
7009  bool null()
7010  {
7011  handle_value(nullptr);
7012  return true;
7013  }
7014 
7015  bool boolean(bool val)
7016  {
7017  handle_value(val);
7018  return true;
7019  }
7020 
7022  {
7023  handle_value(val);
7024  return true;
7025  }
7026 
7028  {
7029  handle_value(val);
7030  return true;
7031  }
7032 
7033  bool number_float(number_float_t val, const string_t& /*unused*/)
7034  {
7035  handle_value(val);
7036  return true;
7037  }
7038 
7039  bool string(string_t& val)
7040  {
7041  handle_value(val);
7042  return true;
7043  }
7044 
7045  bool binary(binary_t& val)
7046  {
7047  handle_value(std::move(val));
7048  return true;
7049  }
7050 
7051  bool start_object(std::size_t len)
7052  {
7053  // check callback for object start
7054  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
7055  keep_stack.push_back(keep);
7056 
7057  auto val = handle_value(BasicJsonType::value_t::object, true);
7058  ref_stack.push_back(val.second);
7059 
7060  // check object limit
7061  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
7062  {
7063  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
7064  }
7065 
7066  return true;
7067  }
7068 
7069  bool key(string_t& val)
7070  {
7071  BasicJsonType k = BasicJsonType(val);
7072 
7073  // check callback for key
7074  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
7075  key_keep_stack.push_back(keep);
7076 
7077  // add discarded value at given key and store the reference for later
7078  if (keep && ref_stack.back())
7079  {
7080  object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded);
7081  }
7082 
7083  return true;
7084  }
7085 
7086  bool end_object()
7087  {
7088  if (ref_stack.back())
7089  {
7090  if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
7091  {
7092  // discard object
7093  *ref_stack.back() = discarded;
7094  }
7095  else
7096  {
7097  ref_stack.back()->set_parents();
7098  }
7099  }
7100 
7101  JSON_ASSERT(!ref_stack.empty());
7102  JSON_ASSERT(!keep_stack.empty());
7103  ref_stack.pop_back();
7104  keep_stack.pop_back();
7105 
7106  if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
7107  {
7108  // remove discarded value
7109  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
7110  {
7111  if (it->is_discarded())
7112  {
7113  ref_stack.back()->erase(it);
7114  break;
7115  }
7116  }
7117  }
7118 
7119  return true;
7120  }
7121 
7122  bool start_array(std::size_t len)
7123  {
7124  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
7125  keep_stack.push_back(keep);
7126 
7127  auto val = handle_value(BasicJsonType::value_t::array, true);
7128  ref_stack.push_back(val.second);
7129 
7130  // check array limit
7131  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
7132  {
7133  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
7134  }
7135 
7136  return true;
7137  }
7138 
7139  bool end_array()
7140  {
7141  bool keep = true;
7142 
7143  if (ref_stack.back())
7144  {
7145  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
7146  if (keep)
7147  {
7148  ref_stack.back()->set_parents();
7149  }
7150  else
7151  {
7152  // discard array
7153  *ref_stack.back() = discarded;
7154  }
7155  }
7156 
7157  JSON_ASSERT(!ref_stack.empty());
7158  JSON_ASSERT(!keep_stack.empty());
7159  ref_stack.pop_back();
7160  keep_stack.pop_back();
7161 
7162  // remove discarded value
7163  if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
7164  {
7165  ref_stack.back()->m_data.m_value.array->pop_back();
7166  }
7167 
7168  return true;
7169  }
7170 
7171  template<class Exception>
7172  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
7173  const Exception& ex)
7174  {
7175  errored = true;
7176  static_cast<void>(ex);
7177  if (allow_exceptions)
7178  {
7179  JSON_THROW(ex);
7180  }
7181  return false;
7182  }
7183 
7184  constexpr bool is_errored() const
7185  {
7186  return errored;
7187  }
7188 
7189  private:
7205  template<typename Value>
7206  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
7207  {
7208  JSON_ASSERT(!keep_stack.empty());
7209 
7210  // do not handle this value if we know it would be added to a discarded
7211  // container
7212  if (!keep_stack.back())
7213  {
7214  return { false, nullptr };
7215  }
7216 
7217  // create value
7218  auto value = BasicJsonType(std::forward<Value>(v));
7219 
7220  // check callback
7221  const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
7222 
7223  // do not handle this value if we just learnt it shall be discarded
7224  if (!keep)
7225  {
7226  return { false, nullptr };
7227  }
7228 
7229  if (ref_stack.empty())
7230  {
7231  root = std::move(value);
7232  return { true, &root };
7233  }
7234 
7235  // skip this value if we already decided to skip the parent
7236  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
7237  if (!ref_stack.back())
7238  {
7239  return { false, nullptr };
7240  }
7241 
7242  // we now only expect arrays and objects
7243  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
7244 
7245  // array
7246  if (ref_stack.back()->is_array())
7247  {
7248  ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));
7249  return { true, &(ref_stack.back()->m_data.m_value.array->back()) };
7250  }
7251 
7252  // object
7253  JSON_ASSERT(ref_stack.back()->is_object());
7254  // check if we should store an element for the current key
7255  JSON_ASSERT(!key_keep_stack.empty());
7256  const bool store_element = key_keep_stack.back();
7257  key_keep_stack.pop_back();
7258 
7259  if (!store_element)
7260  {
7261  return { false, nullptr };
7262  }
7263 
7264  JSON_ASSERT(object_element);
7265  *object_element = std::move(value);
7266  return { true, object_element };
7267  }
7268 
7270  BasicJsonType& root;
7272  std::vector<BasicJsonType*> ref_stack{};
7274  std::vector<bool> keep_stack{};
7276  std::vector<bool> key_keep_stack{};
7278  BasicJsonType* object_element = nullptr;
7280  bool errored = false;
7282  const parser_callback_t callback = nullptr;
7284  const bool allow_exceptions = true;
7286  BasicJsonType discarded = BasicJsonType::value_t::discarded;
7287  };
7288 
7289  template<typename BasicJsonType>
7291  {
7292  public:
7293  using number_integer_t = typename BasicJsonType::number_integer_t;
7294  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7295  using number_float_t = typename BasicJsonType::number_float_t;
7296  using string_t = typename BasicJsonType::string_t;
7297  using binary_t = typename BasicJsonType::binary_t;
7298 
7299  bool null()
7300  {
7301  return true;
7302  }
7303 
7304  bool boolean(bool /*unused*/)
7305  {
7306  return true;
7307  }
7308 
7310  {
7311  return true;
7312  }
7313 
7315  {
7316  return true;
7317  }
7318 
7319  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
7320  {
7321  return true;
7322  }
7323 
7324  bool string(string_t& /*unused*/)
7325  {
7326  return true;
7327  }
7328 
7329  bool binary(binary_t& /*unused*/)
7330  {
7331  return true;
7332  }
7333 
7334  bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7335  {
7336  return true;
7337  }
7338 
7339  bool key(string_t& /*unused*/)
7340  {
7341  return true;
7342  }
7343 
7344  bool end_object()
7345  {
7346  return true;
7347  }
7348 
7349  bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7350  {
7351  return true;
7352  }
7353 
7354  bool end_array()
7355  {
7356  return true;
7357  }
7358 
7359  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
7360  {
7361  return false;
7362  }
7363  };
7364 
7365 } // namespace detail
7367 
7368 // #include <nlohmann/detail/input/lexer.hpp>
7369 // __ _____ _____ _____
7370 // __| | __| | | | JSON for Modern C++
7371 // | | |__ | | | | | | version 3.11.3
7372 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
7373 //
7374 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
7375 // SPDX-License-Identifier: MIT
7376 
7377 
7378 
7379 #include <array> // array
7380 #include <clocale> // localeconv
7381 #include <cstddef> // size_t
7382 #include <cstdio> // snprintf
7383 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7384 #include <initializer_list> // initializer_list
7385 #include <string> // char_traits, string
7386 #include <utility> // move
7387 #include <vector> // vector
7388 
7389 // #include <nlohmann/detail/input/input_adapters.hpp>
7390 
7391 // #include <nlohmann/detail/input/position_t.hpp>
7392 
7393 // #include <nlohmann/detail/macro_scope.hpp>
7394 
7395 // #include <nlohmann/detail/meta/type_traits.hpp>
7396 
7397 
7399 namespace detail
7400 {
7401 
7403  // lexer //
7405 
7406  template<typename BasicJsonType>
7408  {
7409  public:
7411  enum class token_type
7412  {
7413  uninitialized,
7414  literal_true,
7415  literal_false,
7416  literal_null,
7417  value_string,
7418  value_unsigned,
7419  value_integer,
7420  value_float,
7421  begin_array,
7422  begin_object,
7423  end_array,
7424  end_object,
7425  name_separator,
7426  value_separator,
7427  parse_error,
7428  end_of_input,
7429  literal_or_value
7430  };
7431 
7435  static const char* token_type_name(const token_type t) noexcept
7436  {
7437  switch (t)
7438  {
7439  case token_type::uninitialized:
7440  return "<uninitialized>";
7441  case token_type::literal_true:
7442  return "true literal";
7443  case token_type::literal_false:
7444  return "false literal";
7445  case token_type::literal_null:
7446  return "null literal";
7447  case token_type::value_string:
7448  return "string literal";
7449  case token_type::value_unsigned:
7450  case token_type::value_integer:
7451  case token_type::value_float:
7452  return "number literal";
7453  case token_type::begin_array:
7454  return "'['";
7455  case token_type::begin_object:
7456  return "'{'";
7457  case token_type::end_array:
7458  return "']'";
7459  case token_type::end_object:
7460  return "'}'";
7461  case token_type::name_separator:
7462  return "':'";
7463  case token_type::value_separator:
7464  return "','";
7465  case token_type::parse_error:
7466  return "<parse error>";
7467  case token_type::end_of_input:
7468  return "end of input";
7469  case token_type::literal_or_value:
7470  return "'[', '{', or a literal";
7471  // LCOV_EXCL_START
7472  default: // catch non-enum values
7473  return "unknown token";
7474  // LCOV_EXCL_STOP
7475  }
7476  }
7477  };
7483  template<typename BasicJsonType, typename InputAdapterType>
7484  class lexer : public lexer_base<BasicJsonType>
7485  {
7486  using number_integer_t = typename BasicJsonType::number_integer_t;
7487  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7488  using number_float_t = typename BasicJsonType::number_float_t;
7489  using string_t = typename BasicJsonType::string_t;
7490  using char_type = typename InputAdapterType::char_type;
7491  using char_int_type = typename char_traits<char_type>::int_type;
7492 
7493  public:
7495 
7496  explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
7497  : ia(std::move(adapter))
7498  , ignore_comments(ignore_comments_)
7499  , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
7500  {}
7501 
7502  // delete because of pointer members
7503  lexer(const lexer&) = delete;
7504  lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7505  lexer& operator=(lexer&) = delete;
7506  lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7507  ~lexer() = default;
7508 
7509  private:
7511  // locales
7513 
7516  static char get_decimal_point() noexcept
7517  {
7518  const auto* loc = localeconv();
7519  JSON_ASSERT(loc != nullptr);
7520  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7521  }
7522 
7524  // scan functions
7526 
7542  int get_codepoint()
7543  {
7544  // this function only makes sense after reading `\u`
7545  JSON_ASSERT(current == 'u');
7546  int codepoint = 0;
7547 
7548  const auto factors = { 12u, 8u, 4u, 0u };
7549  for (const auto factor : factors)
7550  {
7551  get();
7552 
7553  if (current >= '0' && current <= '9')
7554  {
7555  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7556  }
7557  else if (current >= 'A' && current <= 'F')
7558  {
7559  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7560  }
7561  else if (current >= 'a' && current <= 'f')
7562  {
7563  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7564  }
7565  else
7566  {
7567  return -1;
7568  }
7569  }
7570 
7571  JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7572  return codepoint;
7573  }
7574 
7590  bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7591  {
7592  JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7593  add(current);
7594 
7595  for (auto range = ranges.begin(); range != ranges.end(); ++range)
7596  {
7597  get();
7598  if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) // NOLINT(bugprone-inc-dec-in-conditions)
7599  {
7600  add(current);
7601  }
7602  else
7603  {
7604  error_message = "invalid string: ill-formed UTF-8 byte";
7605  return false;
7606  }
7607  }
7608 
7609  return true;
7610  }
7611 
7627  token_type scan_string()
7628  {
7629  // reset token_buffer (ignore opening quote)
7630  reset();
7631 
7632  // we entered the function by reading an open quote
7633  JSON_ASSERT(current == '\"');
7634 
7635  while (true)
7636  {
7637  // get next character
7638  switch (get())
7639  {
7640  // end of file while parsing string
7641  case char_traits<char_type>::eof():
7642  {
7643  error_message = "invalid string: missing closing quote";
7644  return token_type::parse_error;
7645  }
7646 
7647  // closing quote
7648  case '\"':
7649  {
7650  return token_type::value_string;
7651  }
7652 
7653  // escapes
7654  case '\\':
7655  {
7656  switch (get())
7657  {
7658  // quotation mark
7659  case '\"':
7660  add('\"');
7661  break;
7662  // reverse solidus
7663  case '\\':
7664  add('\\');
7665  break;
7666  // solidus
7667  case '/':
7668  add('/');
7669  break;
7670  // backspace
7671  case 'b':
7672  add('\b');
7673  break;
7674  // form feed
7675  case 'f':
7676  add('\f');
7677  break;
7678  // line feed
7679  case 'n':
7680  add('\n');
7681  break;
7682  // carriage return
7683  case 'r':
7684  add('\r');
7685  break;
7686  // tab
7687  case 't':
7688  add('\t');
7689  break;
7690 
7691  // unicode escapes
7692  case 'u':
7693  {
7694  const int codepoint1 = get_codepoint();
7695  int codepoint = codepoint1; // start with codepoint1
7696 
7697  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7698  {
7699  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7700  return token_type::parse_error;
7701  }
7702 
7703  // check if code point is a high surrogate
7704  if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7705  {
7706  // expect next \uxxxx entry
7707  if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7708  {
7709  const int codepoint2 = get_codepoint();
7710 
7711  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7712  {
7713  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7714  return token_type::parse_error;
7715  }
7716 
7717  // check if codepoint2 is a low surrogate
7718  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7719  {
7720  // overwrite codepoint
7721  codepoint = static_cast<int>(
7722  // high surrogate occupies the most significant 22 bits
7723  (static_cast<unsigned int>(codepoint1) << 10u)
7724  // low surrogate occupies the least significant 15 bits
7725  + static_cast<unsigned int>(codepoint2)
7726  // there is still the 0xD800, 0xDC00 and 0x10000 noise
7727  // in the result, so we have to subtract with:
7728  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7729  -0x35FDC00u);
7730  }
7731  else
7732  {
7733  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7734  return token_type::parse_error;
7735  }
7736  }
7737  else
7738  {
7739  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7740  return token_type::parse_error;
7741  }
7742  }
7743  else
7744  {
7745  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7746  {
7747  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7748  return token_type::parse_error;
7749  }
7750  }
7751 
7752  // result of the above calculation yields a proper codepoint
7753  JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7754 
7755  // translate codepoint into bytes
7756  if (codepoint < 0x80)
7757  {
7758  // 1-byte characters: 0xxxxxxx (ASCII)
7759  add(static_cast<char_int_type>(codepoint));
7760  }
7761  else if (codepoint <= 0x7FF)
7762  {
7763  // 2-byte characters: 110xxxxx 10xxxxxx
7764  add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7765  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7766  }
7767  else if (codepoint <= 0xFFFF)
7768  {
7769  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7770  add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7771  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7772  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7773  }
7774  else
7775  {
7776  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7777  add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7778  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7779  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7780  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7781  }
7782 
7783  break;
7784  }
7785 
7786  // other characters after escape
7787  default:
7788  error_message = "invalid string: forbidden character after backslash";
7789  return token_type::parse_error;
7790  }
7791 
7792  break;
7793  }
7794 
7795  // invalid control characters
7796  case 0x00:
7797  {
7798  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7799  return token_type::parse_error;
7800  }
7801 
7802  case 0x01:
7803  {
7804  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7805  return token_type::parse_error;
7806  }
7807 
7808  case 0x02:
7809  {
7810  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7811  return token_type::parse_error;
7812  }
7813 
7814  case 0x03:
7815  {
7816  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7817  return token_type::parse_error;
7818  }
7819 
7820  case 0x04:
7821  {
7822  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7823  return token_type::parse_error;
7824  }
7825 
7826  case 0x05:
7827  {
7828  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7829  return token_type::parse_error;
7830  }
7831 
7832  case 0x06:
7833  {
7834  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7835  return token_type::parse_error;
7836  }
7837 
7838  case 0x07:
7839  {
7840  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7841  return token_type::parse_error;
7842  }
7843 
7844  case 0x08:
7845  {
7846  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7847  return token_type::parse_error;
7848  }
7849 
7850  case 0x09:
7851  {
7852  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7853  return token_type::parse_error;
7854  }
7855 
7856  case 0x0A:
7857  {
7858  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7859  return token_type::parse_error;
7860  }
7861 
7862  case 0x0B:
7863  {
7864  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7865  return token_type::parse_error;
7866  }
7867 
7868  case 0x0C:
7869  {
7870  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7871  return token_type::parse_error;
7872  }
7873 
7874  case 0x0D:
7875  {
7876  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7877  return token_type::parse_error;
7878  }
7879 
7880  case 0x0E:
7881  {
7882  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7883  return token_type::parse_error;
7884  }
7885 
7886  case 0x0F:
7887  {
7888  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7889  return token_type::parse_error;
7890  }
7891 
7892  case 0x10:
7893  {
7894  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7895  return token_type::parse_error;
7896  }
7897 
7898  case 0x11:
7899  {
7900  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7901  return token_type::parse_error;
7902  }
7903 
7904  case 0x12:
7905  {
7906  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7907  return token_type::parse_error;
7908  }
7909 
7910  case 0x13:
7911  {
7912  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7913  return token_type::parse_error;
7914  }
7915 
7916  case 0x14:
7917  {
7918  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7919  return token_type::parse_error;
7920  }
7921 
7922  case 0x15:
7923  {
7924  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7925  return token_type::parse_error;
7926  }
7927 
7928  case 0x16:
7929  {
7930  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7931  return token_type::parse_error;
7932  }
7933 
7934  case 0x17:
7935  {
7936  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7937  return token_type::parse_error;
7938  }
7939 
7940  case 0x18:
7941  {
7942  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7943  return token_type::parse_error;
7944  }
7945 
7946  case 0x19:
7947  {
7948  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7949  return token_type::parse_error;
7950  }
7951 
7952  case 0x1A:
7953  {
7954  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7955  return token_type::parse_error;
7956  }
7957 
7958  case 0x1B:
7959  {
7960  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7961  return token_type::parse_error;
7962  }
7963 
7964  case 0x1C:
7965  {
7966  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7967  return token_type::parse_error;
7968  }
7969 
7970  case 0x1D:
7971  {
7972  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7973  return token_type::parse_error;
7974  }
7975 
7976  case 0x1E:
7977  {
7978  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7979  return token_type::parse_error;
7980  }
7981 
7982  case 0x1F:
7983  {
7984  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7985  return token_type::parse_error;
7986  }
7987 
7988  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7989  case 0x20:
7990  case 0x21:
7991  case 0x23:
7992  case 0x24:
7993  case 0x25:
7994  case 0x26:
7995  case 0x27:
7996  case 0x28:
7997  case 0x29:
7998  case 0x2A:
7999  case 0x2B:
8000  case 0x2C:
8001  case 0x2D:
8002  case 0x2E:
8003  case 0x2F:
8004  case 0x30:
8005  case 0x31:
8006  case 0x32:
8007  case 0x33:
8008  case 0x34:
8009  case 0x35:
8010  case 0x36:
8011  case 0x37:
8012  case 0x38:
8013  case 0x39:
8014  case 0x3A:
8015  case 0x3B:
8016  case 0x3C:
8017  case 0x3D:
8018  case 0x3E:
8019  case 0x3F:
8020  case 0x40:
8021  case 0x41:
8022  case 0x42:
8023  case 0x43:
8024  case 0x44:
8025  case 0x45:
8026  case 0x46:
8027  case 0x47:
8028  case 0x48:
8029  case 0x49:
8030  case 0x4A:
8031  case 0x4B:
8032  case 0x4C:
8033  case 0x4D:
8034  case 0x4E:
8035  case 0x4F:
8036  case 0x50:
8037  case 0x51:
8038  case 0x52:
8039  case 0x53:
8040  case 0x54:
8041  case 0x55:
8042  case 0x56:
8043  case 0x57:
8044  case 0x58:
8045  case 0x59:
8046  case 0x5A:
8047  case 0x5B:
8048  case 0x5D:
8049  case 0x5E:
8050  case 0x5F:
8051  case 0x60:
8052  case 0x61:
8053  case 0x62:
8054  case 0x63:
8055  case 0x64:
8056  case 0x65:
8057  case 0x66:
8058  case 0x67:
8059  case 0x68:
8060  case 0x69:
8061  case 0x6A:
8062  case 0x6B:
8063  case 0x6C:
8064  case 0x6D:
8065  case 0x6E:
8066  case 0x6F:
8067  case 0x70:
8068  case 0x71:
8069  case 0x72:
8070  case 0x73:
8071  case 0x74:
8072  case 0x75:
8073  case 0x76:
8074  case 0x77:
8075  case 0x78:
8076  case 0x79:
8077  case 0x7A:
8078  case 0x7B:
8079  case 0x7C:
8080  case 0x7D:
8081  case 0x7E:
8082  case 0x7F:
8083  {
8084  add(current);
8085  break;
8086  }
8087 
8088  // U+0080..U+07FF: bytes C2..DF 80..BF
8089  case 0xC2:
8090  case 0xC3:
8091  case 0xC4:
8092  case 0xC5:
8093  case 0xC6:
8094  case 0xC7:
8095  case 0xC8:
8096  case 0xC9:
8097  case 0xCA:
8098  case 0xCB:
8099  case 0xCC:
8100  case 0xCD:
8101  case 0xCE:
8102  case 0xCF:
8103  case 0xD0:
8104  case 0xD1:
8105  case 0xD2:
8106  case 0xD3:
8107  case 0xD4:
8108  case 0xD5:
8109  case 0xD6:
8110  case 0xD7:
8111  case 0xD8:
8112  case 0xD9:
8113  case 0xDA:
8114  case 0xDB:
8115  case 0xDC:
8116  case 0xDD:
8117  case 0xDE:
8118  case 0xDF:
8119  {
8120  if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({ 0x80, 0xBF })))
8121  {
8122  return token_type::parse_error;
8123  }
8124  break;
8125  }
8126 
8127  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
8128  case 0xE0:
8129  {
8130  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0xA0, 0xBF, 0x80, 0xBF }))))
8131  {
8132  return token_type::parse_error;
8133  }
8134  break;
8135  }
8136 
8137  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
8138  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
8139  case 0xE1:
8140  case 0xE2:
8141  case 0xE3:
8142  case 0xE4:
8143  case 0xE5:
8144  case 0xE6:
8145  case 0xE7:
8146  case 0xE8:
8147  case 0xE9:
8148  case 0xEA:
8149  case 0xEB:
8150  case 0xEC:
8151  case 0xEE:
8152  case 0xEF:
8153  {
8154  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF }))))
8155  {
8156  return token_type::parse_error;
8157  }
8158  break;
8159  }
8160 
8161  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
8162  case 0xED:
8163  {
8164  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0x9F, 0x80, 0xBF }))))
8165  {
8166  return token_type::parse_error;
8167  }
8168  break;
8169  }
8170 
8171  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
8172  case 0xF0:
8173  {
8174  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF }))))
8175  {
8176  return token_type::parse_error;
8177  }
8178  break;
8179  }
8180 
8181  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
8182  case 0xF1:
8183  case 0xF2:
8184  case 0xF3:
8185  {
8186  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF }))))
8187  {
8188  return token_type::parse_error;
8189  }
8190  break;
8191  }
8192 
8193  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
8194  case 0xF4:
8195  {
8196  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF }))))
8197  {
8198  return token_type::parse_error;
8199  }
8200  break;
8201  }
8202 
8203  // remaining bytes (80..C1 and F5..FF) are ill-formed
8204  default:
8205  {
8206  error_message = "invalid string: ill-formed UTF-8 byte";
8207  return token_type::parse_error;
8208  }
8209  }
8210  }
8211  }
8212 
8217  bool scan_comment()
8218  {
8219  switch (get())
8220  {
8221  // single-line comments skip input until a newline or EOF is read
8222  case '/':
8223  {
8224  while (true)
8225  {
8226  switch (get())
8227  {
8228  case '\n':
8229  case '\r':
8230  case char_traits<char_type>::eof():
8231  case '\0':
8232  return true;
8233 
8234  default:
8235  break;
8236  }
8237  }
8238  }
8239 
8240  // multi-line comments skip input until */ is read
8241  case '*':
8242  {
8243  while (true)
8244  {
8245  switch (get())
8246  {
8247  case char_traits<char_type>::eof():
8248  case '\0':
8249  {
8250  error_message = "invalid comment; missing closing '*/'";
8251  return false;
8252  }
8253 
8254  case '*':
8255  {
8256  switch (get())
8257  {
8258  case '/':
8259  return true;
8260 
8261  default:
8262  {
8263  unget();
8264  continue;
8265  }
8266  }
8267  }
8268 
8269  default:
8270  continue;
8271  }
8272  }
8273  }
8274 
8275  // unexpected character after reading '/'
8276  default:
8277  {
8278  error_message = "invalid comment; expecting '/' or '*' after '/'";
8279  return false;
8280  }
8281  }
8282  }
8283 
8285  static void strtof(float& f, const char* str, char** endptr) noexcept
8286  {
8287  f = std::strtof(str, endptr);
8288  }
8289 
8291  static void strtof(double& f, const char* str, char** endptr) noexcept
8292  {
8293  f = std::strtod(str, endptr);
8294  }
8295 
8297  static void strtof(long double& f, const char* str, char** endptr) noexcept
8298  {
8299  f = std::strtold(str, endptr);
8300  }
8301 
8342  token_type scan_number() // lgtm [cpp/use-of-goto]
8343  {
8344  // reset token_buffer to store the number's bytes
8345  reset();
8346 
8347  // the type of the parsed number; initially set to unsigned; will be
8348  // changed if minus sign, decimal point or exponent is read
8349  token_type number_type = token_type::value_unsigned;
8350 
8351  // state (init): we just found out we need to scan a number
8352  switch (current)
8353  {
8354  case '-':
8355  {
8356  add(current);
8357  goto scan_number_minus;
8358  }
8359 
8360  case '0':
8361  {
8362  add(current);
8363  goto scan_number_zero;
8364  }
8365 
8366  case '1':
8367  case '2':
8368  case '3':
8369  case '4':
8370  case '5':
8371  case '6':
8372  case '7':
8373  case '8':
8374  case '9':
8375  {
8376  add(current);
8377  goto scan_number_any1;
8378  }
8379 
8380  // all other characters are rejected outside scan_number()
8381  default: // LCOV_EXCL_LINE
8382  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8383  }
8384 
8385  scan_number_minus:
8386  // state: we just parsed a leading minus sign
8387  number_type = token_type::value_integer;
8388  switch (get())
8389  {
8390  case '0':
8391  {
8392  add(current);
8393  goto scan_number_zero;
8394  }
8395 
8396  case '1':
8397  case '2':
8398  case '3':
8399  case '4':
8400  case '5':
8401  case '6':
8402  case '7':
8403  case '8':
8404  case '9':
8405  {
8406  add(current);
8407  goto scan_number_any1;
8408  }
8409 
8410  default:
8411  {
8412  error_message = "invalid number; expected digit after '-'";
8413  return token_type::parse_error;
8414  }
8415  }
8416 
8417  scan_number_zero:
8418  // state: we just parse a zero (maybe with a leading minus sign)
8419  switch (get())
8420  {
8421  case '.':
8422  {
8423  add(decimal_point_char);
8424  goto scan_number_decimal1;
8425  }
8426 
8427  case 'e':
8428  case 'E':
8429  {
8430  add(current);
8431  goto scan_number_exponent;
8432  }
8433 
8434  default:
8435  goto scan_number_done;
8436  }
8437 
8438  scan_number_any1:
8439  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8440  switch (get())
8441  {
8442  case '0':
8443  case '1':
8444  case '2':
8445  case '3':
8446  case '4':
8447  case '5':
8448  case '6':
8449  case '7':
8450  case '8':
8451  case '9':
8452  {
8453  add(current);
8454  goto scan_number_any1;
8455  }
8456 
8457  case '.':
8458  {
8459  add(decimal_point_char);
8460  goto scan_number_decimal1;
8461  }
8462 
8463  case 'e':
8464  case 'E':
8465  {
8466  add(current);
8467  goto scan_number_exponent;
8468  }
8469 
8470  default:
8471  goto scan_number_done;
8472  }
8473 
8474  scan_number_decimal1:
8475  // state: we just parsed a decimal point
8476  number_type = token_type::value_float;
8477  switch (get())
8478  {
8479  case '0':
8480  case '1':
8481  case '2':
8482  case '3':
8483  case '4':
8484  case '5':
8485  case '6':
8486  case '7':
8487  case '8':
8488  case '9':
8489  {
8490  add(current);
8491  goto scan_number_decimal2;
8492  }
8493 
8494  default:
8495  {
8496  error_message = "invalid number; expected digit after '.'";
8497  return token_type::parse_error;
8498  }
8499  }
8500 
8501  scan_number_decimal2:
8502  // we just parsed at least one number after a decimal point
8503  switch (get())
8504  {
8505  case '0':
8506  case '1':
8507  case '2':
8508  case '3':
8509  case '4':
8510  case '5':
8511  case '6':
8512  case '7':
8513  case '8':
8514  case '9':
8515  {
8516  add(current);
8517  goto scan_number_decimal2;
8518  }
8519 
8520  case 'e':
8521  case 'E':
8522  {
8523  add(current);
8524  goto scan_number_exponent;
8525  }
8526 
8527  default:
8528  goto scan_number_done;
8529  }
8530 
8531  scan_number_exponent:
8532  // we just parsed an exponent
8533  number_type = token_type::value_float;
8534  switch (get())
8535  {
8536  case '+':
8537  case '-':
8538  {
8539  add(current);
8540  goto scan_number_sign;
8541  }
8542 
8543  case '0':
8544  case '1':
8545  case '2':
8546  case '3':
8547  case '4':
8548  case '5':
8549  case '6':
8550  case '7':
8551  case '8':
8552  case '9':
8553  {
8554  add(current);
8555  goto scan_number_any2;
8556  }
8557 
8558  default:
8559  {
8560  error_message =
8561  "invalid number; expected '+', '-', or digit after exponent";
8562  return token_type::parse_error;
8563  }
8564  }
8565 
8566  scan_number_sign:
8567  // we just parsed an exponent sign
8568  switch (get())
8569  {
8570  case '0':
8571  case '1':
8572  case '2':
8573  case '3':
8574  case '4':
8575  case '5':
8576  case '6':
8577  case '7':
8578  case '8':
8579  case '9':
8580  {
8581  add(current);
8582  goto scan_number_any2;
8583  }
8584 
8585  default:
8586  {
8587  error_message = "invalid number; expected digit after exponent sign";
8588  return token_type::parse_error;
8589  }
8590  }
8591 
8592  scan_number_any2:
8593  // we just parsed a number after the exponent or exponent sign
8594  switch (get())
8595  {
8596  case '0':
8597  case '1':
8598  case '2':
8599  case '3':
8600  case '4':
8601  case '5':
8602  case '6':
8603  case '7':
8604  case '8':
8605  case '9':
8606  {
8607  add(current);
8608  goto scan_number_any2;
8609  }
8610 
8611  default:
8612  goto scan_number_done;
8613  }
8614 
8615  scan_number_done:
8616  // unget the character after the number (we only read it to know that
8617  // we are done scanning a number)
8618  unget();
8619 
8620  char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8621  errno = 0;
8622 
8623  // try to parse integers first and fall back to floats
8624  if (number_type == token_type::value_unsigned)
8625  {
8626  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8627 
8628  // we checked the number format before
8629  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8630 
8631  if (errno == 0)
8632  {
8633  value_unsigned = static_cast<number_unsigned_t>(x);
8634  if (value_unsigned == x)
8635  {
8636  return token_type::value_unsigned;
8637  }
8638  }
8639  }
8640  else if (number_type == token_type::value_integer)
8641  {
8642  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8643 
8644  // we checked the number format before
8645  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8646 
8647  if (errno == 0)
8648  {
8649  value_integer = static_cast<number_integer_t>(x);
8650  if (value_integer == x)
8651  {
8652  return token_type::value_integer;
8653  }
8654  }
8655  }
8656 
8657  // this code is reached if we parse a floating-point number or if an
8658  // integer conversion above failed
8659  strtof(value_float, token_buffer.data(), &endptr);
8660 
8661  // we checked the number format before
8662  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8663 
8664  return token_type::value_float;
8665  }
8666 
8673  token_type scan_literal(const char_type* literal_text, const std::size_t length,
8674  token_type return_type)
8675  {
8676  JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);
8677  for (std::size_t i = 1; i < length; ++i)
8678  {
8679  if (JSON_HEDLEY_UNLIKELY(char_traits<char_type>::to_char_type(get()) != literal_text[i]))
8680  {
8681  error_message = "invalid literal";
8682  return token_type::parse_error;
8683  }
8684  }
8685  return return_type;
8686  }
8687 
8689  // input management
8691 
8693  void reset() noexcept
8694  {
8695  token_buffer.clear();
8696  token_string.clear();
8697  token_string.push_back(char_traits<char_type>::to_char_type(current));
8698  }
8699 
8700  /*
8701  @brief get next character from the input
8702 
8703  This function provides the interface to the used input adapter. It does
8704  not throw in case the input reached EOF, but returns a
8705  `char_traits<char>::eof()` in that case. Stores the scanned characters
8706  for use in error messages.
8707 
8708  @return character read from the input
8709  */
8710  char_int_type get()
8711  {
8712  ++position.chars_read_total;
8713  ++position.chars_read_current_line;
8714 
8715  if (next_unget)
8716  {
8717  // just reset the next_unget variable and work with current
8718  next_unget = false;
8719  }
8720  else
8721  {
8722  current = ia.get_character();
8723  }
8724 
8725  if (JSON_HEDLEY_LIKELY(current != char_traits<char_type>::eof()))
8726  {
8727  token_string.push_back(char_traits<char_type>::to_char_type(current));
8728  }
8729 
8730  if (current == '\n')
8731  {
8732  ++position.lines_read;
8733  position.chars_read_current_line = 0;
8734  }
8735 
8736  return current;
8737  }
8738 
8747  void unget()
8748  {
8749  next_unget = true;
8750 
8751  --position.chars_read_total;
8752 
8753  // in case we "unget" a newline, we have to also decrement the lines_read
8754  if (position.chars_read_current_line == 0)
8755  {
8756  if (position.lines_read > 0)
8757  {
8758  --position.lines_read;
8759  }
8760  }
8761  else
8762  {
8763  --position.chars_read_current_line;
8764  }
8765 
8766  if (JSON_HEDLEY_LIKELY(current != char_traits<char_type>::eof()))
8767  {
8768  JSON_ASSERT(!token_string.empty());
8769  token_string.pop_back();
8770  }
8771  }
8772 
8774  void add(char_int_type c)
8775  {
8776  token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8777  }
8778 
8779  public:
8781  // value getters
8783 
8785  constexpr number_integer_t get_number_integer() const noexcept
8786  {
8787  return value_integer;
8788  }
8789 
8791  constexpr number_unsigned_t get_number_unsigned() const noexcept
8792  {
8793  return value_unsigned;
8794  }
8795 
8797  constexpr number_float_t get_number_float() const noexcept
8798  {
8799  return value_float;
8800  }
8801 
8803  string_t& get_string()
8804  {
8805  return token_buffer;
8806  }
8807 
8809  // diagnostics
8811 
8813  constexpr position_t get_position() const noexcept
8814  {
8815  return position;
8816  }
8817 
8821  std::string get_token_string() const
8822  {
8823  // escape control characters
8824  std::string result;
8825  for (const auto c : token_string)
8826  {
8827  if (static_cast<unsigned char>(c) <= '\x1F')
8828  {
8829  // escape control characters
8830  std::array<char, 9> cs{ {} };
8831  static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8832  result += cs.data();
8833  }
8834  else
8835  {
8836  // add character as is
8837  result.push_back(static_cast<std::string::value_type>(c));
8838  }
8839  }
8840 
8841  return result;
8842  }
8843 
8846  constexpr const char* get_error_message() const noexcept
8847  {
8848  return error_message;
8849  }
8850 
8852  // actual scanner
8854 
8859  bool skip_bom()
8860  {
8861  if (get() == 0xEF)
8862  {
8863  // check if we completely parse the BOM
8864  return get() == 0xBB && get() == 0xBF;
8865  }
8866 
8867  // the first character is not the beginning of the BOM; unget it to
8868  // process is later
8869  unget();
8870  return true;
8871  }
8872 
8874  {
8875  do
8876  {
8877  get();
8878  } while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8879  }
8880 
8882  {
8883  // initially, skip the BOM
8884  if (position.chars_read_total == 0 && !skip_bom())
8885  {
8886  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8887  return token_type::parse_error;
8888  }
8889 
8890  // read next character and ignore whitespace
8891  skip_whitespace();
8892 
8893  // ignore comments
8894  while (ignore_comments && current == '/')
8895  {
8896  if (!scan_comment())
8897  {
8898  return token_type::parse_error;
8899  }
8900 
8901  // skip following whitespace
8902  skip_whitespace();
8903  }
8904 
8905  switch (current)
8906  {
8907  // structural characters
8908  case '[':
8909  return token_type::begin_array;
8910  case ']':
8911  return token_type::end_array;
8912  case '{':
8913  return token_type::begin_object;
8914  case '}':
8915  return token_type::end_object;
8916  case ':':
8917  return token_type::name_separator;
8918  case ',':
8919  return token_type::value_separator;
8920 
8921  // literals
8922  case 't':
8923  {
8924  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')} };
8925  return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8926  }
8927  case 'f':
8928  {
8929  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')} };
8930  return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8931  }
8932  case 'n':
8933  {
8934  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')} };
8935  return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8936  }
8937 
8938  // string
8939  case '\"':
8940  return scan_string();
8941 
8942  // number
8943  case '-':
8944  case '0':
8945  case '1':
8946  case '2':
8947  case '3':
8948  case '4':
8949  case '5':
8950  case '6':
8951  case '7':
8952  case '8':
8953  case '9':
8954  return scan_number();
8955 
8956  // end of input (the null byte is needed when parsing from
8957  // string literals)
8958  case '\0':
8960  return token_type::end_of_input;
8961 
8962  // error
8963  default:
8964  error_message = "invalid literal";
8965  return token_type::parse_error;
8966  }
8967  }
8968 
8969  private:
8971  InputAdapterType ia;
8972 
8974  const bool ignore_comments = false;
8975 
8977  char_int_type current = char_traits<char_type>::eof();
8978 
8980  bool next_unget = false;
8981 
8983  position_t position{};
8984 
8986  std::vector<char_type> token_string{};
8987 
8989  string_t token_buffer{};
8990 
8992  const char* error_message = "";
8993 
8994  // number values
8995  number_integer_t value_integer = 0;
8996  number_unsigned_t value_unsigned = 0;
8997  number_float_t value_float = 0;
8998 
9000  const char_int_type decimal_point_char = '.';
9001  };
9002 
9003 } // namespace detail
9005 
9006 // #include <nlohmann/detail/macro_scope.hpp>
9007 
9008 // #include <nlohmann/detail/meta/is_sax.hpp>
9009 // __ _____ _____ _____
9010 // __| | __| | | | JSON for Modern C++
9011 // | | |__ | | | | | | version 3.11.3
9012 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
9013 //
9014 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
9015 // SPDX-License-Identifier: MIT
9016 
9017 
9018 
9019 #include <cstdint> // size_t
9020 #include <utility> // declval
9021 #include <string> // string
9022 
9023 // #include <nlohmann/detail/abi_macros.hpp>
9024 
9025 // #include <nlohmann/detail/meta/detected.hpp>
9026 
9027 // #include <nlohmann/detail/meta/type_traits.hpp>
9028 
9029 
9031 namespace detail
9032 {
9033 
9034  template<typename T>
9035  using null_function_t = decltype(std::declval<T&>().null());
9036 
9037  template<typename T>
9039  decltype(std::declval<T&>().boolean(std::declval<bool>()));
9040 
9041  template<typename T, typename Integer>
9043  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
9044 
9045  template<typename T, typename Unsigned>
9047  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
9048 
9049  template<typename T, typename Float, typename String>
9050  using number_float_function_t = decltype(std::declval<T&>().number_float(
9051  std::declval<Float>(), std::declval<const String&>()));
9052 
9053  template<typename T, typename String>
9055  decltype(std::declval<T&>().string(std::declval<String&>()));
9056 
9057  template<typename T, typename Binary>
9059  decltype(std::declval<T&>().binary(std::declval<Binary&>()));
9060 
9061  template<typename T>
9063  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
9064 
9065  template<typename T, typename String>
9067  decltype(std::declval<T&>().key(std::declval<String&>()));
9068 
9069  template<typename T>
9070  using end_object_function_t = decltype(std::declval<T&>().end_object());
9071 
9072  template<typename T>
9074  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
9075 
9076  template<typename T>
9077  using end_array_function_t = decltype(std::declval<T&>().end_array());
9078 
9079  template<typename T, typename Exception>
9080  using parse_error_function_t = decltype(std::declval<T&>().parse_error(
9081  std::declval<std::size_t>(), std::declval<const std::string&>(),
9082  std::declval<const Exception&>()));
9083 
9084  template<typename SAX, typename BasicJsonType>
9085  struct is_sax
9086  {
9087  private:
9089  "BasicJsonType must be of type basic_json<...>");
9090 
9091  using number_integer_t = typename BasicJsonType::number_integer_t;
9092  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9093  using number_float_t = typename BasicJsonType::number_float_t;
9094  using string_t = typename BasicJsonType::string_t;
9095  using binary_t = typename BasicJsonType::binary_t;
9096  using exception_t = typename BasicJsonType::exception;
9097 
9098  public:
9099  static constexpr bool value =
9113  };
9114 
9115  template<typename SAX, typename BasicJsonType>
9117  {
9118  private:
9120  "BasicJsonType must be of type basic_json<...>");
9121 
9122  using number_integer_t = typename BasicJsonType::number_integer_t;
9123  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9124  using number_float_t = typename BasicJsonType::number_float_t;
9125  using string_t = typename BasicJsonType::string_t;
9126  using binary_t = typename BasicJsonType::binary_t;
9127  using exception_t = typename BasicJsonType::exception;
9128 
9129  public:
9131  "Missing/invalid function: bool null()");
9133  "Missing/invalid function: bool boolean(bool)");
9135  "Missing/invalid function: bool boolean(bool)");
9136  static_assert(
9138  number_integer_t>::value,
9139  "Missing/invalid function: bool number_integer(number_integer_t)");
9140  static_assert(
9142  number_unsigned_t>::value,
9143  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
9144  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
9145  number_float_t, string_t>::value,
9146  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
9147  static_assert(
9149  "Missing/invalid function: bool string(string_t&)");
9150  static_assert(
9152  "Missing/invalid function: bool binary(binary_t&)");
9154  "Missing/invalid function: bool start_object(std::size_t)");
9156  "Missing/invalid function: bool key(string_t&)");
9158  "Missing/invalid function: bool end_object()");
9160  "Missing/invalid function: bool start_array(std::size_t)");
9162  "Missing/invalid function: bool end_array()");
9163  static_assert(
9165  "Missing/invalid function: bool parse_error(std::size_t, const "
9166  "std::string&, const exception&)");
9167  };
9168 
9169 } // namespace detail
9171 
9172 // #include <nlohmann/detail/meta/type_traits.hpp>
9173 
9174 // #include <nlohmann/detail/string_concat.hpp>
9175 
9176 // #include <nlohmann/detail/value_t.hpp>
9177 
9178 
9180 namespace detail
9181 {
9182 
9185  {
9186  error,
9187  ignore,
9188  store
9189  };
9190 
9198  static inline bool little_endianness(int num = 1) noexcept
9199  {
9200  return *reinterpret_cast<char*>(&num) == 1;
9201  }
9202 
9204  // binary reader //
9206 
9210  template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
9212  {
9213  using number_integer_t = typename BasicJsonType::number_integer_t;
9214  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9215  using number_float_t = typename BasicJsonType::number_float_t;
9216  using string_t = typename BasicJsonType::string_t;
9217  using binary_t = typename BasicJsonType::binary_t;
9218  using json_sax_t = SAX;
9219  using char_type = typename InputAdapterType::char_type;
9220  using char_int_type = typename char_traits<char_type>::int_type;
9221 
9222  public:
9228  explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
9229  {
9231  }
9232 
9233  // make class move-only
9234  binary_reader(const binary_reader&) = delete;
9235  binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9237  binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9238  ~binary_reader() = default;
9239 
9249  bool sax_parse(const input_format_t format,
9250  json_sax_t* sax_,
9251  const bool strict = true,
9252  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
9253  {
9254  sax = sax_;
9255  bool result = false;
9256 
9257  switch (format)
9258  {
9259  case input_format_t::bson:
9260  result = parse_bson_internal();
9261  break;
9262 
9263  case input_format_t::cbor:
9264  result = parse_cbor_internal(true, tag_handler);
9265  break;
9266 
9268  result = parse_msgpack_internal();
9269  break;
9270 
9273  result = parse_ubjson_internal();
9274  break;
9275 
9276  case input_format_t::json: // LCOV_EXCL_LINE
9277  default: // LCOV_EXCL_LINE
9278  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9279  }
9280 
9281  // strict mode: next byte must be EOF
9282  if (result && strict)
9283  {
9284  if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
9285  {
9286  get_ignore_noop();
9287  }
9288  else
9289  {
9290  get();
9291  }
9292 
9294  {
9295  return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
9296  exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
9297  }
9298  }
9299 
9300  return result;
9301  }
9302 
9303  private:
9305  // BSON //
9307 
9312  bool parse_bson_internal()
9313  {
9314  std::int32_t document_size{};
9315  get_number<std::int32_t, true>(input_format_t::bson, document_size);
9316 
9317  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
9318  {
9319  return false;
9320  }
9321 
9322  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
9323  {
9324  return false;
9325  }
9326 
9327  return sax->end_object();
9328  }
9329 
9337  bool get_bson_cstr(string_t& result)
9338  {
9339  auto out = std::back_inserter(result);
9340  while (true)
9341  {
9342  get();
9343  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
9344  {
9345  return false;
9346  }
9347  if (current == 0x00)
9348  {
9349  return true;
9350  }
9351  *out++ = static_cast<typename string_t::value_type>(current);
9352  }
9353  }
9354 
9366  template<typename NumberType>
9367  bool get_bson_string(const NumberType len, string_t& result)
9368  {
9369  if (JSON_HEDLEY_UNLIKELY(len < 1))
9370  {
9371  auto last_token = get_token_string();
9372  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9373  exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
9374  }
9375 
9376  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != char_traits<char_type>::eof();
9377  }
9378 
9388  template<typename NumberType>
9389  bool get_bson_binary(const NumberType len, binary_t& result)
9390  {
9391  if (JSON_HEDLEY_UNLIKELY(len < 0))
9392  {
9393  auto last_token = get_token_string();
9394  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9395  exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
9396  }
9397 
9398  // All BSON binary values have a subtype
9399  std::uint8_t subtype{};
9400  get_number<std::uint8_t>(input_format_t::bson, subtype);
9401  result.set_subtype(subtype);
9402 
9403  return get_binary(input_format_t::bson, len, result);
9404  }
9405 
9416  bool parse_bson_element_internal(const char_int_type element_type,
9417  const std::size_t element_type_parse_position)
9418  {
9419  switch (element_type)
9420  {
9421  case 0x01: // double
9422  {
9423  double number{};
9424  return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9425  }
9426 
9427  case 0x02: // string
9428  {
9429  std::int32_t len{};
9430  string_t value;
9431  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
9432  }
9433 
9434  case 0x03: // object
9435  {
9436  return parse_bson_internal();
9437  }
9438 
9439  case 0x04: // array
9440  {
9441  return parse_bson_array();
9442  }
9443 
9444  case 0x05: // binary
9445  {
9446  std::int32_t len{};
9447  binary_t value;
9448  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
9449  }
9450 
9451  case 0x08: // boolean
9452  {
9453  return sax->boolean(get() != 0);
9454  }
9455 
9456  case 0x0A: // null
9457  {
9458  return sax->null();
9459  }
9460 
9461  case 0x10: // int32
9462  {
9463  std::int32_t value{};
9464  return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9465  }
9466 
9467  case 0x12: // int64
9468  {
9469  std::int64_t value{};
9470  return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9471  }
9472 
9473  default: // anything else not supported (yet)
9474  {
9475  std::array<char, 3> cr{ {} };
9476  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
9477  const std::string cr_str{ cr.data() };
9478  return sax->parse_error(element_type_parse_position, cr_str,
9479  parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
9480  }
9481  }
9482  }
9483 
9496  bool parse_bson_element_list(const bool is_array)
9497  {
9498  string_t key;
9499 
9500  while (auto element_type = get())
9501  {
9502  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
9503  {
9504  return false;
9505  }
9506 
9507  const std::size_t element_type_parse_position = chars_read;
9508  if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
9509  {
9510  return false;
9511  }
9512 
9513  if (!is_array && !sax->key(key))
9514  {
9515  return false;
9516  }
9517 
9518  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
9519  {
9520  return false;
9521  }
9522 
9523  // get_bson_cstr only appends
9524  key.clear();
9525  }
9526 
9527  return true;
9528  }
9529 
9534  bool parse_bson_array()
9535  {
9536  std::int32_t document_size{};
9537  get_number<std::int32_t, true>(input_format_t::bson, document_size);
9538 
9539  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
9540  {
9541  return false;
9542  }
9543 
9544  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
9545  {
9546  return false;
9547  }
9548 
9549  return sax->end_array();
9550  }
9551 
9553  // CBOR //
9555 
9564  bool parse_cbor_internal(const bool get_char,
9565  const cbor_tag_handler_t tag_handler)
9566  {
9567  switch (get_char ? get() : current)
9568  {
9569  // EOF
9570  case char_traits<char_type>::eof():
9571  return unexpect_eof(input_format_t::cbor, "value");
9572 
9573  // Integer 0x00..0x17 (0..23)
9574  case 0x00:
9575  case 0x01:
9576  case 0x02:
9577  case 0x03:
9578  case 0x04:
9579  case 0x05:
9580  case 0x06:
9581  case 0x07:
9582  case 0x08:
9583  case 0x09:
9584  case 0x0A:
9585  case 0x0B:
9586  case 0x0C:
9587  case 0x0D:
9588  case 0x0E:
9589  case 0x0F:
9590  case 0x10:
9591  case 0x11:
9592  case 0x12:
9593  case 0x13:
9594  case 0x14:
9595  case 0x15:
9596  case 0x16:
9597  case 0x17:
9598  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9599 
9600  case 0x18: // Unsigned integer (one-byte uint8_t follows)
9601  {
9602  std::uint8_t number{};
9603  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9604  }
9605 
9606  case 0x19: // Unsigned integer (two-byte uint16_t follows)
9607  {
9608  std::uint16_t number{};
9609  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9610  }
9611 
9612  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
9613  {
9614  std::uint32_t number{};
9615  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9616  }
9617 
9618  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
9619  {
9620  std::uint64_t number{};
9621  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9622  }
9623 
9624  // Negative integer -1-0x00..-1-0x17 (-1..-24)
9625  case 0x20:
9626  case 0x21:
9627  case 0x22:
9628  case 0x23:
9629  case 0x24:
9630  case 0x25:
9631  case 0x26:
9632  case 0x27:
9633  case 0x28:
9634  case 0x29:
9635  case 0x2A:
9636  case 0x2B:
9637  case 0x2C:
9638  case 0x2D:
9639  case 0x2E:
9640  case 0x2F:
9641  case 0x30:
9642  case 0x31:
9643  case 0x32:
9644  case 0x33:
9645  case 0x34:
9646  case 0x35:
9647  case 0x36:
9648  case 0x37:
9649  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
9650 
9651  case 0x38: // Negative integer (one-byte uint8_t follows)
9652  {
9653  std::uint8_t number{};
9654  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9655  }
9656 
9657  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
9658  {
9659  std::uint16_t number{};
9660  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9661  }
9662 
9663  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
9664  {
9665  std::uint32_t number{};
9666  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9667  }
9668 
9669  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
9670  {
9671  std::uint64_t number{};
9672  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
9673  - static_cast<number_integer_t>(number));
9674  }
9675 
9676  // Binary data (0x00..0x17 bytes follow)
9677  case 0x40:
9678  case 0x41:
9679  case 0x42:
9680  case 0x43:
9681  case 0x44:
9682  case 0x45:
9683  case 0x46:
9684  case 0x47:
9685  case 0x48:
9686  case 0x49:
9687  case 0x4A:
9688  case 0x4B:
9689  case 0x4C:
9690  case 0x4D:
9691  case 0x4E:
9692  case 0x4F:
9693  case 0x50:
9694  case 0x51:
9695  case 0x52:
9696  case 0x53:
9697  case 0x54:
9698  case 0x55:
9699  case 0x56:
9700  case 0x57:
9701  case 0x58: // Binary data (one-byte uint8_t for n follows)
9702  case 0x59: // Binary data (two-byte uint16_t for n follow)
9703  case 0x5A: // Binary data (four-byte uint32_t for n follow)
9704  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9705  case 0x5F: // Binary data (indefinite length)
9706  {
9707  binary_t b;
9708  return get_cbor_binary(b) && sax->binary(b);
9709  }
9710 
9711  // UTF-8 string (0x00..0x17 bytes follow)
9712  case 0x60:
9713  case 0x61:
9714  case 0x62:
9715  case 0x63:
9716  case 0x64:
9717  case 0x65:
9718  case 0x66:
9719  case 0x67:
9720  case 0x68:
9721  case 0x69:
9722  case 0x6A:
9723  case 0x6B:
9724  case 0x6C:
9725  case 0x6D:
9726  case 0x6E:
9727  case 0x6F:
9728  case 0x70:
9729  case 0x71:
9730  case 0x72:
9731  case 0x73:
9732  case 0x74:
9733  case 0x75:
9734  case 0x76:
9735  case 0x77:
9736  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9737  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9738  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9739  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9740  case 0x7F: // UTF-8 string (indefinite length)
9741  {
9742  string_t s;
9743  return get_cbor_string(s) && sax->string(s);
9744  }
9745 
9746  // array (0x00..0x17 data items follow)
9747  case 0x80:
9748  case 0x81:
9749  case 0x82:
9750  case 0x83:
9751  case 0x84:
9752  case 0x85:
9753  case 0x86:
9754  case 0x87:
9755  case 0x88:
9756  case 0x89:
9757  case 0x8A:
9758  case 0x8B:
9759  case 0x8C:
9760  case 0x8D:
9761  case 0x8E:
9762  case 0x8F:
9763  case 0x90:
9764  case 0x91:
9765  case 0x92:
9766  case 0x93:
9767  case 0x94:
9768  case 0x95:
9769  case 0x96:
9770  case 0x97:
9771  return get_cbor_array(
9772  conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9773 
9774  case 0x98: // array (one-byte uint8_t for n follows)
9775  {
9776  std::uint8_t len{};
9777  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9778  }
9779 
9780  case 0x99: // array (two-byte uint16_t for n follow)
9781  {
9782  std::uint16_t len{};
9783  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9784  }
9785 
9786  case 0x9A: // array (four-byte uint32_t for n follow)
9787  {
9788  std::uint32_t len{};
9789  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9790  }
9791 
9792  case 0x9B: // array (eight-byte uint64_t for n follow)
9793  {
9794  std::uint64_t len{};
9795  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9796  }
9797 
9798  case 0x9F: // array (indefinite length)
9799  return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9800 
9801  // map (0x00..0x17 pairs of data items follow)
9802  case 0xA0:
9803  case 0xA1:
9804  case 0xA2:
9805  case 0xA3:
9806  case 0xA4:
9807  case 0xA5:
9808  case 0xA6:
9809  case 0xA7:
9810  case 0xA8:
9811  case 0xA9:
9812  case 0xAA:
9813  case 0xAB:
9814  case 0xAC:
9815  case 0xAD:
9816  case 0xAE:
9817  case 0xAF:
9818  case 0xB0:
9819  case 0xB1:
9820  case 0xB2:
9821  case 0xB3:
9822  case 0xB4:
9823  case 0xB5:
9824  case 0xB6:
9825  case 0xB7:
9826  return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9827 
9828  case 0xB8: // map (one-byte uint8_t for n follows)
9829  {
9830  std::uint8_t len{};
9831  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9832  }
9833 
9834  case 0xB9: // map (two-byte uint16_t for n follow)
9835  {
9836  std::uint16_t len{};
9837  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9838  }
9839 
9840  case 0xBA: // map (four-byte uint32_t for n follow)
9841  {
9842  std::uint32_t len{};
9843  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9844  }
9845 
9846  case 0xBB: // map (eight-byte uint64_t for n follow)
9847  {
9848  std::uint64_t len{};
9849  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9850  }
9851 
9852  case 0xBF: // map (indefinite length)
9853  return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9854 
9855  case 0xC6: // tagged item
9856  case 0xC7:
9857  case 0xC8:
9858  case 0xC9:
9859  case 0xCA:
9860  case 0xCB:
9861  case 0xCC:
9862  case 0xCD:
9863  case 0xCE:
9864  case 0xCF:
9865  case 0xD0:
9866  case 0xD1:
9867  case 0xD2:
9868  case 0xD3:
9869  case 0xD4:
9870  case 0xD8: // tagged item (1 bytes follow)
9871  case 0xD9: // tagged item (2 bytes follow)
9872  case 0xDA: // tagged item (4 bytes follow)
9873  case 0xDB: // tagged item (8 bytes follow)
9874  {
9875  switch (tag_handler)
9876  {
9878  {
9879  auto last_token = get_token_string();
9880  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9881  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9882  }
9883 
9885  {
9886  // ignore binary subtype
9887  switch (current)
9888  {
9889  case 0xD8:
9890  {
9891  std::uint8_t subtype_to_ignore{};
9892  get_number(input_format_t::cbor, subtype_to_ignore);
9893  break;
9894  }
9895  case 0xD9:
9896  {
9897  std::uint16_t subtype_to_ignore{};
9898  get_number(input_format_t::cbor, subtype_to_ignore);
9899  break;
9900  }
9901  case 0xDA:
9902  {
9903  std::uint32_t subtype_to_ignore{};
9904  get_number(input_format_t::cbor, subtype_to_ignore);
9905  break;
9906  }
9907  case 0xDB:
9908  {
9909  std::uint64_t subtype_to_ignore{};
9910  get_number(input_format_t::cbor, subtype_to_ignore);
9911  break;
9912  }
9913  default:
9914  break;
9915  }
9916  return parse_cbor_internal(true, tag_handler);
9917  }
9918 
9920  {
9921  binary_t b;
9922  // use binary subtype and store in binary container
9923  switch (current)
9924  {
9925  case 0xD8:
9926  {
9927  std::uint8_t subtype{};
9928  get_number(input_format_t::cbor, subtype);
9929  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9930  break;
9931  }
9932  case 0xD9:
9933  {
9934  std::uint16_t subtype{};
9935  get_number(input_format_t::cbor, subtype);
9936  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9937  break;
9938  }
9939  case 0xDA:
9940  {
9941  std::uint32_t subtype{};
9942  get_number(input_format_t::cbor, subtype);
9943  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9944  break;
9945  }
9946  case 0xDB:
9947  {
9948  std::uint64_t subtype{};
9949  get_number(input_format_t::cbor, subtype);
9950  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9951  break;
9952  }
9953  default:
9954  return parse_cbor_internal(true, tag_handler);
9955  }
9956  get();
9957  return get_cbor_binary(b) && sax->binary(b);
9958  }
9959 
9960  default: // LCOV_EXCL_LINE
9961  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9962  return false; // LCOV_EXCL_LINE
9963  }
9964  }
9965 
9966  case 0xF4: // false
9967  return sax->boolean(false);
9968 
9969  case 0xF5: // true
9970  return sax->boolean(true);
9971 
9972  case 0xF6: // null
9973  return sax->null();
9974 
9975  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9976  {
9977  const auto byte1_raw = get();
9978  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9979  {
9980  return false;
9981  }
9982  const auto byte2_raw = get();
9983  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9984  {
9985  return false;
9986  }
9987 
9988  const auto byte1 = static_cast<unsigned char>(byte1_raw);
9989  const auto byte2 = static_cast<unsigned char>(byte2_raw);
9990 
9991  // code from RFC 7049, Appendix D, Figure 3:
9992  // As half-precision floating-point numbers were only added
9993  // to IEEE 754 in 2008, today's programming platforms often
9994  // still only have limited support for them. It is very
9995  // easy to include at least decoding support for them even
9996  // without such support. An example of a small decoder for
9997  // half-precision floating-point numbers in the C language
9998  // is shown in Fig. 3.
9999  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
10000  const double val = [&half]
10001  {
10002  const int exp = (half >> 10u) & 0x1Fu;
10003  const unsigned int mant = half & 0x3FFu;
10004  JSON_ASSERT(0 <= exp && exp <= 32);
10005  JSON_ASSERT(mant <= 1024);
10006  switch (exp)
10007  {
10008  case 0:
10009  return std::ldexp(mant, -24);
10010  case 31:
10011  return (mant == 0)
10012  ? std::numeric_limits<double>::infinity()
10013  : std::numeric_limits<double>::quiet_NaN();
10014  default:
10015  return std::ldexp(mant + 1024, exp - 25);
10016  }
10017  }();
10018  return sax->number_float((half & 0x8000u) != 0
10019  ? static_cast<number_float_t>(-val)
10020  : static_cast<number_float_t>(val), "");
10021  }
10022 
10023  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
10024  {
10025  float number{};
10026  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
10027  }
10028 
10029  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
10030  {
10031  double number{};
10032  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
10033  }
10034 
10035  default: // anything else (0xFF is handled inside the other types)
10036  {
10037  auto last_token = get_token_string();
10038  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10039  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
10040  }
10041  }
10042  }
10043 
10055  bool get_cbor_string(string_t& result)
10056  {
10057  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
10058  {
10059  return false;
10060  }
10061 
10062  switch (current)
10063  {
10064  // UTF-8 string (0x00..0x17 bytes follow)
10065  case 0x60:
10066  case 0x61:
10067  case 0x62:
10068  case 0x63:
10069  case 0x64:
10070  case 0x65:
10071  case 0x66:
10072  case 0x67:
10073  case 0x68:
10074  case 0x69:
10075  case 0x6A:
10076  case 0x6B:
10077  case 0x6C:
10078  case 0x6D:
10079  case 0x6E:
10080  case 0x6F:
10081  case 0x70:
10082  case 0x71:
10083  case 0x72:
10084  case 0x73:
10085  case 0x74:
10086  case 0x75:
10087  case 0x76:
10088  case 0x77:
10089  {
10090  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10091  }
10092 
10093  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
10094  {
10095  std::uint8_t len{};
10096  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10097  }
10098 
10099  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
10100  {
10101  std::uint16_t len{};
10102  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10103  }
10104 
10105  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
10106  {
10107  std::uint32_t len{};
10108  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10109  }
10110 
10111  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
10112  {
10113  std::uint64_t len{};
10114  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10115  }
10116 
10117  case 0x7F: // UTF-8 string (indefinite length)
10118  {
10119  while (get() != 0xFF)
10120  {
10121  string_t chunk;
10122  if (!get_cbor_string(chunk))
10123  {
10124  return false;
10125  }
10126  result.append(chunk);
10127  }
10128  return true;
10129  }
10130 
10131  default:
10132  {
10133  auto last_token = get_token_string();
10134  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10135  exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
10136  }
10137  }
10138  }
10139 
10151  bool get_cbor_binary(binary_t& result)
10152  {
10153  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
10154  {
10155  return false;
10156  }
10157 
10158  switch (current)
10159  {
10160  // Binary data (0x00..0x17 bytes follow)
10161  case 0x40:
10162  case 0x41:
10163  case 0x42:
10164  case 0x43:
10165  case 0x44:
10166  case 0x45:
10167  case 0x46:
10168  case 0x47:
10169  case 0x48:
10170  case 0x49:
10171  case 0x4A:
10172  case 0x4B:
10173  case 0x4C:
10174  case 0x4D:
10175  case 0x4E:
10176  case 0x4F:
10177  case 0x50:
10178  case 0x51:
10179  case 0x52:
10180  case 0x53:
10181  case 0x54:
10182  case 0x55:
10183  case 0x56:
10184  case 0x57:
10185  {
10186  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10187  }
10188 
10189  case 0x58: // Binary data (one-byte uint8_t for n follows)
10190  {
10191  std::uint8_t len{};
10192  return get_number(input_format_t::cbor, len) &&
10193  get_binary(input_format_t::cbor, len, result);
10194  }
10195 
10196  case 0x59: // Binary data (two-byte uint16_t for n follow)
10197  {
10198  std::uint16_t len{};
10199  return get_number(input_format_t::cbor, len) &&
10200  get_binary(input_format_t::cbor, len, result);
10201  }
10202 
10203  case 0x5A: // Binary data (four-byte uint32_t for n follow)
10204  {
10205  std::uint32_t len{};
10206  return get_number(input_format_t::cbor, len) &&
10207  get_binary(input_format_t::cbor, len, result);
10208  }
10209 
10210  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10211  {
10212  std::uint64_t len{};
10213  return get_number(input_format_t::cbor, len) &&
10214  get_binary(input_format_t::cbor, len, result);
10215  }
10216 
10217  case 0x5F: // Binary data (indefinite length)
10218  {
10219  while (get() != 0xFF)
10220  {
10221  binary_t chunk;
10222  if (!get_cbor_binary(chunk))
10223  {
10224  return false;
10225  }
10226  result.insert(result.end(), chunk.begin(), chunk.end());
10227  }
10228  return true;
10229  }
10230 
10231  default:
10232  {
10233  auto last_token = get_token_string();
10234  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10235  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));
10236  }
10237  }
10238  }
10239 
10246  bool get_cbor_array(const std::size_t len,
10247  const cbor_tag_handler_t tag_handler)
10248  {
10249  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10250  {
10251  return false;
10252  }
10253 
10254  if (len != static_cast<std::size_t>(-1))
10255  {
10256  for (std::size_t i = 0; i < len; ++i)
10257  {
10258  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10259  {
10260  return false;
10261  }
10262  }
10263  }
10264  else
10265  {
10266  while (get() != 0xFF)
10267  {
10268  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
10269  {
10270  return false;
10271  }
10272  }
10273  }
10274 
10275  return sax->end_array();
10276  }
10277 
10284  bool get_cbor_object(const std::size_t len,
10285  const cbor_tag_handler_t tag_handler)
10286  {
10287  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10288  {
10289  return false;
10290  }
10291 
10292  if (len != 0)
10293  {
10294  string_t key;
10295  if (len != static_cast<std::size_t>(-1))
10296  {
10297  for (std::size_t i = 0; i < len; ++i)
10298  {
10299  get();
10300  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10301  {
10302  return false;
10303  }
10304 
10305  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10306  {
10307  return false;
10308  }
10309  key.clear();
10310  }
10311  }
10312  else
10313  {
10314  while (get() != 0xFF)
10315  {
10316  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10317  {
10318  return false;
10319  }
10320 
10321  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10322  {
10323  return false;
10324  }
10325  key.clear();
10326  }
10327  }
10328  }
10329 
10330  return sax->end_object();
10331  }
10332 
10334  // MsgPack //
10336 
10340  bool parse_msgpack_internal()
10341  {
10342  switch (get())
10343  {
10344  // EOF
10345  case char_traits<char_type>::eof():
10346  return unexpect_eof(input_format_t::msgpack, "value");
10347 
10348  // positive fixint
10349  case 0x00:
10350  case 0x01:
10351  case 0x02:
10352  case 0x03:
10353  case 0x04:
10354  case 0x05:
10355  case 0x06:
10356  case 0x07:
10357  case 0x08:
10358  case 0x09:
10359  case 0x0A:
10360  case 0x0B:
10361  case 0x0C:
10362  case 0x0D:
10363  case 0x0E:
10364  case 0x0F:
10365  case 0x10:
10366  case 0x11:
10367  case 0x12:
10368  case 0x13:
10369  case 0x14:
10370  case 0x15:
10371  case 0x16:
10372  case 0x17:
10373  case 0x18:
10374  case 0x19:
10375  case 0x1A:
10376  case 0x1B:
10377  case 0x1C:
10378  case 0x1D:
10379  case 0x1E:
10380  case 0x1F:
10381  case 0x20:
10382  case 0x21:
10383  case 0x22:
10384  case 0x23:
10385  case 0x24:
10386  case 0x25:
10387  case 0x26:
10388  case 0x27:
10389  case 0x28:
10390  case 0x29:
10391  case 0x2A:
10392  case 0x2B:
10393  case 0x2C:
10394  case 0x2D:
10395  case 0x2E:
10396  case 0x2F:
10397  case 0x30:
10398  case 0x31:
10399  case 0x32:
10400  case 0x33:
10401  case 0x34:
10402  case 0x35:
10403  case 0x36:
10404  case 0x37:
10405  case 0x38:
10406  case 0x39:
10407  case 0x3A:
10408  case 0x3B:
10409  case 0x3C:
10410  case 0x3D:
10411  case 0x3E:
10412  case 0x3F:
10413  case 0x40:
10414  case 0x41:
10415  case 0x42:
10416  case 0x43:
10417  case 0x44:
10418  case 0x45:
10419  case 0x46:
10420  case 0x47:
10421  case 0x48:
10422  case 0x49:
10423  case 0x4A:
10424  case 0x4B:
10425  case 0x4C:
10426  case 0x4D:
10427  case 0x4E:
10428  case 0x4F:
10429  case 0x50:
10430  case 0x51:
10431  case 0x52:
10432  case 0x53:
10433  case 0x54:
10434  case 0x55:
10435  case 0x56:
10436  case 0x57:
10437  case 0x58:
10438  case 0x59:
10439  case 0x5A:
10440  case 0x5B:
10441  case 0x5C:
10442  case 0x5D:
10443  case 0x5E:
10444  case 0x5F:
10445  case 0x60:
10446  case 0x61:
10447  case 0x62:
10448  case 0x63:
10449  case 0x64:
10450  case 0x65:
10451  case 0x66:
10452  case 0x67:
10453  case 0x68:
10454  case 0x69:
10455  case 0x6A:
10456  case 0x6B:
10457  case 0x6C:
10458  case 0x6D:
10459  case 0x6E:
10460  case 0x6F:
10461  case 0x70:
10462  case 0x71:
10463  case 0x72:
10464  case 0x73:
10465  case 0x74:
10466  case 0x75:
10467  case 0x76:
10468  case 0x77:
10469  case 0x78:
10470  case 0x79:
10471  case 0x7A:
10472  case 0x7B:
10473  case 0x7C:
10474  case 0x7D:
10475  case 0x7E:
10476  case 0x7F:
10477  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
10478 
10479  // fixmap
10480  case 0x80:
10481  case 0x81:
10482  case 0x82:
10483  case 0x83:
10484  case 0x84:
10485  case 0x85:
10486  case 0x86:
10487  case 0x87:
10488  case 0x88:
10489  case 0x89:
10490  case 0x8A:
10491  case 0x8B:
10492  case 0x8C:
10493  case 0x8D:
10494  case 0x8E:
10495  case 0x8F:
10496  return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10497 
10498  // fixarray
10499  case 0x90:
10500  case 0x91:
10501  case 0x92:
10502  case 0x93:
10503  case 0x94:
10504  case 0x95:
10505  case 0x96:
10506  case 0x97:
10507  case 0x98:
10508  case 0x99:
10509  case 0x9A:
10510  case 0x9B:
10511  case 0x9C:
10512  case 0x9D:
10513  case 0x9E:
10514  case 0x9F:
10515  return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10516 
10517  // fixstr
10518  case 0xA0:
10519  case 0xA1:
10520  case 0xA2:
10521  case 0xA3:
10522  case 0xA4:
10523  case 0xA5:
10524  case 0xA6:
10525  case 0xA7:
10526  case 0xA8:
10527  case 0xA9:
10528  case 0xAA:
10529  case 0xAB:
10530  case 0xAC:
10531  case 0xAD:
10532  case 0xAE:
10533  case 0xAF:
10534  case 0xB0:
10535  case 0xB1:
10536  case 0xB2:
10537  case 0xB3:
10538  case 0xB4:
10539  case 0xB5:
10540  case 0xB6:
10541  case 0xB7:
10542  case 0xB8:
10543  case 0xB9:
10544  case 0xBA:
10545  case 0xBB:
10546  case 0xBC:
10547  case 0xBD:
10548  case 0xBE:
10549  case 0xBF:
10550  case 0xD9: // str 8
10551  case 0xDA: // str 16
10552  case 0xDB: // str 32
10553  {
10554  string_t s;
10555  return get_msgpack_string(s) && sax->string(s);
10556  }
10557 
10558  case 0xC0: // nil
10559  return sax->null();
10560 
10561  case 0xC2: // false
10562  return sax->boolean(false);
10563 
10564  case 0xC3: // true
10565  return sax->boolean(true);
10566 
10567  case 0xC4: // bin 8
10568  case 0xC5: // bin 16
10569  case 0xC6: // bin 32
10570  case 0xC7: // ext 8
10571  case 0xC8: // ext 16
10572  case 0xC9: // ext 32
10573  case 0xD4: // fixext 1
10574  case 0xD5: // fixext 2
10575  case 0xD6: // fixext 4
10576  case 0xD7: // fixext 8
10577  case 0xD8: // fixext 16
10578  {
10579  binary_t b;
10580  return get_msgpack_binary(b) && sax->binary(b);
10581  }
10582 
10583  case 0xCA: // float 32
10584  {
10585  float number{};
10586  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10587  }
10588 
10589  case 0xCB: // float 64
10590  {
10591  double number{};
10592  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10593  }
10594 
10595  case 0xCC: // uint 8
10596  {
10597  std::uint8_t number{};
10598  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10599  }
10600 
10601  case 0xCD: // uint 16
10602  {
10603  std::uint16_t number{};
10604  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10605  }
10606 
10607  case 0xCE: // uint 32
10608  {
10609  std::uint32_t number{};
10610  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10611  }
10612 
10613  case 0xCF: // uint 64
10614  {
10615  std::uint64_t number{};
10616  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10617  }
10618 
10619  case 0xD0: // int 8
10620  {
10621  std::int8_t number{};
10622  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10623  }
10624 
10625  case 0xD1: // int 16
10626  {
10627  std::int16_t number{};
10628  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10629  }
10630 
10631  case 0xD2: // int 32
10632  {
10633  std::int32_t number{};
10634  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10635  }
10636 
10637  case 0xD3: // int 64
10638  {
10639  std::int64_t number{};
10640  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10641  }
10642 
10643  case 0xDC: // array 16
10644  {
10645  std::uint16_t len{};
10646  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
10647  }
10648 
10649  case 0xDD: // array 32
10650  {
10651  std::uint32_t len{};
10652  return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));
10653  }
10654 
10655  case 0xDE: // map 16
10656  {
10657  std::uint16_t len{};
10658  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
10659  }
10660 
10661  case 0xDF: // map 32
10662  {
10663  std::uint32_t len{};
10664  return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));
10665  }
10666 
10667  // negative fixint
10668  case 0xE0:
10669  case 0xE1:
10670  case 0xE2:
10671  case 0xE3:
10672  case 0xE4:
10673  case 0xE5:
10674  case 0xE6:
10675  case 0xE7:
10676  case 0xE8:
10677  case 0xE9:
10678  case 0xEA:
10679  case 0xEB:
10680  case 0xEC:
10681  case 0xED:
10682  case 0xEE:
10683  case 0xEF:
10684  case 0xF0:
10685  case 0xF1:
10686  case 0xF2:
10687  case 0xF3:
10688  case 0xF4:
10689  case 0xF5:
10690  case 0xF6:
10691  case 0xF7:
10692  case 0xF8:
10693  case 0xF9:
10694  case 0xFA:
10695  case 0xFB:
10696  case 0xFC:
10697  case 0xFD:
10698  case 0xFE:
10699  case 0xFF:
10700  return sax->number_integer(static_cast<std::int8_t>(current));
10701 
10702  default: // anything else
10703  {
10704  auto last_token = get_token_string();
10705  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10706  exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10707  }
10708  }
10709  }
10710 
10721  bool get_msgpack_string(string_t& result)
10722  {
10723  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
10724  {
10725  return false;
10726  }
10727 
10728  switch (current)
10729  {
10730  // fixstr
10731  case 0xA0:
10732  case 0xA1:
10733  case 0xA2:
10734  case 0xA3:
10735  case 0xA4:
10736  case 0xA5:
10737  case 0xA6:
10738  case 0xA7:
10739  case 0xA8:
10740  case 0xA9:
10741  case 0xAA:
10742  case 0xAB:
10743  case 0xAC:
10744  case 0xAD:
10745  case 0xAE:
10746  case 0xAF:
10747  case 0xB0:
10748  case 0xB1:
10749  case 0xB2:
10750  case 0xB3:
10751  case 0xB4:
10752  case 0xB5:
10753  case 0xB6:
10754  case 0xB7:
10755  case 0xB8:
10756  case 0xB9:
10757  case 0xBA:
10758  case 0xBB:
10759  case 0xBC:
10760  case 0xBD:
10761  case 0xBE:
10762  case 0xBF:
10763  {
10764  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10765  }
10766 
10767  case 0xD9: // str 8
10768  {
10769  std::uint8_t len{};
10770  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10771  }
10772 
10773  case 0xDA: // str 16
10774  {
10775  std::uint16_t len{};
10776  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10777  }
10778 
10779  case 0xDB: // str 32
10780  {
10781  std::uint32_t len{};
10782  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10783  }
10784 
10785  default:
10786  {
10787  auto last_token = get_token_string();
10788  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10789  exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10790  }
10791  }
10792  }
10793 
10804  bool get_msgpack_binary(binary_t& result)
10805  {
10806  // helper function to set the subtype
10807  auto assign_and_return_true = [&result](std::int8_t subtype)
10808  {
10809  result.set_subtype(static_cast<std::uint8_t>(subtype));
10810  return true;
10811  };
10812 
10813  switch (current)
10814  {
10815  case 0xC4: // bin 8
10816  {
10817  std::uint8_t len{};
10818  return get_number(input_format_t::msgpack, len) &&
10819  get_binary(input_format_t::msgpack, len, result);
10820  }
10821 
10822  case 0xC5: // bin 16
10823  {
10824  std::uint16_t len{};
10825  return get_number(input_format_t::msgpack, len) &&
10826  get_binary(input_format_t::msgpack, len, result);
10827  }
10828 
10829  case 0xC6: // bin 32
10830  {
10831  std::uint32_t len{};
10832  return get_number(input_format_t::msgpack, len) &&
10833  get_binary(input_format_t::msgpack, len, result);
10834  }
10835 
10836  case 0xC7: // ext 8
10837  {
10838  std::uint8_t len{};
10839  std::int8_t subtype{};
10840  return get_number(input_format_t::msgpack, len) &&
10841  get_number(input_format_t::msgpack, subtype) &&
10842  get_binary(input_format_t::msgpack, len, result) &&
10843  assign_and_return_true(subtype);
10844  }
10845 
10846  case 0xC8: // ext 16
10847  {
10848  std::uint16_t len{};
10849  std::int8_t subtype{};
10850  return get_number(input_format_t::msgpack, len) &&
10851  get_number(input_format_t::msgpack, subtype) &&
10852  get_binary(input_format_t::msgpack, len, result) &&
10853  assign_and_return_true(subtype);
10854  }
10855 
10856  case 0xC9: // ext 32
10857  {
10858  std::uint32_t len{};
10859  std::int8_t subtype{};
10860  return get_number(input_format_t::msgpack, len) &&
10861  get_number(input_format_t::msgpack, subtype) &&
10862  get_binary(input_format_t::msgpack, len, result) &&
10863  assign_and_return_true(subtype);
10864  }
10865 
10866  case 0xD4: // fixext 1
10867  {
10868  std::int8_t subtype{};
10869  return get_number(input_format_t::msgpack, subtype) &&
10870  get_binary(input_format_t::msgpack, 1, result) &&
10871  assign_and_return_true(subtype);
10872  }
10873 
10874  case 0xD5: // fixext 2
10875  {
10876  std::int8_t subtype{};
10877  return get_number(input_format_t::msgpack, subtype) &&
10878  get_binary(input_format_t::msgpack, 2, result) &&
10879  assign_and_return_true(subtype);
10880  }
10881 
10882  case 0xD6: // fixext 4
10883  {
10884  std::int8_t subtype{};
10885  return get_number(input_format_t::msgpack, subtype) &&
10886  get_binary(input_format_t::msgpack, 4, result) &&
10887  assign_and_return_true(subtype);
10888  }
10889 
10890  case 0xD7: // fixext 8
10891  {
10892  std::int8_t subtype{};
10893  return get_number(input_format_t::msgpack, subtype) &&
10894  get_binary(input_format_t::msgpack, 8, result) &&
10895  assign_and_return_true(subtype);
10896  }
10897 
10898  case 0xD8: // fixext 16
10899  {
10900  std::int8_t subtype{};
10901  return get_number(input_format_t::msgpack, subtype) &&
10902  get_binary(input_format_t::msgpack, 16, result) &&
10903  assign_and_return_true(subtype);
10904  }
10905 
10906  default: // LCOV_EXCL_LINE
10907  return false; // LCOV_EXCL_LINE
10908  }
10909  }
10910 
10915  bool get_msgpack_array(const std::size_t len)
10916  {
10917  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10918  {
10919  return false;
10920  }
10921 
10922  for (std::size_t i = 0; i < len; ++i)
10923  {
10924  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10925  {
10926  return false;
10927  }
10928  }
10929 
10930  return sax->end_array();
10931  }
10932 
10937  bool get_msgpack_object(const std::size_t len)
10938  {
10939  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10940  {
10941  return false;
10942  }
10943 
10944  string_t key;
10945  for (std::size_t i = 0; i < len; ++i)
10946  {
10947  get();
10948  if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10949  {
10950  return false;
10951  }
10952 
10953  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10954  {
10955  return false;
10956  }
10957  key.clear();
10958  }
10959 
10960  return sax->end_object();
10961  }
10962 
10964  // UBJSON //
10966 
10974  bool parse_ubjson_internal(const bool get_char = true)
10975  {
10976  return get_ubjson_value(get_char ? get_ignore_noop() : current);
10977  }
10978 
10993  bool get_ubjson_string(string_t& result, const bool get_char = true)
10994  {
10995  if (get_char)
10996  {
10997  get(); // TODO(niels): may we ignore N here?
10998  }
10999 
11000  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
11001  {
11002  return false;
11003  }
11004 
11005  switch (current)
11006  {
11007  case 'U':
11008  {
11009  std::uint8_t len{};
11010  return get_number(input_format, len) && get_string(input_format, len, result);
11011  }
11012 
11013  case 'i':
11014  {
11015  std::int8_t len{};
11016  return get_number(input_format, len) && get_string(input_format, len, result);
11017  }
11018 
11019  case 'I':
11020  {
11021  std::int16_t len{};
11022  return get_number(input_format, len) && get_string(input_format, len, result);
11023  }
11024 
11025  case 'l':
11026  {
11027  std::int32_t len{};
11028  return get_number(input_format, len) && get_string(input_format, len, result);
11029  }
11030 
11031  case 'L':
11032  {
11033  std::int64_t len{};
11034  return get_number(input_format, len) && get_string(input_format, len, result);
11035  }
11036 
11037  case 'u':
11038  {
11039  if (input_format != input_format_t::bjdata)
11040  {
11041  break;
11042  }
11043  std::uint16_t len{};
11044  return get_number(input_format, len) && get_string(input_format, len, result);
11045  }
11046 
11047  case 'm':
11048  {
11049  if (input_format != input_format_t::bjdata)
11050  {
11051  break;
11052  }
11053  std::uint32_t len{};
11054  return get_number(input_format, len) && get_string(input_format, len, result);
11055  }
11056 
11057  case 'M':
11058  {
11059  if (input_format != input_format_t::bjdata)
11060  {
11061  break;
11062  }
11063  std::uint64_t len{};
11064  return get_number(input_format, len) && get_string(input_format, len, result);
11065  }
11066 
11067  default:
11068  break;
11069  }
11070  auto last_token = get_token_string();
11071  std::string message;
11072 
11073  if (input_format != input_format_t::bjdata)
11074  {
11075  message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
11076  }
11077  else
11078  {
11079  message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
11080  }
11081  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
11082  }
11083 
11088  bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
11089  {
11090  std::pair<std::size_t, char_int_type> size_and_type;
11091  size_t dimlen = 0;
11092  bool no_ndarray = true;
11093 
11094  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
11095  {
11096  return false;
11097  }
11098 
11099  if (size_and_type.first != npos)
11100  {
11101  if (size_and_type.second != 0)
11102  {
11103  if (size_and_type.second != 'N')
11104  {
11105  for (std::size_t i = 0; i < size_and_type.first; ++i)
11106  {
11107  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
11108  {
11109  return false;
11110  }
11111  dim.push_back(dimlen);
11112  }
11113  }
11114  }
11115  else
11116  {
11117  for (std::size_t i = 0; i < size_and_type.first; ++i)
11118  {
11119  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
11120  {
11121  return false;
11122  }
11123  dim.push_back(dimlen);
11124  }
11125  }
11126  }
11127  else
11128  {
11129  while (current != ']')
11130  {
11131  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
11132  {
11133  return false;
11134  }
11135  dim.push_back(dimlen);
11136  get_ignore_noop();
11137  }
11138  }
11139  return true;
11140  }
11141 
11153  bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
11154  {
11155  if (prefix == 0)
11156  {
11157  prefix = get_ignore_noop();
11158  }
11159 
11160  switch (prefix)
11161  {
11162  case 'U':
11163  {
11164  std::uint8_t number{};
11165  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11166  {
11167  return false;
11168  }
11169  result = static_cast<std::size_t>(number);
11170  return true;
11171  }
11172 
11173  case 'i':
11174  {
11175  std::int8_t number{};
11176  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11177  {
11178  return false;
11179  }
11180  if (number < 0)
11181  {
11182  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11183  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11184  }
11185  result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
11186  return true;
11187  }
11188 
11189  case 'I':
11190  {
11191  std::int16_t number{};
11192  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11193  {
11194  return false;
11195  }
11196  if (number < 0)
11197  {
11198  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11199  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11200  }
11201  result = static_cast<std::size_t>(number);
11202  return true;
11203  }
11204 
11205  case 'l':
11206  {
11207  std::int32_t number{};
11208  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11209  {
11210  return false;
11211  }
11212  if (number < 0)
11213  {
11214  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11215  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11216  }
11217  result = static_cast<std::size_t>(number);
11218  return true;
11219  }
11220 
11221  case 'L':
11222  {
11223  std::int64_t number{};
11224  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11225  {
11226  return false;
11227  }
11228  if (number < 0)
11229  {
11230  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11231  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11232  }
11233  if (!value_in_range_of<std::size_t>(number))
11234  {
11235  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11236  exception_message(input_format, "integer value overflow", "size"), nullptr));
11237  }
11238  result = static_cast<std::size_t>(number);
11239  return true;
11240  }
11241 
11242  case 'u':
11243  {
11244  if (input_format != input_format_t::bjdata)
11245  {
11246  break;
11247  }
11248  std::uint16_t number{};
11249  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11250  {
11251  return false;
11252  }
11253  result = static_cast<std::size_t>(number);
11254  return true;
11255  }
11256 
11257  case 'm':
11258  {
11259  if (input_format != input_format_t::bjdata)
11260  {
11261  break;
11262  }
11263  std::uint32_t number{};
11264  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11265  {
11266  return false;
11267  }
11268  result = conditional_static_cast<std::size_t>(number);
11269  return true;
11270  }
11271 
11272  case 'M':
11273  {
11274  if (input_format != input_format_t::bjdata)
11275  {
11276  break;
11277  }
11278  std::uint64_t number{};
11279  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11280  {
11281  return false;
11282  }
11283  if (!value_in_range_of<std::size_t>(number))
11284  {
11285  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11286  exception_message(input_format, "integer value overflow", "size"), nullptr));
11287  }
11288  result = detail::conditional_static_cast<std::size_t>(number);
11289  return true;
11290  }
11291 
11292  case '[':
11293  {
11294  if (input_format != input_format_t::bjdata)
11295  {
11296  break;
11297  }
11298  if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
11299  {
11300  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));
11301  }
11302  std::vector<size_t> dim;
11303  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
11304  {
11305  return false;
11306  }
11307  if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
11308  {
11309  result = dim.at(dim.size() - 1);
11310  return true;
11311  }
11312  if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
11313  {
11314  for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
11315  {
11316  if (i == 0)
11317  {
11318  result = 0;
11319  return true;
11320  }
11321  }
11322 
11323  string_t key = "_ArraySize_";
11324  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
11325  {
11326  return false;
11327  }
11328  result = 1;
11329  for (auto i : dim)
11330  {
11331  result *= i;
11332  if (result == 0 || result == npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be npos as it is used to initialize size in get_ubjson_size_type()
11333  {
11334  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));
11335  }
11336  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
11337  {
11338  return false;
11339  }
11340  }
11341  is_ndarray = true;
11342  return sax->end_array();
11343  }
11344  result = 0;
11345  return true;
11346  }
11347 
11348  default:
11349  break;
11350  }
11351  auto last_token = get_token_string();
11352  std::string message;
11353 
11354  if (input_format != input_format_t::bjdata)
11355  {
11356  message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
11357  }
11358  else
11359  {
11360  message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
11361  }
11362  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
11363  }
11364 
11376  bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
11377  {
11378  result.first = npos; // size
11379  result.second = 0; // type
11380  bool is_ndarray = false;
11381 
11382  get_ignore_noop();
11383 
11384  if (current == '$')
11385  {
11386  result.second = get(); // must not ignore 'N', because 'N' maybe the type
11387  if (input_format == input_format_t::bjdata
11388  && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
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, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
11393  }
11394 
11395  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
11396  {
11397  return false;
11398  }
11399 
11400  get_ignore_noop();
11401  if (JSON_HEDLEY_UNLIKELY(current != '#'))
11402  {
11403  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
11404  {
11405  return false;
11406  }
11407  auto last_token = get_token_string();
11408  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11409  exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
11410  }
11411 
11412  const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11413  if (input_format == input_format_t::bjdata && is_ndarray)
11414  {
11415  if (inside_ndarray)
11416  {
11417  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11418  exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
11419  }
11420  result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
11421  }
11422  return is_error;
11423  }
11424 
11425  if (current == '#')
11426  {
11427  const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11428  if (input_format == input_format_t::bjdata && is_ndarray)
11429  {
11430  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11431  exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
11432  }
11433  return is_error;
11434  }
11435 
11436  return true;
11437  }
11438 
11443  bool get_ubjson_value(const char_int_type prefix)
11444  {
11445  switch (prefix)
11446  {
11447  case char_traits<char_type>::eof(): // EOF
11448  return unexpect_eof(input_format, "value");
11449 
11450  case 'T': // true
11451  return sax->boolean(true);
11452  case 'F': // false
11453  return sax->boolean(false);
11454 
11455  case 'Z': // null
11456  return sax->null();
11457 
11458  case 'U':
11459  {
11460  std::uint8_t number{};
11461  return get_number(input_format, number) && sax->number_unsigned(number);
11462  }
11463 
11464  case 'i':
11465  {
11466  std::int8_t number{};
11467  return get_number(input_format, number) && sax->number_integer(number);
11468  }
11469 
11470  case 'I':
11471  {
11472  std::int16_t number{};
11473  return get_number(input_format, number) && sax->number_integer(number);
11474  }
11475 
11476  case 'l':
11477  {
11478  std::int32_t number{};
11479  return get_number(input_format, number) && sax->number_integer(number);
11480  }
11481 
11482  case 'L':
11483  {
11484  std::int64_t number{};
11485  return get_number(input_format, number) && sax->number_integer(number);
11486  }
11487 
11488  case 'u':
11489  {
11490  if (input_format != input_format_t::bjdata)
11491  {
11492  break;
11493  }
11494  std::uint16_t number{};
11495  return get_number(input_format, number) && sax->number_unsigned(number);
11496  }
11497 
11498  case 'm':
11499  {
11500  if (input_format != input_format_t::bjdata)
11501  {
11502  break;
11503  }
11504  std::uint32_t number{};
11505  return get_number(input_format, number) && sax->number_unsigned(number);
11506  }
11507 
11508  case 'M':
11509  {
11510  if (input_format != input_format_t::bjdata)
11511  {
11512  break;
11513  }
11514  std::uint64_t number{};
11515  return get_number(input_format, number) && sax->number_unsigned(number);
11516  }
11517 
11518  case 'h':
11519  {
11520  if (input_format != input_format_t::bjdata)
11521  {
11522  break;
11523  }
11524  const auto byte1_raw = get();
11525  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11526  {
11527  return false;
11528  }
11529  const auto byte2_raw = get();
11530  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11531  {
11532  return false;
11533  }
11534 
11535  const auto byte1 = static_cast<unsigned char>(byte1_raw);
11536  const auto byte2 = static_cast<unsigned char>(byte2_raw);
11537 
11538  // code from RFC 7049, Appendix D, Figure 3:
11539  // As half-precision floating-point numbers were only added
11540  // to IEEE 754 in 2008, today's programming platforms often
11541  // still only have limited support for them. It is very
11542  // easy to include at least decoding support for them even
11543  // without such support. An example of a small decoder for
11544  // half-precision floating-point numbers in the C language
11545  // is shown in Fig. 3.
11546  const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
11547  const double val = [&half]
11548  {
11549  const int exp = (half >> 10u) & 0x1Fu;
11550  const unsigned int mant = half & 0x3FFu;
11551  JSON_ASSERT(0 <= exp && exp <= 32);
11552  JSON_ASSERT(mant <= 1024);
11553  switch (exp)
11554  {
11555  case 0:
11556  return std::ldexp(mant, -24);
11557  case 31:
11558  return (mant == 0)
11559  ? std::numeric_limits<double>::infinity()
11560  : std::numeric_limits<double>::quiet_NaN();
11561  default:
11562  return std::ldexp(mant + 1024, exp - 25);
11563  }
11564  }();
11565  return sax->number_float((half & 0x8000u) != 0
11566  ? static_cast<number_float_t>(-val)
11567  : static_cast<number_float_t>(val), "");
11568  }
11569 
11570  case 'd':
11571  {
11572  float number{};
11573  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11574  }
11575 
11576  case 'D':
11577  {
11578  double number{};
11579  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11580  }
11581 
11582  case 'H':
11583  {
11584  return get_ubjson_high_precision_number();
11585  }
11586 
11587  case 'C': // char
11588  {
11589  get();
11590  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
11591  {
11592  return false;
11593  }
11594  if (JSON_HEDLEY_UNLIKELY(current > 127))
11595  {
11596  auto last_token = get_token_string();
11597  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11598  exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
11599  }
11600  string_t s(1, static_cast<typename string_t::value_type>(current));
11601  return sax->string(s);
11602  }
11603 
11604  case 'S': // string
11605  {
11606  string_t s;
11607  return get_ubjson_string(s) && sax->string(s);
11608  }
11609 
11610  case '[': // array
11611  return get_ubjson_array();
11612 
11613  case '{': // object
11614  return get_ubjson_object();
11615 
11616  default: // anything else
11617  break;
11618  }
11619  auto last_token = get_token_string();
11620  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));
11621  }
11622 
11626  bool get_ubjson_array()
11627  {
11628  std::pair<std::size_t, char_int_type> size_and_type;
11629  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11630  {
11631  return false;
11632  }
11633 
11634  // 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):
11635  // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
11636 
11637  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11638  {
11639  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
11640  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)
11641  {
11642  return p.first < t;
11643  });
11644  string_t key = "_ArrayType_";
11645  if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
11646  {
11647  auto last_token = get_token_string();
11648  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11649  exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
11650  }
11651 
11652  string_t type = it->second; // sax->string() takes a reference
11653  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type)))
11654  {
11655  return false;
11656  }
11657 
11658  if (size_and_type.second == 'C')
11659  {
11660  size_and_type.second = 'U';
11661  }
11662 
11663  key = "_ArrayData_";
11664  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first)))
11665  {
11666  return false;
11667  }
11668 
11669  for (std::size_t i = 0; i < size_and_type.first; ++i)
11670  {
11671  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11672  {
11673  return false;
11674  }
11675  }
11676 
11677  return (sax->end_array() && sax->end_object());
11678  }
11679 
11680  if (size_and_type.first != npos)
11681  {
11682  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
11683  {
11684  return false;
11685  }
11686 
11687  if (size_and_type.second != 0)
11688  {
11689  if (size_and_type.second != 'N')
11690  {
11691  for (std::size_t i = 0; i < size_and_type.first; ++i)
11692  {
11693  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11694  {
11695  return false;
11696  }
11697  }
11698  }
11699  }
11700  else
11701  {
11702  for (std::size_t i = 0; i < size_and_type.first; ++i)
11703  {
11704  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11705  {
11706  return false;
11707  }
11708  }
11709  }
11710  }
11711  else
11712  {
11713  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11714  {
11715  return false;
11716  }
11717 
11718  while (current != ']')
11719  {
11720  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
11721  {
11722  return false;
11723  }
11724  get_ignore_noop();
11725  }
11726  }
11727 
11728  return sax->end_array();
11729  }
11730 
11734  bool get_ubjson_object()
11735  {
11736  std::pair<std::size_t, char_int_type> size_and_type;
11737  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11738  {
11739  return false;
11740  }
11741 
11742  // do not accept ND-array size in objects in BJData
11743  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11744  {
11745  auto last_token = get_token_string();
11746  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11747  exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
11748  }
11749 
11750  string_t key;
11751  if (size_and_type.first != npos)
11752  {
11753  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
11754  {
11755  return false;
11756  }
11757 
11758  if (size_and_type.second != 0)
11759  {
11760  for (std::size_t i = 0; i < size_and_type.first; ++i)
11761  {
11762  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11763  {
11764  return false;
11765  }
11766  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11767  {
11768  return false;
11769  }
11770  key.clear();
11771  }
11772  }
11773  else
11774  {
11775  for (std::size_t i = 0; i < size_and_type.first; ++i)
11776  {
11777  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11778  {
11779  return false;
11780  }
11781  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11782  {
11783  return false;
11784  }
11785  key.clear();
11786  }
11787  }
11788  }
11789  else
11790  {
11791  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11792  {
11793  return false;
11794  }
11795 
11796  while (current != '}')
11797  {
11798  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11799  {
11800  return false;
11801  }
11802  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11803  {
11804  return false;
11805  }
11806  get_ignore_noop();
11807  key.clear();
11808  }
11809  }
11810 
11811  return sax->end_object();
11812  }
11813 
11814  // Note, no reader for UBJSON binary types is implemented because they do
11815  // not exist
11816 
11817  bool get_ubjson_high_precision_number()
11818  {
11819  // get size of following number string
11820  std::size_t size{};
11821  bool no_ndarray = true;
11822  auto res = get_ubjson_size_value(size, no_ndarray);
11823  if (JSON_HEDLEY_UNLIKELY(!res))
11824  {
11825  return res;
11826  }
11827 
11828  // get number string
11829  std::vector<char> number_vector;
11830  for (std::size_t i = 0; i < size; ++i)
11831  {
11832  get();
11833  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11834  {
11835  return false;
11836  }
11837  number_vector.push_back(static_cast<char>(current));
11838  }
11839 
11840  // parse number string
11841  using ia_type = decltype(detail::input_adapter(number_vector));
11842  auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11843  const auto result_number = number_lexer.scan();
11844  const auto number_string = number_lexer.get_token_string();
11845  const auto result_remainder = number_lexer.scan();
11846 
11847  using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11848 
11849  if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11850  {
11851  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11852  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11853  }
11854 
11855  switch (result_number)
11856  {
11857  case token_type::value_integer:
11858  return sax->number_integer(number_lexer.get_number_integer());
11859  case token_type::value_unsigned:
11860  return sax->number_unsigned(number_lexer.get_number_unsigned());
11861  case token_type::value_float:
11862  return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11863  case token_type::uninitialized:
11864  case token_type::literal_true:
11865  case token_type::literal_false:
11866  case token_type::literal_null:
11867  case token_type::value_string:
11868  case token_type::begin_array:
11869  case token_type::begin_object:
11870  case token_type::end_array:
11871  case token_type::end_object:
11872  case token_type::name_separator:
11873  case token_type::value_separator:
11874  case token_type::parse_error:
11875  case token_type::end_of_input:
11876  case token_type::literal_or_value:
11877  default:
11878  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11879  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11880  }
11881  }
11882 
11884  // Utility functions //
11886 
11896  char_int_type get()
11897  {
11898  ++chars_read;
11899  return current = ia.get_character();
11900  }
11901 
11905  char_int_type get_ignore_noop()
11906  {
11907  do
11908  {
11909  get();
11910  } while (current == 'N');
11911 
11912  return current;
11913  }
11914 
11915  /*
11916  @brief read a number from the input
11917 
11918  @tparam NumberType the type of the number
11919  @param[in] format the current format (for diagnostics)
11920  @param[out] result number of type @a NumberType
11921 
11922  @return whether conversion completed
11923 
11924  @note This function needs to respect the system's endianness, because
11925  bytes in CBOR, MessagePack, and UBJSON are stored in network order
11926  (big endian) and therefore need reordering on little endian systems.
11927  On the other hand, BSON and BJData use little endian and should reorder
11928  on big endian systems.
11929  */
11930  template<typename NumberType, bool InputIsLittleEndian = false>
11931  bool get_number(const input_format_t format, NumberType& result)
11932  {
11933  // step 1: read input into array with system's byte order
11934  std::array<std::uint8_t, sizeof(NumberType)> vec{};
11935  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11936  {
11937  get();
11938  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11939  {
11940  return false;
11941  }
11942 
11943  // reverse byte order prior to conversion if necessary
11944  if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11945  {
11946  vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11947  }
11948  else
11949  {
11950  vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11951  }
11952  }
11953 
11954  // step 2: convert array into number of type T and return
11955  std::memcpy(&result, vec.data(), sizeof(NumberType));
11956  return true;
11957  }
11958 
11973  template<typename NumberType>
11974  bool get_string(const input_format_t format,
11975  const NumberType len,
11976  string_t& result)
11977  {
11978  bool success = true;
11979  for (NumberType i = 0; i < len; i++)
11980  {
11981  get();
11982  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11983  {
11984  success = false;
11985  break;
11986  }
11987  result.push_back(static_cast<typename string_t::value_type>(current));
11988  }
11989  return success;
11990  }
11991 
12006  template<typename NumberType>
12007  bool get_binary(const input_format_t format,
12008  const NumberType len,
12009  binary_t& result)
12010  {
12011  bool success = true;
12012  for (NumberType i = 0; i < len; i++)
12013  {
12014  get();
12015  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
12016  {
12017  success = false;
12018  break;
12019  }
12020  result.push_back(static_cast<std::uint8_t>(current));
12021  }
12022  return success;
12023  }
12024 
12031  bool unexpect_eof(const input_format_t format, const char* context) const
12032  {
12033  if (JSON_HEDLEY_UNLIKELY(current == char_traits<char_type>::eof()))
12034  {
12035  return sax->parse_error(chars_read, "<end of file>",
12036  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
12037  }
12038  return true;
12039  }
12040 
12044  std::string get_token_string() const
12045  {
12046  std::array<char, 3> cr{ {} };
12047  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
12048  return std::string{ cr.data() };
12049  }
12050 
12057  std::string exception_message(const input_format_t format,
12058  const std::string& detail,
12059  const std::string& context) const
12060  {
12061  std::string error_msg = "syntax error while parsing ";
12062 
12063  switch (format)
12064  {
12065  case input_format_t::cbor:
12066  error_msg += "CBOR";
12067  break;
12068 
12070  error_msg += "MessagePack";
12071  break;
12072 
12074  error_msg += "UBJSON";
12075  break;
12076 
12077  case input_format_t::bson:
12078  error_msg += "BSON";
12079  break;
12080 
12082  error_msg += "BJData";
12083  break;
12084 
12085  case input_format_t::json: // LCOV_EXCL_LINE
12086  default: // LCOV_EXCL_LINE
12087  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
12088  }
12089 
12090  return concat(error_msg, ' ', context, ": ", detail);
12091  }
12092 
12093  private:
12094  static JSON_INLINE_VARIABLE constexpr std::size_t npos = static_cast<std::size_t>(-1);
12095 
12097  InputAdapterType ia;
12098 
12100  char_int_type current = char_traits<char_type>::eof();
12101 
12103  std::size_t chars_read = 0;
12104 
12106  const bool is_little_endian = little_endianness();
12107 
12109  const input_format_t input_format = input_format_t::json;
12110 
12112  json_sax_t* sax = nullptr;
12113 
12114  // excluded markers in bjdata optimized type
12115 #define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \
12116  make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
12117 
12118 #define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
12119  make_array<bjd_type>( \
12120  bjd_type{'C', "char"}, \
12121  bjd_type{'D', "double"}, \
12122  bjd_type{'I', "int16"}, \
12123  bjd_type{'L', "int64"}, \
12124  bjd_type{'M', "uint64"}, \
12125  bjd_type{'U', "uint8"}, \
12126  bjd_type{'d', "single"}, \
12127  bjd_type{'i', "int8"}, \
12128  bjd_type{'l', "int32"}, \
12129  bjd_type{'m', "uint32"}, \
12130  bjd_type{'u', "uint16"})
12131 
12133  // lookup tables
12134  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12135  const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =
12137 
12138  using bjd_type = std::pair<char_int_type, string_t>;
12139  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12140  const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map =
12142 
12143 #undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
12144 #undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
12145  };
12146 
12147 #ifndef JSON_HAS_CPP_17
12148  template<typename BasicJsonType, typename InputAdapterType, typename SAX>
12149  constexpr std::size_t binary_reader<BasicJsonType, InputAdapterType, SAX>::npos;
12150 #endif
12151 
12152 } // namespace detail
12154 
12155 // #include <nlohmann/detail/input/input_adapters.hpp>
12156 
12157 // #include <nlohmann/detail/input/lexer.hpp>
12158 
12159 // #include <nlohmann/detail/input/parser.hpp>
12160 // __ _____ _____ _____
12161 // __| | __| | | | JSON for Modern C++
12162 // | | |__ | | | | | | version 3.11.3
12163 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12164 //
12165 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12166 // SPDX-License-Identifier: MIT
12167 
12168 
12169 
12170 #include <cmath> // isfinite
12171 #include <cstdint> // uint8_t
12172 #include <functional> // function
12173 #include <string> // string
12174 #include <utility> // move
12175 #include <vector> // vector
12176 
12177 // #include <nlohmann/detail/exceptions.hpp>
12178 
12179 // #include <nlohmann/detail/input/input_adapters.hpp>
12180 
12181 // #include <nlohmann/detail/input/json_sax.hpp>
12182 
12183 // #include <nlohmann/detail/input/lexer.hpp>
12184 
12185 // #include <nlohmann/detail/macro_scope.hpp>
12186 
12187 // #include <nlohmann/detail/meta/is_sax.hpp>
12188 
12189 // #include <nlohmann/detail/string_concat.hpp>
12190 
12191 // #include <nlohmann/detail/value_t.hpp>
12192 
12193 
12195 namespace detail
12196 {
12198  // parser //
12200 
12201  enum class parse_event_t : std::uint8_t
12202  {
12204  object_start,
12206  object_end,
12208  array_start,
12210  array_end,
12212  key,
12214  value
12215  };
12216 
12217  template<typename BasicJsonType>
12219  std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
12220 
12226  template<typename BasicJsonType, typename InputAdapterType>
12227  class parser
12228  {
12229  using number_integer_t = typename BasicJsonType::number_integer_t;
12230  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12231  using number_float_t = typename BasicJsonType::number_float_t;
12232  using string_t = typename BasicJsonType::string_t;
12234  using token_type = typename lexer_t::token_type;
12235 
12236  public:
12238  explicit parser(InputAdapterType&& adapter,
12239  const parser_callback_t<BasicJsonType> cb = nullptr,
12240  const bool allow_exceptions_ = true,
12241  const bool skip_comments = false)
12242  : callback(cb)
12243  , m_lexer(std::move(adapter), skip_comments)
12244  , allow_exceptions(allow_exceptions_)
12245  {
12246  // read first token
12247  get_token();
12248  }
12249 
12260  void parse(const bool strict, BasicJsonType& result)
12261  {
12262  if (callback)
12263  {
12264  json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
12265  sax_parse_internal(&sdp);
12266 
12267  // in strict mode, input must be completely read
12268  if (strict && (get_token() != token_type::end_of_input))
12269  {
12270  sdp.parse_error(m_lexer.get_position(),
12271  m_lexer.get_token_string(),
12272  parse_error::create(101, m_lexer.get_position(),
12273  exception_message(token_type::end_of_input, "value"), nullptr));
12274  }
12275 
12276  // in case of an error, return discarded value
12277  if (sdp.is_errored())
12278  {
12279  result = value_t::discarded;
12280  return;
12281  }
12282 
12283  // set top-level value to null if it was discarded by the callback
12284  // function
12285  if (result.is_discarded())
12286  {
12287  result = nullptr;
12288  }
12289  }
12290  else
12291  {
12292  json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
12293  sax_parse_internal(&sdp);
12294 
12295  // in strict mode, input must be completely read
12296  if (strict && (get_token() != token_type::end_of_input))
12297  {
12298  sdp.parse_error(m_lexer.get_position(),
12299  m_lexer.get_token_string(),
12300  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12301  }
12302 
12303  // in case of an error, return discarded value
12304  if (sdp.is_errored())
12305  {
12306  result = value_t::discarded;
12307  return;
12308  }
12309  }
12310 
12311  result.assert_invariant();
12312  }
12313 
12320  bool accept(const bool strict = true)
12321  {
12322  json_sax_acceptor<BasicJsonType> sax_acceptor;
12323  return sax_parse(&sax_acceptor, strict);
12324  }
12325 
12326  template<typename SAX>
12328  bool sax_parse(SAX* sax, const bool strict = true)
12329  {
12331  const bool result = sax_parse_internal(sax);
12332 
12333  // strict mode: next byte must be EOF
12334  if (result && strict && (get_token() != token_type::end_of_input))
12335  {
12336  return sax->parse_error(m_lexer.get_position(),
12337  m_lexer.get_token_string(),
12338  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12339  }
12340 
12341  return result;
12342  }
12343 
12344  private:
12345  template<typename SAX>
12347  bool sax_parse_internal(SAX* sax)
12348  {
12349  // stack to remember the hierarchy of structured values we are parsing
12350  // true = array; false = object
12351  std::vector<bool> states;
12352  // value to avoid a goto (see comment where set to true)
12353  bool skip_to_state_evaluation = false;
12354 
12355  while (true)
12356  {
12357  if (!skip_to_state_evaluation)
12358  {
12359  // invariant: get_token() was called before each iteration
12360  switch (last_token)
12361  {
12362  case token_type::begin_object:
12363  {
12364  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
12365  {
12366  return false;
12367  }
12368 
12369  // closing } -> we are done
12370  if (get_token() == token_type::end_object)
12371  {
12372  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12373  {
12374  return false;
12375  }
12376  break;
12377  }
12378 
12379  // parse key
12380  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
12381  {
12382  return sax->parse_error(m_lexer.get_position(),
12383  m_lexer.get_token_string(),
12384  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12385  }
12386  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12387  {
12388  return false;
12389  }
12390 
12391  // parse separator (:)
12392  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12393  {
12394  return sax->parse_error(m_lexer.get_position(),
12395  m_lexer.get_token_string(),
12396  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12397  }
12398 
12399  // remember we are now inside an object
12400  states.push_back(false);
12401 
12402  // parse values
12403  get_token();
12404  continue;
12405  }
12406 
12407  case token_type::begin_array:
12408  {
12409  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
12410  {
12411  return false;
12412  }
12413 
12414  // closing ] -> we are done
12415  if (get_token() == token_type::end_array)
12416  {
12417  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12418  {
12419  return false;
12420  }
12421  break;
12422  }
12423 
12424  // remember we are now inside an array
12425  states.push_back(true);
12426 
12427  // parse values (no need to call get_token)
12428  continue;
12429  }
12430 
12431  case token_type::value_float:
12432  {
12433  const auto res = m_lexer.get_number_float();
12434 
12435  if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
12436  {
12437  return sax->parse_error(m_lexer.get_position(),
12438  m_lexer.get_token_string(),
12439  out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
12440  }
12441 
12442  if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
12443  {
12444  return false;
12445  }
12446 
12447  break;
12448  }
12449 
12450  case token_type::literal_false:
12451  {
12452  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
12453  {
12454  return false;
12455  }
12456  break;
12457  }
12458 
12459  case token_type::literal_null:
12460  {
12461  if (JSON_HEDLEY_UNLIKELY(!sax->null()))
12462  {
12463  return false;
12464  }
12465  break;
12466  }
12467 
12468  case token_type::literal_true:
12469  {
12470  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
12471  {
12472  return false;
12473  }
12474  break;
12475  }
12476 
12477  case token_type::value_integer:
12478  {
12479  if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
12480  {
12481  return false;
12482  }
12483  break;
12484  }
12485 
12486  case token_type::value_string:
12487  {
12488  if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
12489  {
12490  return false;
12491  }
12492  break;
12493  }
12494 
12495  case token_type::value_unsigned:
12496  {
12497  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
12498  {
12499  return false;
12500  }
12501  break;
12502  }
12503 
12504  case token_type::parse_error:
12505  {
12506  // using "uninitialized" to avoid "expected" message
12507  return sax->parse_error(m_lexer.get_position(),
12508  m_lexer.get_token_string(),
12509  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
12510  }
12511  case token_type::end_of_input:
12512  {
12514  {
12515  return sax->parse_error(m_lexer.get_position(),
12516  m_lexer.get_token_string(),
12517  parse_error::create(101, m_lexer.get_position(),
12518  "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
12519  }
12520 
12521  return sax->parse_error(m_lexer.get_position(),
12522  m_lexer.get_token_string(),
12523  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12524  }
12525  case token_type::uninitialized:
12526  case token_type::end_array:
12527  case token_type::end_object:
12528  case token_type::name_separator:
12529  case token_type::value_separator:
12530  case token_type::literal_or_value:
12531  default: // the last token was unexpected
12532  {
12533  return sax->parse_error(m_lexer.get_position(),
12534  m_lexer.get_token_string(),
12535  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12536  }
12537  }
12538  }
12539  else
12540  {
12541  skip_to_state_evaluation = false;
12542  }
12543 
12544  // we reached this line after we successfully parsed a value
12545  if (states.empty())
12546  {
12547  // empty stack: we reached the end of the hierarchy: done
12548  return true;
12549  }
12550 
12551  if (states.back()) // array
12552  {
12553  // comma -> next value
12554  if (get_token() == token_type::value_separator)
12555  {
12556  // parse a new value
12557  get_token();
12558  continue;
12559  }
12560 
12561  // closing ]
12562  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
12563  {
12564  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12565  {
12566  return false;
12567  }
12568 
12569  // We are done with this array. Before we can parse a
12570  // new value, we need to evaluate the new state first.
12571  // By setting skip_to_state_evaluation to false, we
12572  // are effectively jumping to the beginning of this if.
12573  JSON_ASSERT(!states.empty());
12574  states.pop_back();
12575  skip_to_state_evaluation = true;
12576  continue;
12577  }
12578 
12579  return sax->parse_error(m_lexer.get_position(),
12580  m_lexer.get_token_string(),
12581  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
12582  }
12583 
12584  // states.back() is false -> object
12585 
12586  // comma -> next value
12587  if (get_token() == token_type::value_separator)
12588  {
12589  // parse key
12590  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
12591  {
12592  return sax->parse_error(m_lexer.get_position(),
12593  m_lexer.get_token_string(),
12594  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12595  }
12596 
12597  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12598  {
12599  return false;
12600  }
12601 
12602  // parse separator (:)
12603  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12604  {
12605  return sax->parse_error(m_lexer.get_position(),
12606  m_lexer.get_token_string(),
12607  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12608  }
12609 
12610  // parse values
12611  get_token();
12612  continue;
12613  }
12614 
12615  // closing }
12616  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
12617  {
12618  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12619  {
12620  return false;
12621  }
12622 
12623  // We are done with this object. Before we can parse a
12624  // new value, we need to evaluate the new state first.
12625  // By setting skip_to_state_evaluation to false, we
12626  // are effectively jumping to the beginning of this if.
12627  JSON_ASSERT(!states.empty());
12628  states.pop_back();
12629  skip_to_state_evaluation = true;
12630  continue;
12631  }
12632 
12633  return sax->parse_error(m_lexer.get_position(),
12634  m_lexer.get_token_string(),
12635  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
12636  }
12637  }
12638 
12640  token_type get_token()
12641  {
12642  return last_token = m_lexer.scan();
12643  }
12644 
12645  std::string exception_message(const token_type expected, const std::string& context)
12646  {
12647  std::string error_msg = "syntax error ";
12648 
12649  if (!context.empty())
12650  {
12651  error_msg += concat("while parsing ", context, ' ');
12652  }
12653 
12654  error_msg += "- ";
12655 
12656  if (last_token == token_type::parse_error)
12657  {
12658  error_msg += concat(m_lexer.get_error_message(), "; last read: '",
12659  m_lexer.get_token_string(), '\'');
12660  }
12661  else
12662  {
12663  error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
12664  }
12665 
12666  if (expected != token_type::uninitialized)
12667  {
12668  error_msg += concat("; expected ", lexer_t::token_type_name(expected));
12669  }
12670 
12671  return error_msg;
12672  }
12673 
12674  private:
12676  const parser_callback_t<BasicJsonType> callback = nullptr;
12678  token_type last_token = token_type::uninitialized;
12680  lexer_t m_lexer;
12682  const bool allow_exceptions = true;
12683  };
12684 
12685 } // namespace detail
12687 
12688 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
12689 // __ _____ _____ _____
12690 // __| | __| | | | JSON for Modern C++
12691 // | | |__ | | | | | | version 3.11.3
12692 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12693 //
12694 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12695 // SPDX-License-Identifier: MIT
12696 
12697 
12698 
12699 // #include <nlohmann/detail/abi_macros.hpp>
12700 
12701 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12702 // __ _____ _____ _____
12703 // __| | __| | | | JSON for Modern C++
12704 // | | |__ | | | | | | version 3.11.3
12705 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12706 //
12707 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12708 // SPDX-License-Identifier: MIT
12709 
12710 
12711 
12712 #include <cstddef> // ptrdiff_t
12713 #include <limits> // numeric_limits
12714 
12715 // #include <nlohmann/detail/macro_scope.hpp>
12716 
12717 
12719 namespace detail
12720 {
12721 
12722  /*
12723  @brief an iterator for primitive JSON types
12724 
12725  This class models an iterator for primitive JSON types (boolean, number,
12726  string). It's only purpose is to allow the iterator/const_iterator classes
12727  to "iterate" over primitive values. Internally, the iterator is modeled by
12728  a `difference_type` variable. Value begin_value (`0`) models the begin,
12729  end_value (`1`) models past the end.
12730  */
12732  {
12733  private:
12734  using difference_type = std::ptrdiff_t;
12735  static constexpr difference_type begin_value = 0;
12736  static constexpr difference_type end_value = begin_value + 1;
12737 
12740  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
12741 
12742  public:
12743  constexpr difference_type get_value() const noexcept
12744  {
12745  return m_it;
12746  }
12747 
12749  void set_begin() noexcept
12750  {
12751  m_it = begin_value;
12752  }
12753 
12755  void set_end() noexcept
12756  {
12757  m_it = end_value;
12758  }
12759 
12761  constexpr bool is_begin() const noexcept
12762  {
12763  return m_it == begin_value;
12764  }
12765 
12767  constexpr bool is_end() const noexcept
12768  {
12769  return m_it == end_value;
12770  }
12771 
12772  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12773  {
12774  return lhs.m_it == rhs.m_it;
12775  }
12776 
12777  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12778  {
12779  return lhs.m_it < rhs.m_it;
12780  }
12781 
12782  primitive_iterator_t operator+(difference_type n) noexcept
12783  {
12784  auto result = *this;
12785  result += n;
12786  return result;
12787  }
12788 
12789  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12790  {
12791  return lhs.m_it - rhs.m_it;
12792  }
12793 
12795  {
12796  ++m_it;
12797  return *this;
12798  }
12799 
12800  primitive_iterator_t operator++(int)&noexcept // NOLINT(cert-dcl21-cpp)
12801  {
12802  auto result = *this;
12803  ++m_it;
12804  return result;
12805  }
12806 
12808  {
12809  --m_it;
12810  return *this;
12811  }
12812 
12813  primitive_iterator_t operator--(int)&noexcept // NOLINT(cert-dcl21-cpp)
12814  {
12815  auto result = *this;
12816  --m_it;
12817  return result;
12818  }
12819 
12820  primitive_iterator_t& operator+=(difference_type n) noexcept
12821  {
12822  m_it += n;
12823  return *this;
12824  }
12825 
12826  primitive_iterator_t& operator-=(difference_type n) noexcept
12827  {
12828  m_it -= n;
12829  return *this;
12830  }
12831  };
12832 
12833 } // namespace detail
12835 
12836 
12838 namespace detail
12839 {
12840 
12847  template<typename BasicJsonType> struct internal_iterator
12848  {
12850  typename BasicJsonType::object_t::iterator object_iterator{};
12852  typename BasicJsonType::array_t::iterator array_iterator{};
12855  };
12856 
12857 } // namespace detail
12859 
12860 // #include <nlohmann/detail/iterators/iter_impl.hpp>
12861 // __ _____ _____ _____
12862 // __| | __| | | | JSON for Modern C++
12863 // | | |__ | | | | | | version 3.11.3
12864 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12865 //
12866 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12867 // SPDX-License-Identifier: MIT
12868 
12869 
12870 
12871 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12872 #include <type_traits> // conditional, is_const, remove_const
12873 
12874 // #include <nlohmann/detail/exceptions.hpp>
12875 
12876 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
12877 
12878 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12879 
12880 // #include <nlohmann/detail/macro_scope.hpp>
12881 
12882 // #include <nlohmann/detail/meta/cpp_future.hpp>
12883 
12884 // #include <nlohmann/detail/meta/type_traits.hpp>
12885 
12886 // #include <nlohmann/detail/value_t.hpp>
12887 
12888 
12890 namespace detail
12891 {
12892 
12893  // forward declare, to be able to friend it later on
12894  template<typename IteratorType> class iteration_proxy;
12895  template<typename IteratorType> class iteration_proxy_value;
12896 
12913  template<typename BasicJsonType>
12914  class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12915  {
12917  using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
12919  friend other_iter_impl;
12920  friend BasicJsonType;
12923 
12924  using object_t = typename BasicJsonType::object_t;
12925  using array_t = typename BasicJsonType::array_t;
12926  // make sure BasicJsonType is basic_json or const basic_json
12927  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
12928  "iter_impl only accepts (const) basic_json");
12929  // superficial check for the LegacyBidirectionalIterator named requirement
12930  static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
12931  && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
12932  "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
12933 
12934  public:
12940  using iterator_category = std::bidirectional_iterator_tag;
12941 
12943  using value_type = typename BasicJsonType::value_type;
12945  using difference_type = typename BasicJsonType::difference_type;
12947  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12948  typename BasicJsonType::const_pointer,
12949  typename BasicJsonType::pointer>::type;
12951  using reference =
12952  typename std::conditional<std::is_const<BasicJsonType>::value,
12953  typename BasicJsonType::const_reference,
12954  typename BasicJsonType::reference>::type;
12955 
12956  iter_impl() = default;
12957  ~iter_impl() = default;
12958  iter_impl(iter_impl&&) noexcept = default;
12959  iter_impl& operator=(iter_impl&&) noexcept = default;
12960 
12967  explicit iter_impl(pointer object) noexcept : m_object(object)
12968  {
12969  JSON_ASSERT(m_object != nullptr);
12970 
12971  switch (m_object->m_data.m_type)
12972  {
12973  case value_t::object:
12974  {
12975  m_it.object_iterator = typename object_t::iterator();
12976  break;
12977  }
12978 
12979  case value_t::array:
12980  {
12981  m_it.array_iterator = typename array_t::iterator();
12982  break;
12983  }
12984 
12985  case value_t::null:
12986  case value_t::string:
12987  case value_t::boolean:
12990  case value_t::number_float:
12991  case value_t::binary:
12992  case value_t::discarded:
12993  default:
12994  {
12996  break;
12997  }
12998  }
12999  }
13000 
13018  : m_object(other.m_object), m_it(other.m_it)
13019  {}
13020 
13028  {
13029  if (&other != this)
13030  {
13031  m_object = other.m_object;
13032  m_it = other.m_it;
13033  }
13034  return *this;
13035  }
13036 
13042  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
13043  : m_object(other.m_object), m_it(other.m_it)
13044  {}
13045 
13052  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
13053  {
13054  m_object = other.m_object;
13055  m_it = other.m_it;
13056  return *this;
13057  }
13058 
13064  void set_begin() noexcept
13065  {
13066  JSON_ASSERT(m_object != nullptr);
13067 
13068  switch (m_object->m_data.m_type)
13069  {
13070  case value_t::object:
13071  {
13072  m_it.object_iterator = m_object->m_data.m_value.object->begin();
13073  break;
13074  }
13075 
13076  case value_t::array:
13077  {
13078  m_it.array_iterator = m_object->m_data.m_value.array->begin();
13079  break;
13080  }
13081 
13082  case value_t::null:
13083  {
13084  // set to end so begin()==end() is true: null is empty
13086  break;
13087  }
13088 
13089  case value_t::string:
13090  case value_t::boolean:
13093  case value_t::number_float:
13094  case value_t::binary:
13095  case value_t::discarded:
13096  default:
13097  {
13099  break;
13100  }
13101  }
13102  }
13103 
13108  void set_end() noexcept
13109  {
13110  JSON_ASSERT(m_object != nullptr);
13111 
13112  switch (m_object->m_data.m_type)
13113  {
13114  case value_t::object:
13115  {
13116  m_it.object_iterator = m_object->m_data.m_value.object->end();
13117  break;
13118  }
13119 
13120  case value_t::array:
13121  {
13122  m_it.array_iterator = m_object->m_data.m_value.array->end();
13123  break;
13124  }
13125 
13126  case value_t::null:
13127  case value_t::string:
13128  case value_t::boolean:
13131  case value_t::number_float:
13132  case value_t::binary:
13133  case value_t::discarded:
13134  default:
13135  {
13137  break;
13138  }
13139  }
13140  }
13141 
13142  public:
13148  {
13149  JSON_ASSERT(m_object != nullptr);
13150 
13151  switch (m_object->m_data.m_type)
13152  {
13153  case value_t::object:
13154  {
13155  JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13156  return m_it.object_iterator->second;
13157  }
13158 
13159  case value_t::array:
13160  {
13161  JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13162  return *m_it.array_iterator;
13163  }
13164 
13165  case value_t::null:
13166  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13167 
13168  case value_t::string:
13169  case value_t::boolean:
13172  case value_t::number_float:
13173  case value_t::binary:
13174  case value_t::discarded:
13175  default:
13176  {
13178  {
13179  return *m_object;
13180  }
13181 
13182  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13183  }
13184  }
13185  }
13186 
13192  {
13193  JSON_ASSERT(m_object != nullptr);
13194 
13195  switch (m_object->m_data.m_type)
13196  {
13197  case value_t::object:
13198  {
13199  JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13200  return &(m_it.object_iterator->second);
13201  }
13202 
13203  case value_t::array:
13204  {
13205  JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13206  return &*m_it.array_iterator;
13207  }
13208 
13209  case value_t::null:
13210  case value_t::string:
13211  case value_t::boolean:
13214  case value_t::number_float:
13215  case value_t::binary:
13216  case value_t::discarded:
13217  default:
13218  {
13220  {
13221  return m_object;
13222  }
13223 
13224  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13225  }
13226  }
13227  }
13228 
13233  iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
13234  {
13235  auto result = *this;
13236  ++(*this);
13237  return result;
13238  }
13239 
13245  {
13246  JSON_ASSERT(m_object != nullptr);
13247 
13248  switch (m_object->m_data.m_type)
13249  {
13250  case value_t::object:
13251  {
13252  std::advance(m_it.object_iterator, 1);
13253  break;
13254  }
13255 
13256  case value_t::array:
13257  {
13258  std::advance(m_it.array_iterator, 1);
13259  break;
13260  }
13261 
13262  case value_t::null:
13263  case value_t::string:
13264  case value_t::boolean:
13267  case value_t::number_float:
13268  case value_t::binary:
13269  case value_t::discarded:
13270  default:
13271  {
13273  break;
13274  }
13275  }
13276 
13277  return *this;
13278  }
13279 
13284  iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
13285  {
13286  auto result = *this;
13287  --(*this);
13288  return result;
13289  }
13290 
13296  {
13297  JSON_ASSERT(m_object != nullptr);
13298 
13299  switch (m_object->m_data.m_type)
13300  {
13301  case value_t::object:
13302  {
13303  std::advance(m_it.object_iterator, -1);
13304  break;
13305  }
13306 
13307  case value_t::array:
13308  {
13309  std::advance(m_it.array_iterator, -1);
13310  break;
13311  }
13312 
13313  case value_t::null:
13314  case value_t::string:
13315  case value_t::boolean:
13318  case value_t::number_float:
13319  case value_t::binary:
13320  case value_t::discarded:
13321  default:
13322  {
13324  break;
13325  }
13326  }
13327 
13328  return *this;
13329  }
13330 
13335  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 >
13336  bool operator==(const IterImpl& other) const
13337  {
13338  // if objects are not the same, the comparison is undefined
13339  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13340  {
13341  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13342  }
13343 
13344  JSON_ASSERT(m_object != nullptr);
13345 
13346  switch (m_object->m_data.m_type)
13347  {
13348  case value_t::object:
13349  return (m_it.object_iterator == other.m_it.object_iterator);
13350 
13351  case value_t::array:
13352  return (m_it.array_iterator == other.m_it.array_iterator);
13353 
13354  case value_t::null:
13355  case value_t::string:
13356  case value_t::boolean:
13359  case value_t::number_float:
13360  case value_t::binary:
13361  case value_t::discarded:
13362  default:
13363  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
13364  }
13365  }
13366 
13371  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 >
13372  bool operator!=(const IterImpl& other) const
13373  {
13374  return !operator==(other);
13375  }
13376 
13381  bool operator<(const iter_impl& other) const
13382  {
13383  // if objects are not the same, the comparison is undefined
13384  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13385  {
13386  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13387  }
13388 
13389  JSON_ASSERT(m_object != nullptr);
13390 
13391  switch (m_object->m_data.m_type)
13392  {
13393  case value_t::object:
13394  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
13395 
13396  case value_t::array:
13397  return (m_it.array_iterator < other.m_it.array_iterator);
13398 
13399  case value_t::null:
13400  case value_t::string:
13401  case value_t::boolean:
13404  case value_t::number_float:
13405  case value_t::binary:
13406  case value_t::discarded:
13407  default:
13409  }
13410  }
13411 
13416  bool operator<=(const iter_impl& other) const
13417  {
13418  return !other.operator < (*this);
13419  }
13420 
13425  bool operator>(const iter_impl& other) const
13426  {
13427  return !operator<=(other);
13428  }
13429 
13434  bool operator>=(const iter_impl& other) const
13435  {
13436  return !operator<(other);
13437  }
13438 
13444  {
13445  JSON_ASSERT(m_object != nullptr);
13446 
13447  switch (m_object->m_data.m_type)
13448  {
13449  case value_t::object:
13450  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13451 
13452  case value_t::array:
13453  {
13454  std::advance(m_it.array_iterator, i);
13455  break;
13456  }
13457 
13458  case value_t::null:
13459  case value_t::string:
13460  case value_t::boolean:
13463  case value_t::number_float:
13464  case value_t::binary:
13465  case value_t::discarded:
13466  default:
13467  {
13468  m_it.primitive_iterator += i;
13469  break;
13470  }
13471  }
13472 
13473  return *this;
13474  }
13475 
13481  {
13482  return operator+=(-i);
13483  }
13484 
13490  {
13491  auto result = *this;
13492  result += i;
13493  return result;
13494  }
13495 
13501  {
13502  auto result = it;
13503  result += i;
13504  return result;
13505  }
13506 
13512  {
13513  auto result = *this;
13514  result -= i;
13515  return result;
13516  }
13517 
13523  {
13524  JSON_ASSERT(m_object != nullptr);
13525 
13526  switch (m_object->m_data.m_type)
13527  {
13528  case value_t::object:
13529  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13530 
13531  case value_t::array:
13532  return m_it.array_iterator - other.m_it.array_iterator;
13533 
13534  case value_t::null:
13535  case value_t::string:
13536  case value_t::boolean:
13539  case value_t::number_float:
13540  case value_t::binary:
13541  case value_t::discarded:
13542  default:
13544  }
13545  }
13546 
13552  {
13553  JSON_ASSERT(m_object != nullptr);
13554 
13555  switch (m_object->m_data.m_type)
13556  {
13557  case value_t::object:
13558  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
13559 
13560  case value_t::array:
13561  return *std::next(m_it.array_iterator, n);
13562 
13563  case value_t::null:
13564  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13565 
13566  case value_t::string:
13567  case value_t::boolean:
13570  case value_t::number_float:
13571  case value_t::binary:
13572  case value_t::discarded:
13573  default:
13574  {
13576  {
13577  return *m_object;
13578  }
13579 
13580  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13581  }
13582  }
13583  }
13584 
13589  const typename object_t::key_type& key() const
13590  {
13591  JSON_ASSERT(m_object != nullptr);
13592 
13593  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
13594  {
13595  return m_it.object_iterator->first;
13596  }
13597 
13598  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
13599  }
13600 
13606  {
13607  return operator*();
13608  }
13609 
13612  pointer m_object = nullptr;
13615  };
13616 
13617 } // namespace detail
13619 
13620 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
13621 
13622 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
13623 // __ _____ _____ _____
13624 // __| | __| | | | JSON for Modern C++
13625 // | | |__ | | | | | | version 3.11.3
13626 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13627 //
13628 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
13629 // SPDX-License-Identifier: MIT
13630 
13631 
13632 
13633 #include <cstddef> // ptrdiff_t
13634 #include <iterator> // reverse_iterator
13635 #include <utility> // declval
13636 
13637 // #include <nlohmann/detail/abi_macros.hpp>
13638 
13639 
13641 namespace detail
13642 {
13643 
13645  // reverse_iterator //
13647 
13666  template<typename Base>
13667  class json_reverse_iterator : public std::reverse_iterator<Base>
13668  {
13669  public:
13670  using difference_type = std::ptrdiff_t;
13672  using base_iterator = std::reverse_iterator<Base>;
13674  using reference = typename Base::reference;
13675 
13677  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
13678  : base_iterator(it) {}
13679 
13681  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
13682 
13684  json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
13685  {
13686  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
13687  }
13688 
13691  {
13692  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
13693  }
13694 
13696  json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
13697  {
13698  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
13699  }
13700 
13703  {
13704  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
13705  }
13706 
13709  {
13710  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
13711  }
13712 
13715  {
13716  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
13717  }
13718 
13721  {
13722  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
13723  }
13724 
13727  {
13728  return base_iterator(*this) - base_iterator(other);
13729  }
13730 
13733  {
13734  return *(this->operator+(n));
13735  }
13736 
13738  auto key() const -> decltype(std::declval<Base>().key())
13739  {
13740  auto it = --this->base();
13741  return it.key();
13742  }
13743 
13746  {
13747  auto it = --this->base();
13748  return it.operator * ();
13749  }
13750  };
13751 
13752 } // namespace detail
13754 
13755 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13756 
13757 // #include <nlohmann/detail/json_custom_base_class.hpp>
13758 // __ _____ _____ _____
13759 // __| | __| | | | JSON for Modern C++
13760 // | | |__ | | | | | | version 3.11.3
13761 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13762 //
13763 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
13764 // SPDX-License-Identifier: MIT
13765 
13766 
13767 
13768 #include <type_traits> // conditional, is_same
13769 
13770 // #include <nlohmann/detail/abi_macros.hpp>
13771 
13772 
13774 namespace detail
13775 {
13776 
13788 
13789  template<class T>
13790  using json_base_class = typename std::conditional <
13791  std::is_same<T, void>::value,
13793  T
13794  >::type;
13795 
13796 } // namespace detail
13798 
13799 // #include <nlohmann/detail/json_pointer.hpp>
13800 // __ _____ _____ _____
13801 // __| | __| | | | JSON for Modern C++
13802 // | | |__ | | | | | | version 3.11.3
13803 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13804 //
13805 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
13806 // SPDX-License-Identifier: MIT
13807 
13808 
13809 
13810 #include <algorithm> // all_of
13811 #include <cctype> // isdigit
13812 #include <cerrno> // errno, ERANGE
13813 #include <cstdlib> // strtoull
13814 #ifndef JSON_NO_IO
13815 #include <iosfwd> // ostream
13816 #endif // JSON_NO_IO
13817 #include <limits> // max
13818 #include <numeric> // accumulate
13819 #include <string> // string
13820 #include <utility> // move
13821 #include <vector> // vector
13822 
13823 // #include <nlohmann/detail/exceptions.hpp>
13824 
13825 // #include <nlohmann/detail/macro_scope.hpp>
13826 
13827 // #include <nlohmann/detail/string_concat.hpp>
13828 
13829 // #include <nlohmann/detail/string_escape.hpp>
13830 
13831 // #include <nlohmann/detail/value_t.hpp>
13832 
13833 
13835 
13838 template<typename RefStringType>
13840 {
13841  // allow basic_json to access private members
13843  friend class basic_json;
13844 
13845  template<typename>
13846  friend class json_pointer;
13847 
13848  template<typename T>
13849  struct string_t_helper
13850  {
13851  using type = T;
13852  };
13853 
13855  struct string_t_helper<NLOHMANN_BASIC_JSON_TPL>
13856  {
13857  using type = StringType;
13858  };
13859 
13860 public:
13861  // for backwards compatibility accept BasicJsonType
13862  using string_t = typename string_t_helper<RefStringType>::type;
13863 
13866  explicit json_pointer(const string_t& s = "")
13867  : reference_tokens(split(s))
13868  {}
13869 
13873  {
13874  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
13875  string_t{},
13876  [](const string_t& a, const string_t& b)
13877  {
13878  return detail::concat(a, '/', detail::escape(b));
13879  });
13880  }
13881 
13885  operator string_t() const
13886  {
13887  return to_string();
13888  }
13889 
13890 #ifndef JSON_NO_IO
13893  friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
13894  {
13895  o << ptr.to_string();
13896  return o;
13897  }
13898 #endif
13899 
13903  {
13904  reference_tokens.insert(reference_tokens.end(),
13905  ptr.reference_tokens.begin(),
13906  ptr.reference_tokens.end());
13907  return *this;
13908  }
13909 
13913  {
13914  push_back(std::move(token));
13915  return *this;
13916  }
13917 
13920  json_pointer& operator/=(std::size_t array_idx)
13921  {
13922  return *this /= std::to_string(array_idx);
13923  }
13924 
13928  const json_pointer& rhs)
13929  {
13930  return json_pointer(lhs) /= rhs;
13931  }
13932 
13935  friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
13936  {
13937  return json_pointer(lhs) /= std::move(token);
13938  }
13939 
13942  friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13943  {
13944  return json_pointer(lhs) /= array_idx;
13945  }
13946 
13950  {
13951  if (empty())
13952  {
13953  return *this;
13954  }
13955 
13956  json_pointer res = *this;
13957  res.pop_back();
13958  return res;
13959  }
13960 
13963  void pop_back()
13964  {
13965  if (JSON_HEDLEY_UNLIKELY(empty()))
13966  {
13967  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13968  }
13969 
13970  reference_tokens.pop_back();
13971  }
13972 
13975  const string_t& back() const
13976  {
13977  if (JSON_HEDLEY_UNLIKELY(empty()))
13978  {
13979  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13980  }
13981 
13982  return reference_tokens.back();
13983  }
13984 
13987  void push_back(const string_t& token)
13988  {
13989  reference_tokens.push_back(token);
13990  }
13991 
13994  void push_back(string_t&& token)
13995  {
13996  reference_tokens.push_back(std::move(token));
13997  }
13998 
14001  bool empty() const noexcept
14002  {
14003  return reference_tokens.empty();
14004  }
14005 
14006 private:
14017  template<typename BasicJsonType>
14018  static typename BasicJsonType::size_type array_index(const string_t& s)
14019  {
14020  using size_type = typename BasicJsonType::size_type;
14021 
14022  // error condition (cf. RFC 6901, Sect. 4)
14023  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
14024  {
14025  JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
14026  }
14027 
14028  // error condition (cf. RFC 6901, Sect. 4)
14029  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
14030  {
14031  JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
14032  }
14033 
14034  const char* p = s.c_str();
14035  char* p_end = nullptr;
14036  errno = 0; // strtoull doesn't reset errno
14037  const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
14038  if (p == p_end // invalid input or empty string
14039  || errno == ERANGE // out of range
14040  || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
14041  {
14042  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
14043  }
14044 
14045  // only triggered on special platforms (like 32bit), see also
14046  // https://github.com/nlohmann/json/pull/2203
14047  if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
14048  {
14049  JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
14050  }
14051 
14052  return static_cast<size_type>(res);
14053  }
14054 
14056  json_pointer top() const
14057  {
14058  if (JSON_HEDLEY_UNLIKELY(empty()))
14059  {
14060  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
14061  }
14062 
14063  json_pointer result = *this;
14064  result.reference_tokens = { reference_tokens[0] };
14065  return result;
14066  }
14067 
14068 private:
14077  template<typename BasicJsonType>
14078  BasicJsonType& get_and_create(BasicJsonType& j) const
14079  {
14080  auto* result = &j;
14081 
14082  // in case no reference tokens exist, return a reference to the JSON value
14083  // j which will be overwritten by a primitive value
14084  for (const auto& reference_token : reference_tokens)
14085  {
14086  switch (result->type())
14087  {
14088  case detail::value_t::null:
14089  {
14090  if (reference_token == "0")
14091  {
14092  // start a new array if reference token is 0
14093  result = &result->operator[](0);
14094  }
14095  else
14096  {
14097  // start a new object otherwise
14098  result = &result->operator[](reference_token);
14099  }
14100  break;
14101  }
14102 
14104  {
14105  // create an entry in the object
14106  result = &result->operator[](reference_token);
14107  break;
14108  }
14109 
14111  {
14112  // create an entry in the array
14113  result = &result->operator[](array_index<BasicJsonType>(reference_token));
14114  break;
14115  }
14116 
14117  /*
14118  The following code is only reached if there exists a reference
14119  token _and_ the current value is primitive. In this case, we have
14120  an error situation, because primitive values may only occur as
14121  single value; that is, with an empty list of reference tokens.
14122  */
14130  default:
14131  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
14132  }
14133  }
14134 
14135  return *result;
14136  }
14137 
14157  template<typename BasicJsonType>
14158  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
14159  {
14160  for (const auto& reference_token : reference_tokens)
14161  {
14162  // convert null values to arrays or objects before continuing
14163  if (ptr->is_null())
14164  {
14165  // check if reference token is a number
14166  const bool nums =
14167  std::all_of(reference_token.begin(), reference_token.end(),
14168  [](const unsigned char x)
14169  {
14170  return std::isdigit(x);
14171  });
14172 
14173  // change value to array for numbers or "-" or to object otherwise
14174  *ptr = (nums || reference_token == "-")
14177  }
14178 
14179  switch (ptr->type())
14180  {
14182  {
14183  // use unchecked object access
14184  ptr = &ptr->operator[](reference_token);
14185  break;
14186  }
14187 
14189  {
14190  if (reference_token == "-")
14191  {
14192  // explicitly treat "-" as index beyond the end
14193  ptr = &ptr->operator[](ptr->m_data.m_value.array->size());
14194  }
14195  else
14196  {
14197  // convert array index to number; unchecked access
14198  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14199  }
14200  break;
14201  }
14202 
14203  case detail::value_t::null:
14211  default:
14212  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14213  }
14214  }
14215 
14216  return *ptr;
14217  }
14218 
14225  template<typename BasicJsonType>
14226  BasicJsonType& get_checked(BasicJsonType* ptr) const
14227  {
14228  for (const auto& reference_token : reference_tokens)
14229  {
14230  switch (ptr->type())
14231  {
14233  {
14234  // note: at performs range check
14235  ptr = &ptr->at(reference_token);
14236  break;
14237  }
14238 
14240  {
14241  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14242  {
14243  // "-" always fails the range check
14245  "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
14246  ") is out of range"), ptr));
14247  }
14248 
14249  // note: at performs range check
14250  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14251  break;
14252  }
14253 
14254  case detail::value_t::null:
14262  default:
14263  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14264  }
14265  }
14266 
14267  return *ptr;
14268  }
14269 
14283  template<typename BasicJsonType>
14284  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
14285  {
14286  for (const auto& reference_token : reference_tokens)
14287  {
14288  switch (ptr->type())
14289  {
14291  {
14292  // use unchecked object access
14293  ptr = &ptr->operator[](reference_token);
14294  break;
14295  }
14296 
14298  {
14299  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14300  {
14301  // "-" cannot be used for const access
14302  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));
14303  }
14304 
14305  // use unchecked array access
14306  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14307  break;
14308  }
14309 
14310  case detail::value_t::null:
14318  default:
14319  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14320  }
14321  }
14322 
14323  return *ptr;
14324  }
14325 
14332  template<typename BasicJsonType>
14333  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
14334  {
14335  for (const auto& reference_token : reference_tokens)
14336  {
14337  switch (ptr->type())
14338  {
14340  {
14341  // note: at performs range check
14342  ptr = &ptr->at(reference_token);
14343  break;
14344  }
14345 
14347  {
14348  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14349  {
14350  // "-" always fails the range check
14352  "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
14353  ") is out of range"), ptr));
14354  }
14355 
14356  // note: at performs range check
14357  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14358  break;
14359  }
14360 
14361  case detail::value_t::null:
14369  default:
14370  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14371  }
14372  }
14373 
14374  return *ptr;
14375  }
14376 
14381  template<typename BasicJsonType>
14382  bool contains(const BasicJsonType* ptr) const
14383  {
14384  for (const auto& reference_token : reference_tokens)
14385  {
14386  switch (ptr->type())
14387  {
14389  {
14390  if (!ptr->contains(reference_token))
14391  {
14392  // we did not find the key in the object
14393  return false;
14394  }
14395 
14396  ptr = &ptr->operator[](reference_token);
14397  break;
14398  }
14399 
14401  {
14402  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14403  {
14404  // "-" always fails the range check
14405  return false;
14406  }
14407  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
14408  {
14409  // invalid char
14410  return false;
14411  }
14412  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
14413  {
14414  if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
14415  {
14416  // first char should be between '1' and '9'
14417  return false;
14418  }
14419  for (std::size_t i = 1; i < reference_token.size(); i++)
14420  {
14421  if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
14422  {
14423  // other char should be between '0' and '9'
14424  return false;
14425  }
14426  }
14427  }
14428 
14429  const auto idx = array_index<BasicJsonType>(reference_token);
14430  if (idx >= ptr->size())
14431  {
14432  // index out of range
14433  return false;
14434  }
14435 
14436  ptr = &ptr->operator[](idx);
14437  break;
14438  }
14439 
14440  case detail::value_t::null:
14448  default:
14449  {
14450  // we do not expect primitive values if there is still a
14451  // reference token to process
14452  return false;
14453  }
14454  }
14455  }
14456 
14457  // no reference token left means we found a primitive value
14458  return true;
14459  }
14460 
14470  static std::vector<string_t> split(const string_t& reference_string)
14471  {
14472  std::vector<string_t> result;
14473 
14474  // special case: empty reference string -> no reference tokens
14475  if (reference_string.empty())
14476  {
14477  return result;
14478  }
14479 
14480  // check if nonempty reference string begins with slash
14481  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
14482  {
14483  JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
14484  }
14485 
14486  // extract the reference tokens:
14487  // - slash: position of the last read slash (or end of string)
14488  // - start: position after the previous slash
14489  for (
14490  // search for the first slash after the first character
14491  std::size_t slash = reference_string.find_first_of('/', 1),
14492  // set the beginning of the first reference token
14493  start = 1;
14494  // we can stop if start == 0 (if slash == string_t::npos)
14495  start != 0;
14496  // set the beginning of the next reference token
14497  // (will eventually be 0 if slash == string_t::npos)
14498  start = (slash == string_t::npos) ? 0 : slash + 1,
14499  // find next slash
14500  slash = reference_string.find_first_of('/', start))
14501  {
14502  // use the text between the beginning of the reference token
14503  // (start) and the last slash (slash).
14504  auto reference_token = reference_string.substr(start, slash - start);
14505 
14506  // check reference tokens are properly escaped
14507  for (std::size_t pos = reference_token.find_first_of('~');
14508  pos != string_t::npos;
14509  pos = reference_token.find_first_of('~', pos + 1))
14510  {
14511  JSON_ASSERT(reference_token[pos] == '~');
14512 
14513  // ~ must be followed by 0 or 1
14514  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
14515  (reference_token[pos + 1] != '0' &&
14516  reference_token[pos + 1] != '1')))
14517  {
14518  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
14519  }
14520  }
14521 
14522  // finally, store the reference token
14523  detail::unescape(reference_token);
14524  result.push_back(reference_token);
14525  }
14526 
14527  return result;
14528  }
14529 
14530 private:
14538  template<typename BasicJsonType>
14539  static void flatten(const string_t& reference_string,
14540  const BasicJsonType& value,
14541  BasicJsonType& result)
14542  {
14543  switch (value.type())
14544  {
14546  {
14547  if (value.m_data.m_value.array->empty())
14548  {
14549  // flatten empty array as null
14550  result[reference_string] = nullptr;
14551  }
14552  else
14553  {
14554  // iterate array and use index as reference string
14555  for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)
14556  {
14557  flatten(detail::concat(reference_string, '/', std::to_string(i)),
14558  value.m_data.m_value.array->operator[](i), result);
14559  }
14560  }
14561  break;
14562  }
14563 
14565  {
14566  if (value.m_data.m_value.object->empty())
14567  {
14568  // flatten empty object as null
14569  result[reference_string] = nullptr;
14570  }
14571  else
14572  {
14573  // iterate object and use keys as reference string
14574  for (const auto& element : *value.m_data.m_value.object)
14575  {
14576  flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
14577  }
14578  }
14579  break;
14580  }
14581 
14582  case detail::value_t::null:
14590  default:
14591  {
14592  // add primitive value with its reference string
14593  result[reference_string] = value;
14594  break;
14595  }
14596  }
14597  }
14598 
14609  template<typename BasicJsonType>
14610  static BasicJsonType
14611  unflatten(const BasicJsonType& value)
14612  {
14613  if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
14614  {
14615  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
14616  }
14617 
14618  BasicJsonType result;
14619 
14620  // iterate the JSON object values
14621  for (const auto& element : *value.m_data.m_value.object)
14622  {
14623  if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
14624  {
14625  JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
14626  }
14627 
14628  // assign value to reference pointed to by JSON pointer; Note that if
14629  // the JSON pointer is "" (i.e., points to the whole value), function
14630  // get_and_create returns a reference to result itself. An assignment
14631  // will then create a primitive value.
14632  json_pointer(element.first).get_and_create(result) = element.second;
14633  }
14634 
14635  return result;
14636  }
14637 
14638  // can't use conversion operator because of ambiguity
14639  json_pointer<string_t> convert() const&
14640  {
14641  json_pointer<string_t> result;
14642  result.reference_tokens = reference_tokens;
14643  return result;
14644  }
14645 
14646  json_pointer<string_t> convert()&&
14647  {
14648  json_pointer<string_t> result;
14649  result.reference_tokens = std::move(reference_tokens);
14650  return result;
14651  }
14652 
14653 public:
14654 #if JSON_HAS_THREE_WAY_COMPARISON
14657  template<typename RefStringTypeRhs>
14658  bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept
14659  {
14660  return reference_tokens == rhs.reference_tokens;
14661  }
14662 
14665  JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))
14666  bool operator==(const string_t& rhs) const
14667  {
14668  return *this == json_pointer(rhs);
14669  }
14670 
14672  template<typename RefStringTypeRhs>
14673  std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
14674  {
14675  return reference_tokens <=> rhs.reference_tokens; // *NOPAD*
14676  }
14677 #else
14680  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14681  // NOLINTNEXTLINE(readability-redundant-declaration)
14682  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14683  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14684 
14687  template<typename RefStringTypeLhs, typename StringType>
14688  // NOLINTNEXTLINE(readability-redundant-declaration)
14689  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14690  const StringType& rhs);
14691 
14694  template<typename RefStringTypeRhs, typename StringType>
14695  // NOLINTNEXTLINE(readability-redundant-declaration)
14696  friend bool operator==(const StringType& lhs,
14697  const json_pointer<RefStringTypeRhs>& rhs);
14698 
14701  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14702  // NOLINTNEXTLINE(readability-redundant-declaration)
14703  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14704  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14705 
14708  template<typename RefStringTypeLhs, typename StringType>
14709  // NOLINTNEXTLINE(readability-redundant-declaration)
14710  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14711  const StringType& rhs);
14712 
14715  template<typename RefStringTypeRhs, typename StringType>
14716  // NOLINTNEXTLINE(readability-redundant-declaration)
14717  friend bool operator!=(const StringType& lhs,
14718  const json_pointer<RefStringTypeRhs>& rhs);
14719 
14721  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14722  // NOLINTNEXTLINE(readability-redundant-declaration)
14723  friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
14724  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14725 #endif
14726 
14727 private:
14729  std::vector<string_t> reference_tokens;
14730 };
14731 
14732 #if !JSON_HAS_THREE_WAY_COMPARISON
14733 // functions cannot be defined inside class due to ODR violations
14734 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14736  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14737 {
14738  return lhs.reference_tokens == rhs.reference_tokens;
14739 }
14740 
14741 template<typename RefStringTypeLhs,
14742  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14744 inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14745  const StringType& rhs)
14746 {
14747  return lhs == json_pointer<RefStringTypeLhs>(rhs);
14748 }
14749 
14750 template<typename RefStringTypeRhs,
14751  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14753 inline bool operator==(const StringType& lhs,
14754  const json_pointer<RefStringTypeRhs>& rhs)
14755 {
14756  return json_pointer<RefStringTypeRhs>(lhs) == rhs;
14757 }
14758 
14759 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14761  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14762 {
14763  return !(lhs == rhs);
14764 }
14765 
14766 template<typename RefStringTypeLhs,
14767  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14769 inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14770  const StringType& rhs)
14771 {
14772  return !(lhs == rhs);
14773 }
14774 
14775 template<typename RefStringTypeRhs,
14776  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14778 inline bool operator!=(const StringType& lhs,
14779  const json_pointer<RefStringTypeRhs>& rhs)
14780 {
14781  return !(lhs == rhs);
14782 }
14783 
14784 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14786  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14787 {
14788  return lhs.reference_tokens < rhs.reference_tokens;
14789 }
14790 #endif
14791 
14793 
14794 // #include <nlohmann/detail/json_ref.hpp>
14795 // __ _____ _____ _____
14796 // __| | __| | | | JSON for Modern C++
14797 // | | |__ | | | | | | version 3.11.3
14798 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14799 //
14800 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
14801 // SPDX-License-Identifier: MIT
14802 
14803 
14804 
14805 #include <initializer_list>
14806 #include <utility>
14807 
14808 // #include <nlohmann/detail/abi_macros.hpp>
14809 
14810 // #include <nlohmann/detail/meta/type_traits.hpp>
14811 
14812 
14814 namespace detail
14815 {
14816 
14817  template<typename BasicJsonType>
14818  class json_ref
14819  {
14820  public:
14821  using value_type = BasicJsonType;
14822 
14824  : owned_value(std::move(value))
14825  {}
14826 
14827  json_ref(const value_type& value)
14828  : value_ref(&value)
14829  {}
14830 
14831  json_ref(std::initializer_list<json_ref> init)
14832  : owned_value(init)
14833  {}
14834 
14835  template <
14836  class... Args,
14837  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
14838  json_ref(Args && ... args)
14839  : owned_value(std::forward<Args>(args)...)
14840  {}
14841 
14842  // class should be movable only
14843  json_ref(json_ref&&) noexcept = default;
14844  json_ref(const json_ref&) = delete;
14845  json_ref& operator=(const json_ref&) = delete;
14846  json_ref& operator=(json_ref&&) = delete;
14847  ~json_ref() = default;
14848 
14850  {
14851  if (value_ref == nullptr)
14852  {
14853  return std::move(owned_value);
14854  }
14855  return *value_ref;
14856  }
14857 
14858  value_type const& operator*() const
14859  {
14860  return value_ref ? *value_ref : owned_value;
14861  }
14862 
14863  value_type const* operator->() const
14864  {
14865  return &**this;
14866  }
14867 
14868  private:
14869  mutable value_type owned_value = nullptr;
14870  value_type const* value_ref = nullptr;
14871  };
14872 
14873 } // namespace detail
14875 
14876 // #include <nlohmann/detail/macro_scope.hpp>
14877 
14878 // #include <nlohmann/detail/string_concat.hpp>
14879 
14880 // #include <nlohmann/detail/string_escape.hpp>
14881 
14882 // #include <nlohmann/detail/meta/cpp_future.hpp>
14883 
14884 // #include <nlohmann/detail/meta/type_traits.hpp>
14885 
14886 // #include <nlohmann/detail/output/binary_writer.hpp>
14887 // __ _____ _____ _____
14888 // __| | __| | | | JSON for Modern C++
14889 // | | |__ | | | | | | version 3.11.3
14890 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14891 //
14892 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
14893 // SPDX-License-Identifier: MIT
14894 
14895 
14896 
14897 #include <algorithm> // reverse
14898 #include <array> // array
14899 #include <map> // map
14900 #include <cmath> // isnan, isinf
14901 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
14902 #include <cstring> // memcpy
14903 #include <limits> // numeric_limits
14904 #include <string> // string
14905 #include <utility> // move
14906 #include <vector> // vector
14907 
14908 // #include <nlohmann/detail/input/binary_reader.hpp>
14909 
14910 // #include <nlohmann/detail/macro_scope.hpp>
14911 
14912 // #include <nlohmann/detail/output/output_adapters.hpp>
14913 // __ _____ _____ _____
14914 // __| | __| | | | JSON for Modern C++
14915 // | | |__ | | | | | | version 3.11.3
14916 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14917 //
14918 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
14919 // SPDX-License-Identifier: MIT
14920 
14921 
14922 
14923 #include <algorithm> // copy
14924 #include <cstddef> // size_t
14925 #include <iterator> // back_inserter
14926 #include <memory> // shared_ptr, make_shared
14927 #include <string> // basic_string
14928 #include <vector> // vector
14929 
14930 #ifndef JSON_NO_IO
14931 #include <ios> // streamsize
14932 #include <ostream> // basic_ostream
14933 #endif // JSON_NO_IO
14934 
14935 // #include <nlohmann/detail/macro_scope.hpp>
14936 
14937 
14939 namespace detail
14940 {
14941 
14943  template<typename CharType> struct output_adapter_protocol
14944  {
14945  virtual void write_character(CharType c) = 0;
14946  virtual void write_characters(const CharType* s, std::size_t length) = 0;
14947  virtual ~output_adapter_protocol() = default;
14948 
14952  output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
14953  output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
14954  };
14955 
14957  template<typename CharType>
14958  using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
14959 
14961  template<typename CharType, typename AllocatorType = std::allocator<CharType>>
14963  {
14964  public:
14965  explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
14966  : v(vec)
14967  {}
14968 
14969  void write_character(CharType c) override
14970  {
14971  v.push_back(c);
14972  }
14973 
14975  void write_characters(const CharType* s, std::size_t length) override
14976  {
14977  v.insert(v.end(), s, s + length);
14978  }
14979 
14980  private:
14981  std::vector<CharType, AllocatorType>& v;
14982  };
14983 
14984 #ifndef JSON_NO_IO
14986  template<typename CharType>
14988  {
14989  public:
14990  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
14991  : stream(s)
14992  {}
14993 
14994  void write_character(CharType c) override
14995  {
14996  stream.put(c);
14997  }
14998 
15000  void write_characters(const CharType* s, std::size_t length) override
15001  {
15002  stream.write(s, static_cast<std::streamsize>(length));
15003  }
15004 
15005  private:
15006  std::basic_ostream<CharType>& stream;
15007  };
15008 #endif // JSON_NO_IO
15009 
15011  template<typename CharType, typename StringType = std::basic_string<CharType>>
15013  {
15014  public:
15015  explicit output_string_adapter(StringType& s) noexcept
15016  : str(s)
15017  {}
15018 
15019  void write_character(CharType c) override
15020  {
15021  str.push_back(c);
15022  }
15023 
15025  void write_characters(const CharType* s, std::size_t length) override
15026  {
15027  str.append(s, length);
15028  }
15029 
15030  private:
15031  StringType& str;
15032  };
15033 
15034  template<typename CharType, typename StringType = std::basic_string<CharType>>
15036  {
15037  public:
15038  template<typename AllocatorType = std::allocator<CharType>>
15039  output_adapter(std::vector<CharType, AllocatorType>& vec)
15040  : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
15041 
15042 #ifndef JSON_NO_IO
15043  output_adapter(std::basic_ostream<CharType>& s)
15044  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
15045 #endif // JSON_NO_IO
15046 
15047  output_adapter(StringType& s)
15048  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
15049 
15051  {
15052  return oa;
15053  }
15054 
15055  private:
15056  output_adapter_t<CharType> oa = nullptr;
15057  };
15058 
15059 } // namespace detail
15061 
15062 // #include <nlohmann/detail/string_concat.hpp>
15063 
15064 
15066 namespace detail
15067 {
15068 
15070  // binary writer //
15072 
15076  template<typename BasicJsonType, typename CharType>
15078  {
15079  using string_t = typename BasicJsonType::string_t;
15080  using binary_t = typename BasicJsonType::binary_t;
15081  using number_float_t = typename BasicJsonType::number_float_t;
15082 
15083  public:
15089  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
15090  {
15091  JSON_ASSERT(oa);
15092  }
15093 
15098  void write_bson(const BasicJsonType& j)
15099  {
15100  switch (j.type())
15101  {
15102  case value_t::object:
15103  {
15104  write_bson_object(*j.m_data.m_value.object);
15105  break;
15106  }
15107 
15108  case value_t::null:
15109  case value_t::array:
15110  case value_t::string:
15111  case value_t::boolean:
15112  case value_t::number_integer:
15113  case value_t::number_unsigned:
15114  case value_t::number_float:
15115  case value_t::binary:
15116  case value_t::discarded:
15117  default:
15118  {
15119  JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
15120  }
15121  }
15122  }
15123 
15127  void write_cbor(const BasicJsonType& j)
15128  {
15129  switch (j.type())
15130  {
15131  case value_t::null:
15132  {
15133  oa->write_character(to_char_type(0xF6));
15134  break;
15135  }
15136 
15137  case value_t::boolean:
15138  {
15139  oa->write_character(j.m_data.m_value.boolean
15140  ? to_char_type(0xF5)
15141  : to_char_type(0xF4));
15142  break;
15143  }
15144 
15145  case value_t::number_integer:
15146  {
15147  if (j.m_data.m_value.number_integer >= 0)
15148  {
15149  // CBOR does not differentiate between positive signed
15150  // integers and unsigned integers. Therefore, we used the
15151  // code from the value_t::number_unsigned case here.
15152  if (j.m_data.m_value.number_integer <= 0x17)
15153  {
15154  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15155  }
15156  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15157  {
15158  oa->write_character(to_char_type(0x18));
15159  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15160  }
15161  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
15162  {
15163  oa->write_character(to_char_type(0x19));
15164  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15165  }
15166  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
15167  {
15168  oa->write_character(to_char_type(0x1A));
15169  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15170  }
15171  else
15172  {
15173  oa->write_character(to_char_type(0x1B));
15174  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15175  }
15176  }
15177  else
15178  {
15179  // The conversions below encode the sign in the first
15180  // byte, and the value is converted to a positive number.
15181  const auto positive_number = -1 - j.m_data.m_value.number_integer;
15182  if (j.m_data.m_value.number_integer >= -24)
15183  {
15184  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
15185  }
15186  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
15187  {
15188  oa->write_character(to_char_type(0x38));
15189  write_number(static_cast<std::uint8_t>(positive_number));
15190  }
15191  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
15192  {
15193  oa->write_character(to_char_type(0x39));
15194  write_number(static_cast<std::uint16_t>(positive_number));
15195  }
15196  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
15197  {
15198  oa->write_character(to_char_type(0x3A));
15199  write_number(static_cast<std::uint32_t>(positive_number));
15200  }
15201  else
15202  {
15203  oa->write_character(to_char_type(0x3B));
15204  write_number(static_cast<std::uint64_t>(positive_number));
15205  }
15206  }
15207  break;
15208  }
15209 
15210  case value_t::number_unsigned:
15211  {
15212  if (j.m_data.m_value.number_unsigned <= 0x17)
15213  {
15214  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15215  }
15216  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15217  {
15218  oa->write_character(to_char_type(0x18));
15219  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15220  }
15221  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15222  {
15223  oa->write_character(to_char_type(0x19));
15224  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
15225  }
15226  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15227  {
15228  oa->write_character(to_char_type(0x1A));
15229  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
15230  }
15231  else
15232  {
15233  oa->write_character(to_char_type(0x1B));
15234  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
15235  }
15236  break;
15237  }
15238 
15239  case value_t::number_float:
15240  {
15241  if (std::isnan(j.m_data.m_value.number_float))
15242  {
15243  // NaN is 0xf97e00 in CBOR
15244  oa->write_character(to_char_type(0xF9));
15245  oa->write_character(to_char_type(0x7E));
15246  oa->write_character(to_char_type(0x00));
15247  }
15248  else if (std::isinf(j.m_data.m_value.number_float))
15249  {
15250  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
15251  oa->write_character(to_char_type(0xf9));
15252  oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
15253  oa->write_character(to_char_type(0x00));
15254  }
15255  else
15256  {
15257  write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::cbor);
15258  }
15259  break;
15260  }
15261 
15262  case value_t::string:
15263  {
15264  // step 1: write control byte and the string length
15265  const auto N = j.m_data.m_value.string->size();
15266  if (N <= 0x17)
15267  {
15268  write_number(static_cast<std::uint8_t>(0x60 + N));
15269  }
15270  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15271  {
15272  oa->write_character(to_char_type(0x78));
15273  write_number(static_cast<std::uint8_t>(N));
15274  }
15275  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15276  {
15277  oa->write_character(to_char_type(0x79));
15278  write_number(static_cast<std::uint16_t>(N));
15279  }
15280  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15281  {
15282  oa->write_character(to_char_type(0x7A));
15283  write_number(static_cast<std::uint32_t>(N));
15284  }
15285  // LCOV_EXCL_START
15286  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15287  {
15288  oa->write_character(to_char_type(0x7B));
15289  write_number(static_cast<std::uint64_t>(N));
15290  }
15291  // LCOV_EXCL_STOP
15292 
15293  // step 2: write the string
15294  oa->write_characters(
15295  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15296  j.m_data.m_value.string->size());
15297  break;
15298  }
15299 
15300  case value_t::array:
15301  {
15302  // step 1: write control byte and the array size
15303  const auto N = j.m_data.m_value.array->size();
15304  if (N <= 0x17)
15305  {
15306  write_number(static_cast<std::uint8_t>(0x80 + N));
15307  }
15308  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15309  {
15310  oa->write_character(to_char_type(0x98));
15311  write_number(static_cast<std::uint8_t>(N));
15312  }
15313  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15314  {
15315  oa->write_character(to_char_type(0x99));
15316  write_number(static_cast<std::uint16_t>(N));
15317  }
15318  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15319  {
15320  oa->write_character(to_char_type(0x9A));
15321  write_number(static_cast<std::uint32_t>(N));
15322  }
15323  // LCOV_EXCL_START
15324  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15325  {
15326  oa->write_character(to_char_type(0x9B));
15327  write_number(static_cast<std::uint64_t>(N));
15328  }
15329  // LCOV_EXCL_STOP
15330 
15331  // step 2: write each element
15332  for (const auto& el : *j.m_data.m_value.array)
15333  {
15334  write_cbor(el);
15335  }
15336  break;
15337  }
15338 
15339  case value_t::binary:
15340  {
15341  if (j.m_data.m_value.binary->has_subtype())
15342  {
15343  if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
15344  {
15345  write_number(static_cast<std::uint8_t>(0xd8));
15346  write_number(static_cast<std::uint8_t>(j.m_data.m_value.binary->subtype()));
15347  }
15348  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
15349  {
15350  write_number(static_cast<std::uint8_t>(0xd9));
15351  write_number(static_cast<std::uint16_t>(j.m_data.m_value.binary->subtype()));
15352  }
15353  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
15354  {
15355  write_number(static_cast<std::uint8_t>(0xda));
15356  write_number(static_cast<std::uint32_t>(j.m_data.m_value.binary->subtype()));
15357  }
15358  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
15359  {
15360  write_number(static_cast<std::uint8_t>(0xdb));
15361  write_number(static_cast<std::uint64_t>(j.m_data.m_value.binary->subtype()));
15362  }
15363  }
15364 
15365  // step 1: write control byte and the binary array size
15366  const auto N = j.m_data.m_value.binary->size();
15367  if (N <= 0x17)
15368  {
15369  write_number(static_cast<std::uint8_t>(0x40 + N));
15370  }
15371  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15372  {
15373  oa->write_character(to_char_type(0x58));
15374  write_number(static_cast<std::uint8_t>(N));
15375  }
15376  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15377  {
15378  oa->write_character(to_char_type(0x59));
15379  write_number(static_cast<std::uint16_t>(N));
15380  }
15381  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15382  {
15383  oa->write_character(to_char_type(0x5A));
15384  write_number(static_cast<std::uint32_t>(N));
15385  }
15386  // LCOV_EXCL_START
15387  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15388  {
15389  oa->write_character(to_char_type(0x5B));
15390  write_number(static_cast<std::uint64_t>(N));
15391  }
15392  // LCOV_EXCL_STOP
15393 
15394  // step 2: write each element
15395  oa->write_characters(
15396  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15397  N);
15398 
15399  break;
15400  }
15401 
15402  case value_t::object:
15403  {
15404  // step 1: write control byte and the object size
15405  const auto N = j.m_data.m_value.object->size();
15406  if (N <= 0x17)
15407  {
15408  write_number(static_cast<std::uint8_t>(0xA0 + N));
15409  }
15410  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15411  {
15412  oa->write_character(to_char_type(0xB8));
15413  write_number(static_cast<std::uint8_t>(N));
15414  }
15415  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15416  {
15417  oa->write_character(to_char_type(0xB9));
15418  write_number(static_cast<std::uint16_t>(N));
15419  }
15420  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15421  {
15422  oa->write_character(to_char_type(0xBA));
15423  write_number(static_cast<std::uint32_t>(N));
15424  }
15425  // LCOV_EXCL_START
15426  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15427  {
15428  oa->write_character(to_char_type(0xBB));
15429  write_number(static_cast<std::uint64_t>(N));
15430  }
15431  // LCOV_EXCL_STOP
15432 
15433  // step 2: write each element
15434  for (const auto& el : *j.m_data.m_value.object)
15435  {
15436  write_cbor(el.first);
15437  write_cbor(el.second);
15438  }
15439  break;
15440  }
15441 
15442  case value_t::discarded:
15443  default:
15444  break;
15445  }
15446  }
15447 
15451  void write_msgpack(const BasicJsonType& j)
15452  {
15453  switch (j.type())
15454  {
15455  case value_t::null: // nil
15456  {
15457  oa->write_character(to_char_type(0xC0));
15458  break;
15459  }
15460 
15461  case value_t::boolean: // true and false
15462  {
15463  oa->write_character(j.m_data.m_value.boolean
15464  ? to_char_type(0xC3)
15465  : to_char_type(0xC2));
15466  break;
15467  }
15468 
15469  case value_t::number_integer:
15470  {
15471  if (j.m_data.m_value.number_integer >= 0)
15472  {
15473  // MessagePack does not differentiate between positive
15474  // signed integers and unsigned integers. Therefore, we used
15475  // the code from the value_t::number_unsigned case here.
15476  if (j.m_data.m_value.number_unsigned < 128)
15477  {
15478  // positive fixnum
15479  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15480  }
15481  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15482  {
15483  // uint 8
15484  oa->write_character(to_char_type(0xCC));
15485  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15486  }
15487  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15488  {
15489  // uint 16
15490  oa->write_character(to_char_type(0xCD));
15491  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15492  }
15493  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15494  {
15495  // uint 32
15496  oa->write_character(to_char_type(0xCE));
15497  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15498  }
15499  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15500  {
15501  // uint 64
15502  oa->write_character(to_char_type(0xCF));
15503  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15504  }
15505  }
15506  else
15507  {
15508  if (j.m_data.m_value.number_integer >= -32)
15509  {
15510  // negative fixnum
15511  write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
15512  }
15513  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
15514  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15515  {
15516  // int 8
15517  oa->write_character(to_char_type(0xD0));
15518  write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
15519  }
15520  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
15521  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15522  {
15523  // int 16
15524  oa->write_character(to_char_type(0xD1));
15525  write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));
15526  }
15527  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
15528  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15529  {
15530  // int 32
15531  oa->write_character(to_char_type(0xD2));
15532  write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));
15533  }
15534  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
15535  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15536  {
15537  // int 64
15538  oa->write_character(to_char_type(0xD3));
15539  write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
15540  }
15541  }
15542  break;
15543  }
15544 
15545  case value_t::number_unsigned:
15546  {
15547  if (j.m_data.m_value.number_unsigned < 128)
15548  {
15549  // positive fixnum
15550  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15551  }
15552  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15553  {
15554  // uint 8
15555  oa->write_character(to_char_type(0xCC));
15556  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15557  }
15558  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15559  {
15560  // uint 16
15561  oa->write_character(to_char_type(0xCD));
15562  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15563  }
15564  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15565  {
15566  // uint 32
15567  oa->write_character(to_char_type(0xCE));
15568  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15569  }
15570  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15571  {
15572  // uint 64
15573  oa->write_character(to_char_type(0xCF));
15574  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15575  }
15576  break;
15577  }
15578 
15579  case value_t::number_float:
15580  {
15581  write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::msgpack);
15582  break;
15583  }
15584 
15585  case value_t::string:
15586  {
15587  // step 1: write control byte and the string length
15588  const auto N = j.m_data.m_value.string->size();
15589  if (N <= 31)
15590  {
15591  // fixstr
15592  write_number(static_cast<std::uint8_t>(0xA0 | N));
15593  }
15594  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15595  {
15596  // str 8
15597  oa->write_character(to_char_type(0xD9));
15598  write_number(static_cast<std::uint8_t>(N));
15599  }
15600  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15601  {
15602  // str 16
15603  oa->write_character(to_char_type(0xDA));
15604  write_number(static_cast<std::uint16_t>(N));
15605  }
15606  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15607  {
15608  // str 32
15609  oa->write_character(to_char_type(0xDB));
15610  write_number(static_cast<std::uint32_t>(N));
15611  }
15612 
15613  // step 2: write the string
15614  oa->write_characters(
15615  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15616  j.m_data.m_value.string->size());
15617  break;
15618  }
15619 
15620  case value_t::array:
15621  {
15622  // step 1: write control byte and the array size
15623  const auto N = j.m_data.m_value.array->size();
15624  if (N <= 15)
15625  {
15626  // fixarray
15627  write_number(static_cast<std::uint8_t>(0x90 | N));
15628  }
15629  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15630  {
15631  // array 16
15632  oa->write_character(to_char_type(0xDC));
15633  write_number(static_cast<std::uint16_t>(N));
15634  }
15635  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15636  {
15637  // array 32
15638  oa->write_character(to_char_type(0xDD));
15639  write_number(static_cast<std::uint32_t>(N));
15640  }
15641 
15642  // step 2: write each element
15643  for (const auto& el : *j.m_data.m_value.array)
15644  {
15645  write_msgpack(el);
15646  }
15647  break;
15648  }
15649 
15650  case value_t::binary:
15651  {
15652  // step 0: determine if the binary type has a set subtype to
15653  // determine whether or not to use the ext or fixext types
15654  const bool use_ext = j.m_data.m_value.binary->has_subtype();
15655 
15656  // step 1: write control byte and the byte string length
15657  const auto N = j.m_data.m_value.binary->size();
15658  if (N <= (std::numeric_limits<std::uint8_t>::max)())
15659  {
15660  std::uint8_t output_type{};
15661  bool fixed = true;
15662  if (use_ext)
15663  {
15664  switch (N)
15665  {
15666  case 1:
15667  output_type = 0xD4; // fixext 1
15668  break;
15669  case 2:
15670  output_type = 0xD5; // fixext 2
15671  break;
15672  case 4:
15673  output_type = 0xD6; // fixext 4
15674  break;
15675  case 8:
15676  output_type = 0xD7; // fixext 8
15677  break;
15678  case 16:
15679  output_type = 0xD8; // fixext 16
15680  break;
15681  default:
15682  output_type = 0xC7; // ext 8
15683  fixed = false;
15684  break;
15685  }
15686 
15687  }
15688  else
15689  {
15690  output_type = 0xC4; // bin 8
15691  fixed = false;
15692  }
15693 
15694  oa->write_character(to_char_type(output_type));
15695  if (!fixed)
15696  {
15697  write_number(static_cast<std::uint8_t>(N));
15698  }
15699  }
15700  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15701  {
15702  const std::uint8_t output_type = use_ext
15703  ? 0xC8 // ext 16
15704  : 0xC5; // bin 16
15705 
15706  oa->write_character(to_char_type(output_type));
15707  write_number(static_cast<std::uint16_t>(N));
15708  }
15709  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15710  {
15711  const std::uint8_t output_type = use_ext
15712  ? 0xC9 // ext 32
15713  : 0xC6; // bin 32
15714 
15715  oa->write_character(to_char_type(output_type));
15716  write_number(static_cast<std::uint32_t>(N));
15717  }
15718 
15719  // step 1.5: if this is an ext type, write the subtype
15720  if (use_ext)
15721  {
15722  write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));
15723  }
15724 
15725  // step 2: write the byte string
15726  oa->write_characters(
15727  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15728  N);
15729 
15730  break;
15731  }
15732 
15733  case value_t::object:
15734  {
15735  // step 1: write control byte and the object size
15736  const auto N = j.m_data.m_value.object->size();
15737  if (N <= 15)
15738  {
15739  // fixmap
15740  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
15741  }
15742  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15743  {
15744  // map 16
15745  oa->write_character(to_char_type(0xDE));
15746  write_number(static_cast<std::uint16_t>(N));
15747  }
15748  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15749  {
15750  // map 32
15751  oa->write_character(to_char_type(0xDF));
15752  write_number(static_cast<std::uint32_t>(N));
15753  }
15754 
15755  // step 2: write each element
15756  for (const auto& el : *j.m_data.m_value.object)
15757  {
15758  write_msgpack(el.first);
15759  write_msgpack(el.second);
15760  }
15761  break;
15762  }
15763 
15764  case value_t::discarded:
15765  default:
15766  break;
15767  }
15768  }
15769 
15777  void write_ubjson(const BasicJsonType& j, const bool use_count,
15778  const bool use_type, const bool add_prefix = true,
15779  const bool use_bjdata = false)
15780  {
15781  switch (j.type())
15782  {
15783  case value_t::null:
15784  {
15785  if (add_prefix)
15786  {
15787  oa->write_character(to_char_type('Z'));
15788  }
15789  break;
15790  }
15791 
15792  case value_t::boolean:
15793  {
15794  if (add_prefix)
15795  {
15796  oa->write_character(j.m_data.m_value.boolean
15797  ? to_char_type('T')
15798  : to_char_type('F'));
15799  }
15800  break;
15801  }
15802 
15803  case value_t::number_integer:
15804  {
15805  write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);
15806  break;
15807  }
15808 
15809  case value_t::number_unsigned:
15810  {
15811  write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);
15812  break;
15813  }
15814 
15815  case value_t::number_float:
15816  {
15817  write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);
15818  break;
15819  }
15820 
15821  case value_t::string:
15822  {
15823  if (add_prefix)
15824  {
15825  oa->write_character(to_char_type('S'));
15826  }
15827  write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
15828  oa->write_characters(
15829  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15830  j.m_data.m_value.string->size());
15831  break;
15832  }
15833 
15834  case value_t::array:
15835  {
15836  if (add_prefix)
15837  {
15838  oa->write_character(to_char_type('['));
15839  }
15840 
15841  bool prefix_required = true;
15842  if (use_type && !j.m_data.m_value.array->empty())
15843  {
15844  JSON_ASSERT(use_count);
15845  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15846  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
15847  [this, first_prefix, use_bjdata](const BasicJsonType& v)
15848  {
15849  return ubjson_prefix(v, use_bjdata) == first_prefix;
15850  });
15851 
15852  std::vector<CharType> bjdx = { '[', '{', 'S', 'H', 'T', 'F', 'N', 'Z' }; // excluded markers in bjdata optimized type
15853 
15854  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15855  {
15856  prefix_required = false;
15857  oa->write_character(to_char_type('$'));
15858  oa->write_character(first_prefix);
15859  }
15860  }
15861 
15862  if (use_count)
15863  {
15864  oa->write_character(to_char_type('#'));
15865  write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
15866  }
15867 
15868  for (const auto& el : *j.m_data.m_value.array)
15869  {
15870  write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
15871  }
15872 
15873  if (!use_count)
15874  {
15875  oa->write_character(to_char_type(']'));
15876  }
15877 
15878  break;
15879  }
15880 
15881  case value_t::binary:
15882  {
15883  if (add_prefix)
15884  {
15885  oa->write_character(to_char_type('['));
15886  }
15887 
15888  if (use_type && !j.m_data.m_value.binary->empty())
15889  {
15890  JSON_ASSERT(use_count);
15891  oa->write_character(to_char_type('$'));
15892  oa->write_character('U');
15893  }
15894 
15895  if (use_count)
15896  {
15897  oa->write_character(to_char_type('#'));
15898  write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);
15899  }
15900 
15901  if (use_type)
15902  {
15903  oa->write_characters(
15904  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15905  j.m_data.m_value.binary->size());
15906  }
15907  else
15908  {
15909  for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
15910  {
15911  oa->write_character(to_char_type('U'));
15912  oa->write_character(j.m_data.m_value.binary->data()[i]);
15913  }
15914  }
15915 
15916  if (!use_count)
15917  {
15918  oa->write_character(to_char_type(']'));
15919  }
15920 
15921  break;
15922  }
15923 
15924  case value_t::object:
15925  {
15926  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())
15927  {
15928  if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
15929  {
15930  break;
15931  }
15932  }
15933 
15934  if (add_prefix)
15935  {
15936  oa->write_character(to_char_type('{'));
15937  }
15938 
15939  bool prefix_required = true;
15940  if (use_type && !j.m_data.m_value.object->empty())
15941  {
15942  JSON_ASSERT(use_count);
15943  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15944  const bool same_prefix = std::all_of(j.begin(), j.end(),
15945  [this, first_prefix, use_bjdata](const BasicJsonType& v)
15946  {
15947  return ubjson_prefix(v, use_bjdata) == first_prefix;
15948  });
15949 
15950  std::vector<CharType> bjdx = { '[', '{', 'S', 'H', 'T', 'F', 'N', 'Z' }; // excluded markers in bjdata optimized type
15951 
15952  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15953  {
15954  prefix_required = false;
15955  oa->write_character(to_char_type('$'));
15956  oa->write_character(first_prefix);
15957  }
15958  }
15959 
15960  if (use_count)
15961  {
15962  oa->write_character(to_char_type('#'));
15963  write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
15964  }
15965 
15966  for (const auto& el : *j.m_data.m_value.object)
15967  {
15968  write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
15969  oa->write_characters(
15970  reinterpret_cast<const CharType*>(el.first.c_str()),
15971  el.first.size());
15972  write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
15973  }
15974 
15975  if (!use_count)
15976  {
15977  oa->write_character(to_char_type('}'));
15978  }
15979 
15980  break;
15981  }
15982 
15983  case value_t::discarded:
15984  default:
15985  break;
15986  }
15987  }
15988 
15989  private:
15991  // BSON //
15993 
15998  static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
15999  {
16000  const auto it = name.find(static_cast<typename string_t::value_type>(0));
16001  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
16002  {
16003  JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
16004  static_cast<void>(j);
16005  }
16006 
16007  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
16008  }
16009 
16013  void write_bson_entry_header(const string_t& name,
16014  const std::uint8_t element_type)
16015  {
16016  oa->write_character(to_char_type(element_type)); // boolean
16017  oa->write_characters(
16018  reinterpret_cast<const CharType*>(name.c_str()),
16019  name.size() + 1u);
16020  }
16021 
16025  void write_bson_boolean(const string_t& name,
16026  const bool value)
16027  {
16028  write_bson_entry_header(name, 0x08);
16029  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
16030  }
16031 
16035  void write_bson_double(const string_t& name,
16036  const double value)
16037  {
16038  write_bson_entry_header(name, 0x01);
16039  write_number<double>(value, true);
16040  }
16041 
16045  static std::size_t calc_bson_string_size(const string_t& value)
16046  {
16047  return sizeof(std::int32_t) + value.size() + 1ul;
16048  }
16049 
16053  void write_bson_string(const string_t& name,
16054  const string_t& value)
16055  {
16056  write_bson_entry_header(name, 0x02);
16057 
16058  write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
16059  oa->write_characters(
16060  reinterpret_cast<const CharType*>(value.c_str()),
16061  value.size() + 1);
16062  }
16063 
16067  void write_bson_null(const string_t& name)
16068  {
16069  write_bson_entry_header(name, 0x0A);
16070  }
16071 
16075  static std::size_t calc_bson_integer_size(const std::int64_t value)
16076  {
16077  return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
16078  ? sizeof(std::int32_t)
16079  : sizeof(std::int64_t);
16080  }
16081 
16085  void write_bson_integer(const string_t& name,
16086  const std::int64_t value)
16087  {
16088  if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
16089  {
16090  write_bson_entry_header(name, 0x10); // int32
16091  write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
16092  }
16093  else
16094  {
16095  write_bson_entry_header(name, 0x12); // int64
16096  write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
16097  }
16098  }
16099 
16103  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
16104  {
16105  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16106  ? sizeof(std::int32_t)
16107  : sizeof(std::int64_t);
16108  }
16109 
16113  void write_bson_unsigned(const string_t& name,
16114  const BasicJsonType& j)
16115  {
16116  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16117  {
16118  write_bson_entry_header(name, 0x10 /* int32 */);
16119  write_number<std::int32_t>(static_cast<std::int32_t>(j.m_data.m_value.number_unsigned), true);
16120  }
16121  else if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16122  {
16123  write_bson_entry_header(name, 0x12 /* int64 */);
16124  write_number<std::int64_t>(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned), true);
16125  }
16126  else
16127  {
16128  JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
16129  }
16130  }
16131 
16135  void write_bson_object_entry(const string_t& name,
16136  const typename BasicJsonType::object_t& value)
16137  {
16138  write_bson_entry_header(name, 0x03); // object
16139  write_bson_object(value);
16140  }
16141 
16145  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
16146  {
16147  std::size_t array_index = 0ul;
16148 
16149  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)
16150  {
16151  return result + calc_bson_element_size(std::to_string(array_index++), el);
16152  });
16153 
16154  return sizeof(std::int32_t) + embedded_document_size + 1ul;
16155  }
16156 
16160  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
16161  {
16162  return sizeof(std::int32_t) + value.size() + 1ul;
16163  }
16164 
16168  void write_bson_array(const string_t& name,
16169  const typename BasicJsonType::array_t& value)
16170  {
16171  write_bson_entry_header(name, 0x04); // array
16172  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
16173 
16174  std::size_t array_index = 0ul;
16175 
16176  for (const auto& el : value)
16177  {
16178  write_bson_element(std::to_string(array_index++), el);
16179  }
16180 
16181  oa->write_character(to_char_type(0x00));
16182  }
16183 
16187  void write_bson_binary(const string_t& name,
16188  const binary_t& value)
16189  {
16190  write_bson_entry_header(name, 0x05);
16191 
16192  write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
16193  write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
16194 
16195  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
16196  }
16197 
16202  static std::size_t calc_bson_element_size(const string_t& name,
16203  const BasicJsonType& j)
16204  {
16205  const auto header_size = calc_bson_entry_header_size(name, j);
16206  switch (j.type())
16207  {
16208  case value_t::object:
16209  return header_size + calc_bson_object_size(*j.m_data.m_value.object);
16210 
16211  case value_t::array:
16212  return header_size + calc_bson_array_size(*j.m_data.m_value.array);
16213 
16214  case value_t::binary:
16215  return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);
16216 
16217  case value_t::boolean:
16218  return header_size + 1ul;
16219 
16220  case value_t::number_float:
16221  return header_size + 8ul;
16222 
16223  case value_t::number_integer:
16224  return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);
16225 
16226  case value_t::number_unsigned:
16227  return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);
16228 
16229  case value_t::string:
16230  return header_size + calc_bson_string_size(*j.m_data.m_value.string);
16231 
16232  case value_t::null:
16233  return header_size + 0ul;
16234 
16235  // LCOV_EXCL_START
16236  case value_t::discarded:
16237  default:
16238  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16239  return 0ul;
16240  // LCOV_EXCL_STOP
16241  }
16242  }
16243 
16250  void write_bson_element(const string_t& name,
16251  const BasicJsonType& j)
16252  {
16253  switch (j.type())
16254  {
16255  case value_t::object:
16256  return write_bson_object_entry(name, *j.m_data.m_value.object);
16257 
16258  case value_t::array:
16259  return write_bson_array(name, *j.m_data.m_value.array);
16260 
16261  case value_t::binary:
16262  return write_bson_binary(name, *j.m_data.m_value.binary);
16263 
16264  case value_t::boolean:
16265  return write_bson_boolean(name, j.m_data.m_value.boolean);
16266 
16267  case value_t::number_float:
16268  return write_bson_double(name, j.m_data.m_value.number_float);
16269 
16270  case value_t::number_integer:
16271  return write_bson_integer(name, j.m_data.m_value.number_integer);
16272 
16273  case value_t::number_unsigned:
16274  return write_bson_unsigned(name, j);
16275 
16276  case value_t::string:
16277  return write_bson_string(name, *j.m_data.m_value.string);
16278 
16279  case value_t::null:
16280  return write_bson_null(name);
16281 
16282  // LCOV_EXCL_START
16283  case value_t::discarded:
16284  default:
16285  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16286  return;
16287  // LCOV_EXCL_STOP
16288  }
16289  }
16290 
16297  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
16298  {
16299  const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
16300  [](size_t result, const typename BasicJsonType::object_t::value_type& el)
16301  {
16302  return result += calc_bson_element_size(el.first, el.second);
16303  });
16304 
16305  return sizeof(std::int32_t) + document_size + 1ul;
16306  }
16307 
16312  void write_bson_object(const typename BasicJsonType::object_t& value)
16313  {
16314  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
16315 
16316  for (const auto& el : value)
16317  {
16318  write_bson_element(el.first, el.second);
16319  }
16320 
16321  oa->write_character(to_char_type(0x00));
16322  }
16323 
16325  // CBOR //
16327 
16328  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
16329  {
16330  return to_char_type(0xFA); // Single-Precision Float
16331  }
16332 
16333  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
16334  {
16335  return to_char_type(0xFB); // Double-Precision Float
16336  }
16337 
16339  // MsgPack //
16341 
16342  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
16343  {
16344  return to_char_type(0xCA); // float 32
16345  }
16346 
16347  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
16348  {
16349  return to_char_type(0xCB); // float 64
16350  }
16351 
16353  // UBJSON //
16355 
16356  // UBJSON: write number (floating point)
16357  template<typename NumberType, typename std::enable_if<
16358  std::is_floating_point<NumberType>::value, int>::type = 0>
16359  void write_number_with_ubjson_prefix(const NumberType n,
16360  const bool add_prefix,
16361  const bool use_bjdata)
16362  {
16363  if (add_prefix)
16364  {
16365  oa->write_character(get_ubjson_float_prefix(n));
16366  }
16367  write_number(n, use_bjdata);
16368  }
16369 
16370  // UBJSON: write number (unsigned integer)
16371  template<typename NumberType, typename std::enable_if<
16372  std::is_unsigned<NumberType>::value, int>::type = 0>
16373  void write_number_with_ubjson_prefix(const NumberType n,
16374  const bool add_prefix,
16375  const bool use_bjdata)
16376  {
16377  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16378  {
16379  if (add_prefix)
16380  {
16381  oa->write_character(to_char_type('i')); // int8
16382  }
16383  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16384  }
16385  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
16386  {
16387  if (add_prefix)
16388  {
16389  oa->write_character(to_char_type('U')); // uint8
16390  }
16391  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16392  }
16393  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16394  {
16395  if (add_prefix)
16396  {
16397  oa->write_character(to_char_type('I')); // int16
16398  }
16399  write_number(static_cast<std::int16_t>(n), use_bjdata);
16400  }
16401  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
16402  {
16403  if (add_prefix)
16404  {
16405  oa->write_character(to_char_type('u')); // uint16 - bjdata only
16406  }
16407  write_number(static_cast<std::uint16_t>(n), use_bjdata);
16408  }
16409  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16410  {
16411  if (add_prefix)
16412  {
16413  oa->write_character(to_char_type('l')); // int32
16414  }
16415  write_number(static_cast<std::int32_t>(n), use_bjdata);
16416  }
16417  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
16418  {
16419  if (add_prefix)
16420  {
16421  oa->write_character(to_char_type('m')); // uint32 - bjdata only
16422  }
16423  write_number(static_cast<std::uint32_t>(n), use_bjdata);
16424  }
16425  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16426  {
16427  if (add_prefix)
16428  {
16429  oa->write_character(to_char_type('L')); // int64
16430  }
16431  write_number(static_cast<std::int64_t>(n), use_bjdata);
16432  }
16433  else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
16434  {
16435  if (add_prefix)
16436  {
16437  oa->write_character(to_char_type('M')); // uint64 - bjdata only
16438  }
16439  write_number(static_cast<std::uint64_t>(n), use_bjdata);
16440  }
16441  else
16442  {
16443  if (add_prefix)
16444  {
16445  oa->write_character(to_char_type('H')); // high-precision number
16446  }
16447 
16448  const auto number = BasicJsonType(n).dump();
16449  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16450  for (std::size_t i = 0; i < number.size(); ++i)
16451  {
16452  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16453  }
16454  }
16455  }
16456 
16457  // UBJSON: write number (signed integer)
16458  template < typename NumberType, typename std::enable_if <
16459  std::is_signed<NumberType>::value &&
16460  !std::is_floating_point<NumberType>::value, int >::type = 0 >
16461  void write_number_with_ubjson_prefix(const NumberType n,
16462  const bool add_prefix,
16463  const bool use_bjdata)
16464  {
16465  if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
16466  {
16467  if (add_prefix)
16468  {
16469  oa->write_character(to_char_type('i')); // int8
16470  }
16471  write_number(static_cast<std::int8_t>(n), use_bjdata);
16472  }
16473  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)()))
16474  {
16475  if (add_prefix)
16476  {
16477  oa->write_character(to_char_type('U')); // uint8
16478  }
16479  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16480  }
16481  else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
16482  {
16483  if (add_prefix)
16484  {
16485  oa->write_character(to_char_type('I')); // int16
16486  }
16487  write_number(static_cast<std::int16_t>(n), use_bjdata);
16488  }
16489  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)())))
16490  {
16491  if (add_prefix)
16492  {
16493  oa->write_character(to_char_type('u')); // uint16 - bjdata only
16494  }
16495  write_number(static_cast<uint16_t>(n), use_bjdata);
16496  }
16497  else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
16498  {
16499  if (add_prefix)
16500  {
16501  oa->write_character(to_char_type('l')); // int32
16502  }
16503  write_number(static_cast<std::int32_t>(n), use_bjdata);
16504  }
16505  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)())))
16506  {
16507  if (add_prefix)
16508  {
16509  oa->write_character(to_char_type('m')); // uint32 - bjdata only
16510  }
16511  write_number(static_cast<uint32_t>(n), use_bjdata);
16512  }
16513  else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
16514  {
16515  if (add_prefix)
16516  {
16517  oa->write_character(to_char_type('L')); // int64
16518  }
16519  write_number(static_cast<std::int64_t>(n), use_bjdata);
16520  }
16521  // LCOV_EXCL_START
16522  else
16523  {
16524  if (add_prefix)
16525  {
16526  oa->write_character(to_char_type('H')); // high-precision number
16527  }
16528 
16529  const auto number = BasicJsonType(n).dump();
16530  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16531  for (std::size_t i = 0; i < number.size(); ++i)
16532  {
16533  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16534  }
16535  }
16536  // LCOV_EXCL_STOP
16537  }
16538 
16542  CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
16543  {
16544  switch (j.type())
16545  {
16546  case value_t::null:
16547  return 'Z';
16548 
16549  case value_t::boolean:
16550  return j.m_data.m_value.boolean ? 'T' : 'F';
16551 
16552  case value_t::number_integer:
16553  {
16554  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)())
16555  {
16556  return 'i';
16557  }
16558  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)())
16559  {
16560  return 'U';
16561  }
16562  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)())
16563  {
16564  return 'I';
16565  }
16566  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)()))
16567  {
16568  return 'u';
16569  }
16570  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)())
16571  {
16572  return 'l';
16573  }
16574  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)()))
16575  {
16576  return 'm';
16577  }
16578  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)())
16579  {
16580  return 'L';
16581  }
16582  // anything else is treated as high-precision number
16583  return 'H'; // LCOV_EXCL_LINE
16584  }
16585 
16586  case value_t::number_unsigned:
16587  {
16588  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16589  {
16590  return 'i';
16591  }
16592  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
16593  {
16594  return 'U';
16595  }
16596  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16597  {
16598  return 'I';
16599  }
16600  if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
16601  {
16602  return 'u';
16603  }
16604  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16605  {
16606  return 'l';
16607  }
16608  if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
16609  {
16610  return 'm';
16611  }
16612  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16613  {
16614  return 'L';
16615  }
16616  if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16617  {
16618  return 'M';
16619  }
16620  // anything else is treated as high-precision number
16621  return 'H'; // LCOV_EXCL_LINE
16622  }
16623 
16624  case value_t::number_float:
16625  return get_ubjson_float_prefix(j.m_data.m_value.number_float);
16626 
16627  case value_t::string:
16628  return 'S';
16629 
16630  case value_t::array: // fallthrough
16631  case value_t::binary:
16632  return '[';
16633 
16634  case value_t::object:
16635  return '{';
16636 
16637  case value_t::discarded:
16638  default: // discarded values
16639  return 'N';
16640  }
16641  }
16642 
16643  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
16644  {
16645  return 'd'; // float 32
16646  }
16647 
16648  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
16649  {
16650  return 'D'; // float 64
16651  }
16652 
16656  bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
16657  {
16658  std::map<string_t, CharType> bjdtype = { {"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
16659  {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
16660  };
16661 
16662  string_t key = "_ArrayType_";
16663  auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
16664  if (it == bjdtype.end())
16665  {
16666  return true;
16667  }
16668  CharType dtype = it->second;
16669 
16670  key = "_ArraySize_";
16671  std::size_t len = (value.at(key).empty() ? 0 : 1);
16672  for (const auto& el : value.at(key))
16673  {
16674  len *= static_cast<std::size_t>(el.m_data.m_value.number_unsigned);
16675  }
16676 
16677  key = "_ArrayData_";
16678  if (value.at(key).size() != len)
16679  {
16680  return true;
16681  }
16682 
16683  oa->write_character('[');
16684  oa->write_character('$');
16685  oa->write_character(dtype);
16686  oa->write_character('#');
16687 
16688  key = "_ArraySize_";
16689  write_ubjson(value.at(key), use_count, use_type, true, true);
16690 
16691  key = "_ArrayData_";
16692  if (dtype == 'U' || dtype == 'C')
16693  {
16694  for (const auto& el : value.at(key))
16695  {
16696  write_number(static_cast<std::uint8_t>(el.m_data.m_value.number_unsigned), true);
16697  }
16698  }
16699  else if (dtype == 'i')
16700  {
16701  for (const auto& el : value.at(key))
16702  {
16703  write_number(static_cast<std::int8_t>(el.m_data.m_value.number_integer), true);
16704  }
16705  }
16706  else if (dtype == 'u')
16707  {
16708  for (const auto& el : value.at(key))
16709  {
16710  write_number(static_cast<std::uint16_t>(el.m_data.m_value.number_unsigned), true);
16711  }
16712  }
16713  else if (dtype == 'I')
16714  {
16715  for (const auto& el : value.at(key))
16716  {
16717  write_number(static_cast<std::int16_t>(el.m_data.m_value.number_integer), true);
16718  }
16719  }
16720  else if (dtype == 'm')
16721  {
16722  for (const auto& el : value.at(key))
16723  {
16724  write_number(static_cast<std::uint32_t>(el.m_data.m_value.number_unsigned), true);
16725  }
16726  }
16727  else if (dtype == 'l')
16728  {
16729  for (const auto& el : value.at(key))
16730  {
16731  write_number(static_cast<std::int32_t>(el.m_data.m_value.number_integer), true);
16732  }
16733  }
16734  else if (dtype == 'M')
16735  {
16736  for (const auto& el : value.at(key))
16737  {
16738  write_number(static_cast<std::uint64_t>(el.m_data.m_value.number_unsigned), true);
16739  }
16740  }
16741  else if (dtype == 'L')
16742  {
16743  for (const auto& el : value.at(key))
16744  {
16745  write_number(static_cast<std::int64_t>(el.m_data.m_value.number_integer), true);
16746  }
16747  }
16748  else if (dtype == 'd')
16749  {
16750  for (const auto& el : value.at(key))
16751  {
16752  write_number(static_cast<float>(el.m_data.m_value.number_float), true);
16753  }
16754  }
16755  else if (dtype == 'D')
16756  {
16757  for (const auto& el : value.at(key))
16758  {
16759  write_number(static_cast<double>(el.m_data.m_value.number_float), true);
16760  }
16761  }
16762  return false;
16763  }
16764 
16766  // Utility functions //
16768 
16769  /*
16770  @brief write a number to output input
16771  @param[in] n number of type @a NumberType
16772  @param[in] OutputIsLittleEndian Set to true if output data is
16773  required to be little endian
16774  @tparam NumberType the type of the number
16775 
16776  @note This function needs to respect the system's endianness, because bytes
16777  in CBOR, MessagePack, and UBJSON are stored in network order (big
16778  endian) and therefore need reordering on little endian systems.
16779  On the other hand, BSON and BJData use little endian and should reorder
16780  on big endian systems.
16781  */
16782  template<typename NumberType>
16783  void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
16784  {
16785  // step 1: write number to array of length NumberType
16786  std::array<CharType, sizeof(NumberType)> vec{};
16787  std::memcpy(vec.data(), &n, sizeof(NumberType));
16788 
16789  // step 2: write array to output (with possible reordering)
16790  if (is_little_endian != OutputIsLittleEndian)
16791  {
16792  // reverse byte order prior to conversion if necessary
16793  std::reverse(vec.begin(), vec.end());
16794  }
16795 
16796  oa->write_characters(vec.data(), sizeof(NumberType));
16797  }
16798 
16799  void write_compact_float(const number_float_t n, detail::input_format_t format)
16800  {
16801 #ifdef __GNUC__
16802 #pragma GCC diagnostic push
16803 #pragma GCC diagnostic ignored "-Wfloat-equal"
16804 #endif
16805  if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
16806  static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
16807  static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
16808  {
16809  oa->write_character(format == detail::input_format_t::cbor
16810  ? get_cbor_float_prefix(static_cast<float>(n))
16811  : get_msgpack_float_prefix(static_cast<float>(n)));
16812  write_number(static_cast<float>(n));
16813  }
16814  else
16815  {
16816  oa->write_character(format == detail::input_format_t::cbor
16817  ? get_cbor_float_prefix(n)
16818  : get_msgpack_float_prefix(n));
16819  write_number(n);
16820  }
16821 #ifdef __GNUC__
16822 #pragma GCC diagnostic pop
16823 #endif
16824  }
16825 
16826  public:
16827  // The following to_char_type functions are implement the conversion
16828  // between uint8_t and CharType. In case CharType is not unsigned,
16829  // such a conversion is required to allow values greater than 128.
16830  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
16831  template < typename C = CharType,
16832  enable_if_t < std::is_signed<C>::value&& std::is_signed<char>::value >* = nullptr >
16833  static constexpr CharType to_char_type(std::uint8_t x) noexcept
16834  {
16835  return *reinterpret_cast<char*>(&x);
16836  }
16837 
16838  template < typename C = CharType,
16839  enable_if_t < std::is_signed<C>::value&& std::is_unsigned<char>::value >* = nullptr >
16840  static CharType to_char_type(std::uint8_t x) noexcept
16841  {
16842  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
16843  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
16844  CharType result;
16845  std::memcpy(&result, &x, sizeof(x));
16846  return result;
16847  }
16848 
16849  template<typename C = CharType,
16851  static constexpr CharType to_char_type(std::uint8_t x) noexcept
16852  {
16853  return x;
16854  }
16855 
16856  template < typename InputCharType, typename C = CharType,
16857  enable_if_t <
16858  std::is_signed<C>::value&&
16859  std::is_signed<char>::value&&
16860  std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
16861  >* = nullptr >
16862  static constexpr CharType to_char_type(InputCharType x) noexcept
16863  {
16864  return x;
16865  }
16866 
16867  private:
16869  const bool is_little_endian = little_endianness();
16870 
16872  output_adapter_t<CharType> oa = nullptr;
16873  };
16874 
16875 } // namespace detail
16877 
16878 // #include <nlohmann/detail/output/output_adapters.hpp>
16879 
16880 // #include <nlohmann/detail/output/serializer.hpp>
16881 // __ _____ _____ _____
16882 // __| | __| | | | JSON for Modern C++
16883 // | | |__ | | | | | | version 3.11.3
16884 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
16885 //
16886 // SPDX-FileCopyrightText: 2008-2009 Björn Hoehrmann <bjoern@hoehrmann.de>
16887 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
16888 // SPDX-License-Identifier: MIT
16889 
16890 
16891 
16892 #include <algorithm> // reverse, remove, fill, find, none_of
16893 #include <array> // array
16894 #include <clocale> // localeconv, lconv
16895 #include <cmath> // labs, isfinite, isnan, signbit
16896 #include <cstddef> // size_t, ptrdiff_t
16897 #include <cstdint> // uint8_t
16898 #include <cstdio> // snprintf
16899 #include <limits> // numeric_limits
16900 #include <string> // string, char_traits
16901 #include <iomanip> // setfill, setw
16902 #include <type_traits> // is_same
16903 #include <utility> // move
16904 
16905 // #include <nlohmann/detail/conversions/to_chars.hpp>
16906 // __ _____ _____ _____
16907 // __| | __| | | | JSON for Modern C++
16908 // | | |__ | | | | | | version 3.11.3
16909 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
16910 //
16911 // SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>
16912 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
16913 // SPDX-License-Identifier: MIT
16914 
16915 
16916 
16917 #include <array> // array
16918 #include <cmath> // signbit, isfinite
16919 #include <cstdint> // intN_t, uintN_t
16920 #include <cstring> // memcpy, memmove
16921 #include <limits> // numeric_limits
16922 #include <type_traits> // conditional
16923 
16924 // #include <nlohmann/detail/macro_scope.hpp>
16925 
16926 
16928 namespace detail
16929 {
16930 
16950  namespace dtoa_impl
16951  {
16952 
16953  template<typename Target, typename Source>
16954  Target reinterpret_bits(const Source source)
16955  {
16956  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
16957 
16958  Target target;
16959  std::memcpy(&target, &source, sizeof(Source));
16960  return target;
16961  }
16962 
16963  struct diyfp // f * 2^e
16964  {
16965  static constexpr int kPrecision = 64; // = q
16966 
16967  std::uint64_t f = 0;
16968  int e = 0;
16969 
16970  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
16971 
16976  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
16977  {
16978  JSON_ASSERT(x.e == y.e);
16979  JSON_ASSERT(x.f >= y.f);
16980 
16981  return { x.f - y.f, x.e };
16982  }
16983 
16988  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
16989  {
16990  static_assert(kPrecision == 64, "internal error");
16991 
16992  // Computes:
16993  // f = round((x.f * y.f) / 2^q)
16994  // e = x.e + y.e + q
16995 
16996  // Emulate the 64-bit * 64-bit multiplication:
16997  //
16998  // p = u * v
16999  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
17000  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
17001  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
17002  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
17003  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
17004  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
17005  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
17006  //
17007  // (Since Q might be larger than 2^32 - 1)
17008  //
17009  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
17010  //
17011  // (Q_hi + H does not overflow a 64-bit int)
17012  //
17013  // = p_lo + 2^64 p_hi
17014 
17015  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
17016  const std::uint64_t u_hi = x.f >> 32u;
17017  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
17018  const std::uint64_t v_hi = y.f >> 32u;
17019 
17020  const std::uint64_t p0 = u_lo * v_lo;
17021  const std::uint64_t p1 = u_lo * v_hi;
17022  const std::uint64_t p2 = u_hi * v_lo;
17023  const std::uint64_t p3 = u_hi * v_hi;
17024 
17025  const std::uint64_t p0_hi = p0 >> 32u;
17026  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
17027  const std::uint64_t p1_hi = p1 >> 32u;
17028  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
17029  const std::uint64_t p2_hi = p2 >> 32u;
17030 
17031  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
17032 
17033  // The full product might now be computed as
17034  //
17035  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
17036  // p_lo = p0_lo + (Q << 32)
17037  //
17038  // But in this particular case here, the full p_lo is not required.
17039  // Effectively we only need to add the highest bit in p_lo to p_hi (and
17040  // Q_hi + 1 does not overflow).
17041 
17042  Q += std::uint64_t{ 1 } << (64u - 32u - 1u); // round, ties up
17043 
17044  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
17045 
17046  return { h, x.e + y.e + 64 };
17047  }
17048 
17053  static diyfp normalize(diyfp x) noexcept
17054  {
17055  JSON_ASSERT(x.f != 0);
17056 
17057  while ((x.f >> 63u) == 0)
17058  {
17059  x.f <<= 1u;
17060  x.e--;
17061  }
17062 
17063  return x;
17064  }
17065 
17070  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
17071  {
17072  const int delta = x.e - target_exponent;
17073 
17074  JSON_ASSERT(delta >= 0);
17075  JSON_ASSERT(((x.f << delta) >> delta) == x.f);
17076 
17077  return { x.f << delta, target_exponent };
17078  }
17079  };
17080 
17081  struct boundaries
17082  {
17086  };
17087 
17094  template<typename FloatType>
17096  {
17097  JSON_ASSERT(std::isfinite(value));
17098  JSON_ASSERT(value > 0);
17099 
17100  // Convert the IEEE representation into a diyfp.
17101  //
17102  // If v is denormal:
17103  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
17104  // If v is normalized:
17105  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
17106 
17107  static_assert(std::numeric_limits<FloatType>::is_iec559,
17108  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
17109 
17110  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
17111  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
17112  constexpr int kMinExp = 1 - kBias;
17113  constexpr std::uint64_t kHiddenBit = std::uint64_t{ 1 } << (kPrecision - 1); // = 2^(p-1)
17114 
17115  using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
17116 
17117  const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
17118  const std::uint64_t E = bits >> (kPrecision - 1);
17119  const std::uint64_t F = bits & (kHiddenBit - 1);
17120 
17121  const bool is_denormal = E == 0;
17122  const diyfp v = is_denormal
17123  ? diyfp(F, kMinExp)
17124  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
17125 
17126  // Compute the boundaries m- and m+ of the floating-point value
17127  // v = f * 2^e.
17128  //
17129  // Determine v- and v+, the floating-point predecessor and successor if v,
17130  // respectively.
17131  //
17132  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
17133  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
17134  //
17135  // v+ = v + 2^e
17136  //
17137  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
17138  // between m- and m+ round to v, regardless of how the input rounding
17139  // algorithm breaks ties.
17140  //
17141  // ---+-------------+-------------+-------------+-------------+--- (A)
17142  // v- m- v m+ v+
17143  //
17144  // -----------------+------+------+-------------+-------------+--- (B)
17145  // v- m- v m+ v+
17146 
17147  const bool lower_boundary_is_closer = F == 0 && E > 1;
17148  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
17149  const diyfp m_minus = lower_boundary_is_closer
17150  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
17151  : diyfp(2 * v.f - 1, v.e - 1); // (A)
17152 
17153  // Determine the normalized w+ = m+.
17154  const diyfp w_plus = diyfp::normalize(m_plus);
17155 
17156  // Determine w- = m- such that e_(w-) = e_(w+).
17157  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
17158 
17159  return { diyfp::normalize(v), w_minus, w_plus };
17160  }
17161 
17162  // Given normalized diyfp w, Grisu needs to find a (normalized) cached
17163  // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
17164  // within a certain range [alpha, gamma] (Definition 3.2 from [1])
17165  //
17166  // alpha <= e = e_c + e_w + q <= gamma
17167  //
17168  // or
17169  //
17170  // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
17171  // <= f_c * f_w * 2^gamma
17172  //
17173  // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
17174  //
17175  // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
17176  //
17177  // or
17178  //
17179  // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
17180  //
17181  // The choice of (alpha,gamma) determines the size of the table and the form of
17182  // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
17183  // in practice:
17184  //
17185  // The idea is to cut the number c * w = f * 2^e into two parts, which can be
17186  // processed independently: An integral part p1, and a fractional part p2:
17187  //
17188  // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
17189  // = (f div 2^-e) + (f mod 2^-e) * 2^e
17190  // = p1 + p2 * 2^e
17191  //
17192  // The conversion of p1 into decimal form requires a series of divisions and
17193  // modulos by (a power of) 10. These operations are faster for 32-bit than for
17194  // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
17195  // achieved by choosing
17196  //
17197  // -e >= 32 or e <= -32 := gamma
17198  //
17199  // In order to convert the fractional part
17200  //
17201  // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
17202  //
17203  // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
17204  // d[-i] are extracted in order:
17205  //
17206  // (10 * p2) div 2^-e = d[-1]
17207  // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
17208  //
17209  // The multiplication by 10 must not overflow. It is sufficient to choose
17210  //
17211  // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
17212  //
17213  // Since p2 = f mod 2^-e < 2^-e,
17214  //
17215  // -e <= 60 or e >= -60 := alpha
17216 
17217  constexpr int kAlpha = -60;
17218  constexpr int kGamma = -32;
17219 
17220  struct cached_power // c = f * 2^e ~= 10^k
17221  {
17222  std::uint64_t f;
17223  int e;
17224  int k;
17225  };
17226 
17235  {
17236  // Now
17237  //
17238  // alpha <= e_c + e + q <= gamma (1)
17239  // ==> f_c * 2^alpha <= c * 2^e * 2^q
17240  //
17241  // and since the c's are normalized, 2^(q-1) <= f_c,
17242  //
17243  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
17244  // ==> 2^(alpha - e - 1) <= c
17245  //
17246  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
17247  //
17248  // k = ceil( log_10( 2^(alpha - e - 1) ) )
17249  // = ceil( (alpha - e - 1) * log_10(2) )
17250  //
17251  // From the paper:
17252  // "In theory the result of the procedure could be wrong since c is rounded,
17253  // and the computation itself is approximated [...]. In practice, however,
17254  // this simple function is sufficient."
17255  //
17256  // For IEEE double precision floating-point numbers converted into
17257  // normalized diyfp's w = f * 2^e, with q = 64,
17258  //
17259  // e >= -1022 (min IEEE exponent)
17260  // -52 (p - 1)
17261  // -52 (p - 1, possibly normalize denormal IEEE numbers)
17262  // -11 (normalize the diyfp)
17263  // = -1137
17264  //
17265  // and
17266  //
17267  // e <= +1023 (max IEEE exponent)
17268  // -52 (p - 1)
17269  // -11 (normalize the diyfp)
17270  // = 960
17271  //
17272  // This binary exponent range [-1137,960] results in a decimal exponent
17273  // range [-307,324]. One does not need to store a cached power for each
17274  // k in this range. For each such k it suffices to find a cached power
17275  // such that the exponent of the product lies in [alpha,gamma].
17276  // This implies that the difference of the decimal exponents of adjacent
17277  // table entries must be less than or equal to
17278  //
17279  // floor( (gamma - alpha) * log_10(2) ) = 8.
17280  //
17281  // (A smaller distance gamma-alpha would require a larger table.)
17282 
17283  // NB:
17284  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
17285 
17286  constexpr int kCachedPowersMinDecExp = -300;
17287  constexpr int kCachedPowersDecStep = 8;
17288 
17289  static constexpr std::array<cached_power, 79> kCachedPowers =
17290  {
17291  {
17292  { 0xAB70FE17C79AC6CA, -1060, -300 },
17293  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
17294  { 0xBE5691EF416BD60C, -1007, -284 },
17295  { 0x8DD01FAD907FFC3C, -980, -276 },
17296  { 0xD3515C2831559A83, -954, -268 },
17297  { 0x9D71AC8FADA6C9B5, -927, -260 },
17298  { 0xEA9C227723EE8BCB, -901, -252 },
17299  { 0xAECC49914078536D, -874, -244 },
17300  { 0x823C12795DB6CE57, -847, -236 },
17301  { 0xC21094364DFB5637, -821, -228 },
17302  { 0x9096EA6F3848984F, -794, -220 },
17303  { 0xD77485CB25823AC7, -768, -212 },
17304  { 0xA086CFCD97BF97F4, -741, -204 },
17305  { 0xEF340A98172AACE5, -715, -196 },
17306  { 0xB23867FB2A35B28E, -688, -188 },
17307  { 0x84C8D4DFD2C63F3B, -661, -180 },
17308  { 0xC5DD44271AD3CDBA, -635, -172 },
17309  { 0x936B9FCEBB25C996, -608, -164 },
17310  { 0xDBAC6C247D62A584, -582, -156 },
17311  { 0xA3AB66580D5FDAF6, -555, -148 },
17312  { 0xF3E2F893DEC3F126, -529, -140 },
17313  { 0xB5B5ADA8AAFF80B8, -502, -132 },
17314  { 0x87625F056C7C4A8B, -475, -124 },
17315  { 0xC9BCFF6034C13053, -449, -116 },
17316  { 0x964E858C91BA2655, -422, -108 },
17317  { 0xDFF9772470297EBD, -396, -100 },
17318  { 0xA6DFBD9FB8E5B88F, -369, -92 },
17319  { 0xF8A95FCF88747D94, -343, -84 },
17320  { 0xB94470938FA89BCF, -316, -76 },
17321  { 0x8A08F0F8BF0F156B, -289, -68 },
17322  { 0xCDB02555653131B6, -263, -60 },
17323  { 0x993FE2C6D07B7FAC, -236, -52 },
17324  { 0xE45C10C42A2B3B06, -210, -44 },
17325  { 0xAA242499697392D3, -183, -36 },
17326  { 0xFD87B5F28300CA0E, -157, -28 },
17327  { 0xBCE5086492111AEB, -130, -20 },
17328  { 0x8CBCCC096F5088CC, -103, -12 },
17329  { 0xD1B71758E219652C, -77, -4 },
17330  { 0x9C40000000000000, -50, 4 },
17331  { 0xE8D4A51000000000, -24, 12 },
17332  { 0xAD78EBC5AC620000, 3, 20 },
17333  { 0x813F3978F8940984, 30, 28 },
17334  { 0xC097CE7BC90715B3, 56, 36 },
17335  { 0x8F7E32CE7BEA5C70, 83, 44 },
17336  { 0xD5D238A4ABE98068, 109, 52 },
17337  { 0x9F4F2726179A2245, 136, 60 },
17338  { 0xED63A231D4C4FB27, 162, 68 },
17339  { 0xB0DE65388CC8ADA8, 189, 76 },
17340  { 0x83C7088E1AAB65DB, 216, 84 },
17341  { 0xC45D1DF942711D9A, 242, 92 },
17342  { 0x924D692CA61BE758, 269, 100 },
17343  { 0xDA01EE641A708DEA, 295, 108 },
17344  { 0xA26DA3999AEF774A, 322, 116 },
17345  { 0xF209787BB47D6B85, 348, 124 },
17346  { 0xB454E4A179DD1877, 375, 132 },
17347  { 0x865B86925B9BC5C2, 402, 140 },
17348  { 0xC83553C5C8965D3D, 428, 148 },
17349  { 0x952AB45CFA97A0B3, 455, 156 },
17350  { 0xDE469FBD99A05FE3, 481, 164 },
17351  { 0xA59BC234DB398C25, 508, 172 },
17352  { 0xF6C69A72A3989F5C, 534, 180 },
17353  { 0xB7DCBF5354E9BECE, 561, 188 },
17354  { 0x88FCF317F22241E2, 588, 196 },
17355  { 0xCC20CE9BD35C78A5, 614, 204 },
17356  { 0x98165AF37B2153DF, 641, 212 },
17357  { 0xE2A0B5DC971F303A, 667, 220 },
17358  { 0xA8D9D1535CE3B396, 694, 228 },
17359  { 0xFB9B7CD9A4A7443C, 720, 236 },
17360  { 0xBB764C4CA7A44410, 747, 244 },
17361  { 0x8BAB8EEFB6409C1A, 774, 252 },
17362  { 0xD01FEF10A657842C, 800, 260 },
17363  { 0x9B10A4E5E9913129, 827, 268 },
17364  { 0xE7109BFBA19C0C9D, 853, 276 },
17365  { 0xAC2820D9623BF429, 880, 284 },
17366  { 0x80444B5E7AA7CF85, 907, 292 },
17367  { 0xBF21E44003ACDD2D, 933, 300 },
17368  { 0x8E679C2F5E44FF8F, 960, 308 },
17369  { 0xD433179D9C8CB841, 986, 316 },
17370  { 0x9E19DB92B4E31BA9, 1013, 324 },
17371  }
17372  };
17373 
17374  // This computation gives exactly the same results for k as
17375  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
17376  // for |e| <= 1500, but doesn't require floating-point operations.
17377  // NB: log_10(2) ~= 78913 / 2^18
17378  JSON_ASSERT(e >= -1500);
17379  JSON_ASSERT(e <= 1500);
17380  const int f = kAlpha - e - 1;
17381  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
17382 
17383  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
17384  JSON_ASSERT(index >= 0);
17385  JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
17386 
17387  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
17388  JSON_ASSERT(kAlpha <= cached.e + e + 64);
17389  JSON_ASSERT(kGamma >= cached.e + e + 64);
17390 
17391  return cached;
17392  }
17393 
17398  inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
17399  {
17400  // LCOV_EXCL_START
17401  if (n >= 1000000000)
17402  {
17403  pow10 = 1000000000;
17404  return 10;
17405  }
17406  // LCOV_EXCL_STOP
17407  if (n >= 100000000)
17408  {
17409  pow10 = 100000000;
17410  return 9;
17411  }
17412  if (n >= 10000000)
17413  {
17414  pow10 = 10000000;
17415  return 8;
17416  }
17417  if (n >= 1000000)
17418  {
17419  pow10 = 1000000;
17420  return 7;
17421  }
17422  if (n >= 100000)
17423  {
17424  pow10 = 100000;
17425  return 6;
17426  }
17427  if (n >= 10000)
17428  {
17429  pow10 = 10000;
17430  return 5;
17431  }
17432  if (n >= 1000)
17433  {
17434  pow10 = 1000;
17435  return 4;
17436  }
17437  if (n >= 100)
17438  {
17439  pow10 = 100;
17440  return 3;
17441  }
17442  if (n >= 10)
17443  {
17444  pow10 = 10;
17445  return 2;
17446  }
17447 
17448  pow10 = 1;
17449  return 1;
17450  }
17451 
17452  inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
17453  std::uint64_t rest, std::uint64_t ten_k)
17454  {
17455  JSON_ASSERT(len >= 1);
17456  JSON_ASSERT(dist <= delta);
17457  JSON_ASSERT(rest <= delta);
17458  JSON_ASSERT(ten_k > 0);
17459 
17460  // <--------------------------- delta ---->
17461  // <---- dist --------->
17462  // --------------[------------------+-------------------]--------------
17463  // M- w M+
17464  //
17465  // ten_k
17466  // <------>
17467  // <---- rest ---->
17468  // --------------[------------------+----+--------------]--------------
17469  // w V
17470  // = buf * 10^k
17471  //
17472  // ten_k represents a unit-in-the-last-place in the decimal representation
17473  // stored in buf.
17474  // Decrement buf by ten_k while this takes buf closer to w.
17475 
17476  // The tests are written in this order to avoid overflow in unsigned
17477  // integer arithmetic.
17478 
17479  while (rest < dist
17480  && delta - rest >= ten_k
17481  && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
17482  {
17483  JSON_ASSERT(buf[len - 1] != '0');
17484  buf[len - 1]--;
17485  rest += ten_k;
17486  }
17487  }
17488 
17493  inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
17494  diyfp M_minus, diyfp w, diyfp M_plus)
17495  {
17496  static_assert(kAlpha >= -60, "internal error");
17497  static_assert(kGamma <= -32, "internal error");
17498 
17499  // Generates the digits (and the exponent) of a decimal floating-point
17500  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
17501  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
17502  //
17503  // <--------------------------- delta ---->
17504  // <---- dist --------->
17505  // --------------[------------------+-------------------]--------------
17506  // M- w M+
17507  //
17508  // Grisu2 generates the digits of M+ from left to right and stops as soon as
17509  // V is in [M-,M+].
17510 
17511  JSON_ASSERT(M_plus.e >= kAlpha);
17512  JSON_ASSERT(M_plus.e <= kGamma);
17513 
17514  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
17515  std::uint64_t dist = diyfp::sub(M_plus, w).f; // (significand of (M+ - w ), implicit exponent is e)
17516 
17517  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
17518  //
17519  // M+ = f * 2^e
17520  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
17521  // = ((p1 ) * 2^-e + (p2 )) * 2^e
17522  // = p1 + p2 * 2^e
17523 
17524  const diyfp one(std::uint64_t{ 1 } << -M_plus.e, M_plus.e);
17525 
17526  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.)
17527  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
17528 
17529  // 1)
17530  //
17531  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
17532 
17533  JSON_ASSERT(p1 > 0);
17534 
17535  std::uint32_t pow10{};
17536  const int k = find_largest_pow10(p1, pow10);
17537 
17538  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
17539  //
17540  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
17541  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
17542  //
17543  // M+ = p1 + p2 * 2^e
17544  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
17545  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
17546  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
17547  //
17548  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
17549  //
17550  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
17551  //
17552  // but stop as soon as
17553  //
17554  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
17555 
17556  int n = k;
17557  while (n > 0)
17558  {
17559  // Invariants:
17560  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
17561  // pow10 = 10^(n-1) <= p1 < 10^n
17562  //
17563  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
17564  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
17565  //
17566  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
17567  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
17568  //
17569  JSON_ASSERT(d <= 9);
17570  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17571  //
17572  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
17573  //
17574  p1 = r;
17575  n--;
17576  //
17577  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
17578  // pow10 = 10^n
17579  //
17580 
17581  // Now check if enough digits have been generated.
17582  // Compute
17583  //
17584  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
17585  //
17586  // Note:
17587  // Since rest and delta share the same exponent e, it suffices to
17588  // compare the significands.
17589  const std::uint64_t rest = (std::uint64_t{ p1 } << -one.e) + p2;
17590  if (rest <= delta)
17591  {
17592  // V = buffer * 10^n, with M- <= V <= M+.
17593 
17594  decimal_exponent += n;
17595 
17596  // We may now just stop. But instead look if the buffer could be
17597  // decremented to bring V closer to w.
17598  //
17599  // pow10 = 10^n is now 1 ulp in the decimal representation V.
17600  // The rounding procedure works with diyfp's with an implicit
17601  // exponent of e.
17602  //
17603  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
17604  //
17605  const std::uint64_t ten_n = std::uint64_t{ pow10 } << -one.e;
17606  grisu2_round(buffer, length, dist, delta, rest, ten_n);
17607 
17608  return;
17609  }
17610 
17611  pow10 /= 10;
17612  //
17613  // pow10 = 10^(n-1) <= p1 < 10^n
17614  // Invariants restored.
17615  }
17616 
17617  // 2)
17618  //
17619  // The digits of the integral part have been generated:
17620  //
17621  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
17622  // = buffer + p2 * 2^e
17623  //
17624  // Now generate the digits of the fractional part p2 * 2^e.
17625  //
17626  // Note:
17627  // No decimal point is generated: the exponent is adjusted instead.
17628  //
17629  // p2 actually represents the fraction
17630  //
17631  // p2 * 2^e
17632  // = p2 / 2^-e
17633  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
17634  //
17635  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
17636  //
17637  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
17638  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
17639  //
17640  // using
17641  //
17642  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
17643  // = ( d) * 2^-e + ( r)
17644  //
17645  // or
17646  // 10^m * p2 * 2^e = d + r * 2^e
17647  //
17648  // i.e.
17649  //
17650  // M+ = buffer + p2 * 2^e
17651  // = buffer + 10^-m * (d + r * 2^e)
17652  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
17653  //
17654  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
17655 
17656  JSON_ASSERT(p2 > delta);
17657 
17658  int m = 0;
17659  for (;;)
17660  {
17661  // Invariant:
17662  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
17663  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
17664  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
17665  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
17666  //
17667  JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
17668  p2 *= 10;
17669  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
17670  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
17671  //
17672  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
17673  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
17674  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
17675  //
17676  JSON_ASSERT(d <= 9);
17677  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17678  //
17679  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
17680  //
17681  p2 = r;
17682  m++;
17683  //
17684  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
17685  // Invariant restored.
17686 
17687  // Check if enough digits have been generated.
17688  //
17689  // 10^-m * p2 * 2^e <= delta * 2^e
17690  // p2 * 2^e <= 10^m * delta * 2^e
17691  // p2 <= 10^m * delta
17692  delta *= 10;
17693  dist *= 10;
17694  if (p2 <= delta)
17695  {
17696  break;
17697  }
17698  }
17699 
17700  // V = buffer * 10^-m, with M- <= V <= M+.
17701 
17702  decimal_exponent -= m;
17703 
17704  // 1 ulp in the decimal representation is now 10^-m.
17705  // Since delta and dist are now scaled by 10^m, we need to do the
17706  // same with ulp in order to keep the units in sync.
17707  //
17708  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
17709  //
17710  const std::uint64_t ten_m = one.f;
17711  grisu2_round(buffer, length, dist, delta, p2, ten_m);
17712 
17713  // By construction this algorithm generates the shortest possible decimal
17714  // number (Loitsch, Theorem 6.2) which rounds back to w.
17715  // For an input number of precision p, at least
17716  //
17717  // N = 1 + ceil(p * log_10(2))
17718  //
17719  // decimal digits are sufficient to identify all binary floating-point
17720  // numbers (Matula, "In-and-Out conversions").
17721  // This implies that the algorithm does not produce more than N decimal
17722  // digits.
17723  //
17724  // N = 17 for p = 53 (IEEE double precision)
17725  // N = 9 for p = 24 (IEEE single precision)
17726  }
17727 
17734  inline void grisu2(char* buf, int& len, int& decimal_exponent,
17735  diyfp m_minus, diyfp v, diyfp m_plus)
17736  {
17737  JSON_ASSERT(m_plus.e == m_minus.e);
17738  JSON_ASSERT(m_plus.e == v.e);
17739 
17740  // --------(-----------------------+-----------------------)-------- (A)
17741  // m- v m+
17742  //
17743  // --------------------(-----------+-----------------------)-------- (B)
17744  // m- v m+
17745  //
17746  // First scale v (and m- and m+) such that the exponent is in the range
17747  // [alpha, gamma].
17748 
17749  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
17750 
17751  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
17752 
17753  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
17754  const diyfp w = diyfp::mul(v, c_minus_k);
17755  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
17756  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
17757 
17758  // ----(---+---)---------------(---+---)---------------(---+---)----
17759  // w- w w+
17760  // = c*m- = c*v = c*m+
17761  //
17762  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
17763  // w+ are now off by a small amount.
17764  // In fact:
17765  //
17766  // w - v * 10^k < 1 ulp
17767  //
17768  // To account for this inaccuracy, add resp. subtract 1 ulp.
17769  //
17770  // --------+---[---------------(---+---)---------------]---+--------
17771  // w- M- w M+ w+
17772  //
17773  // Now any number in [M-, M+] (bounds included) will round to w when input,
17774  // regardless of how the input rounding algorithm breaks ties.
17775  //
17776  // And digit_gen generates the shortest possible such number in [M-, M+].
17777  // Note that this does not mean that Grisu2 always generates the shortest
17778  // possible number in the interval (m-, m+).
17779  const diyfp M_minus(w_minus.f + 1, w_minus.e);
17780  const diyfp M_plus(w_plus.f - 1, w_plus.e);
17781 
17782  decimal_exponent = -cached.k; // = -(-k) = k
17783 
17784  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
17785  }
17786 
17792  template<typename FloatType>
17794  void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
17795  {
17796  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
17797  "internal error: not enough precision");
17798 
17799  JSON_ASSERT(std::isfinite(value));
17800  JSON_ASSERT(value > 0);
17801 
17802  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
17803  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
17804  // decimal representations are not exactly "short".
17805  //
17806  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
17807  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
17808  // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
17809  // does.
17810  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
17811  // representation using the corresponding std::from_chars function recovers value exactly". That
17812  // indicates that single precision floating-point numbers should be recovered using
17813  // 'std::strtof'.
17814  //
17815  // NB: If the neighbors are computed for single-precision numbers, there is a single float
17816  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
17817  // value is off by 1 ulp.
17818 #if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)
17819  const boundaries w = compute_boundaries(static_cast<double>(value));
17820 #else
17821  const boundaries w = compute_boundaries(value);
17822 #endif
17823 
17824  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
17825  }
17826 
17834  inline char* append_exponent(char* buf, int e)
17835  {
17836  JSON_ASSERT(e > -1000);
17837  JSON_ASSERT(e < 1000);
17838 
17839  if (e < 0)
17840  {
17841  e = -e;
17842  *buf++ = '-';
17843  }
17844  else
17845  {
17846  *buf++ = '+';
17847  }
17848 
17849  auto k = static_cast<std::uint32_t>(e);
17850  if (k < 10)
17851  {
17852  // Always print at least two digits in the exponent.
17853  // This is for compatibility with printf("%g").
17854  *buf++ = '0';
17855  *buf++ = static_cast<char>('0' + k);
17856  }
17857  else if (k < 100)
17858  {
17859  *buf++ = static_cast<char>('0' + k / 10);
17860  k %= 10;
17861  *buf++ = static_cast<char>('0' + k);
17862  }
17863  else
17864  {
17865  *buf++ = static_cast<char>('0' + k / 100);
17866  k %= 100;
17867  *buf++ = static_cast<char>('0' + k / 10);
17868  k %= 10;
17869  *buf++ = static_cast<char>('0' + k);
17870  }
17871 
17872  return buf;
17873  }
17874 
17886  inline char* format_buffer(char* buf, int len, int decimal_exponent,
17887  int min_exp, int max_exp)
17888  {
17889  JSON_ASSERT(min_exp < 0);
17890  JSON_ASSERT(max_exp > 0);
17891 
17892  const int k = len;
17893  const int n = len + decimal_exponent;
17894 
17895  // v = buf * 10^(n-k)
17896  // k is the length of the buffer (number of decimal digits)
17897  // n is the position of the decimal point relative to the start of the buffer.
17898 
17899  if (k <= n && n <= max_exp)
17900  {
17901  // digits[000]
17902  // len <= max_exp + 2
17903 
17904  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
17905  // Make it look like a floating-point number (#362, #378)
17906  buf[n + 0] = '.';
17907  buf[n + 1] = '0';
17908  return buf + (static_cast<size_t>(n) + 2);
17909  }
17910 
17911  if (0 < n && n <= max_exp)
17912  {
17913  // dig.its
17914  // len <= max_digits10 + 1
17915 
17916  JSON_ASSERT(k > n);
17917 
17918  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
17919  buf[n] = '.';
17920  return buf + (static_cast<size_t>(k) + 1U);
17921  }
17922 
17923  if (min_exp < n && n <= 0)
17924  {
17925  // 0.[000]digits
17926  // len <= 2 + (-min_exp - 1) + max_digits10
17927 
17928  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
17929  buf[0] = '0';
17930  buf[1] = '.';
17931  std::memset(buf + 2, '0', static_cast<size_t>(-n));
17932  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
17933  }
17934 
17935  if (k == 1)
17936  {
17937  // dE+123
17938  // len <= 1 + 5
17939 
17940  buf += 1;
17941  }
17942  else
17943  {
17944  // d.igitsE+123
17945  // len <= max_digits10 + 1 + 5
17946 
17947  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
17948  buf[1] = '.';
17949  buf += 1 + static_cast<size_t>(k);
17950  }
17951 
17952  *buf++ = 'e';
17953  return append_exponent(buf, n - 1);
17954  }
17955 
17956  } // namespace dtoa_impl
17957 
17968  template<typename FloatType>
17969  JSON_HEDLEY_NON_NULL(1, 2)
17971  char* to_chars(char* first, const char* last, FloatType value)
17972  {
17973  static_cast<void>(last); // maybe unused - fix warning
17974  JSON_ASSERT(std::isfinite(value));
17975 
17976  // Use signbit(value) instead of (value < 0) since signbit works for -0.
17977  if (std::signbit(value))
17978  {
17979  value = -value;
17980  *first++ = '-';
17981  }
17982 
17983 #ifdef __GNUC__
17984 #pragma GCC diagnostic push
17985 #pragma GCC diagnostic ignored "-Wfloat-equal"
17986 #endif
17987  if (value == 0) // +-0
17988  {
17989  *first++ = '0';
17990  // Make it look like a floating-point number (#362, #378)
17991  *first++ = '.';
17992  *first++ = '0';
17993  return first;
17994  }
17995 #ifdef __GNUC__
17996 #pragma GCC diagnostic pop
17997 #endif
17998 
17999  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
18000 
18001  // Compute v = buffer * 10^decimal_exponent.
18002  // The decimal digits are stored in the buffer, which needs to be interpreted
18003  // as an unsigned decimal integer.
18004  // len is the length of the buffer, i.e. the number of decimal digits.
18005  int len = 0;
18006  int decimal_exponent = 0;
18007  dtoa_impl::grisu2(first, len, decimal_exponent, value);
18008 
18009  JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
18010 
18011  // Format the buffer like printf("%.*g", prec, value)
18012  constexpr int kMinExp = -4;
18013  // Use digits10 here to increase compatibility with version 2.
18014  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
18015 
18016  JSON_ASSERT(last - first >= kMaxExp + 2);
18017  JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
18018  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
18019 
18020  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
18021  }
18022 
18023 } // namespace detail
18025 
18026 // #include <nlohmann/detail/exceptions.hpp>
18027 
18028 // #include <nlohmann/detail/macro_scope.hpp>
18029 
18030 // #include <nlohmann/detail/meta/cpp_future.hpp>
18031 
18032 // #include <nlohmann/detail/output/binary_writer.hpp>
18033 
18034 // #include <nlohmann/detail/output/output_adapters.hpp>
18035 
18036 // #include <nlohmann/detail/string_concat.hpp>
18037 
18038 // #include <nlohmann/detail/value_t.hpp>
18039 
18040 
18042 namespace detail
18043 {
18044 
18046  // serialization //
18048 
18050  enum class error_handler_t
18051  {
18052  strict,
18053  replace,
18054  ignore
18055  };
18056 
18057  template<typename BasicJsonType>
18059  {
18060  using string_t = typename BasicJsonType::string_t;
18061  using number_float_t = typename BasicJsonType::number_float_t;
18062  using number_integer_t = typename BasicJsonType::number_integer_t;
18063  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18064  using binary_char_t = typename BasicJsonType::binary_t::value_type;
18065  static constexpr std::uint8_t UTF8_ACCEPT = 0;
18066  static constexpr std::uint8_t UTF8_REJECT = 1;
18067 
18068  public:
18074  serializer(output_adapter_t<char> s, const char ichar,
18075  error_handler_t error_handler_ = error_handler_t::strict)
18076  : o(std::move(s))
18077  , loc(std::localeconv())
18078  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->thousands_sep)))
18079  , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->decimal_point)))
18080  , indent_char(ichar)
18081  , indent_string(512, indent_char)
18082  , error_handler(error_handler_)
18083  {}
18084 
18085  // delete because of pointer members
18086  serializer(const serializer&) = delete;
18087  serializer& operator=(const serializer&) = delete;
18088  serializer(serializer&&) = delete;
18090  ~serializer() = default;
18091 
18114  void dump(const BasicJsonType& val,
18115  const bool pretty_print,
18116  const bool ensure_ascii,
18117  const unsigned int indent_step,
18118  const unsigned int current_indent = 0)
18119  {
18120  switch (val.m_data.m_type)
18121  {
18122  case value_t::object:
18123  {
18124  if (val.m_data.m_value.object->empty())
18125  {
18126  o->write_characters("{}", 2);
18127  return;
18128  }
18129 
18130  if (pretty_print)
18131  {
18132  o->write_characters("{\n", 2);
18133 
18134  // variable to hold indentation for recursive calls
18135  const auto new_indent = current_indent + indent_step;
18136  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18137  {
18138  indent_string.resize(indent_string.size() * 2, ' ');
18139  }
18140 
18141  // first n-1 elements
18142  auto i = val.m_data.m_value.object->cbegin();
18143  for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18144  {
18145  o->write_characters(indent_string.c_str(), new_indent);
18146  o->write_character('\"');
18147  dump_escaped(i->first, ensure_ascii);
18148  o->write_characters("\": ", 3);
18149  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18150  o->write_characters(",\n", 2);
18151  }
18152 
18153  // last element
18154  JSON_ASSERT(i != val.m_data.m_value.object->cend());
18155  JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18156  o->write_characters(indent_string.c_str(), new_indent);
18157  o->write_character('\"');
18158  dump_escaped(i->first, ensure_ascii);
18159  o->write_characters("\": ", 3);
18160  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18161 
18162  o->write_character('\n');
18163  o->write_characters(indent_string.c_str(), current_indent);
18164  o->write_character('}');
18165  }
18166  else
18167  {
18168  o->write_character('{');
18169 
18170  // first n-1 elements
18171  auto i = val.m_data.m_value.object->cbegin();
18172  for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18173  {
18174  o->write_character('\"');
18175  dump_escaped(i->first, ensure_ascii);
18176  o->write_characters("\":", 2);
18177  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18178  o->write_character(',');
18179  }
18180 
18181  // last element
18182  JSON_ASSERT(i != val.m_data.m_value.object->cend());
18183  JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18184  o->write_character('\"');
18185  dump_escaped(i->first, ensure_ascii);
18186  o->write_characters("\":", 2);
18187  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18188 
18189  o->write_character('}');
18190  }
18191 
18192  return;
18193  }
18194 
18195  case value_t::array:
18196  {
18197  if (val.m_data.m_value.array->empty())
18198  {
18199  o->write_characters("[]", 2);
18200  return;
18201  }
18202 
18203  if (pretty_print)
18204  {
18205  o->write_characters("[\n", 2);
18206 
18207  // variable to hold indentation for recursive calls
18208  const auto new_indent = current_indent + indent_step;
18209  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18210  {
18211  indent_string.resize(indent_string.size() * 2, ' ');
18212  }
18213 
18214  // first n-1 elements
18215  for (auto i = val.m_data.m_value.array->cbegin();
18216  i != val.m_data.m_value.array->cend() - 1; ++i)
18217  {
18218  o->write_characters(indent_string.c_str(), new_indent);
18219  dump(*i, true, ensure_ascii, indent_step, new_indent);
18220  o->write_characters(",\n", 2);
18221  }
18222 
18223  // last element
18224  JSON_ASSERT(!val.m_data.m_value.array->empty());
18225  o->write_characters(indent_string.c_str(), new_indent);
18226  dump(val.m_data.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
18227 
18228  o->write_character('\n');
18229  o->write_characters(indent_string.c_str(), current_indent);
18230  o->write_character(']');
18231  }
18232  else
18233  {
18234  o->write_character('[');
18235 
18236  // first n-1 elements
18237  for (auto i = val.m_data.m_value.array->cbegin();
18238  i != val.m_data.m_value.array->cend() - 1; ++i)
18239  {
18240  dump(*i, false, ensure_ascii, indent_step, current_indent);
18241  o->write_character(',');
18242  }
18243 
18244  // last element
18245  JSON_ASSERT(!val.m_data.m_value.array->empty());
18246  dump(val.m_data.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
18247 
18248  o->write_character(']');
18249  }
18250 
18251  return;
18252  }
18253 
18254  case value_t::string:
18255  {
18256  o->write_character('\"');
18257  dump_escaped(*val.m_data.m_value.string, ensure_ascii);
18258  o->write_character('\"');
18259  return;
18260  }
18261 
18262  case value_t::binary:
18263  {
18264  if (pretty_print)
18265  {
18266  o->write_characters("{\n", 2);
18267 
18268  // variable to hold indentation for recursive calls
18269  const auto new_indent = current_indent + indent_step;
18270  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18271  {
18272  indent_string.resize(indent_string.size() * 2, ' ');
18273  }
18274 
18275  o->write_characters(indent_string.c_str(), new_indent);
18276 
18277  o->write_characters("\"bytes\": [", 10);
18278 
18279  if (!val.m_data.m_value.binary->empty())
18280  {
18281  for (auto i = val.m_data.m_value.binary->cbegin();
18282  i != val.m_data.m_value.binary->cend() - 1; ++i)
18283  {
18284  dump_integer(*i);
18285  o->write_characters(", ", 2);
18286  }
18287  dump_integer(val.m_data.m_value.binary->back());
18288  }
18289 
18290  o->write_characters("],\n", 3);
18291  o->write_characters(indent_string.c_str(), new_indent);
18292 
18293  o->write_characters("\"subtype\": ", 11);
18294  if (val.m_data.m_value.binary->has_subtype())
18295  {
18296  dump_integer(val.m_data.m_value.binary->subtype());
18297  }
18298  else
18299  {
18300  o->write_characters("null", 4);
18301  }
18302  o->write_character('\n');
18303  o->write_characters(indent_string.c_str(), current_indent);
18304  o->write_character('}');
18305  }
18306  else
18307  {
18308  o->write_characters("{\"bytes\":[", 10);
18309 
18310  if (!val.m_data.m_value.binary->empty())
18311  {
18312  for (auto i = val.m_data.m_value.binary->cbegin();
18313  i != val.m_data.m_value.binary->cend() - 1; ++i)
18314  {
18315  dump_integer(*i);
18316  o->write_character(',');
18317  }
18318  dump_integer(val.m_data.m_value.binary->back());
18319  }
18320 
18321  o->write_characters("],\"subtype\":", 12);
18322  if (val.m_data.m_value.binary->has_subtype())
18323  {
18324  dump_integer(val.m_data.m_value.binary->subtype());
18325  o->write_character('}');
18326  }
18327  else
18328  {
18329  o->write_characters("null}", 5);
18330  }
18331  }
18332  return;
18333  }
18334 
18335  case value_t::boolean:
18336  {
18337  if (val.m_data.m_value.boolean)
18338  {
18339  o->write_characters("true", 4);
18340  }
18341  else
18342  {
18343  o->write_characters("false", 5);
18344  }
18345  return;
18346  }
18347 
18349  {
18350  dump_integer(val.m_data.m_value.number_integer);
18351  return;
18352  }
18353 
18355  {
18356  dump_integer(val.m_data.m_value.number_unsigned);
18357  return;
18358  }
18359 
18360  case value_t::number_float:
18361  {
18362  dump_float(val.m_data.m_value.number_float);
18363  return;
18364  }
18365 
18366  case value_t::discarded:
18367  {
18368  o->write_characters("<discarded>", 11);
18369  return;
18370  }
18371 
18372  case value_t::null:
18373  {
18374  o->write_characters("null", 4);
18375  return;
18376  }
18377 
18378  default: // LCOV_EXCL_LINE
18379  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18380  }
18381  }
18382 
18398  void dump_escaped(const string_t& s, const bool ensure_ascii)
18399  {
18400  std::uint32_t codepoint{};
18401  std::uint8_t state = UTF8_ACCEPT;
18402  std::size_t bytes = 0; // number of bytes written to string_buffer
18403 
18404  // number of bytes written at the point of the last valid byte
18405  std::size_t bytes_after_last_accept = 0;
18406  std::size_t undumped_chars = 0;
18407 
18408  for (std::size_t i = 0; i < s.size(); ++i)
18409  {
18410  const auto byte = static_cast<std::uint8_t>(s[i]);
18411 
18412  switch (decode(state, codepoint, byte))
18413  {
18414  case UTF8_ACCEPT: // decode found a new code point
18415  {
18416  switch (codepoint)
18417  {
18418  case 0x08: // backspace
18419  {
18420  string_buffer[bytes++] = '\\';
18421  string_buffer[bytes++] = 'b';
18422  break;
18423  }
18424 
18425  case 0x09: // horizontal tab
18426  {
18427  string_buffer[bytes++] = '\\';
18428  string_buffer[bytes++] = 't';
18429  break;
18430  }
18431 
18432  case 0x0A: // newline
18433  {
18434  string_buffer[bytes++] = '\\';
18435  string_buffer[bytes++] = 'n';
18436  break;
18437  }
18438 
18439  case 0x0C: // formfeed
18440  {
18441  string_buffer[bytes++] = '\\';
18442  string_buffer[bytes++] = 'f';
18443  break;
18444  }
18445 
18446  case 0x0D: // carriage return
18447  {
18448  string_buffer[bytes++] = '\\';
18449  string_buffer[bytes++] = 'r';
18450  break;
18451  }
18452 
18453  case 0x22: // quotation mark
18454  {
18455  string_buffer[bytes++] = '\\';
18456  string_buffer[bytes++] = '\"';
18457  break;
18458  }
18459 
18460  case 0x5C: // reverse solidus
18461  {
18462  string_buffer[bytes++] = '\\';
18463  string_buffer[bytes++] = '\\';
18464  break;
18465  }
18466 
18467  default:
18468  {
18469  // escape control characters (0x00..0x1F) or, if
18470  // ensure_ascii parameter is used, non-ASCII characters
18471  if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
18472  {
18473  if (codepoint <= 0xFFFF)
18474  {
18475  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18476  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
18477  static_cast<std::uint16_t>(codepoint)));
18478  bytes += 6;
18479  }
18480  else
18481  {
18482  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18483  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
18484  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
18485  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
18486  bytes += 12;
18487  }
18488  }
18489  else
18490  {
18491  // copy byte to buffer (all previous bytes
18492  // been copied have in default case above)
18493  string_buffer[bytes++] = s[i];
18494  }
18495  break;
18496  }
18497  }
18498 
18499  // write buffer and reset index; there must be 13 bytes
18500  // left, as this is the maximal number of bytes to be
18501  // written ("\uxxxx\uxxxx\0") for one code point
18502  if (string_buffer.size() - bytes < 13)
18503  {
18504  o->write_characters(string_buffer.data(), bytes);
18505  bytes = 0;
18506  }
18507 
18508  // remember the byte position of this accept
18510  undumped_chars = 0;
18511  break;
18512  }
18513 
18514  case UTF8_REJECT: // decode found invalid UTF-8 byte
18515  {
18516  switch (error_handler)
18517  {
18519  {
18520  JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
18521  }
18522 
18525  {
18526  // in case we saw this character the first time, we
18527  // would like to read it again, because the byte
18528  // may be OK for itself, but just not OK for the
18529  // previous sequence
18530  if (undumped_chars > 0)
18531  {
18532  --i;
18533  }
18534 
18535  // reset length buffer to the last accepted index;
18536  // thus removing/ignoring the invalid characters
18538 
18540  {
18541  // add a replacement character
18542  if (ensure_ascii)
18543  {
18544  string_buffer[bytes++] = '\\';
18545  string_buffer[bytes++] = 'u';
18546  string_buffer[bytes++] = 'f';
18547  string_buffer[bytes++] = 'f';
18548  string_buffer[bytes++] = 'f';
18549  string_buffer[bytes++] = 'd';
18550  }
18551  else
18552  {
18556  }
18557 
18558  // write buffer and reset index; there must be 13 bytes
18559  // left, as this is the maximal number of bytes to be
18560  // written ("\uxxxx\uxxxx\0") for one code point
18561  if (string_buffer.size() - bytes < 13)
18562  {
18563  o->write_characters(string_buffer.data(), bytes);
18564  bytes = 0;
18565  }
18566 
18568  }
18569 
18570  undumped_chars = 0;
18571 
18572  // continue processing the string
18573  state = UTF8_ACCEPT;
18574  break;
18575  }
18576 
18577  default: // LCOV_EXCL_LINE
18578  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18579  }
18580  break;
18581  }
18582 
18583  default: // decode found yet incomplete multi-byte code point
18584  {
18585  if (!ensure_ascii)
18586  {
18587  // code point will not be escaped - copy byte to buffer
18588  string_buffer[bytes++] = s[i];
18589  }
18590  ++undumped_chars;
18591  break;
18592  }
18593  }
18594  }
18595 
18596  // we finished processing the string
18597  if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
18598  {
18599  // write buffer
18600  if (bytes > 0)
18601  {
18602  o->write_characters(string_buffer.data(), bytes);
18603  }
18604  }
18605  else
18606  {
18607  // we finish reading, but do not accept: string was incomplete
18608  switch (error_handler)
18609  {
18611  {
18612  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));
18613  }
18614 
18616  {
18617  // write all accepted bytes
18618  o->write_characters(string_buffer.data(), bytes_after_last_accept);
18619  break;
18620  }
18621 
18623  {
18624  // write all accepted bytes
18625  o->write_characters(string_buffer.data(), bytes_after_last_accept);
18626  // add a replacement character
18627  if (ensure_ascii)
18628  {
18629  o->write_characters("\\ufffd", 6);
18630  }
18631  else
18632  {
18633  o->write_characters("\xEF\xBF\xBD", 3);
18634  }
18635  break;
18636  }
18637 
18638  default: // LCOV_EXCL_LINE
18639  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18640  }
18641  }
18642  }
18643 
18644  private:
18653  inline unsigned int count_digits(number_unsigned_t x) noexcept
18654  {
18655  unsigned int n_digits = 1;
18656  for (;;)
18657  {
18658  if (x < 10)
18659  {
18660  return n_digits;
18661  }
18662  if (x < 100)
18663  {
18664  return n_digits + 1;
18665  }
18666  if (x < 1000)
18667  {
18668  return n_digits + 2;
18669  }
18670  if (x < 10000)
18671  {
18672  return n_digits + 3;
18673  }
18674  x = x / 10000u;
18675  n_digits += 4;
18676  }
18677  }
18678 
18684  static std::string hex_bytes(std::uint8_t byte)
18685  {
18686  std::string result = "FF";
18687  constexpr const char* nibble_to_hex = "0123456789ABCDEF";
18688  result[0] = nibble_to_hex[byte / 16];
18689  result[1] = nibble_to_hex[byte % 16];
18690  return result;
18691  }
18692 
18693  // templates to avoid warnings about useless casts
18694  template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
18695  bool is_negative_number(NumberType x)
18696  {
18697  return x < 0;
18698  }
18699 
18700  template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
18701  bool is_negative_number(NumberType /*unused*/)
18702  {
18703  return false;
18704  }
18705 
18715  template < typename NumberType, detail::enable_if_t <
18716  std::is_integral<NumberType>::value ||
18717  std::is_same<NumberType, number_unsigned_t>::value ||
18718  std::is_same<NumberType, number_integer_t>::value ||
18719  std::is_same<NumberType, binary_char_t>::value,
18720  int > = 0 >
18721  void dump_integer(NumberType x)
18722  {
18723  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
18724  {
18725  {
18726  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
18727  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
18728  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
18729  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
18730  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
18731  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
18732  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
18733  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
18734  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
18735  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
18736  }
18737  };
18738 
18739  // special case for "0"
18740  if (x == 0)
18741  {
18742  o->write_character('0');
18743  return;
18744  }
18745 
18746  // use a pointer to fill the buffer
18747  auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18748 
18749  number_unsigned_t abs_value;
18750 
18751  unsigned int n_chars{};
18752 
18753  if (is_negative_number(x))
18754  {
18755  *buffer_ptr = '-';
18756  abs_value = remove_sign(static_cast<number_integer_t>(x));
18757 
18758  // account one more byte for the minus sign
18759  n_chars = 1 + count_digits(abs_value);
18760  }
18761  else
18762  {
18763  abs_value = static_cast<number_unsigned_t>(x);
18764  n_chars = count_digits(abs_value);
18765  }
18766 
18767  // spare 1 byte for '\0'
18768  JSON_ASSERT(n_chars < number_buffer.size() - 1);
18769 
18770  // jump to the end to generate the string from backward,
18771  // so we later avoid reversing the result
18772  buffer_ptr += n_chars;
18773 
18774  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
18775  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
18776  while (abs_value >= 100)
18777  {
18778  const auto digits_index = static_cast<unsigned>((abs_value % 100));
18779  abs_value /= 100;
18780  *(--buffer_ptr) = digits_to_99[digits_index][1];
18781  *(--buffer_ptr) = digits_to_99[digits_index][0];
18782  }
18783 
18784  if (abs_value >= 10)
18785  {
18786  const auto digits_index = static_cast<unsigned>(abs_value);
18787  *(--buffer_ptr) = digits_to_99[digits_index][1];
18788  *(--buffer_ptr) = digits_to_99[digits_index][0];
18789  }
18790  else
18791  {
18792  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
18793  }
18794 
18795  o->write_characters(number_buffer.data(), n_chars);
18796  }
18797 
18806  void dump_float(number_float_t x)
18807  {
18808  // NaN / inf
18809  if (!std::isfinite(x))
18810  {
18811  o->write_characters("null", 4);
18812  return;
18813  }
18814 
18815  // If number_float_t is an IEEE-754 single or double precision number,
18816  // use the Grisu2 algorithm to produce short numbers which are
18817  // guaranteed to round-trip, using strtof and strtod, resp.
18818  //
18819  // NB: The test below works if <long double> == <double>.
18820  static constexpr bool is_ieee_single_or_double
18821  = (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) ||
18822  (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);
18823 
18824  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
18825  }
18826 
18827  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
18828  {
18829  auto* begin = number_buffer.data();
18830  auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
18831 
18832  o->write_characters(begin, static_cast<size_t>(end - begin));
18833  }
18834 
18835  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
18836  {
18837  // get number of digits for a float -> text -> float round-trip
18838  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
18839 
18840  // the actual conversion
18841  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18842  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
18843 
18844  // negative value indicates an error
18845  JSON_ASSERT(len > 0);
18846  // check if buffer was large enough
18847  JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
18848 
18849  // erase thousands separator
18850  if (thousands_sep != '\0')
18851  {
18852  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
18853  const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
18854  std::fill(end, number_buffer.end(), '\0');
18855  JSON_ASSERT((end - number_buffer.begin()) <= len);
18856  len = (end - number_buffer.begin());
18857  }
18858 
18859  // convert decimal point to '.'
18860  if (decimal_point != '\0' && decimal_point != '.')
18861  {
18862  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
18863  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
18864  if (dec_pos != number_buffer.end())
18865  {
18866  *dec_pos = '.';
18867  }
18868  }
18869 
18870  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
18871 
18872  // determine if we need to append ".0"
18873  const bool value_is_int_like =
18874  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
18875  [](char c)
18876  {
18877  return c == '.' || c == 'e';
18878  });
18879 
18880  if (value_is_int_like)
18881  {
18882  o->write_characters(".0", 2);
18883  }
18884  }
18885 
18907  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
18908  {
18909  static const std::array<std::uint8_t, 400> utf8d =
18910  {
18911  {
18912  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
18913  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
18914  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
18915  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
18916  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
18917  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
18918  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
18919  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
18920  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
18921  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
18922  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
18923  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
18924  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
18925  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
18926  }
18927  };
18928 
18929  JSON_ASSERT(byte < utf8d.size());
18930  const std::uint8_t type = utf8d[byte];
18931 
18932  codep = (state != UTF8_ACCEPT)
18933  ? (byte & 0x3fu) | (codep << 6u)
18934  : (0xFFu >> type) & (byte);
18935 
18936  const std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
18937  JSON_ASSERT(index < utf8d.size());
18938  state = utf8d[index];
18939  return state;
18940  }
18941 
18942  /*
18943  * Overload to make the compiler happy while it is instantiating
18944  * dump_integer for number_unsigned_t.
18945  * Must never be called.
18946  */
18947  number_unsigned_t remove_sign(number_unsigned_t x)
18948  {
18949  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18950  return x; // LCOV_EXCL_LINE
18951  }
18952 
18953  /*
18954  * Helper function for dump_integer
18955  *
18956  * This function takes a negative signed integer and returns its absolute
18957  * value as unsigned integer. The plus/minus shuffling is necessary as we can
18958  * not directly remove the sign of an arbitrary signed integer as the
18959  * absolute values of INT_MIN and INT_MAX are usually not the same. See
18960  * #1708 for details.
18961  */
18962  inline number_unsigned_t remove_sign(number_integer_t x) noexcept
18963  {
18964  JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
18965  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
18966  }
18967 
18968  private:
18970  output_adapter_t<char> o = nullptr;
18971 
18973  std::array<char, 64> number_buffer{ {} };
18974 
18976  const std::lconv* loc = nullptr;
18978  const char thousands_sep = '\0';
18980  const char decimal_point = '\0';
18981 
18983  std::array<char, 512> string_buffer{ {} };
18984 
18986  const char indent_char;
18988  string_t indent_string;
18989 
18992  };
18993 
18994 } // namespace detail
18996 
18997 // #include <nlohmann/detail/value_t.hpp>
18998 
18999 // #include <nlohmann/json_fwd.hpp>
19000 
19001 // #include <nlohmann/ordered_map.hpp>
19002 // __ _____ _____ _____
19003 // __| | __| | | | JSON for Modern C++
19004 // | | |__ | | | | | | version 3.11.3
19005 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
19006 //
19007 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
19008 // SPDX-License-Identifier: MIT
19009 
19010 
19011 
19012 #include <functional> // equal_to, less
19013 #include <initializer_list> // initializer_list
19014 #include <iterator> // input_iterator_tag, iterator_traits
19015 #include <memory> // allocator
19016 #include <stdexcept> // for out_of_range
19017 #include <type_traits> // enable_if, is_convertible
19018 #include <utility> // pair
19019 #include <vector> // vector
19020 
19021 // #include <nlohmann/detail/macro_scope.hpp>
19022 
19023 // #include <nlohmann/detail/meta/type_traits.hpp>
19024 
19025 
19027 
19030 template <class Key, class T, class IgnoredLess = std::less<Key>,
19031  class Allocator = std::allocator<std::pair<const Key, T>>>
19032 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
19033 {
19034  using key_type = Key;
19035  using mapped_type = T;
19036  using Container = std::vector<std::pair<const Key, T>, Allocator>;
19037  using iterator = typename Container::iterator;
19038  using const_iterator = typename Container::const_iterator;
19039  using size_type = typename Container::size_type;
19040  using value_type = typename Container::value_type;
19041 #ifdef JSON_HAS_CPP_14
19042  using key_compare = std::equal_to<>;
19043 #else
19044  using key_compare = std::equal_to<Key>;
19045 #endif
19046 
19047  // Explicit constructors instead of `using Container::Container`
19048  // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
19049  ordered_map() noexcept(noexcept(Container())) : Container{} {}
19050  explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{ alloc } {}
19051  template <class It>
19052  ordered_map(It first, It last, const Allocator& alloc = Allocator())
19053  : Container{ first, last, alloc } {}
19054  ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator())
19055  : Container{ init, alloc } {}
19056 
19057  std::pair<iterator, bool> emplace(const key_type& key, T&& t)
19058  {
19059  for (auto it = this->begin(); it != this->end(); ++it)
19060  {
19061  if (m_compare(it->first, key))
19062  {
19063  return { it, false };
19064  }
19065  }
19066  Container::emplace_back(key, std::forward<T>(t));
19067  return { std::prev(this->end()), true };
19068  }
19069 
19070  template<class KeyType, detail::enable_if_t<
19072  std::pair<iterator, bool> emplace(KeyType&& key, T&& t)
19073  {
19074  for (auto it = this->begin(); it != this->end(); ++it)
19075  {
19076  if (m_compare(it->first, key))
19077  {
19078  return { it, false };
19079  }
19080  }
19081  Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
19082  return { std::prev(this->end()), true };
19083  }
19084 
19085  T& operator[](const key_type& key)
19086  {
19087  return emplace(key, T{}).first->second;
19088  }
19089 
19090  template<class KeyType, detail::enable_if_t<
19092  T& operator[](KeyType&& key)
19093  {
19094  return emplace(std::forward<KeyType>(key), T{}).first->second;
19095  }
19096 
19097  const T& operator[](const key_type& key) const
19098  {
19099  return at(key);
19100  }
19101 
19102  template<class KeyType, detail::enable_if_t<
19104  const T& operator[](KeyType&& key) const
19105  {
19106  return at(std::forward<KeyType>(key));
19107  }
19108 
19109  T& at(const key_type& key)
19110  {
19111  for (auto it = this->begin(); it != this->end(); ++it)
19112  {
19113  if (m_compare(it->first, key))
19114  {
19115  return it->second;
19116  }
19117  }
19118 
19119  JSON_THROW(std::out_of_range("key not found"));
19120  }
19121 
19122  template<class KeyType, detail::enable_if_t<
19124  T& at(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
19125  {
19126  for (auto it = this->begin(); it != this->end(); ++it)
19127  {
19128  if (m_compare(it->first, key))
19129  {
19130  return it->second;
19131  }
19132  }
19133 
19134  JSON_THROW(std::out_of_range("key not found"));
19135  }
19136 
19137  const T& at(const key_type& key) const
19138  {
19139  for (auto it = this->begin(); it != this->end(); ++it)
19140  {
19141  if (m_compare(it->first, key))
19142  {
19143  return it->second;
19144  }
19145  }
19146 
19147  JSON_THROW(std::out_of_range("key not found"));
19148  }
19149 
19150  template<class KeyType, detail::enable_if_t<
19152  const T& at(KeyType&& key) const // NOLINT(cppcoreguidelines-missing-std-forward)
19153  {
19154  for (auto it = this->begin(); it != this->end(); ++it)
19155  {
19156  if (m_compare(it->first, key))
19157  {
19158  return it->second;
19159  }
19160  }
19161 
19162  JSON_THROW(std::out_of_range("key not found"));
19163  }
19164 
19166  {
19167  for (auto it = this->begin(); it != this->end(); ++it)
19168  {
19169  if (m_compare(it->first, key))
19170  {
19171  // Since we cannot move const Keys, re-construct them in place
19172  for (auto next = it; ++next != this->end(); ++it)
19173  {
19174  it->~value_type(); // Destroy but keep allocation
19175  new (&*it) value_type{ std::move(*next) };
19176  }
19177  Container::pop_back();
19178  return 1;
19179  }
19180  }
19181  return 0;
19182  }
19183 
19184  template<class KeyType, detail::enable_if_t<
19186  size_type erase(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
19187  {
19188  for (auto it = this->begin(); it != this->end(); ++it)
19189  {
19190  if (m_compare(it->first, key))
19191  {
19192  // Since we cannot move const Keys, re-construct them in place
19193  for (auto next = it; ++next != this->end(); ++it)
19194  {
19195  it->~value_type(); // Destroy but keep allocation
19196  new (&*it) value_type{ std::move(*next) };
19197  }
19198  Container::pop_back();
19199  return 1;
19200  }
19201  }
19202  return 0;
19203  }
19204 
19206  {
19207  return erase(pos, std::next(pos));
19208  }
19209 
19211  {
19212  if (first == last)
19213  {
19214  return first;
19215  }
19216 
19217  const auto elements_affected = std::distance(first, last);
19218  const auto offset = std::distance(Container::begin(), first);
19219 
19220  // This is the start situation. We need to delete elements_affected
19221  // elements (3 in this example: e, f, g), and need to return an
19222  // iterator past the last deleted element (h in this example).
19223  // Note that offset is the distance from the start of the vector
19224  // to first. We will need this later.
19225 
19226  // [ a, b, c, d, e, f, g, h, i, j ]
19227  // ^ ^
19228  // first last
19229 
19230  // Since we cannot move const Keys, we re-construct them in place.
19231  // We start at first and re-construct (viz. copy) the elements from
19232  // the back of the vector. Example for first iteration:
19233 
19234  // ,--------.
19235  // v | destroy e and re-construct with h
19236  // [ a, b, c, d, e, f, g, h, i, j ]
19237  // ^ ^
19238  // it it + elements_affected
19239 
19240  for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
19241  {
19242  it->~value_type(); // destroy but keep allocation
19243  new (&*it) value_type{ std::move(*std::next(it, elements_affected)) }; // "move" next element to it
19244  }
19245 
19246  // [ a, b, c, d, h, i, j, h, i, j ]
19247  // ^ ^
19248  // first last
19249 
19250  // remove the unneeded elements at the end of the vector
19251  Container::resize(this->size() - static_cast<size_type>(elements_affected));
19252 
19253  // [ a, b, c, d, h, i, j ]
19254  // ^ ^
19255  // first last
19256 
19257  // first is now pointing past the last deleted element, but we cannot
19258  // use this iterator, because it may have been invalidated by the
19259  // resize call. Instead, we can return begin() + offset.
19260  return Container::begin() + offset;
19261  }
19262 
19263  size_type count(const key_type& key) const
19264  {
19265  for (auto it = this->begin(); it != this->end(); ++it)
19266  {
19267  if (m_compare(it->first, key))
19268  {
19269  return 1;
19270  }
19271  }
19272  return 0;
19273  }
19274 
19275  template<class KeyType, detail::enable_if_t<
19277  size_type count(KeyType&& key) const // NOLINT(cppcoreguidelines-missing-std-forward)
19278  {
19279  for (auto it = this->begin(); it != this->end(); ++it)
19280  {
19281  if (m_compare(it->first, key))
19282  {
19283  return 1;
19284  }
19285  }
19286  return 0;
19287  }
19288 
19289  iterator find(const key_type& key)
19290  {
19291  for (auto it = this->begin(); it != this->end(); ++it)
19292  {
19293  if (m_compare(it->first, key))
19294  {
19295  return it;
19296  }
19297  }
19298  return Container::end();
19299  }
19300 
19301  template<class KeyType, detail::enable_if_t<
19303  iterator find(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
19304  {
19305  for (auto it = this->begin(); it != this->end(); ++it)
19306  {
19307  if (m_compare(it->first, key))
19308  {
19309  return it;
19310  }
19311  }
19312  return Container::end();
19313  }
19314 
19315  const_iterator find(const key_type& key) const
19316  {
19317  for (auto it = this->begin(); it != this->end(); ++it)
19318  {
19319  if (m_compare(it->first, key))
19320  {
19321  return it;
19322  }
19323  }
19324  return Container::end();
19325  }
19326 
19327  std::pair<iterator, bool> insert(value_type&& value)
19328  {
19329  return emplace(value.first, std::move(value.second));
19330  }
19331 
19332  std::pair<iterator, bool> insert(const value_type& value)
19333  {
19334  for (auto it = this->begin(); it != this->end(); ++it)
19335  {
19336  if (m_compare(it->first, value.first))
19337  {
19338  return { it, false };
19339  }
19340  }
19341  Container::push_back(value);
19342  return { --this->end(), true };
19343  }
19344 
19345  template<typename InputIt>
19346  using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
19347  std::input_iterator_tag>::value>::type;
19348 
19349  template<typename InputIt, typename = require_input_iter<InputIt>>
19350  void insert(InputIt first, InputIt last)
19351  {
19352  for (auto it = first; it != last; ++it)
19353  {
19354  insert(*it);
19355  }
19356  }
19357 
19358 private:
19360 };
19361 
19363 
19364 
19365 #if defined(JSON_HAS_CPP_17)
19366 #if JSON_HAS_STATIC_RTTI
19367 #include <any>
19368 #endif
19369 #include <string_view>
19370 #endif
19371 
19378 
19398 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
19399  : public ::nlohmann::detail::json_base_class<CustomBaseClass>
19400 {
19401 private:
19402  template<detail::value_t> friend struct detail::external_constructor;
19403 
19404  template<typename>
19405  friend class ::nlohmann::json_pointer;
19406  // can be restored when json_pointer backwards compatibility is removed
19407  // friend ::nlohmann::json_pointer<StringType>;
19408 
19409  template<typename BasicJsonType, typename InputType>
19410  friend class ::nlohmann::detail::parser;
19411  friend ::nlohmann::detail::serializer<basic_json>;
19412  template<typename BasicJsonType>
19413  friend class ::nlohmann::detail::iter_impl;
19414  template<typename BasicJsonType, typename CharType>
19415  friend class ::nlohmann::detail::binary_writer;
19416  template<typename BasicJsonType, typename InputType, typename SAX>
19417  friend class ::nlohmann::detail::binary_reader;
19418  template<typename BasicJsonType>
19419  friend class ::nlohmann::detail::json_sax_dom_parser;
19420  template<typename BasicJsonType>
19421  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
19422  friend class ::nlohmann::detail::exception;
19423 
19425  using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
19426  using json_base_class_t = ::nlohmann::detail::json_base_class<CustomBaseClass>;
19427 
19429  // convenience aliases for types residing in namespace detail;
19430  using lexer = ::nlohmann::detail::lexer_base<basic_json>;
19431 
19432  template<typename InputAdapterType>
19433  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
19434  InputAdapterType adapter,
19436  const bool allow_exceptions = true,
19437  const bool ignore_comments = false
19438  )
19439  {
19440  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
19441  std::move(cb), allow_exceptions, ignore_comments);
19442  }
19443 
19444 private:
19445  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
19446  template<typename BasicJsonType>
19447  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
19448  template<typename BasicJsonType>
19449  using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
19450  template<typename Iterator>
19451  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
19452  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
19453 
19454  template<typename CharType>
19455  using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
19456 
19457  template<typename InputType>
19458  using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
19459  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
19460 
19462  using serializer = ::nlohmann::detail::serializer<basic_json>;
19463 
19464 public:
19467  using json_pointer = ::nlohmann::json_pointer<StringType>;
19468  template<typename T, typename SFINAE>
19469  using json_serializer = JSONSerializer<T, SFINAE>;
19475  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
19476 
19480 
19482  // exceptions //
19484 
19488 
19495 
19497 
19499  // container types //
19501 
19506 
19509 
19513  using const_reference = const value_type&;
19514 
19516  using difference_type = std::ptrdiff_t;
19518  using size_type = std::size_t;
19519 
19521  using allocator_type = AllocatorType<basic_json>;
19522 
19524  using pointer = typename std::allocator_traits<allocator_type>::pointer;
19526  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
19527 
19529  using iterator = iter_impl<basic_json>;
19531  using const_iterator = iter_impl<const basic_json>;
19533  using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
19535  using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
19536 
19538 
19542  {
19543  return allocator_type();
19544  }
19545 
19549  static basic_json meta()
19550  {
19551  basic_json result;
19552 
19553  result["copyright"] = "(C) 2013-2023 Niels Lohmann";
19554  result["name"] = "JSON for Modern C++";
19555  result["url"] = "https://github.com/nlohmann/json";
19556  result["version"]["string"] =
19560  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
19561  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
19562  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
19563 
19564 #ifdef _WIN32
19565  result["platform"] = "win32";
19566 #elif defined __linux__
19567  result["platform"] = "linux";
19568 #elif defined __APPLE__
19569  result["platform"] = "apple";
19570 #elif defined __unix__
19571  result["platform"] = "unix";
19572 #else
19573  result["platform"] = "unknown";
19574 #endif
19575 
19576 #if defined(__ICC) || defined(__INTEL_COMPILER)
19577  result["compiler"] = { {"family", "icc"}, {"version", __INTEL_COMPILER} };
19578 #elif defined(__clang__)
19579  result["compiler"] = { {"family", "clang"}, {"version", __clang_version__} };
19580 #elif defined(__GNUC__) || defined(__GNUG__)
19581  result["compiler"] = { {"family", "gcc"}, {"version", detail::concat(
19582  std::to_string(__GNUC__), '.',
19583  std::to_string(__GNUC_MINOR__), '.',
19584  std::to_string(__GNUC_PATCHLEVEL__))
19585  }
19586  };
19587 #elif defined(__HP_cc) || defined(__HP_aCC)
19588  result["compiler"] = "hp"
19589 #elif defined(__IBMCPP__)
19590  result["compiler"] = { {"family", "ilecpp"}, {"version", __IBMCPP__} };
19591 #elif defined(_MSC_VER)
19592  result["compiler"] = { {"family", "msvc"}, {"version", _MSC_VER} };
19593 #elif defined(__PGI)
19594  result["compiler"] = { {"family", "pgcpp"}, {"version", __PGI} };
19595 #elif defined(__SUNPRO_CC)
19596  result["compiler"] = { {"family", "sunpro"}, {"version", __SUNPRO_CC} };
19597 #else
19598  result["compiler"] = { {"family", "unknown"}, {"version", "unknown"} };
19599 #endif
19600 
19601 #if defined(_MSVC_LANG)
19602  result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
19603 #elif defined(__cplusplus)
19604  result["compiler"]["c++"] = std::to_string(__cplusplus);
19605 #else
19606  result["compiler"]["c++"] = "unknown";
19607 #endif
19608  return result;
19609  }
19610 
19612  // JSON value data types //
19614 
19619 
19624 #if defined(JSON_HAS_CPP_14)
19625  // use of transparent comparator avoids unnecessary repeated construction of temporaries
19626  // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
19627  using default_object_comparator_t = std::less<>;
19628 #else
19629  using default_object_comparator_t = std::less<StringType>;
19630 #endif
19631 
19634  using object_t = ObjectType<StringType,
19635  basic_json,
19637  AllocatorType<std::pair<const StringType,
19638  basic_json>>>;
19639 
19642  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
19643 
19646  using string_t = StringType;
19647 
19650  using boolean_t = BooleanType;
19651 
19654  using number_integer_t = NumberIntegerType;
19655 
19658  using number_unsigned_t = NumberUnsignedType;
19659 
19662  using number_float_t = NumberFloatType;
19663 
19666  using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
19667 
19671 
19673 
19674 private:
19675 
19677  template<typename T, typename... Args>
19679  static T* create(Args&& ... args)
19680  {
19681  AllocatorType<T> alloc;
19682  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
19683 
19684  auto deleter = [&](T* obj)
19685  {
19686  AllocatorTraits::deallocate(alloc, obj, 1);
19687  };
19688  std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
19689  AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
19690  JSON_ASSERT(obj != nullptr);
19691  return obj.release();
19692  }
19693 
19695  // JSON value storage //
19697 
19724  union json_value
19725  {
19727  object_t* object;
19729  array_t* array;
19731  string_t* string;
19733  binary_t* binary;
19735  boolean_t boolean;
19737  number_integer_t number_integer;
19739  number_unsigned_t number_unsigned;
19741  number_float_t number_float;
19742 
19744  json_value() = default;
19746  json_value(boolean_t v) noexcept : boolean(v) {}
19748  json_value(number_integer_t v) noexcept : number_integer(v) {}
19750  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
19752  json_value(number_float_t v) noexcept : number_float(v) {}
19754  json_value(value_t t)
19755  {
19756  switch (t)
19757  {
19758  case value_t::object:
19759  {
19760  object = create<object_t>();
19761  break;
19762  }
19763 
19764  case value_t::array:
19765  {
19766  array = create<array_t>();
19767  break;
19768  }
19769 
19770  case value_t::string:
19771  {
19772  string = create<string_t>("");
19773  break;
19774  }
19775 
19776  case value_t::binary:
19777  {
19778  binary = create<binary_t>();
19779  break;
19780  }
19781 
19782  case value_t::boolean:
19783  {
19784  boolean = static_cast<boolean_t>(false);
19785  break;
19786  }
19787 
19789  {
19790  number_integer = static_cast<number_integer_t>(0);
19791  break;
19792  }
19793 
19795  {
19796  number_unsigned = static_cast<number_unsigned_t>(0);
19797  break;
19798  }
19799 
19800  case value_t::number_float:
19801  {
19802  number_float = static_cast<number_float_t>(0.0);
19803  break;
19804  }
19805 
19806  case value_t::null:
19807  {
19808  object = nullptr; // silence warning, see #821
19809  break;
19810  }
19811 
19812  case value_t::discarded:
19813  default:
19814  {
19815  object = nullptr; // silence warning, see #821
19817  {
19818  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.3", nullptr)); // LCOV_EXCL_LINE
19819  }
19820  break;
19821  }
19822  }
19823  }
19824 
19826  json_value(const string_t& value) : string(create<string_t>(value)) {}
19827 
19829  json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
19830 
19832  json_value(const object_t& value) : object(create<object_t>(value)) {}
19833 
19835  json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
19836 
19838  json_value(const array_t& value) : array(create<array_t>(value)) {}
19839 
19841  json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
19842 
19844  json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
19845 
19847  json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
19848 
19850  json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
19851 
19853  json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
19854 
19855  void destroy(value_t t)
19856  {
19857  if (
19858  (t == value_t::object && object == nullptr) ||
19859  (t == value_t::array && array == nullptr) ||
19860  (t == value_t::string && string == nullptr) ||
19861  (t == value_t::binary && binary == nullptr)
19862  )
19863  {
19864  //not initialized (e.g. due to exception in the ctor)
19865  return;
19866  }
19867  if (t == value_t::array || t == value_t::object)
19868  {
19869  // flatten the current json_value to a heap-allocated stack
19870  std::vector<basic_json> stack;
19871 
19872  // move the top-level items to stack
19873  if (t == value_t::array)
19874  {
19875  stack.reserve(array->size());
19876  std::move(array->begin(), array->end(), std::back_inserter(stack));
19877  }
19878  else
19879  {
19880  stack.reserve(object->size());
19881  for (auto&& it : *object)
19882  {
19883  stack.push_back(std::move(it.second));
19884  }
19885  }
19886 
19887  while (!stack.empty())
19888  {
19889  // move the last item to local variable to be processed
19890  basic_json current_item(std::move(stack.back()));
19891  stack.pop_back();
19892 
19893  // if current_item is array/object, move
19894  // its children to the stack to be processed later
19895  if (current_item.is_array())
19896  {
19897  std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
19898 
19899  current_item.m_data.m_value.array->clear();
19900  }
19901  else if (current_item.is_object())
19902  {
19903  for (auto&& it : *current_item.m_data.m_value.object)
19904  {
19905  stack.push_back(std::move(it.second));
19906  }
19907 
19908  current_item.m_data.m_value.object->clear();
19909  }
19910 
19911  // it's now safe that current_item get destructed
19912  // since it doesn't have any children
19913  }
19914  }
19915 
19916  switch (t)
19917  {
19918  case value_t::object:
19919  {
19920  AllocatorType<object_t> alloc;
19921  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
19922  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
19923  break;
19924  }
19925 
19926  case value_t::array:
19927  {
19928  AllocatorType<array_t> alloc;
19929  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
19930  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
19931  break;
19932  }
19933 
19934  case value_t::string:
19935  {
19936  AllocatorType<string_t> alloc;
19937  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
19938  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
19939  break;
19940  }
19941 
19942  case value_t::binary:
19943  {
19944  AllocatorType<binary_t> alloc;
19945  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
19946  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
19947  break;
19948  }
19949 
19950  case value_t::null:
19951  case value_t::boolean:
19954  case value_t::number_float:
19955  case value_t::discarded:
19956  default:
19957  {
19958  break;
19959  }
19960  }
19961  }
19962  };
19963 
19964 private:
19983  void assert_invariant(bool check_parents = true) const noexcept
19984  {
19985  JSON_ASSERT(m_data.m_type != value_t::object || m_data.m_value.object != nullptr);
19986  JSON_ASSERT(m_data.m_type != value_t::array || m_data.m_value.array != nullptr);
19987  JSON_ASSERT(m_data.m_type != value_t::string || m_data.m_value.string != nullptr);
19988  JSON_ASSERT(m_data.m_type != value_t::binary || m_data.m_value.binary != nullptr);
19989 
19990 #if JSON_DIAGNOSTICS
19991  JSON_TRY
19992  {
19993  // cppcheck-suppress assertWithSideEffect
19994  JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json& j)
19995  {
19996  return j.m_parent == this;
19997  }));
19998  }
19999  JSON_CATCH(...) {} // LCOV_EXCL_LINE
20000 #endif
20001  static_cast<void>(check_parents);
20002  }
20003 
20004  void set_parents()
20005  {
20006 #if JSON_DIAGNOSTICS
20007  switch (m_data.m_type)
20008  {
20009  case value_t::array:
20010  {
20011  for (auto& element : *m_data.m_value.array)
20012  {
20013  element.m_parent = this;
20014  }
20015  break;
20016  }
20017 
20018  case value_t::object:
20019  {
20020  for (auto& element : *m_data.m_value.object)
20021  {
20022  element.second.m_parent = this;
20023  }
20024  break;
20025  }
20026 
20027  case value_t::null:
20028  case value_t::string:
20029  case value_t::boolean:
20032  case value_t::number_float:
20033  case value_t::binary:
20034  case value_t::discarded:
20035  default:
20036  break;
20037  }
20038 #endif
20039  }
20040 
20041  iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
20042  {
20043 #if JSON_DIAGNOSTICS
20044  for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
20045  {
20046  (it + i)->m_parent = this;
20047  }
20048 #else
20049  static_cast<void>(count_set_parents);
20050 #endif
20051  return it;
20052  }
20053 
20054  reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
20055  {
20056 #if JSON_DIAGNOSTICS
20057  if (old_capacity != static_cast<std::size_t>(-1))
20058  {
20059  // see https://github.com/nlohmann/json/issues/2838
20061  if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
20062  {
20063  // capacity has changed: update all parents
20064  set_parents();
20065  return j;
20066  }
20067  }
20068 
20069  // ordered_json uses a vector internally, so pointers could have
20070  // been invalidated; see https://github.com/nlohmann/json/issues/2962
20071 #ifdef JSON_HEDLEY_MSVC_VERSION
20072 #pragma warning(push )
20073 #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
20074 #endif
20076  {
20077  set_parents();
20078  return j;
20079  }
20080 #ifdef JSON_HEDLEY_MSVC_VERSION
20081 #pragma warning( pop )
20082 #endif
20083 
20084  j.m_parent = this;
20085 #else
20086  static_cast<void>(j);
20087  static_cast<void>(old_capacity);
20088 #endif
20089  return j;
20090  }
20091 
20092 public:
20094  // JSON parser callback //
20096 
20100 
20104 
20106  // constructors //
20108 
20113 
20117  : m_data(v)
20118  {
20119  assert_invariant();
20120  }
20121 
20124  basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
20125  : basic_json(value_t::null)
20126  {
20127  assert_invariant();
20128  }
20129 
20132  template < typename CompatibleType,
20133  typename U = detail::uncvref_t<CompatibleType>,
20136  basic_json(CompatibleType&& val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
20137  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
20138  std::forward<CompatibleType>(val))))
20139  {
20140  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
20141  set_parents();
20142  assert_invariant();
20143  }
20144 
20147  template < typename BasicJsonType,
20149  detail::is_basic_json<BasicJsonType>::value && !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
20150  basic_json(const BasicJsonType& val)
20151  {
20152  using other_boolean_t = typename BasicJsonType::boolean_t;
20153  using other_number_float_t = typename BasicJsonType::number_float_t;
20154  using other_number_integer_t = typename BasicJsonType::number_integer_t;
20155  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
20156  using other_string_t = typename BasicJsonType::string_t;
20157  using other_object_t = typename BasicJsonType::object_t;
20158  using other_array_t = typename BasicJsonType::array_t;
20159  using other_binary_t = typename BasicJsonType::binary_t;
20160 
20161  switch (val.type())
20162  {
20163  case value_t::boolean:
20164  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
20165  break;
20166  case value_t::number_float:
20167  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
20168  break;
20170  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
20171  break;
20173  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
20174  break;
20175  case value_t::string:
20176  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
20177  break;
20178  case value_t::object:
20179  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
20180  break;
20181  case value_t::array:
20182  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
20183  break;
20184  case value_t::binary:
20185  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
20186  break;
20187  case value_t::null:
20188  *this = nullptr;
20189  break;
20190  case value_t::discarded:
20191  m_data.m_type = value_t::discarded;
20192  break;
20193  default: // LCOV_EXCL_LINE
20194  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
20195  }
20196  JSON_ASSERT(m_data.m_type == val.type());
20197  set_parents();
20198  assert_invariant();
20199  }
20200 
20204  bool type_deduction = true,
20205  value_t manual_type = value_t::array)
20206  {
20207  // check if each element is an array with two elements whose first
20208  // element is a string
20209  bool is_an_object = std::all_of(init.begin(), init.end(),
20210  [](const detail::json_ref<basic_json>& element_ref)
20211  {
20212  // The cast is to ensure op[size_type] is called, bearing in mind size_type may not be int;
20213  // (many string types can be constructed from 0 via its null-pointer guise, so we get a
20214  // broken call to op[key_type], the wrong semantics and a 4804 warning on Windows)
20215  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[static_cast<size_type>(0)].is_string();
20216  });
20217 
20218  // adjust type if type deduction is not wanted
20219  if (!type_deduction)
20220  {
20221  // if array is wanted, do not create an object though possible
20222  if (manual_type == value_t::array)
20223  {
20224  is_an_object = false;
20225  }
20226 
20227  // if object is wanted but impossible, throw an exception
20228  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
20229  {
20230  JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
20231  }
20232  }
20233 
20234  if (is_an_object)
20235  {
20236  // the initializer list is a list of pairs -> create object
20237  m_data.m_type = value_t::object;
20238  m_data.m_value = value_t::object;
20239 
20240  for (auto& element_ref : init)
20241  {
20242  auto element = element_ref.moved_or_copied();
20243  m_data.m_value.object->emplace(
20244  std::move(*((*element.m_data.m_value.array)[0].m_data.m_value.string)),
20245  std::move((*element.m_data.m_value.array)[1]));
20246  }
20247  }
20248  else
20249  {
20250  // the initializer list describes an array -> create array
20251  m_data.m_type = value_t::array;
20252  m_data.m_value.array = create<array_t>(init.begin(), init.end());
20253  }
20254 
20255  set_parents();
20256  assert_invariant();
20257  }
20258 
20262  static basic_json binary(const typename binary_t::container_type& init)
20263  {
20264  auto res = basic_json();
20265  res.m_data.m_type = value_t::binary;
20266  res.m_data.m_value = init;
20267  return res;
20268  }
20269 
20273  static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
20274  {
20275  auto res = basic_json();
20276  res.m_data.m_type = value_t::binary;
20277  res.m_data.m_value = binary_t(init, subtype);
20278  return res;
20279  }
20280 
20284  static basic_json binary(typename binary_t::container_type&& init)
20285  {
20286  auto res = basic_json();
20287  res.m_data.m_type = value_t::binary;
20288  res.m_data.m_value = std::move(init);
20289  return res;
20290  }
20291 
20295  static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
20296  {
20297  auto res = basic_json();
20298  res.m_data.m_type = value_t::binary;
20299  res.m_data.m_value = binary_t(std::move(init), subtype);
20300  return res;
20301  }
20302 
20307  {
20308  return basic_json(init, false, value_t::array);
20309  }
20310 
20315  {
20316  return basic_json(init, false, value_t::object);
20317  }
20318 
20321  basic_json(size_type cnt, const basic_json& val) :
20322  m_data{ cnt, val }
20323  {
20324  set_parents();
20325  assert_invariant();
20326  }
20327 
20330  template < class InputIT, typename std::enable_if <
20331  std::is_same<InputIT, typename basic_json_t::iterator>::value ||
20332  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
20333  basic_json(InputIT first, InputIT last)
20334  {
20335  JSON_ASSERT(first.m_object != nullptr);
20336  JSON_ASSERT(last.m_object != nullptr);
20337 
20338  // make sure iterator fits the current value
20339  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20340  {
20341  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
20342  }
20343 
20344  // copy type from first iterator
20345  m_data.m_type = first.m_object->m_data.m_type;
20346 
20347  // check if iterator range is complete for primitive values
20348  switch (m_data.m_type)
20349  {
20350  case value_t::boolean:
20351  case value_t::number_float:
20354  case value_t::string:
20355  {
20356  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
20357  || !last.m_it.primitive_iterator.is_end()))
20358  {
20359  JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
20360  }
20361  break;
20362  }
20363 
20364  case value_t::null:
20365  case value_t::object:
20366  case value_t::array:
20367  case value_t::binary:
20368  case value_t::discarded:
20369  default:
20370  break;
20371  }
20372 
20373  switch (m_data.m_type)
20374  {
20376  {
20377  m_data.m_value.number_integer = first.m_object->m_data.m_value.number_integer;
20378  break;
20379  }
20380 
20382  {
20383  m_data.m_value.number_unsigned = first.m_object->m_data.m_value.number_unsigned;
20384  break;
20385  }
20386 
20387  case value_t::number_float:
20388  {
20389  m_data.m_value.number_float = first.m_object->m_data.m_value.number_float;
20390  break;
20391  }
20392 
20393  case value_t::boolean:
20394  {
20395  m_data.m_value.boolean = first.m_object->m_data.m_value.boolean;
20396  break;
20397  }
20398 
20399  case value_t::string:
20400  {
20401  m_data.m_value = *first.m_object->m_data.m_value.string;
20402  break;
20403  }
20404 
20405  case value_t::object:
20406  {
20407  m_data.m_value.object = create<object_t>(first.m_it.object_iterator,
20408  last.m_it.object_iterator);
20409  break;
20410  }
20411 
20412  case value_t::array:
20413  {
20414  m_data.m_value.array = create<array_t>(first.m_it.array_iterator,
20415  last.m_it.array_iterator);
20416  break;
20417  }
20418 
20419  case value_t::binary:
20420  {
20421  m_data.m_value = *first.m_object->m_data.m_value.binary;
20422  break;
20423  }
20424 
20425  case value_t::null:
20426  case value_t::discarded:
20427  default:
20428  JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
20429  }
20430 
20431  set_parents();
20432  assert_invariant();
20433  }
20434 
20436  // other constructors and destructor //
20438 
20439  template<typename JsonRef,
20441  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
20442  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
20443 
20446  basic_json(const basic_json& other)
20447  : json_base_class_t(other)
20448  {
20449  m_data.m_type = other.m_data.m_type;
20450  // check of passed value is valid
20451  other.assert_invariant();
20452 
20453  switch (m_data.m_type)
20454  {
20455  case value_t::object:
20456  {
20457  m_data.m_value = *other.m_data.m_value.object;
20458  break;
20459  }
20460 
20461  case value_t::array:
20462  {
20463  m_data.m_value = *other.m_data.m_value.array;
20464  break;
20465  }
20466 
20467  case value_t::string:
20468  {
20469  m_data.m_value = *other.m_data.m_value.string;
20470  break;
20471  }
20472 
20473  case value_t::boolean:
20474  {
20475  m_data.m_value = other.m_data.m_value.boolean;
20476  break;
20477  }
20478 
20480  {
20481  m_data.m_value = other.m_data.m_value.number_integer;
20482  break;
20483  }
20484 
20486  {
20487  m_data.m_value = other.m_data.m_value.number_unsigned;
20488  break;
20489  }
20490 
20491  case value_t::number_float:
20492  {
20493  m_data.m_value = other.m_data.m_value.number_float;
20494  break;
20495  }
20496 
20497  case value_t::binary:
20498  {
20499  m_data.m_value = *other.m_data.m_value.binary;
20500  break;
20501  }
20502 
20503  case value_t::null:
20504  case value_t::discarded:
20505  default:
20506  break;
20507  }
20508 
20509  set_parents();
20510  assert_invariant();
20511  }
20512 
20515  basic_json(basic_json&& other) noexcept
20516  : json_base_class_t(std::forward<json_base_class_t>(other)),
20517  m_data(std::move(other.m_data))
20518  {
20519  // check that passed value is valid
20520  other.assert_invariant(false);
20521 
20522  // invalidate payload
20523  other.m_data.m_type = value_t::null;
20524  other.m_data.m_value = {};
20525 
20526  set_parents();
20527  assert_invariant();
20528  }
20529 
20532  basic_json& operator=(basic_json other) noexcept (
20533  std::is_nothrow_move_constructible<value_t>::value&&
20534  std::is_nothrow_move_assignable<value_t>::value&&
20535  std::is_nothrow_move_constructible<json_value>::value&&
20536  std::is_nothrow_move_assignable<json_value>::value&&
20537  std::is_nothrow_move_assignable<json_base_class_t>::value
20538  )
20539  {
20540  // check that passed value is valid
20541  other.assert_invariant();
20542 
20543  using std::swap;
20544  swap(m_data.m_type, other.m_data.m_type);
20545  swap(m_data.m_value, other.m_data.m_value);
20546  json_base_class_t::operator=(std::move(other));
20547 
20548  set_parents();
20549  assert_invariant();
20550  return *this;
20551  }
20552 
20555  ~basic_json() noexcept
20556  {
20557  assert_invariant(false);
20558  }
20559 
20561 
20562 public:
20564  // object inspection //
20566 
20570 
20573  string_t dump(const int indent = -1,
20574  const char indent_char = ' ',
20575  const bool ensure_ascii = false,
20576  const error_handler_t error_handler = error_handler_t::strict) const
20577  {
20578  string_t result;
20579  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
20580 
20581  if (indent >= 0)
20582  {
20583  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
20584  }
20585  else
20586  {
20587  s.dump(*this, false, ensure_ascii, 0);
20588  }
20589 
20590  return result;
20591  }
20592 
20595  constexpr value_t type() const noexcept
20596  {
20597  return m_data.m_type;
20598  }
20599 
20602  constexpr bool is_primitive() const noexcept
20603  {
20604  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20605  }
20606 
20609  constexpr bool is_structured() const noexcept
20610  {
20611  return is_array() || is_object();
20612  }
20613 
20616  constexpr bool is_null() const noexcept
20617  {
20618  return m_data.m_type == value_t::null;
20619  }
20620 
20623  constexpr bool is_boolean() const noexcept
20624  {
20625  return m_data.m_type == value_t::boolean;
20626  }
20627 
20630  constexpr bool is_number() const noexcept
20631  {
20632  return is_number_integer() || is_number_float();
20633  }
20634 
20637  constexpr bool is_number_integer() const noexcept
20638  {
20639  return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
20640  }
20641 
20644  constexpr bool is_number_unsigned() const noexcept
20645  {
20646  return m_data.m_type == value_t::number_unsigned;
20647  }
20648 
20651  constexpr bool is_number_float() const noexcept
20652  {
20653  return m_data.m_type == value_t::number_float;
20654  }
20655 
20658  constexpr bool is_object() const noexcept
20659  {
20660  return m_data.m_type == value_t::object;
20661  }
20662 
20665  constexpr bool is_array() const noexcept
20666  {
20667  return m_data.m_type == value_t::array;
20668  }
20669 
20672  constexpr bool is_string() const noexcept
20673  {
20674  return m_data.m_type == value_t::string;
20675  }
20676 
20679  constexpr bool is_binary() const noexcept
20680  {
20681  return m_data.m_type == value_t::binary;
20682  }
20683 
20686  constexpr bool is_discarded() const noexcept
20687  {
20688  return m_data.m_type == value_t::discarded;
20689  }
20690 
20693  constexpr operator value_t() const noexcept
20694  {
20695  return m_data.m_type;
20696  }
20697 
20699 
20700 private:
20702  // value access //
20704 
20706  boolean_t get_impl(boolean_t* /*unused*/) const
20707  {
20709  {
20710  return m_data.m_value.boolean;
20711  }
20712 
20713  JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
20714  }
20715 
20717  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20718  {
20719  return is_object() ? m_data.m_value.object : nullptr;
20720  }
20721 
20723  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20724  {
20725  return is_object() ? m_data.m_value.object : nullptr;
20726  }
20727 
20729  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20730  {
20731  return is_array() ? m_data.m_value.array : nullptr;
20732  }
20733 
20735  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20736  {
20737  return is_array() ? m_data.m_value.array : nullptr;
20738  }
20739 
20741  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20742  {
20743  return is_string() ? m_data.m_value.string : nullptr;
20744  }
20745 
20747  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20748  {
20749  return is_string() ? m_data.m_value.string : nullptr;
20750  }
20751 
20753  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20754  {
20755  return is_boolean() ? &m_data.m_value.boolean : nullptr;
20756  }
20757 
20759  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20760  {
20761  return is_boolean() ? &m_data.m_value.boolean : nullptr;
20762  }
20763 
20765  number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20766  {
20767  return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
20768  }
20769 
20771  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20772  {
20773  return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
20774  }
20775 
20777  number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20778  {
20779  return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
20780  }
20781 
20783  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20784  {
20785  return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
20786  }
20787 
20789  number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20790  {
20791  return is_number_float() ? &m_data.m_value.number_float : nullptr;
20792  }
20793 
20795  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20796  {
20797  return is_number_float() ? &m_data.m_value.number_float : nullptr;
20798  }
20799 
20801  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20802  {
20803  return is_binary() ? m_data.m_value.binary : nullptr;
20804  }
20805 
20807  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20808  {
20809  return is_binary() ? m_data.m_value.binary : nullptr;
20810  }
20811 
20823  template<typename ReferenceType, typename ThisType>
20824  static ReferenceType get_ref_impl(ThisType& obj)
20825  {
20826  // delegate the call to get_ptr<>()
20827  auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20828 
20829  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20830  {
20831  return *ptr;
20832  }
20833 
20834  JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
20835  }
20836 
20837 public:
20841 
20844  template<typename PointerType, typename std::enable_if<
20845  std::is_pointer<PointerType>::value, int>::type = 0>
20846  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20847  {
20848  // delegate the call to get_impl_ptr<>()
20849  return get_impl_ptr(static_cast<PointerType>(nullptr));
20850  }
20851 
20854  template < typename PointerType, typename std::enable_if <
20855  std::is_pointer<PointerType>::value&&
20856  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20857  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20858  {
20859  // delegate the call to get_impl_ptr<>() const
20860  return get_impl_ptr(static_cast<PointerType>(nullptr));
20861  }
20862 
20863 private:
20902  template < typename ValueType,
20906  int > = 0 >
20907  ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20908  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20909  {
20910  auto ret = ValueType();
20912  return ret;
20913  }
20914 
20945  template < typename ValueType,
20948  int > = 0 >
20949  ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20950  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20951  {
20953  }
20954 
20970  template < typename BasicJsonType,
20973  int > = 0 >
20974  BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20975  {
20976  return *this;
20977  }
20978 
20993  template<typename BasicJsonType,
20995  std::is_same<BasicJsonType, basic_json_t>::value,
20996  int> = 0>
20997  basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20998  {
20999  return *this;
21000  }
21001 
21006  template<typename PointerType,
21008  std::is_pointer<PointerType>::value,
21009  int> = 0>
21010  constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
21011  -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
21012  {
21013  // delegate the call to get_ptr
21014  return get_ptr<PointerType>();
21015  }
21016 
21017 public:
21041  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
21042 #if defined(JSON_HAS_CPP_14)
21043  constexpr
21044 #endif
21045  auto get() const noexcept(
21046  noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
21047  -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
21048  {
21049  // we cannot static_assert on ValueTypeCV being non-const, because
21050  // there is support for get<const basic_json_t>(), which is why we
21051  // still need the uncvref
21052  static_assert(!std::is_reference<ValueTypeCV>::value,
21053  "get() cannot be used with reference types, you might want to use get_ref()");
21054  return get_impl<ValueType>(detail::priority_tag<4> {});
21055  }
21056 
21084  template<typename PointerType, typename std::enable_if<
21085  std::is_pointer<PointerType>::value, int>::type = 0>
21086  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
21087  {
21088  // delegate the call to get_ptr
21089  return get_ptr<PointerType>();
21090  }
21091 
21094  template < typename ValueType,
21098  int > = 0 >
21099  ValueType& get_to(ValueType& v) const noexcept(noexcept(
21100  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
21101  {
21103  return v;
21104  }
21105 
21106  // specialization to allow calling get_to with a basic_json value
21107  // see https://github.com/nlohmann/json/issues/2175
21108  template<typename ValueType,
21111  int> = 0>
21112  ValueType& get_to(ValueType& v) const
21113  {
21114  v = *this;
21115  return v;
21116  }
21117 
21118  template <
21119  typename T, std::size_t N,
21120  typename Array = T(&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21123  Array get_to(T(&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21124  noexcept(noexcept(JSONSerializer<Array>::from_json(
21125  std::declval<const basic_json_t&>(), v)))
21126  {
21128  return v;
21129  }
21130 
21133  template<typename ReferenceType, typename std::enable_if<
21134  std::is_reference<ReferenceType>::value, int>::type = 0>
21135  ReferenceType get_ref()
21136  {
21137  // delegate call to get_ref_impl
21138  return get_ref_impl<ReferenceType>(*this);
21139  }
21140 
21143  template < typename ReferenceType, typename std::enable_if <
21144  std::is_reference<ReferenceType>::value&&
21145  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
21146  ReferenceType get_ref() const
21147  {
21148  // delegate call to get_ref_impl
21149  return get_ref_impl<ReferenceType>(*this);
21150  }
21151 
21181  template < typename ValueType, typename std::enable_if <
21189 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
21191 #endif
21192 #if defined(JSON_HAS_CPP_17) && JSON_HAS_STATIC_RTTI
21194 #endif
21196  >::value, int >::type = 0 >
21197  JSON_EXPLICIT operator ValueType() const
21198  {
21199  // delegate the call to get<>() const
21200  return get<ValueType>();
21201  }
21202 
21206  {
21207  if (!is_binary())
21208  {
21209  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21210  }
21211 
21212  return *get_ptr<binary_t*>();
21213  }
21214 
21217  const binary_t& get_binary() const
21218  {
21219  if (!is_binary())
21220  {
21221  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21222  }
21223 
21224  return *get_ptr<const binary_t*>();
21225  }
21226 
21228 
21230  // element access //
21232 
21236 
21240  {
21241  // at only works for arrays
21243  {
21244  JSON_TRY
21245  {
21246  return set_parent(m_data.m_value.array->at(idx));
21247  }
21248  JSON_CATCH(std::out_of_range&)
21249  {
21250  // create better exception explanation
21251  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21252  }
21253  }
21254  else
21255  {
21256  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21257  }
21258  }
21259 
21263  {
21264  // at only works for arrays
21266  {
21267  JSON_TRY
21268  {
21269  return m_data.m_value.array->at(idx);
21270  }
21271  JSON_CATCH(std::out_of_range&)
21272  {
21273  // create better exception explanation
21274  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21275  }
21276  }
21277  else
21278  {
21279  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21280  }
21281  }
21282 
21285  reference at(const typename object_t::key_type& key)
21286  {
21287  // at only works for objects
21289  {
21290  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21291  }
21292 
21293  auto it = m_data.m_value.object->find(key);
21294  if (it == m_data.m_value.object->end())
21295  {
21296  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21297  }
21298  return set_parent(it->second);
21299  }
21300 
21303  template<class KeyType, detail::enable_if_t<
21305  reference at(KeyType&& key)
21306  {
21307  // at only works for objects
21309  {
21310  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21311  }
21312 
21313  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21314  if (it == m_data.m_value.object->end())
21315  {
21316  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21317  }
21318  return set_parent(it->second);
21319  }
21320 
21323  const_reference at(const typename object_t::key_type& key) const
21324  {
21325  // at only works for objects
21327  {
21328  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21329  }
21330 
21331  auto it = m_data.m_value.object->find(key);
21332  if (it == m_data.m_value.object->end())
21333  {
21334  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21335  }
21336  return it->second;
21337  }
21338 
21341  template<class KeyType, detail::enable_if_t<
21343  const_reference at(KeyType&& key) const
21344  {
21345  // at only works for objects
21347  {
21348  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21349  }
21350 
21351  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21352  if (it == m_data.m_value.object->end())
21353  {
21354  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21355  }
21356  return it->second;
21357  }
21358 
21362  {
21363  // implicitly convert null value to an empty array
21364  if (is_null())
21365  {
21366  m_data.m_type = value_t::array;
21367  m_data.m_value.array = create<array_t>();
21368  assert_invariant();
21369  }
21370 
21371  // operator[] only works for arrays
21373  {
21374  // fill up array with null values if given idx is outside range
21375  if (idx >= m_data.m_value.array->size())
21376  {
21377 #if JSON_DIAGNOSTICS
21378  // remember array size & capacity before resizing
21379  const auto old_size = m_data.m_value.array->size();
21380  const auto old_capacity = m_data.m_value.array->capacity();
21381 #endif
21382  m_data.m_value.array->resize(idx + 1);
21383 
21384 #if JSON_DIAGNOSTICS
21385  if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
21386  {
21387  // capacity has changed: update all parents
21388  set_parents();
21389  }
21390  else
21391  {
21392  // set parent for values added above
21393  set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21394  }
21395 #endif
21396  assert_invariant();
21397  }
21398 
21399  return m_data.m_value.array->operator[](idx);
21400  }
21401 
21402  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21403  }
21404 
21408  {
21409  // const operator[] only works for arrays
21411  {
21412  return m_data.m_value.array->operator[](idx);
21413  }
21414 
21415  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21416  }
21417 
21420  reference operator[](typename object_t::key_type key)
21421  {
21422  // implicitly convert null value to an empty object
21423  if (is_null())
21424  {
21425  m_data.m_type = value_t::object;
21426  m_data.m_value.object = create<object_t>();
21427  assert_invariant();
21428  }
21429 
21430  // operator[] only works for objects
21432  {
21433  auto result = m_data.m_value.object->emplace(std::move(key), nullptr);
21434  return set_parent(result.first->second);
21435  }
21436 
21437  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21438  }
21439 
21442  const_reference operator[](const typename object_t::key_type& key) const
21443  {
21444  // const operator[] only works for objects
21446  {
21447  auto it = m_data.m_value.object->find(key);
21448  JSON_ASSERT(it != m_data.m_value.object->end());
21449  return it->second;
21450  }
21451 
21452  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21453  }
21454 
21455  // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
21456  // (they seemingly cannot be constrained to resolve the ambiguity)
21457  template<typename T>
21459  {
21460  return operator[](typename object_t::key_type(key));
21461  }
21462 
21463  template<typename T>
21465  {
21466  return operator[](typename object_t::key_type(key));
21467  }
21468 
21471  template<class KeyType, detail::enable_if_t<
21473  reference operator[](KeyType&& key)
21474  {
21475  // implicitly convert null value to an empty object
21476  if (is_null())
21477  {
21478  m_data.m_type = value_t::object;
21479  m_data.m_value.object = create<object_t>();
21480  assert_invariant();
21481  }
21482 
21483  // operator[] only works for objects
21485  {
21486  auto result = m_data.m_value.object->emplace(std::forward<KeyType>(key), nullptr);
21487  return set_parent(result.first->second);
21488  }
21489 
21490  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21491  }
21492 
21495  template<class KeyType, detail::enable_if_t<
21497  const_reference operator[](KeyType&& key) const
21498  {
21499  // const operator[] only works for objects
21501  {
21502  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21503  JSON_ASSERT(it != m_data.m_value.object->end());
21504  return it->second;
21505  }
21506 
21507  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21508  }
21509 
21510 private:
21511  template<typename KeyType>
21512  using is_comparable_with_object_key = detail::is_comparable <
21513  object_comparator_t, const typename object_t::key_type&, KeyType >;
21514 
21515  template<typename ValueType>
21516  using value_return_type = std::conditional <
21518  string_t, typename std::decay<ValueType>::type >;
21519 
21520 public:
21523  template < class ValueType, detail::enable_if_t <
21526  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21527  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21528  {
21529  // value only works for objects
21531  {
21532  // if key is found, return value and given default value otherwise
21533  const auto it = find(key);
21534  if (it != end())
21535  {
21536  return it->template get<ValueType>();
21537  }
21538 
21539  return default_value;
21540  }
21541 
21542  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21543  }
21544 
21547  template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21551  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21552  ReturnType value(const typename object_t::key_type& key, ValueType&& default_value) const
21553  {
21554  // value only works for objects
21556  {
21557  // if key is found, return value and given default value otherwise
21558  const auto it = find(key);
21559  if (it != end())
21560  {
21561  return it->template get<ReturnType>();
21562  }
21563 
21564  return std::forward<ValueType>(default_value);
21565  }
21566 
21567  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21568  }
21569 
21572  template < class ValueType, class KeyType, detail::enable_if_t <
21575  && is_comparable_with_object_key<KeyType>::value
21577  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21578  ValueType value(KeyType&& key, const ValueType& default_value) const
21579  {
21580  // value only works for objects
21582  {
21583  // if key is found, return value and given default value otherwise
21584  const auto it = find(std::forward<KeyType>(key));
21585  if (it != end())
21586  {
21587  return it->template get<ValueType>();
21588  }
21589 
21590  return default_value;
21591  }
21592 
21593  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21594  }
21595 
21598  template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,
21602  && is_comparable_with_object_key<KeyType>::value
21604  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21605  ReturnType value(KeyType&& key, ValueType&& default_value) const
21606  {
21607  // value only works for objects
21609  {
21610  // if key is found, return value and given default value otherwise
21611  const auto it = find(std::forward<KeyType>(key));
21612  if (it != end())
21613  {
21614  return it->template get<ReturnType>();
21615  }
21616 
21617  return std::forward<ValueType>(default_value);
21618  }
21619 
21620  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21621  }
21622 
21625  template < class ValueType, detail::enable_if_t <
21627  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21628  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21629  {
21630  // value only works for objects
21632  {
21633  // if pointer resolves a value, return it or use default value
21634  JSON_TRY
21635  {
21636  return ptr.get_checked(this).template get<ValueType>();
21637  }
21639  {
21640  return default_value;
21641  }
21642  }
21643 
21644  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21645  }
21646 
21649  template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21652  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21653  ReturnType value(const json_pointer& ptr, ValueType&& default_value) const
21654  {
21655  // value only works for objects
21657  {
21658  // if pointer resolves a value, return it or use default value
21659  JSON_TRY
21660  {
21661  return ptr.get_checked(this).template get<ReturnType>();
21662  }
21664  {
21665  return std::forward<ValueType>(default_value);
21666  }
21667  }
21668 
21669  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21670  }
21671 
21672  template < class ValueType, class BasicJsonType, detail::enable_if_t <
21675  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21676  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21677  ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
21678  {
21679  return value(ptr.convert(), default_value);
21680  }
21681 
21682  template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
21686  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21687  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21688  ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType&& default_value) const
21689  {
21690  return value(ptr.convert(), std::forward<ValueType>(default_value));
21691  }
21692 
21695  reference front()
21696  {
21697  return *begin();
21698  }
21699 
21703  {
21704  return *cbegin();
21705  }
21706 
21710  {
21711  auto tmp = end();
21712  --tmp;
21713  return *tmp;
21714  }
21715 
21719  {
21720  auto tmp = cend();
21721  --tmp;
21722  return *tmp;
21723  }
21724 
21727  template < class IteratorType, detail::enable_if_t <
21728  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21729  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21730  IteratorType erase(IteratorType pos)
21731  {
21732  // make sure iterator fits the current value
21733  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21734  {
21735  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21736  }
21737 
21738  IteratorType result = end();
21739 
21740  switch (m_data.m_type)
21741  {
21742  case value_t::boolean:
21743  case value_t::number_float:
21746  case value_t::string:
21747  case value_t::binary:
21748  {
21749  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21750  {
21751  JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
21752  }
21753 
21754  if (is_string())
21755  {
21756  AllocatorType<string_t> alloc;
21757  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
21758  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
21759  m_data.m_value.string = nullptr;
21760  }
21761  else if (is_binary())
21762  {
21763  AllocatorType<binary_t> alloc;
21764  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
21765  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
21766  m_data.m_value.binary = nullptr;
21767  }
21768 
21769  m_data.m_type = value_t::null;
21770  assert_invariant();
21771  break;
21772  }
21773 
21774  case value_t::object:
21775  {
21776  result.m_it.object_iterator = m_data.m_value.object->erase(pos.m_it.object_iterator);
21777  break;
21778  }
21779 
21780  case value_t::array:
21781  {
21782  result.m_it.array_iterator = m_data.m_value.array->erase(pos.m_it.array_iterator);
21783  break;
21784  }
21785 
21786  case value_t::null:
21787  case value_t::discarded:
21788  default:
21789  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21790  }
21791 
21792  return result;
21793  }
21794 
21797  template < class IteratorType, detail::enable_if_t <
21798  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21799  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21800  IteratorType erase(IteratorType first, IteratorType last)
21801  {
21802  // make sure iterator fits the current value
21803  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21804  {
21805  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
21806  }
21807 
21808  IteratorType result = end();
21809 
21810  switch (m_data.m_type)
21811  {
21812  case value_t::boolean:
21813  case value_t::number_float:
21816  case value_t::string:
21817  case value_t::binary:
21818  {
21819  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21820  || !last.m_it.primitive_iterator.is_end()))
21821  {
21822  JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
21823  }
21824 
21825  if (is_string())
21826  {
21827  AllocatorType<string_t> alloc;
21828  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
21829  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
21830  m_data.m_value.string = nullptr;
21831  }
21832  else if (is_binary())
21833  {
21834  AllocatorType<binary_t> alloc;
21835  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
21836  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
21837  m_data.m_value.binary = nullptr;
21838  }
21839 
21840  m_data.m_type = value_t::null;
21841  assert_invariant();
21842  break;
21843  }
21844 
21845  case value_t::object:
21846  {
21847  result.m_it.object_iterator = m_data.m_value.object->erase(first.m_it.object_iterator,
21848  last.m_it.object_iterator);
21849  break;
21850  }
21851 
21852  case value_t::array:
21853  {
21854  result.m_it.array_iterator = m_data.m_value.array->erase(first.m_it.array_iterator,
21855  last.m_it.array_iterator);
21856  break;
21857  }
21858 
21859  case value_t::null:
21860  case value_t::discarded:
21861  default:
21862  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21863  }
21864 
21865  return result;
21866  }
21867 
21868 private:
21869  template < typename KeyType, detail::enable_if_t <
21871  size_type erase_internal(KeyType&& key)
21872  {
21873  // this erase only works for objects
21875  {
21876  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21877  }
21878 
21879  return m_data.m_value.object->erase(std::forward<KeyType>(key));
21880  }
21881 
21882  template < typename KeyType, detail::enable_if_t <
21884  size_type erase_internal(KeyType&& key)
21885  {
21886  // this erase only works for objects
21888  {
21889  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21890  }
21891 
21892  const auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21893  if (it != m_data.m_value.object->end())
21894  {
21895  m_data.m_value.object->erase(it);
21896  return 1;
21897  }
21898  return 0;
21899  }
21900 
21901 public:
21902 
21905  size_type erase(const typename object_t::key_type& key)
21906  {
21907  // the indirection via erase_internal() is added to avoid making this
21908  // function a template and thus de-rank it during overload resolution
21909  return erase_internal(key);
21910  }
21911 
21914  template<class KeyType, detail::enable_if_t<
21916  size_type erase(KeyType&& key)
21917  {
21918  return erase_internal(std::forward<KeyType>(key));
21919  }
21920 
21923  void erase(const size_type idx)
21924  {
21925  // this erase only works for arrays
21927  {
21928  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21929  {
21930  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21931  }
21932 
21933  m_data.m_value.array->erase(m_data.m_value.array->begin() + static_cast<difference_type>(idx));
21934  }
21935  else
21936  {
21937  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21938  }
21939  }
21940 
21942 
21944  // lookup //
21946 
21949 
21952  iterator find(const typename object_t::key_type& key)
21953  {
21954  auto result = end();
21955 
21956  if (is_object())
21957  {
21958  result.m_it.object_iterator = m_data.m_value.object->find(key);
21959  }
21960 
21961  return result;
21962  }
21963 
21966  const_iterator find(const typename object_t::key_type& key) const
21967  {
21968  auto result = cend();
21969 
21970  if (is_object())
21971  {
21972  result.m_it.object_iterator = m_data.m_value.object->find(key);
21973  }
21974 
21975  return result;
21976  }
21977 
21980  template<class KeyType, detail::enable_if_t<
21982  iterator find(KeyType&& key)
21983  {
21984  auto result = end();
21985 
21986  if (is_object())
21987  {
21988  result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
21989  }
21990 
21991  return result;
21992  }
21993 
21996  template<class KeyType, detail::enable_if_t<
21998  const_iterator find(KeyType&& key) const
21999  {
22000  auto result = cend();
22001 
22002  if (is_object())
22003  {
22004  result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
22005  }
22006 
22007  return result;
22008  }
22009 
22012  size_type count(const typename object_t::key_type& key) const
22013  {
22014  // return 0 for all nonobject types
22015  return is_object() ? m_data.m_value.object->count(key) : 0;
22016  }
22017 
22020  template<class KeyType, detail::enable_if_t<
22022  size_type count(KeyType&& key) const
22023  {
22024  // return 0 for all nonobject types
22025  return is_object() ? m_data.m_value.object->count(std::forward<KeyType>(key)) : 0;
22026  }
22027 
22030  bool contains(const typename object_t::key_type& key) const
22031  {
22032  return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
22033  }
22034 
22037  template<class KeyType, detail::enable_if_t<
22039  bool contains(KeyType&& key) const
22040  {
22041  return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
22042  }
22043 
22046  bool contains(const json_pointer& ptr) const
22047  {
22048  return ptr.contains(this);
22049  }
22050 
22051  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
22052  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
22053  bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
22054  {
22055  return ptr.contains(this);
22056  }
22057 
22059 
22061  // iterators //
22063 
22066 
22069  iterator begin() noexcept
22070  {
22071  iterator result(this);
22072  result.set_begin();
22073  return result;
22074  }
22075 
22078  const_iterator begin() const noexcept
22079  {
22080  return cbegin();
22081  }
22082 
22085  const_iterator cbegin() const noexcept
22086  {
22087  const_iterator result(this);
22088  result.set_begin();
22089  return result;
22090  }
22091 
22094  iterator end() noexcept
22095  {
22096  iterator result(this);
22097  result.set_end();
22098  return result;
22099  }
22100 
22103  const_iterator end() const noexcept
22104  {
22105  return cend();
22106  }
22107 
22110  const_iterator cend() const noexcept
22111  {
22112  const_iterator result(this);
22113  result.set_end();
22114  return result;
22115  }
22116 
22119  reverse_iterator rbegin() noexcept
22120  {
22121  return reverse_iterator(end());
22122  }
22123 
22126  const_reverse_iterator rbegin() const noexcept
22127  {
22128  return crbegin();
22129  }
22130 
22133  reverse_iterator rend() noexcept
22134  {
22135  return reverse_iterator(begin());
22136  }
22137 
22140  const_reverse_iterator rend() const noexcept
22141  {
22142  return crend();
22143  }
22144 
22147  const_reverse_iterator crbegin() const noexcept
22148  {
22149  return const_reverse_iterator(cend());
22150  }
22151 
22154  const_reverse_iterator crend() const noexcept
22155  {
22156  return const_reverse_iterator(cbegin());
22157  }
22158 
22159 public:
22165  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22166  static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22167  {
22168  return ref.items();
22169  }
22170 
22176  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22177  static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22178  {
22179  return ref.items();
22180  }
22181 
22184  iteration_proxy<iterator> items() noexcept
22185  {
22186  return iteration_proxy<iterator>(*this);
22187  }
22188 
22191  iteration_proxy<const_iterator> items() const noexcept
22192  {
22193  return iteration_proxy<const_iterator>(*this);
22194  }
22195 
22197 
22199  // capacity //
22201 
22204 
22207  bool empty() const noexcept
22208  {
22209  switch (m_data.m_type)
22210  {
22211  case value_t::null:
22212  {
22213  // null values are empty
22214  return true;
22215  }
22216 
22217  case value_t::array:
22218  {
22219  // delegate call to array_t::empty()
22220  return m_data.m_value.array->empty();
22221  }
22222 
22223  case value_t::object:
22224  {
22225  // delegate call to object_t::empty()
22226  return m_data.m_value.object->empty();
22227  }
22228 
22229  case value_t::string:
22230  case value_t::boolean:
22233  case value_t::number_float:
22234  case value_t::binary:
22235  case value_t::discarded:
22236  default:
22237  {
22238  // all other types are nonempty
22239  return false;
22240  }
22241  }
22242  }
22243 
22246  size_type size() const noexcept
22247  {
22248  switch (m_data.m_type)
22249  {
22250  case value_t::null:
22251  {
22252  // null values are empty
22253  return 0;
22254  }
22255 
22256  case value_t::array:
22257  {
22258  // delegate call to array_t::size()
22259  return m_data.m_value.array->size();
22260  }
22261 
22262  case value_t::object:
22263  {
22264  // delegate call to object_t::size()
22265  return m_data.m_value.object->size();
22266  }
22267 
22268  case value_t::string:
22269  case value_t::boolean:
22272  case value_t::number_float:
22273  case value_t::binary:
22274  case value_t::discarded:
22275  default:
22276  {
22277  // all other types have size 1
22278  return 1;
22279  }
22280  }
22281  }
22282 
22285  size_type max_size() const noexcept
22286  {
22287  switch (m_data.m_type)
22288  {
22289  case value_t::array:
22290  {
22291  // delegate call to array_t::max_size()
22292  return m_data.m_value.array->max_size();
22293  }
22294 
22295  case value_t::object:
22296  {
22297  // delegate call to object_t::max_size()
22298  return m_data.m_value.object->max_size();
22299  }
22300 
22301  case value_t::null:
22302  case value_t::string:
22303  case value_t::boolean:
22306  case value_t::number_float:
22307  case value_t::binary:
22308  case value_t::discarded:
22309  default:
22310  {
22311  // all other types have max_size() == size()
22312  return size();
22313  }
22314  }
22315  }
22316 
22318 
22320  // modifiers //
22322 
22325 
22328  void clear() noexcept
22329  {
22330  switch (m_data.m_type)
22331  {
22333  {
22334  m_data.m_value.number_integer = 0;
22335  break;
22336  }
22337 
22339  {
22340  m_data.m_value.number_unsigned = 0;
22341  break;
22342  }
22343 
22344  case value_t::number_float:
22345  {
22346  m_data.m_value.number_float = 0.0;
22347  break;
22348  }
22349 
22350  case value_t::boolean:
22351  {
22352  m_data.m_value.boolean = false;
22353  break;
22354  }
22355 
22356  case value_t::string:
22357  {
22358  m_data.m_value.string->clear();
22359  break;
22360  }
22361 
22362  case value_t::binary:
22363  {
22364  m_data.m_value.binary->clear();
22365  break;
22366  }
22367 
22368  case value_t::array:
22369  {
22370  m_data.m_value.array->clear();
22371  break;
22372  }
22373 
22374  case value_t::object:
22375  {
22376  m_data.m_value.object->clear();
22377  break;
22378  }
22379 
22380  case value_t::null:
22381  case value_t::discarded:
22382  default:
22383  break;
22384  }
22385  }
22386 
22389  void push_back(basic_json&& val)
22390  {
22391  // push_back only works for null objects or arrays
22392  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22393  {
22394  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22395  }
22396 
22397  // transform null object into an array
22398  if (is_null())
22399  {
22400  m_data.m_type = value_t::array;
22401  m_data.m_value = value_t::array;
22402  assert_invariant();
22403  }
22404 
22405  // add element to array (move semantics)
22406  const auto old_capacity = m_data.m_value.array->capacity();
22407  m_data.m_value.array->push_back(std::move(val));
22408  set_parent(m_data.m_value.array->back(), old_capacity);
22409  // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
22410  }
22411 
22415  {
22416  push_back(std::move(val));
22417  return *this;
22418  }
22419 
22422  void push_back(const basic_json& val)
22423  {
22424  // push_back only works for null objects or arrays
22425  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22426  {
22427  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22428  }
22429 
22430  // transform null object into an array
22431  if (is_null())
22432  {
22433  m_data.m_type = value_t::array;
22434  m_data.m_value = value_t::array;
22435  assert_invariant();
22436  }
22437 
22438  // add element to array
22439  const auto old_capacity = m_data.m_value.array->capacity();
22440  m_data.m_value.array->push_back(val);
22441  set_parent(m_data.m_value.array->back(), old_capacity);
22442  }
22443 
22447  {
22448  push_back(val);
22449  return *this;
22450  }
22451 
22454  void push_back(const typename object_t::value_type& val)
22455  {
22456  // push_back only works for null objects or objects
22457  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22458  {
22459  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22460  }
22461 
22462  // transform null object into an object
22463  if (is_null())
22464  {
22465  m_data.m_type = value_t::object;
22466  m_data.m_value = value_t::object;
22467  assert_invariant();
22468  }
22469 
22470  // add element to object
22471  auto res = m_data.m_value.object->insert(val);
22472  set_parent(res.first->second);
22473  }
22474 
22477  reference operator+=(const typename object_t::value_type& val)
22478  {
22479  push_back(val);
22480  return *this;
22481  }
22482 
22486  {
22487  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22488  {
22489  basic_json&& key = init.begin()->moved_or_copied();
22490  push_back(typename object_t::value_type(
22491  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22492  }
22493  else
22494  {
22495  push_back(basic_json(init));
22496  }
22497  }
22498 
22502  {
22503  push_back(init);
22504  return *this;
22505  }
22506 
22509  template<class... Args>
22510  reference emplace_back(Args&& ... args)
22511  {
22512  // emplace_back only works for null objects or arrays
22513  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22514  {
22515  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
22516  }
22517 
22518  // transform null object into an array
22519  if (is_null())
22520  {
22521  m_data.m_type = value_t::array;
22522  m_data.m_value = value_t::array;
22523  assert_invariant();
22524  }
22525 
22526  // add element to array (perfect forwarding)
22527  const auto old_capacity = m_data.m_value.array->capacity();
22528  m_data.m_value.array->emplace_back(std::forward<Args>(args)...);
22529  return set_parent(m_data.m_value.array->back(), old_capacity);
22530  }
22531 
22534  template<class... Args>
22535  std::pair<iterator, bool> emplace(Args&& ... args)
22536  {
22537  // emplace only works for null objects or arrays
22538  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22539  {
22540  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
22541  }
22542 
22543  // transform null object into an object
22544  if (is_null())
22545  {
22546  m_data.m_type = value_t::object;
22547  m_data.m_value = value_t::object;
22548  assert_invariant();
22549  }
22550 
22551  // add element to array (perfect forwarding)
22552  auto res = m_data.m_value.object->emplace(std::forward<Args>(args)...);
22553  set_parent(res.first->second);
22554 
22555  // create result iterator and set iterator to the result of emplace
22556  auto it = begin();
22557  it.m_it.object_iterator = res.first;
22558 
22559  // return pair of iterator and boolean
22560  return { it, res.second };
22561  }
22562 
22566  template<typename... Args>
22568  {
22569  iterator result(this);
22570  JSON_ASSERT(m_data.m_value.array != nullptr);
22571 
22572  auto insert_pos = std::distance(m_data.m_value.array->begin(), pos.m_it.array_iterator);
22573  m_data.m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22574  result.m_it.array_iterator = m_data.m_value.array->begin() + insert_pos;
22575 
22576  // This could have been written as:
22577  // result.m_it.array_iterator = m_data.m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22578  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22579 
22580  set_parents();
22581  return result;
22582  }
22583 
22587  {
22588  // insert only works for arrays
22590  {
22591  // check if iterator pos fits to this JSON value
22592  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22593  {
22594  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22595  }
22596 
22597  // insert to array and return iterator
22598  return insert_iterator(pos, val);
22599  }
22600 
22601  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22602  }
22603 
22607  {
22608  return insert(pos, val);
22609  }
22610 
22614  {
22615  // insert only works for arrays
22617  {
22618  // check if iterator pos fits to this JSON value
22619  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22620  {
22621  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22622  }
22623 
22624  // insert to array and return iterator
22625  return insert_iterator(pos, cnt, val);
22626  }
22627 
22628  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22629  }
22630 
22634  {
22635  // insert only works for arrays
22637  {
22638  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22639  }
22640 
22641  // check if iterator pos fits to this JSON value
22642  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22643  {
22644  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22645  }
22646 
22647  // check if range iterators belong to the same JSON object
22648  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22649  {
22650  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22651  }
22652 
22653  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22654  {
22655  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
22656  }
22657 
22658  // insert to array and return iterator
22659  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22660  }
22661 
22665  {
22666  // insert only works for arrays
22668  {
22669  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22670  }
22671 
22672  // check if iterator pos fits to this JSON value
22673  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22674  {
22675  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22676  }
22677 
22678  // insert to array and return iterator
22679  return insert_iterator(pos, ilist.begin(), ilist.end());
22680  }
22681 
22685  {
22686  // insert only works for objects
22688  {
22689  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22690  }
22691 
22692  // check if range iterators belong to the same JSON object
22693  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22694  {
22695  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22696  }
22697 
22698  // passed iterators must belong to objects
22699  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22700  {
22701  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
22702  }
22703 
22704  m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22705  }
22706 
22709  void update(const_reference j, bool merge_objects = false)
22710  {
22711  update(j.begin(), j.end(), merge_objects);
22712  }
22713 
22716  void update(const_iterator first, const_iterator last, bool merge_objects = false)
22717  {
22718  // implicitly convert null value to an empty object
22719  if (is_null())
22720  {
22721  m_data.m_type = value_t::object;
22722  m_data.m_value.object = create<object_t>();
22723  assert_invariant();
22724  }
22725 
22727  {
22728  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
22729  }
22730 
22731  // check if range iterators belong to the same JSON object
22732  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22733  {
22734  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22735  }
22736 
22737  // passed iterators must belong to objects
22738  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22739  {
22740  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
22741  }
22742 
22743  for (auto it = first; it != last; ++it)
22744  {
22745  if (merge_objects && it.value().is_object())
22746  {
22747  auto it2 = m_data.m_value.object->find(it.key());
22748  if (it2 != m_data.m_value.object->end())
22749  {
22750  it2->second.update(it.value(), true);
22751  continue;
22752  }
22753  }
22754  m_data.m_value.object->operator[](it.key()) = it.value();
22755 #if JSON_DIAGNOSTICS
22756  m_data.m_value.object->operator[](it.key()).m_parent = this;
22757 #endif
22758  }
22759  }
22760 
22763  void swap(reference other) noexcept (
22764  std::is_nothrow_move_constructible<value_t>::value&&
22765  std::is_nothrow_move_assignable<value_t>::value&&
22766  std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22767  std::is_nothrow_move_assignable<json_value>::value
22768  )
22769  {
22770  std::swap(m_data.m_type, other.m_data.m_type);
22771  std::swap(m_data.m_value, other.m_data.m_value);
22772 
22773  set_parents();
22774  other.set_parents();
22775  assert_invariant();
22776  }
22777 
22780  friend void swap(reference left, reference right) noexcept (
22781  std::is_nothrow_move_constructible<value_t>::value&&
22782  std::is_nothrow_move_assignable<value_t>::value&&
22783  std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22784  std::is_nothrow_move_assignable<json_value>::value
22785  )
22786  {
22787  left.swap(right);
22788  }
22789 
22792  void swap(array_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22793  {
22794  // swap only works for arrays
22796  {
22797  using std::swap;
22798  swap(*(m_data.m_value.array), other);
22799  }
22800  else
22801  {
22802  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
22803  }
22804  }
22805 
22808  void swap(object_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22809  {
22810  // swap only works for objects
22812  {
22813  using std::swap;
22814  swap(*(m_data.m_value.object), other);
22815  }
22816  else
22817  {
22818  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
22819  }
22820  }
22821 
22824  void swap(string_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22825  {
22826  // swap only works for strings
22828  {
22829  using std::swap;
22830  swap(*(m_data.m_value.string), other);
22831  }
22832  else
22833  {
22834  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
22835  }
22836  }
22837 
22840  void swap(binary_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22841  {
22842  // swap only works for strings
22844  {
22845  using std::swap;
22846  swap(*(m_data.m_value.binary), other);
22847  }
22848  else
22849  {
22850  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
22851  }
22852  }
22853 
22856  void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
22857  {
22858  // swap only works for strings
22860  {
22861  using std::swap;
22862  swap(*(m_data.m_value.binary), other);
22863  }
22864  else
22865  {
22866  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
22867  }
22868  }
22869 
22871 
22873  // lexicographical comparison operators //
22875 
22878 
22879  // note parentheses around operands are necessary; see
22880  // https://github.com/nlohmann/json/issues/1530
22881 #define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
22882  const auto lhs_type = lhs.type(); \
22883  const auto rhs_type = rhs.type(); \
22884  \
22885  if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
22886  { \
22887  switch (lhs_type) \
22888  { \
22889  case value_t::array: \
22890  return (*lhs.m_data.m_value.array) op (*rhs.m_data.m_value.array); \
22891  \
22892  case value_t::object: \
22893  return (*lhs.m_data.m_value.object) op (*rhs.m_data.m_value.object); \
22894  \
22895  case value_t::null: \
22896  return (null_result); \
22897  \
22898  case value_t::string: \
22899  return (*lhs.m_data.m_value.string) op (*rhs.m_data.m_value.string); \
22900  \
22901  case value_t::boolean: \
22902  return (lhs.m_data.m_value.boolean) op (rhs.m_data.m_value.boolean); \
22903  \
22904  case value_t::number_integer: \
22905  return (lhs.m_data.m_value.number_integer) op (rhs.m_data.m_value.number_integer); \
22906  \
22907  case value_t::number_unsigned: \
22908  return (lhs.m_data.m_value.number_unsigned) op (rhs.m_data.m_value.number_unsigned); \
22909  \
22910  case value_t::number_float: \
22911  return (lhs.m_data.m_value.number_float) op (rhs.m_data.m_value.number_float); \
22912  \
22913  case value_t::binary: \
22914  return (*lhs.m_data.m_value.binary) op (*rhs.m_data.m_value.binary); \
22915  \
22916  case value_t::discarded: \
22917  default: \
22918  return (unordered_result); \
22919  } \
22920  } \
22921  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
22922  { \
22923  return static_cast<number_float_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_float; \
22924  } \
22925  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
22926  { \
22927  return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_integer); \
22928  } \
22929  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
22930  { \
22931  return static_cast<number_float_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_float; \
22932  } \
22933  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
22934  { \
22935  return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_unsigned); \
22936  } \
22937  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
22938  { \
22939  return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \
22940  } \
22941  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
22942  { \
22943  return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \
22944  } \
22945  else if(compares_unordered(lhs, rhs))\
22946  {\
22947  return (unordered_result);\
22948  }\
22949  \
22950  return (default_result);
22951 
22953  // returns true if:
22954  // - any operand is NaN and the other operand is of number type
22955  // - any operand is discarded
22956  // in legacy mode, discarded values are considered ordered if
22957  // an operation is computed as an odd number of inverses of others
22958  static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
22959  {
22960  if ((lhs.is_number_float() && std::isnan(lhs.m_data.m_value.number_float) && rhs.is_number())
22961  || (rhs.is_number_float() && std::isnan(rhs.m_data.m_value.number_float) && lhs.is_number()))
22962  {
22963  return true;
22964  }
22965 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22966  return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
22967 #else
22968  static_cast<void>(inverse);
22969  return lhs.is_discarded() || rhs.is_discarded();
22970 #endif
22971  }
22972 
22973 private:
22974  bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
22975  {
22976  return compares_unordered(*this, rhs, inverse);
22977  }
22978 
22979 public:
22980 #if JSON_HAS_THREE_WAY_COMPARISON
22983  bool operator==(const_reference rhs) const noexcept
22984  {
22985 #ifdef __GNUC__
22986 #pragma GCC diagnostic push
22987 #pragma GCC diagnostic ignored "-Wfloat-equal"
22988 #endif
22989  const_reference lhs = *this;
22990  JSON_IMPLEMENT_OPERATOR(== , true, false, false)
22991 #ifdef __GNUC__
22992 #pragma GCC diagnostic pop
22993 #endif
22994  }
22995 
22998  template<typename ScalarType>
22999  requires std::is_scalar_v<ScalarType>
23000  bool operator==(ScalarType rhs) const noexcept
23001  {
23002  return *this == basic_json(rhs);
23003  }
23004 
23007  bool operator!=(const_reference rhs) const noexcept
23008  {
23009  if (compares_unordered(rhs, true))
23010  {
23011  return false;
23012  }
23013  return !operator==(rhs);
23014  }
23015 
23018  std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
23019  {
23020  const_reference lhs = *this;
23021  // default_result is used if we cannot compare values. In that case,
23022  // we compare types.
23023  JSON_IMPLEMENT_OPERATOR(<=> , // *NOPAD*
23024  std::partial_ordering::equivalent,
23025  std::partial_ordering::unordered,
23026  lhs_type <=> rhs_type) // *NOPAD*
23027  }
23028 
23031  template<typename ScalarType>
23032  requires std::is_scalar_v<ScalarType>
23033  std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
23034  {
23035  return *this <=> basic_json(rhs); // *NOPAD*
23036  }
23037 
23038 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
23039  // all operators that are computed as an odd number of inverses of others
23040  // need to be overloaded to emulate the legacy comparison behavior
23041 
23045  bool operator<=(const_reference rhs) const noexcept
23046  {
23047  if (compares_unordered(rhs, true))
23048  {
23049  return false;
23050  }
23051  return !(rhs < *this);
23052  }
23053 
23056  template<typename ScalarType>
23057  requires std::is_scalar_v<ScalarType>
23058  bool operator<=(ScalarType rhs) const noexcept
23059  {
23060  return *this <= basic_json(rhs);
23061  }
23062 
23066  bool operator>=(const_reference rhs) const noexcept
23067  {
23068  if (compares_unordered(rhs, true))
23069  {
23070  return false;
23071  }
23072  return !(*this < rhs);
23073  }
23074 
23077  template<typename ScalarType>
23078  requires std::is_scalar_v<ScalarType>
23079  bool operator>=(ScalarType rhs) const noexcept
23080  {
23081  return *this >= basic_json(rhs);
23082  }
23083 #endif
23084 #else
23087  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23088  {
23089 #ifdef __GNUC__
23090 #pragma GCC diagnostic push
23091 #pragma GCC diagnostic ignored "-Wfloat-equal"
23092 #endif
23093  JSON_IMPLEMENT_OPERATOR(== , true, false, false)
23094 #ifdef __GNUC__
23095 #pragma GCC diagnostic pop
23096 #endif
23097  }
23098 
23101  template<typename ScalarType, typename std::enable_if<
23102  std::is_scalar<ScalarType>::value, int>::type = 0>
23103  friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23104  {
23105  return lhs == basic_json(rhs);
23106  }
23107 
23110  template<typename ScalarType, typename std::enable_if<
23111  std::is_scalar<ScalarType>::value, int>::type = 0>
23112  friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23113  {
23114  return basic_json(lhs) == rhs;
23115  }
23116 
23119  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23120  {
23121  if (compares_unordered(lhs, rhs, true))
23122  {
23123  return false;
23124  }
23125  return !(lhs == rhs);
23126  }
23127 
23130  template<typename ScalarType, typename std::enable_if<
23131  std::is_scalar<ScalarType>::value, int>::type = 0>
23132  friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23133  {
23134  return lhs != basic_json(rhs);
23135  }
23136 
23139  template<typename ScalarType, typename std::enable_if<
23140  std::is_scalar<ScalarType>::value, int>::type = 0>
23141  friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23142  {
23143  return basic_json(lhs) != rhs;
23144  }
23145 
23148  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23149  {
23150  // default_result is used if we cannot compare values. In that case,
23151  // we compare types. Note we have to call the operator explicitly,
23152  // because MSVC has problems otherwise.
23153  JSON_IMPLEMENT_OPERATOR(< , false, false, operator<(lhs_type, rhs_type))
23154  }
23155 
23158  template<typename ScalarType, typename std::enable_if<
23159  std::is_scalar<ScalarType>::value, int>::type = 0>
23160  friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23161  {
23162  return lhs < basic_json(rhs);
23163  }
23164 
23167  template<typename ScalarType, typename std::enable_if<
23168  std::is_scalar<ScalarType>::value, int>::type = 0>
23169  friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
23170  {
23171  return basic_json(lhs) < rhs;
23172  }
23173 
23176  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
23177  {
23178  if (compares_unordered(lhs, rhs, true))
23179  {
23180  return false;
23181  }
23182  return !(rhs < lhs);
23183  }
23184 
23187  template<typename ScalarType, typename std::enable_if<
23188  std::is_scalar<ScalarType>::value, int>::type = 0>
23189  friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
23190  {
23191  return lhs <= basic_json(rhs);
23192  }
23193 
23196  template<typename ScalarType, typename std::enable_if<
23197  std::is_scalar<ScalarType>::value, int>::type = 0>
23198  friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
23199  {
23200  return basic_json(lhs) <= rhs;
23201  }
23202 
23205  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23206  {
23207  // double inverse
23208  if (compares_unordered(lhs, rhs))
23209  {
23210  return false;
23211  }
23212  return !(lhs <= rhs);
23213  }
23214 
23217  template<typename ScalarType, typename std::enable_if<
23218  std::is_scalar<ScalarType>::value, int>::type = 0>
23219  friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
23220  {
23221  return lhs > basic_json(rhs);
23222  }
23223 
23226  template<typename ScalarType, typename std::enable_if<
23227  std::is_scalar<ScalarType>::value, int>::type = 0>
23228  friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
23229  {
23230  return basic_json(lhs) > rhs;
23231  }
23232 
23235  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23236  {
23237  if (compares_unordered(lhs, rhs, true))
23238  {
23239  return false;
23240  }
23241  return !(lhs < rhs);
23242  }
23243 
23246  template<typename ScalarType, typename std::enable_if<
23247  std::is_scalar<ScalarType>::value, int>::type = 0>
23248  friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
23249  {
23250  return lhs >= basic_json(rhs);
23251  }
23252 
23255  template<typename ScalarType, typename std::enable_if<
23256  std::is_scalar<ScalarType>::value, int>::type = 0>
23257  friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
23258  {
23259  return basic_json(lhs) >= rhs;
23260  }
23261 #endif
23262 
23263 #undef JSON_IMPLEMENT_OPERATOR
23264 
23266 
23268  // serialization //
23270 
23273 #ifndef JSON_NO_IO
23276  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23277  {
23278  // read width member and use it as indentation parameter if nonzero
23279  const bool pretty_print = o.width() > 0;
23280  const auto indentation = pretty_print ? o.width() : 0;
23281 
23282  // reset width to 0 for subsequent calls to this stream
23283  o.width(0);
23284 
23285  // do the actual serialization
23286  serializer s(detail::output_adapter<char>(o), o.fill());
23287  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23288  return o;
23289  }
23290 
23297  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23298  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23299  {
23300  return o << j;
23301  }
23302 #endif // JSON_NO_IO
23304 
23306  // deserialization //
23308 
23311 
23314  template<typename InputType>
23316  static basic_json parse(InputType&& i,
23317  const parser_callback_t cb = nullptr,
23318  const bool allow_exceptions = true,
23319  const bool ignore_comments = false)
23320  {
23321  basic_json result;
23322  parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23323  return result;
23324  }
23325 
23328  template<typename IteratorType>
23330  static basic_json parse(IteratorType first,
23331  IteratorType last,
23332  const parser_callback_t cb = nullptr,
23333  const bool allow_exceptions = true,
23334  const bool ignore_comments = false)
23335  {
23336  basic_json result;
23337  parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23338  return result;
23339  }
23340 
23342  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23343  static basic_json parse(detail::span_input_adapter&& i,
23344  const parser_callback_t cb = nullptr,
23345  const bool allow_exceptions = true,
23346  const bool ignore_comments = false)
23347  {
23348  basic_json result;
23349  parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23350  return result;
23351  }
23352 
23355  template<typename InputType>
23356  static bool accept(InputType&& i,
23357  const bool ignore_comments = false)
23358  {
23359  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23360  }
23361 
23364  template<typename IteratorType>
23365  static bool accept(IteratorType first, IteratorType last,
23366  const bool ignore_comments = false)
23367  {
23368  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23369  }
23370 
23372  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23373  static bool accept(detail::span_input_adapter&& i,
23374  const bool ignore_comments = false)
23375  {
23376  return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23377  }
23378 
23381  template <typename InputType, typename SAX>
23383  static bool sax_parse(InputType&& i, SAX* sax,
23385  const bool strict = true,
23386  const bool ignore_comments = false)
23387  {
23388  auto ia = detail::input_adapter(std::forward<InputType>(i));
23389  return format == input_format_t::json
23390  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23391  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23392  }
23393 
23396  template<class IteratorType, class SAX>
23398  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23400  const bool strict = true,
23401  const bool ignore_comments = false)
23402  {
23403  auto ia = detail::input_adapter(std::move(first), std::move(last));
23404  return format == input_format_t::json
23405  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23406  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23407  }
23408 
23414  template <typename SAX>
23415  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23417  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23419  const bool strict = true,
23420  const bool ignore_comments = false)
23421  {
23422  auto ia = i.get();
23423  return format == input_format_t::json
23424  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23425  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23426  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23427  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23428  }
23429 #ifndef JSON_NO_IO
23436  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23437  friend std::istream& operator<<(basic_json& j, std::istream& i)
23438  {
23439  return operator>>(i, j);
23440  }
23441 
23444  friend std::istream& operator>>(std::istream& i, basic_json& j)
23445  {
23446  parser(detail::input_adapter(i)).parse(false, j);
23447  return i;
23448  }
23449 #endif // JSON_NO_IO
23451 
23453  // convenience functions //
23455 
23459  const char* type_name() const noexcept
23460  {
23461  switch (m_data.m_type)
23462  {
23463  case value_t::null:
23464  return "null";
23465  case value_t::object:
23466  return "object";
23467  case value_t::array:
23468  return "array";
23469  case value_t::string:
23470  return "string";
23471  case value_t::boolean:
23472  return "boolean";
23473  case value_t::binary:
23474  return "binary";
23475  case value_t::discarded:
23476  return "discarded";
23479  case value_t::number_float:
23480  default:
23481  return "number";
23482  }
23483  }
23484 
23487  // member variables //
23489 
23490  struct data
23491  {
23493  value_t m_type = value_t::null;
23494 
23496  json_value m_value = {};
23497 
23498  data(const value_t v)
23499  : m_type(v), m_value(v)
23500  {
23501  }
23502 
23503  data(size_type cnt, const basic_json& val)
23504  : m_type(value_t::array)
23505  {
23506  m_value.array = create<array_t>(cnt, val);
23507  }
23508 
23509  data() noexcept = default;
23510  data(data&&) noexcept = default;
23511  data(const data&) noexcept = delete;
23512  data& operator=(data&&) noexcept = delete;
23513  data& operator=(const data&) noexcept = delete;
23514 
23515  ~data() noexcept
23516  {
23517  m_value.destroy(m_type);
23518  }
23519  };
23520 
23521  data m_data = {};
23522 
23523 #if JSON_DIAGNOSTICS
23525  basic_json* m_parent = nullptr;
23526 #endif
23527 
23529  // binary serialization/deserialization //
23531 
23534 
23535 public:
23538  static std::vector<std::uint8_t> to_cbor(const basic_json& j)
23539  {
23540  std::vector<std::uint8_t> result;
23541  to_cbor(j, result);
23542  return result;
23543  }
23544 
23548  {
23549  binary_writer<std::uint8_t>(o).write_cbor(j);
23550  }
23551 
23555  {
23556  binary_writer<char>(o).write_cbor(j);
23557  }
23558 
23561  static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
23562  {
23563  std::vector<std::uint8_t> result;
23564  to_msgpack(j, result);
23565  return result;
23566  }
23567 
23571  {
23572  binary_writer<std::uint8_t>(o).write_msgpack(j);
23573  }
23574 
23578  {
23579  binary_writer<char>(o).write_msgpack(j);
23580  }
23581 
23584  static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
23585  const bool use_size = false,
23586  const bool use_type = false)
23587  {
23588  std::vector<std::uint8_t> result;
23589  to_ubjson(j, result, use_size, use_type);
23590  return result;
23591  }
23592 
23596  const bool use_size = false, const bool use_type = false)
23597  {
23598  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
23599  }
23600 
23604  const bool use_size = false, const bool use_type = false)
23605  {
23606  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23607  }
23608 
23611  static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
23612  const bool use_size = false,
23613  const bool use_type = false)
23614  {
23615  std::vector<std::uint8_t> result;
23616  to_bjdata(j, result, use_size, use_type);
23617  return result;
23618  }
23619 
23623  const bool use_size = false, const bool use_type = false)
23624  {
23625  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
23626  }
23627 
23631  const bool use_size = false, const bool use_type = false)
23632  {
23633  binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
23634  }
23635 
23638  static std::vector<std::uint8_t> to_bson(const basic_json& j)
23639  {
23640  std::vector<std::uint8_t> result;
23641  to_bson(j, result);
23642  return result;
23643  }
23644 
23648  {
23649  binary_writer<std::uint8_t>(o).write_bson(j);
23650  }
23651 
23655  {
23656  binary_writer<char>(o).write_bson(j);
23657  }
23658 
23661  template<typename InputType>
23663  static basic_json from_cbor(InputType&& i,
23664  const bool strict = true,
23665  const bool allow_exceptions = true,
23666  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23667  {
23668  basic_json result;
23669  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23670  auto ia = detail::input_adapter(std::forward<InputType>(i));
23671  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23672  return res ? result : basic_json(value_t::discarded);
23673  }
23674 
23677  template<typename IteratorType>
23679  static basic_json from_cbor(IteratorType first, IteratorType last,
23680  const bool strict = true,
23681  const bool allow_exceptions = true,
23682  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23683  {
23684  basic_json result;
23685  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23686  auto ia = detail::input_adapter(std::move(first), std::move(last));
23687  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23688  return res ? result : basic_json(value_t::discarded);
23689  }
23690 
23691  template<typename T>
23693  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23694  static basic_json from_cbor(const T* ptr, std::size_t len,
23695  const bool strict = true,
23696  const bool allow_exceptions = true,
23697  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23698  {
23699  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23700  }
23701 
23703  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23704  static basic_json from_cbor(detail::span_input_adapter&& i,
23705  const bool strict = true,
23706  const bool allow_exceptions = true,
23707  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23708  {
23709  basic_json result;
23710  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23711  auto ia = i.get();
23712  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23713  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23714  return res ? result : basic_json(value_t::discarded);
23715  }
23716 
23719  template<typename InputType>
23721  static basic_json from_msgpack(InputType&& i,
23722  const bool strict = true,
23723  const bool allow_exceptions = true)
23724  {
23725  basic_json result;
23726  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23727  auto ia = detail::input_adapter(std::forward<InputType>(i));
23728  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23729  return res ? result : basic_json(value_t::discarded);
23730  }
23731 
23734  template<typename IteratorType>
23736  static basic_json from_msgpack(IteratorType first, IteratorType last,
23737  const bool strict = true,
23738  const bool allow_exceptions = true)
23739  {
23740  basic_json result;
23741  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23742  auto ia = detail::input_adapter(std::move(first), std::move(last));
23743  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23744  return res ? result : basic_json(value_t::discarded);
23745  }
23746 
23747  template<typename T>
23749  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23750  static basic_json from_msgpack(const T* ptr, std::size_t len,
23751  const bool strict = true,
23752  const bool allow_exceptions = true)
23753  {
23754  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
23755  }
23756 
23758  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23759  static basic_json from_msgpack(detail::span_input_adapter&& i,
23760  const bool strict = true,
23761  const bool allow_exceptions = true)
23762  {
23763  basic_json result;
23764  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23765  auto ia = i.get();
23766  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23767  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23768  return res ? result : basic_json(value_t::discarded);
23769  }
23770 
23773  template<typename InputType>
23775  static basic_json from_ubjson(InputType&& i,
23776  const bool strict = true,
23777  const bool allow_exceptions = true)
23778  {
23779  basic_json result;
23780  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23781  auto ia = detail::input_adapter(std::forward<InputType>(i));
23782  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23783  return res ? result : basic_json(value_t::discarded);
23784  }
23785 
23788  template<typename IteratorType>
23790  static basic_json from_ubjson(IteratorType first, IteratorType last,
23791  const bool strict = true,
23792  const bool allow_exceptions = true)
23793  {
23794  basic_json result;
23795  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23796  auto ia = detail::input_adapter(std::move(first), std::move(last));
23797  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23798  return res ? result : basic_json(value_t::discarded);
23799  }
23800 
23801  template<typename T>
23803  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23804  static basic_json from_ubjson(const T* ptr, std::size_t len,
23805  const bool strict = true,
23806  const bool allow_exceptions = true)
23807  {
23808  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
23809  }
23810 
23812  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23813  static basic_json from_ubjson(detail::span_input_adapter&& i,
23814  const bool strict = true,
23815  const bool allow_exceptions = true)
23816  {
23817  basic_json result;
23818  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23819  auto ia = i.get();
23820  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23821  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23822  return res ? result : basic_json(value_t::discarded);
23823  }
23824 
23827  template<typename InputType>
23829  static basic_json from_bjdata(InputType&& i,
23830  const bool strict = true,
23831  const bool allow_exceptions = true)
23832  {
23833  basic_json result;
23834  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23835  auto ia = detail::input_adapter(std::forward<InputType>(i));
23836  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23837  return res ? result : basic_json(value_t::discarded);
23838  }
23839 
23842  template<typename IteratorType>
23844  static basic_json from_bjdata(IteratorType first, IteratorType last,
23845  const bool strict = true,
23846  const bool allow_exceptions = true)
23847  {
23848  basic_json result;
23849  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23850  auto ia = detail::input_adapter(std::move(first), std::move(last));
23851  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23852  return res ? result : basic_json(value_t::discarded);
23853  }
23854 
23857  template<typename InputType>
23859  static basic_json from_bson(InputType&& i,
23860  const bool strict = true,
23861  const bool allow_exceptions = true)
23862  {
23863  basic_json result;
23864  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23865  auto ia = detail::input_adapter(std::forward<InputType>(i));
23866  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23867  return res ? result : basic_json(value_t::discarded);
23868  }
23869 
23872  template<typename IteratorType>
23874  static basic_json from_bson(IteratorType first, IteratorType last,
23875  const bool strict = true,
23876  const bool allow_exceptions = true)
23877  {
23878  basic_json result;
23879  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23880  auto ia = detail::input_adapter(std::move(first), std::move(last));
23881  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23882  return res ? result : basic_json(value_t::discarded);
23883  }
23884 
23885  template<typename T>
23887  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23888  static basic_json from_bson(const T* ptr, std::size_t len,
23889  const bool strict = true,
23890  const bool allow_exceptions = true)
23891  {
23892  return from_bson(ptr, ptr + len, strict, allow_exceptions);
23893  }
23894 
23896  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23897  static basic_json from_bson(detail::span_input_adapter&& i,
23898  const bool strict = true,
23899  const bool allow_exceptions = true)
23900  {
23901  basic_json result;
23902  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23903  auto ia = i.get();
23904  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23905  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23906  return res ? result : basic_json(value_t::discarded);
23907  }
23909 
23911  // JSON Pointer support //
23913 
23916 
23920  {
23921  return ptr.get_unchecked(this);
23922  }
23923 
23924  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23925  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23926  reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23927  {
23928  return ptr.get_unchecked(this);
23929  }
23930 
23934  {
23935  return ptr.get_unchecked(this);
23936  }
23937 
23938  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23939  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23940  const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23941  {
23942  return ptr.get_unchecked(this);
23943  }
23944 
23947  reference at(const json_pointer& ptr)
23948  {
23949  return ptr.get_checked(this);
23950  }
23951 
23952  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23953  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23954  reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23955  {
23956  return ptr.get_checked(this);
23957  }
23958 
23961  const_reference at(const json_pointer& ptr) const
23962  {
23963  return ptr.get_checked(this);
23964  }
23965 
23966  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23967  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23968  const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23969  {
23970  return ptr.get_checked(this);
23971  }
23972 
23975  basic_json flatten() const
23976  {
23977  basic_json result(value_t::object);
23978  json_pointer::flatten("", *this, result);
23979  return result;
23980  }
23981 
23984  basic_json unflatten() const
23985  {
23986  return json_pointer::unflatten(*this);
23987  }
23988 
23990 
23992  // JSON Patch functions //
23994 
23997 
24000  void patch_inplace(const basic_json& json_patch)
24001  {
24002  basic_json& result = *this;
24003  // the valid JSON Patch operations
24004  enum class patch_operations { add, remove, replace, move, copy, test, invalid };
24005 
24006  const auto get_op = [](const std::string& op)
24007  {
24008  if (op == "add")
24009  {
24010  return patch_operations::add;
24011  }
24012  if (op == "remove")
24013  {
24014  return patch_operations::remove;
24015  }
24016  if (op == "replace")
24017  {
24018  return patch_operations::replace;
24019  }
24020  if (op == "move")
24021  {
24022  return patch_operations::move;
24023  }
24024  if (op == "copy")
24025  {
24026  return patch_operations::copy;
24027  }
24028  if (op == "test")
24029  {
24030  return patch_operations::test;
24031  }
24032 
24033  return patch_operations::invalid;
24034  };
24035 
24036  // wrapper for "add" operation; add value at ptr
24037  const auto operation_add = [&result](json_pointer& ptr, basic_json val)
24038  {
24039  // adding to the root of the target document means replacing it
24040  if (ptr.empty())
24041  {
24042  result = val;
24043  return;
24044  }
24045 
24046  // make sure the top element of the pointer exists
24047  json_pointer const top_pointer = ptr.top();
24048  if (top_pointer != ptr)
24049  {
24050  result.at(top_pointer);
24051  }
24052 
24053  // get reference to parent of JSON pointer ptr
24054  const auto last_path = ptr.back();
24055  ptr.pop_back();
24056  // parent must exist when performing patch add per RFC6902 specs
24057  basic_json& parent = result.at(ptr);
24058 
24059  switch (parent.m_data.m_type)
24060  {
24061  case value_t::null:
24062  case value_t::object:
24063  {
24064  // use operator[] to add value
24065  parent[last_path] = val;
24066  break;
24067  }
24068 
24069  case value_t::array:
24070  {
24071  if (last_path == "-")
24072  {
24073  // special case: append to back
24074  parent.push_back(val);
24075  }
24076  else
24077  {
24078  const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
24079  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24080  {
24081  // avoid undefined behavior
24082  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
24083  }
24084 
24085  // default case: insert add offset
24086  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24087  }
24088  break;
24089  }
24090 
24091  // if there exists a parent it cannot be primitive
24092  case value_t::string: // LCOV_EXCL_LINE
24093  case value_t::boolean: // LCOV_EXCL_LINE
24094  case value_t::number_integer: // LCOV_EXCL_LINE
24095  case value_t::number_unsigned: // LCOV_EXCL_LINE
24096  case value_t::number_float: // LCOV_EXCL_LINE
24097  case value_t::binary: // LCOV_EXCL_LINE
24098  case value_t::discarded: // LCOV_EXCL_LINE
24099  default: // LCOV_EXCL_LINE
24100  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
24101  }
24102  };
24103 
24104  // wrapper for "remove" operation; remove value at ptr
24105  const auto operation_remove = [this, &result](json_pointer& ptr)
24106  {
24107  // get reference to parent of JSON pointer ptr
24108  const auto last_path = ptr.back();
24109  ptr.pop_back();
24110  basic_json& parent = result.at(ptr);
24111 
24112  // remove child
24113  if (parent.is_object())
24114  {
24115  // perform range check
24116  auto it = parent.find(last_path);
24117  if (JSON_HEDLEY_LIKELY(it != parent.end()))
24118  {
24119  parent.erase(it);
24120  }
24121  else
24122  {
24123  JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
24124  }
24125  }
24126  else if (parent.is_array())
24127  {
24128  // note erase performs range check
24129  parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
24130  }
24131  };
24132 
24133  // type check: top level value must be an array
24134  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24135  {
24136  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
24137  }
24138 
24139  // iterate and apply the operations
24140  for (const auto& val : json_patch)
24141  {
24142  // wrapper to get a value for an operation
24143  const auto get_value = [&val](const std::string& op,
24144  const std::string& member,
24145  bool string_type) -> basic_json&
24146  {
24147  // find value
24148  auto it = val.m_data.m_value.object->find(member);
24149 
24150  // context-sensitive error message
24151  const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
24152 
24153  // check if desired value is present
24154  if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))
24155  {
24156  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24157  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
24158  }
24159 
24160  // check if result is of type string
24161  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24162  {
24163  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24164  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
24165  }
24166 
24167  // no error: return value
24168  return it->second;
24169  };
24170 
24171  // type check: every element of the array must be an object
24172  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24173  {
24174  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
24175  }
24176 
24177  // collect mandatory members
24178  const auto op = get_value("op", "op", true).template get<std::string>();
24179  const auto path = get_value(op, "path", true).template get<std::string>();
24180  json_pointer ptr(path);
24181 
24182  switch (get_op(op))
24183  {
24184  case patch_operations::add:
24185  {
24186  operation_add(ptr, get_value("add", "value", false));
24187  break;
24188  }
24189 
24190  case patch_operations::remove:
24191  {
24192  operation_remove(ptr);
24193  break;
24194  }
24195 
24196  case patch_operations::replace:
24197  {
24198  // the "path" location must exist - use at()
24199  result.at(ptr) = get_value("replace", "value", false);
24200  break;
24201  }
24202 
24203  case patch_operations::move:
24204  {
24205  const auto from_path = get_value("move", "from", true).template get<std::string>();
24206  json_pointer from_ptr(from_path);
24207 
24208  // the "from" location must exist - use at()
24209  basic_json const v = result.at(from_ptr);
24210 
24211  // The move operation is functionally identical to a
24212  // "remove" operation on the "from" location, followed
24213  // immediately by an "add" operation at the target
24214  // location with the value that was just removed.
24215  operation_remove(from_ptr);
24216  operation_add(ptr, v);
24217  break;
24218  }
24219 
24220  case patch_operations::copy:
24221  {
24222  const auto from_path = get_value("copy", "from", true).template get<std::string>();
24223  const json_pointer from_ptr(from_path);
24224 
24225  // the "from" location must exist - use at()
24226  basic_json const v = result.at(from_ptr);
24227 
24228  // The copy is functionally identical to an "add"
24229  // operation at the target location using the value
24230  // specified in the "from" member.
24231  operation_add(ptr, v);
24232  break;
24233  }
24234 
24235  case patch_operations::test:
24236  {
24237  bool success = false;
24238  JSON_TRY
24239  {
24240  // check if "value" matches the one at "path"
24241  // the "path" location must exist - use at()
24242  success = (result.at(ptr) == get_value("test", "value", false));
24243  }
24245  {
24246  // ignore out of range errors: success remains false
24247  }
24248 
24249  // throw an exception if test fails
24250  if (JSON_HEDLEY_UNLIKELY(!success))
24251  {
24252  JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
24253  }
24254 
24255  break;
24256  }
24257 
24258  case patch_operations::invalid:
24259  default:
24260  {
24261  // op must be "add", "remove", "replace", "move", "copy", or
24262  // "test"
24263  JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
24264  }
24265  }
24266  }
24267  }
24268 
24271  basic_json patch(const basic_json& json_patch) const
24272  {
24273  basic_json result = *this;
24274  result.patch_inplace(json_patch);
24275  return result;
24276  }
24277 
24281  static basic_json diff(const basic_json& source, const basic_json& target,
24282  const std::string& path = "")
24283  {
24284  // the patch
24285  basic_json result(value_t::array);
24286 
24287  // if the values are the same, return empty patch
24288  if (source == target)
24289  {
24290  return result;
24291  }
24292 
24293  if (source.type() != target.type())
24294  {
24295  // different types: replace value
24296  result.push_back(
24297  {
24298  {"op", "replace"}, {"path", path}, {"value", target}
24299  });
24300  return result;
24301  }
24302 
24303  switch (source.type())
24304  {
24305  case value_t::array:
24306  {
24307  // first pass: traverse common elements
24308  std::size_t i = 0;
24309  while (i < source.size() && i < target.size())
24310  {
24311  // recursive call to compare array values at index i
24312  auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
24313  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24314  ++i;
24315  }
24316 
24317  // We now reached the end of at least one array
24318  // in a second pass, traverse the remaining elements
24319 
24320  // remove my remaining elements
24321  const auto end_index = static_cast<difference_type>(result.size());
24322  while (i < source.size())
24323  {
24324  // add operations in reverse order to avoid invalid
24325  // indices
24326  result.insert(result.begin() + end_index, object(
24327  {
24328  {"op", "remove"},
24329  {"path", detail::concat(path, '/', std::to_string(i))}
24330  }));
24331  ++i;
24332  }
24333 
24334  // add other remaining elements
24335  while (i < target.size())
24336  {
24337  result.push_back(
24338  {
24339  {"op", "add"},
24340  {"path", detail::concat(path, "/-")},
24341  {"value", target[i]}
24342  });
24343  ++i;
24344  }
24345 
24346  break;
24347  }
24348 
24349  case value_t::object:
24350  {
24351  // first pass: traverse this object's elements
24352  for (auto it = source.cbegin(); it != source.cend(); ++it)
24353  {
24354  // escape the key name to be used in a JSON patch
24355  const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24356 
24357  if (target.find(it.key()) != target.end())
24358  {
24359  // recursive call to compare object values at key it
24360  auto temp_diff = diff(it.value(), target[it.key()], path_key);
24361  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24362  }
24363  else
24364  {
24365  // found a key that is not in o -> remove it
24366  result.push_back(object(
24367  {
24368  {"op", "remove"}, {"path", path_key}
24369  }));
24370  }
24371  }
24372 
24373  // second pass: traverse other object's elements
24374  for (auto it = target.cbegin(); it != target.cend(); ++it)
24375  {
24376  if (source.find(it.key()) == source.end())
24377  {
24378  // found a key that is not in this -> add it
24379  const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24380  result.push_back(
24381  {
24382  {"op", "add"}, {"path", path_key},
24383  {"value", it.value()}
24384  });
24385  }
24386  }
24387 
24388  break;
24389  }
24390 
24391  case value_t::null:
24392  case value_t::string:
24393  case value_t::boolean:
24396  case value_t::number_float:
24397  case value_t::binary:
24398  case value_t::discarded:
24399  default:
24400  {
24401  // both primitive type: replace value
24402  result.push_back(
24403  {
24404  {"op", "replace"}, {"path", path}, {"value", target}
24405  });
24406  break;
24407  }
24408  }
24409 
24410  return result;
24411  }
24413 
24415  // JSON Merge Patch functions //
24417 
24420 
24423  void merge_patch(const basic_json& apply_patch)
24424  {
24425  if (apply_patch.is_object())
24426  {
24427  if (!is_object())
24428  {
24429  *this = object();
24430  }
24431  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24432  {
24433  if (it.value().is_null())
24434  {
24435  erase(it.key());
24436  }
24437  else
24438  {
24439  operator[](it.key()).merge_patch(it.value());
24440  }
24441  }
24442  }
24443  else
24444  {
24445  *this = apply_patch;
24446  }
24447  }
24448 
24450 };
24451 
24455 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
24456 {
24457  return j.dump();
24458 }
24459 
24460 inline namespace literals
24461 {
24462  inline namespace json_literals
24463  {
24464 
24468 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
24469  inline nlohmann::json operator ""_json(const char* s, std::size_t n)
24470 #else
24471  inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24472 #endif
24473  {
24474  return nlohmann::json::parse(s, s + n);
24475  }
24476 
24480 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
24481  inline nlohmann::json::json_pointer operator ""_json_pointer(const char* s, std::size_t n)
24482 #else
24483  inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
24484 #endif
24485  {
24486  return nlohmann::json::json_pointer(std::string(s, n));
24487  }
24488 
24489  } // namespace json_literals
24490 } // namespace literals
24492 
24494 // nonmember support //
24496 
24497 namespace std // NOLINT(cert-dcl58-cpp)
24498 {
24499 
24503  struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp)
24504  {
24505  std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
24506  {
24507  return nlohmann::detail::hash(j);
24508  }
24509  };
24510 
24511  // specialization for std::less<value_t>
24512  template<>
24513  struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
24514  {
24520  ::nlohmann::detail::value_t rhs) const noexcept
24521  {
24522 #if JSON_HAS_THREE_WAY_COMPARISON
24523  return std::is_lt(lhs <=> rhs); // *NOPAD*
24524 #else
24526 #endif
24527  }
24528  };
24529 
24530  // C++20 prohibit function specialization in the std namespace.
24531 #ifndef JSON_HAS_CPP_20
24532 
24536  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)
24537  is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
24538  is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
24539  {
24540  j1.swap(j2);
24541  }
24542 
24543 #endif
24544 
24545 } // namespace std
24546 
24547 #if JSON_USE_GLOBAL_UDLS
24548 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
24549 using nlohmann::literals::json_literals::operator ""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24550 using nlohmann::literals::json_literals::operator ""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24551 #else
24552 using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24553 using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24554 #endif
24555 #endif
24556 
24557 // #include <nlohmann/detail/macro_unscope.hpp>
24558 // __ _____ _____ _____
24559 // __| | __| | | | JSON for Modern C++
24560 // | | |__ | | | | | | version 3.11.3
24561 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
24562 //
24563 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
24564 // SPDX-License-Identifier: MIT
24565 
24566 
24567 
24568 // restore clang diagnostic settings
24569 #if defined(__clang__)
24570 #pragma clang diagnostic pop
24571 #endif
24572 
24573 // clean up
24574 #undef JSON_ASSERT
24575 #undef JSON_INTERNAL_CATCH
24576 #undef JSON_THROW
24577 #undef JSON_PRIVATE_UNLESS_TESTED
24578 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24579 #undef NLOHMANN_BASIC_JSON_TPL
24580 #undef JSON_EXPLICIT
24581 #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
24582 #undef JSON_INLINE_VARIABLE
24583 #undef JSON_NO_UNIQUE_ADDRESS
24584 #undef JSON_DISABLE_ENUM_SERIALIZATION
24585 #undef JSON_USE_GLOBAL_UDLS
24586 
24587 #ifndef JSON_TEST_KEEP_MACROS
24588 #undef JSON_CATCH
24589 #undef JSON_TRY
24590 #undef JSON_HAS_CPP_11
24591 #undef JSON_HAS_CPP_14
24592 #undef JSON_HAS_CPP_17
24593 #undef JSON_HAS_CPP_20
24594 #undef JSON_HAS_FILESYSTEM
24595 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
24596 #undef JSON_HAS_THREE_WAY_COMPARISON
24597 #undef JSON_HAS_RANGES
24598 #undef JSON_HAS_STATIC_RTTI
24599 #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
24600 #endif
24601 
24602 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
24603 // __ _____ _____ _____
24604 // __| | __| | | | JSON for Modern C++
24605 // | | |__ | | | | | | version 3.11.3
24606 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
24607 //
24608 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
24609 // SPDX-License-Identifier: MIT
24610 
24611 
24612 
24613 #undef JSON_HEDLEY_ALWAYS_INLINE
24614 #undef JSON_HEDLEY_ARM_VERSION
24615 #undef JSON_HEDLEY_ARM_VERSION_CHECK
24616 #undef JSON_HEDLEY_ARRAY_PARAM
24617 #undef JSON_HEDLEY_ASSUME
24618 #undef JSON_HEDLEY_BEGIN_C_DECLS
24619 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24620 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24621 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24622 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24623 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24624 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
24625 #undef JSON_HEDLEY_CLANG_HAS_WARNING
24626 #undef JSON_HEDLEY_COMPCERT_VERSION
24627 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24628 #undef JSON_HEDLEY_CONCAT
24629 #undef JSON_HEDLEY_CONCAT3
24630 #undef JSON_HEDLEY_CONCAT3_EX
24631 #undef JSON_HEDLEY_CONCAT_EX
24632 #undef JSON_HEDLEY_CONST
24633 #undef JSON_HEDLEY_CONSTEXPR
24634 #undef JSON_HEDLEY_CONST_CAST
24635 #undef JSON_HEDLEY_CPP_CAST
24636 #undef JSON_HEDLEY_CRAY_VERSION
24637 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
24638 #undef JSON_HEDLEY_C_DECL
24639 #undef JSON_HEDLEY_DEPRECATED
24640 #undef JSON_HEDLEY_DEPRECATED_FOR
24641 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24642 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24643 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24644 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24645 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24646 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
24647 #undef JSON_HEDLEY_DIAGNOSTIC_POP
24648 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24649 #undef JSON_HEDLEY_DMC_VERSION
24650 #undef JSON_HEDLEY_DMC_VERSION_CHECK
24651 #undef JSON_HEDLEY_EMPTY_BASES
24652 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24653 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24654 #undef JSON_HEDLEY_END_C_DECLS
24655 #undef JSON_HEDLEY_FLAGS
24656 #undef JSON_HEDLEY_FLAGS_CAST
24657 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24658 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
24659 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24660 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24661 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
24662 #undef JSON_HEDLEY_GCC_HAS_FEATURE
24663 #undef JSON_HEDLEY_GCC_HAS_WARNING
24664 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24665 #undef JSON_HEDLEY_GCC_VERSION
24666 #undef JSON_HEDLEY_GCC_VERSION_CHECK
24667 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24668 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24669 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24670 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24671 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24672 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
24673 #undef JSON_HEDLEY_GNUC_HAS_WARNING
24674 #undef JSON_HEDLEY_GNUC_VERSION
24675 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
24676 #undef JSON_HEDLEY_HAS_ATTRIBUTE
24677 #undef JSON_HEDLEY_HAS_BUILTIN
24678 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24679 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24680 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24681 #undef JSON_HEDLEY_HAS_EXTENSION
24682 #undef JSON_HEDLEY_HAS_FEATURE
24683 #undef JSON_HEDLEY_HAS_WARNING
24684 #undef JSON_HEDLEY_IAR_VERSION
24685 #undef JSON_HEDLEY_IAR_VERSION_CHECK
24686 #undef JSON_HEDLEY_IBM_VERSION
24687 #undef JSON_HEDLEY_IBM_VERSION_CHECK
24688 #undef JSON_HEDLEY_IMPORT
24689 #undef JSON_HEDLEY_INLINE
24690 #undef JSON_HEDLEY_INTEL_CL_VERSION
24691 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
24692 #undef JSON_HEDLEY_INTEL_VERSION
24693 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
24694 #undef JSON_HEDLEY_IS_CONSTANT
24695 #undef JSON_HEDLEY_IS_CONSTEXPR_
24696 #undef JSON_HEDLEY_LIKELY
24697 #undef JSON_HEDLEY_MALLOC
24698 #undef JSON_HEDLEY_MCST_LCC_VERSION
24699 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
24700 #undef JSON_HEDLEY_MESSAGE
24701 #undef JSON_HEDLEY_MSVC_VERSION
24702 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
24703 #undef JSON_HEDLEY_NEVER_INLINE
24704 #undef JSON_HEDLEY_NON_NULL
24705 #undef JSON_HEDLEY_NO_ESCAPE
24706 #undef JSON_HEDLEY_NO_RETURN
24707 #undef JSON_HEDLEY_NO_THROW
24708 #undef JSON_HEDLEY_NULL
24709 #undef JSON_HEDLEY_PELLES_VERSION
24710 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
24711 #undef JSON_HEDLEY_PGI_VERSION
24712 #undef JSON_HEDLEY_PGI_VERSION_CHECK
24713 #undef JSON_HEDLEY_PREDICT
24714 #undef JSON_HEDLEY_PRINTF_FORMAT
24715 #undef JSON_HEDLEY_PRIVATE
24716 #undef JSON_HEDLEY_PUBLIC
24717 #undef JSON_HEDLEY_PURE
24718 #undef JSON_HEDLEY_REINTERPRET_CAST
24719 #undef JSON_HEDLEY_REQUIRE
24720 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24721 #undef JSON_HEDLEY_REQUIRE_MSG
24722 #undef JSON_HEDLEY_RESTRICT
24723 #undef JSON_HEDLEY_RETURNS_NON_NULL
24724 #undef JSON_HEDLEY_SENTINEL
24725 #undef JSON_HEDLEY_STATIC_ASSERT
24726 #undef JSON_HEDLEY_STATIC_CAST
24727 #undef JSON_HEDLEY_STRINGIFY
24728 #undef JSON_HEDLEY_STRINGIFY_EX
24729 #undef JSON_HEDLEY_SUNPRO_VERSION
24730 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24731 #undef JSON_HEDLEY_TINYC_VERSION
24732 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
24733 #undef JSON_HEDLEY_TI_ARMCL_VERSION
24734 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24735 #undef JSON_HEDLEY_TI_CL2000_VERSION
24736 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24737 #undef JSON_HEDLEY_TI_CL430_VERSION
24738 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24739 #undef JSON_HEDLEY_TI_CL6X_VERSION
24740 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24741 #undef JSON_HEDLEY_TI_CL7X_VERSION
24742 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24743 #undef JSON_HEDLEY_TI_CLPRU_VERSION
24744 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24745 #undef JSON_HEDLEY_TI_VERSION
24746 #undef JSON_HEDLEY_TI_VERSION_CHECK
24747 #undef JSON_HEDLEY_UNAVAILABLE
24748 #undef JSON_HEDLEY_UNLIKELY
24749 #undef JSON_HEDLEY_UNPREDICTABLE
24750 #undef JSON_HEDLEY_UNREACHABLE
24751 #undef JSON_HEDLEY_UNREACHABLE_RETURN
24752 #undef JSON_HEDLEY_VERSION
24753 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24754 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
24755 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
24756 #undef JSON_HEDLEY_VERSION_ENCODE
24757 #undef JSON_HEDLEY_WARNING
24758 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
24759 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
24760 #undef JSON_HEDLEY_FALL_THROUGH
24761 
24762 
24763 
24764 #endif // INCLUDE_NLOHMANN_JSON_HPP_
namespace for Niels Lohmann
Definition: json.hpp:19400
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:20672
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:21099
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:21905
reference operator[](KeyType &&key)
access specified object element
Definition: json.hpp:21473
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:23679
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:21045
reference back()
access the last element
Definition: json.hpp:21709
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:20136
basic_json patch(const basic_json &json_patch) const
applies a JSON patch to a copy of the current object
Definition: json.hpp:24271
const_reference front() const
access the first element
Definition: json.hpp:21702
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:23939
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:20665
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:22763
ReturnType value(const json_pointer &ptr, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21653
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:22022
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:19531
static void to_bjdata(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23630
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:19475
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:20637
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:19535
data(size_type cnt, const basic_json &val)
Definition: json.hpp:23503
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:23874
static void to_bjdata(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23622
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:23919
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:19526
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:23953
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:19518
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:20609
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.hpp:21497
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:19513
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:22840
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:21135
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22709
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:21146
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:20686
JSON_PRIVATE_UNLESS_TESTED const_reference rhs
Definition: json.hpp:22958
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:22501
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:21676
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.hpp:21442
const_reference back() const
access the last element
Definition: json.hpp:21718
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:21800
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:22446
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:22780
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:23775
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:20273
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.hpp:22613
const binary_t & get_binary() const
get a binary value
Definition: json.hpp:21217
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:23859
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:19541
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:19666
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.hpp:21305
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:20644
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:22716
data m_data
Definition: json.hpp:23521
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:22485
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:20103
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:20314
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:23577
JSON_PRIVATE_UNLESS_TESTED const_reference bool inverse
Definition: json.hpp:22958
ReturnType value(const typename object_t::key_type &key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:21552
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:23829
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23961
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition: json.hpp:20284
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:20124
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:23663
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:23790
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition: json.hpp:21916
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:23437
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.hpp:22633
ReturnType value(KeyType &&key, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21605
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:24281
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23933
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:19642
value_type & reference
the type of an element reference
Definition: json.hpp:19511
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:22039
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:23547
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:23654
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.hpp:21952
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:20262
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.hpp:21343
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:19549
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:20321
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.hpp:21966
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21730
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.hpp:22586
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:19662
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21527
ValueType & get_to(ValueType &v) const
Definition: json.hpp:21112
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:19521
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:19524
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:20573
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:24423
reference operator[](T *key)
Definition: json.hpp:21458
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:21239
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.hpp:21982
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:20651
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:19650
detail::value_t value_t
Definition: json.hpp:19465
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:19629
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22477
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23538
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.hpp:21420
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:20857
~basic_json() noexcept
destructor
Definition: json.hpp:20555
detail::out_of_range out_of_range
Definition: json.hpp:19493
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:20203
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:22856
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:20630
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:23444
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.hpp:22684
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:20532
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:23721
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:21086
const_reference operator[](T *key) const
Definition: json.hpp:21464
data(const value_t v)
Definition: json.hpp:23498
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:21361
basic_json(const JsonRef &ref)
Definition: json.hpp:20442
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:19469
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:23603
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:21123
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:19654
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20846
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:21323
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:20679
void swap(object_t &other)
exchanges the values
Definition: json.hpp:22808
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.hpp:22664
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:20295
void swap(array_t &other)
exchanges the values
Definition: json.hpp:22792
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:21923
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:22535
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22414
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:22046
binary_t & get_binary()
get a binary value
Definition: json.hpp:21205
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:20595
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:22510
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21628
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:20306
data() noexcept=default
StringType string_t
a type for a string
Definition: json.hpp:19646
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:19638
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:22422
ValueType value(KeyType &&key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21578
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:21285
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:23844
json_value m_value
the value of the current element
Definition: json.hpp:23496
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:20623
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:22012
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23561
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:20602
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:20616
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:23595
JSON_PRIVATE_UNLESS_TESTED const_reference bool static SAX bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
Definition: json.hpp:23383
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition: json.hpp:23638
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:20515
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:19529
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:20116
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:21407
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:19516
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.hpp:22606
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:19658
void swap(string_t &other)
exchanges the values
Definition: json.hpp:22824
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:20150
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:19533
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:21262
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.hpp:19670
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:20446
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22454
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:23554
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:20658
static std::vector< std::uint8_t > to_bjdata(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23611
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:23570
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:23736
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:22567
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:20333
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:23925
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:23584
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:23459
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition: json.hpp:22030
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:23647
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.hpp:21998
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:19467
an internal type for a backed binary type
Definition: json.hpp:5892
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5932
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5898
std::uint64_t subtype_type
Definition: json.hpp:5895
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5926
BinaryType container_type
Definition: json.hpp:5894
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5920
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5908
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5947
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5913
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5954
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5903
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5939
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5961
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:9212
binary_reader(const binary_reader &)=delete
binary_reader(binary_reader &&)=default
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition: json.hpp:9228
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:9249
binary_reader & operator=(binary_reader &&)=default
binary_reader & operator=(const binary_reader &)=delete
serialization to CBOR and MessagePack values
Definition: json.hpp:15078
void write_bson(const BasicJsonType &j)
Definition: json.hpp:15098
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16833
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16840
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:15089
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:16862
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true, const bool use_bjdata=false)
Definition: json.hpp:15777
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:15451
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:15127
general exception of the basic_json class
Definition: json.hpp:4373
const int id
the id of the exception
Definition: json.hpp:4382
static std::string diagnostics(std::nullptr_t)
Definition: json.hpp:4393
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:4376
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:4388
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.hpp:4399
Definition: json.hpp:6189
char char_type
Definition: json.hpp:6191
file_input_adapter(const file_input_adapter &)=delete
file_input_adapter(file_input_adapter &&) noexcept=default
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6207
Definition: json.hpp:6227
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:6250
~input_stream_adapter()
Definition: json.hpp:6231
char char_type
Definition: json.hpp:6229
input_stream_adapter(const input_stream_adapter &)=delete
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter & operator=(input_stream_adapter &&)=delete
std::char_traits< char >::int_type get_character()
Definition: json.hpp:6260
input_stream_adapter(std::istream &i)
Definition: json.hpp:6241
exception indicating errors with iterators
Definition: json.hpp:4524
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4527
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:12915
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:13027
~iter_impl()=default
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:13489
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:13480
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13443
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:13434
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:13042
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:13381
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:13416
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:13244
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:13336
iter_impl operator++(int) &
post-increment (it++)
Definition: json.hpp:13233
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:13295
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13551
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:13589
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:12945
pointer operator->() const
dereference the iterator
Definition: json.hpp:13191
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:13052
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:13614
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:13522
iter_impl(iter_impl &&) noexcept=default
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:12940
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:13500
reference value() const
return the value of an iterator
Definition: json.hpp:13605
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:13425
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:12949
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:12943
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:13147
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13511
iter_impl()=default
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:13372
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.hpp:13284
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:12954
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:13017
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:13108
Definition: json.hpp:5187
iteration_proxy_value operator++(int) &
Definition: json.hpp:5243
iteration_proxy_value(iteration_proxy_value const &)=default
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:5252
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:5258
std::ptrdiff_t difference_type
Definition: json.hpp:5189
iteration_proxy_value(IteratorType it, std::size_t array_index_=0) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_default_constructible< string_type >::value)
Definition: json.hpp:5210
const string_type & key() const
return key of the iterator
Definition: json.hpp:5264
iteration_proxy_value(iteration_proxy_value &&) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_move_constructible< string_type >::value)=default
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:5194
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:5300
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:5235
iteration_proxy_value & operator=(iteration_proxy_value const &)=default
std::input_iterator_tag iterator_category
Definition: json.hpp:5193
proxy class for the items() function
Definition: json.hpp:5308
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:5333
iteration_proxy(iteration_proxy const &)=default
iteration_proxy(iteration_proxy &&) noexcept=default
iteration_proxy_value< IteratorType > begin() const noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:5327
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:5317
iteration_proxy & operator=(iteration_proxy const &)=default
Definition: json.hpp:6282
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6286
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:6284
char_traits< char_type >::int_type get_character()
Definition: json.hpp:6290
Definition: json.hpp:14819
json_ref(json_ref &&) noexcept=default
json_ref(const value_type &value)
Definition: json.hpp:14827
json_ref(value_type &&value)
Definition: json.hpp:14823
value_type const & operator*() const
Definition: json.hpp:14858
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:14831
json_ref(Args &&... args)
Definition: json.hpp:14838
value_type moved_or_copied() const
Definition: json.hpp:14849
BasicJsonType value_type
Definition: json.hpp:14821
value_type const * operator->() const
Definition: json.hpp:14863
a template for a reverse iterator class
Definition: json.hpp:13668
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.hpp:13684
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:13690
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.hpp:13696
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:13702
std::ptrdiff_t difference_type
Definition: json.hpp:13670
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13732
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:13738
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:13726
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13708
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:13674
reference value() const
return the value of an iterator
Definition: json.hpp:13745
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:13681
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:13672
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13720
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:13677
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:13714
Definition: json.hpp:7291
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:7294
bool end_object()
Definition: json.hpp:7344
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7334
bool binary(binary_t &)
Definition: json.hpp:7329
bool number_integer(number_integer_t)
Definition: json.hpp:7309
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7349
bool boolean(bool)
Definition: json.hpp:7304
bool end_array()
Definition: json.hpp:7354
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:7314
bool string(string_t &)
Definition: json.hpp:7324
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:7297
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:7319
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:7359
bool key(string_t &)
Definition: json.hpp:7339
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:7293
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:7295
typename BasicJsonType::string_t string_t
Definition: json.hpp:7296
Definition: json.hpp:6984
bool boolean(bool val)
Definition: json.hpp:7015
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:7172
typename BasicJsonType::string_t string_t
Definition: json.hpp:6989
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:7033
constexpr bool is_errored() const
Definition: json.hpp:7184
bool string(string_t &val)
Definition: json.hpp:7039
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6987
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6990
bool start_object(std::size_t len)
Definition: json.hpp:7051
bool start_array(std::size_t len)
Definition: json.hpp:7122
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6986
bool end_array()
Definition: json.hpp:7139
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool key(string_t &val)
Definition: json.hpp:7069
bool end_object()
Definition: json.hpp:7086
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:6992
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:6991
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:7027
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.hpp:6994
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6988
bool number_integer(number_integer_t val)
Definition: json.hpp:7021
bool binary(binary_t &val)
Definition: json.hpp:7045
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:6801
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
json_sax_dom_parser(const json_sax_dom_parser &)=delete
bool string(string_t &val)
Definition: json.hpp:6855
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:6814
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6922
typename BasicJsonType::string_t string_t
Definition: json.hpp:6806
bool start_object(std::size_t len)
Definition: json.hpp:6867
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6804
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6843
bool number_integer(number_integer_t val)
Definition: json.hpp:6837
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6803
bool binary(binary_t &val)
Definition: json.hpp:6861
json_sax_dom_parser(json_sax_dom_parser &&)=default
bool boolean(bool val)
Definition: json.hpp:6831
bool end_array()
Definition: json.hpp:6911
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6849
bool end_object()
Definition: json.hpp:6889
constexpr bool is_errored() const
Definition: json.hpp:6934
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6807
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6805
bool start_array(std::size_t len)
Definition: json.hpp:6899
bool key(string_t &val)
Definition: json.hpp:6879
Definition: json.hpp:7408
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:7435
token_type
token types for the parser
Definition: json.hpp:7412
lexical analysis
Definition: json.hpp:7485
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8859
void skip_whitespace()
Definition: json.hpp:8873
lexer & operator=(lexer &&)=default
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:7496
std::string get_token_string() const
Definition: json.hpp:8821
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8785
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8813
token_type scan()
Definition: json.hpp:8881
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8791
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:7494
lexer(lexer &&)=default
~lexer()=default
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8803
lexer & operator=(lexer &)=delete
lexer(const lexer &)=delete
constexpr JSON_HEDLEY_RETURNS_NON_NULL const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8846
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8797
exception indicating other library errors
Definition: json.hpp:4576
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4579
exception indicating access out of the defined range
Definition: json.hpp:4559
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4562
Definition: json.hpp:15036
output_adapter(StringType &s)
Definition: json.hpp:15047
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:15043
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:15039
output adapter for output streams
Definition: json.hpp:14988
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:14990
void write_character(CharType c) override
Definition: json.hpp:14994
output adapter for basic_string
Definition: json.hpp:15013
void write_character(CharType c) override
Definition: json.hpp:15019
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:15015
output adapter for byte vectors
Definition: json.hpp:14963
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:14965
void write_character(CharType c) override
Definition: json.hpp:14969
exception indicating a parse error
Definition: json.hpp:4471
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, BasicJsonContext context)
create a parse error exception
Definition: json.hpp:4483
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4491
const std::size_t byte
byte index of the parse error
Definition: json.hpp:4508
syntax analysis
Definition: json.hpp:12228
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.hpp:12238
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:12260
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:12320
bool sax_parse(SAX *sax, const bool strict=true)
Definition: json.hpp:12328
Definition: json.hpp:12732
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:12820
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:12807
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:12761
constexpr friend bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12777
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:12794
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:12755
constexpr friend difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12789
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:12767
primitive_iterator_t operator++(int) &noexcept
Definition: json.hpp:12800
constexpr difference_type get_value() const noexcept
Definition: json.hpp:12743
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:12782
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:12826
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:12749
primitive_iterator_t operator--(int) &noexcept
Definition: json.hpp:12813
constexpr friend bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12772
Definition: json.hpp:18059
serializer & operator=(serializer &&)=delete
std::array< char, 512 > string_buffer
string buffer
Definition: json.hpp:18983
std::uint8_t state
Definition: json.hpp:18401
std::size_t bytes_after_last_accept
Definition: json.hpp:18405
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:18074
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition: json.hpp:18399
std::size_t undumped_chars
Definition: json.hpp:18406
const char thousands_sep
the locale's thousand separator character
Definition: json.hpp:18978
const char decimal_point
the locale's decimal point character
Definition: json.hpp:18980
~serializer()=default
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:18991
string_t indent_string
the indentation string
Definition: json.hpp:18988
const std::lconv * loc
the locale
Definition: json.hpp:18976
serializer & operator=(const serializer &)=delete
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition: json.hpp:18973
const char indent_char
the indentation character
Definition: json.hpp:18986
std::size_t bytes
Definition: json.hpp:18402
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:18114
serializer(const serializer &)=delete
serializer(serializer &&)=delete
Definition: json.hpp:6606
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:6614
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6621
contiguous_bytes_input_adapter && get()
Definition: json.hpp:6624
exception indicating executing a member function with a wrong type
Definition: json.hpp:4542
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4545
Definition: json.hpp:6441
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:6445
char char_type
Definition: json.hpp:6443
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6448
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition: json.hpp:13840
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:13935
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:13912
typename string_t_helper< RefStringType >::type string_t
Definition: json.hpp:13862
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:13942
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:13902
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.hpp:13866
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:14001
friend bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:14735
friend std::ostream & operator<<(std::ostream &o, const json_pointer &ptr)
write string representation of the JSON pointer to stream
Definition: json.hpp:13893
void pop_back()
remove last reference token
Definition: json.hpp:13963
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:13872
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13994
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:13927
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:13949
friend bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:14760
friend class json_pointer
Definition: json.hpp:13846
const string_t & back() const
return last reference token
Definition: json.hpp:13975
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13987
friend bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointer for less-than
Definition: json.hpp:14785
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:13920
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:5381
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2596
#define JSON_HEDLEY_CONST
Definition: json.hpp:1818
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:1102
#define JSON_INLINE_VARIABLE
Definition: json.hpp:2499
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1448
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2559
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:70
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1713
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1606
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2526
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:24455
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:2047
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14735
#define JSON_CATCH(exception)
Definition: json.hpp:2525
#define JSON_ASSERT(x)
Definition: json.hpp:2552
#define JSON_THROW(exception)
Definition: json.hpp:2523
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition: json.hpp:77
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:68
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2606
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1714
#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
Definition: json.hpp:12118
#define JSON_TRY
Definition: json.hpp:2524
#define NLOHMANN_JSON_NAMESPACE_END
Definition: json.hpp:144
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.hpp:2505
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14760
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:69
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition: json.hpp:2786
#define NLOHMANN_JSON_NAMESPACE_BEGIN
Definition: json.hpp:134
#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
Definition: json.hpp:12115
basic_json<> json
default specialization
Definition: json.hpp:3423
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:1103
#define JSON_EXPLICIT
Definition: json.hpp:2823
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.hpp:1396
#define JSON_HEDLEY_PURE
Definition: json.hpp:1787
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14785
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition: json.hpp:22881
fill
Definition: OrderbookView.py:93
root
Definition: addOrder.py:127
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:17398
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:17234
Target reinterpret_bits(const Source source)
Definition: json.hpp:16954
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:17095
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:17834
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:17886
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:17452
constexpr int kAlpha
Definition: json.hpp:17217
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:17734
constexpr int kGamma
Definition: json.hpp:17218
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:17493
constexpr bool is_transparent()
Definition: json.hpp:4195
constexpr bool is_c_string()
Definition: json.hpp:4167
detail namespace with internal helper functions
Definition: json.hpp:249
input_format_t
the supported input formats
Definition: json.hpp:6177
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:5781
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:309
typename make_void< Ts... >::type void_t
Definition: json.hpp:255
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:9074
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:14958
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition: json.hpp:4276
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:9082
constexpr std::array< T, sizeof...(Args)> make_array(Args &&... args)
Definition: json.hpp:3223
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:12219
OutStringType concat(Args &&... args)
Definition: json.hpp:4350
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.hpp:4285
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 >>, priority_tag< 0 >)
Definition: json.hpp:5011
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3518
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3524
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:4017
void to_json(BasicJsonType &j, const T &b)
Definition: json.hpp:5775
typename T::pointer pointer_t
Definition: json.hpp:3509
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition: json.hpp:4270
parse_event_t
Definition: json.hpp:12202
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.hpp:4279
integer_sequence< size_t, Ints... > index_sequence
Definition: json.hpp:3138
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:4822
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3184
typename T::value_type value_type_t
Definition: json.hpp:3503
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:313
T conditional_static_cast(U value)
Definition: json.hpp:4051
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.hpp:4291
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3096
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.hpp:5070
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:9043
typename T::mapped_type mapped_type_t
Definition: json.hpp:3497
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition: json.hpp:2971
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:9051
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3745
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:5343
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:9185
@ 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:306
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3521
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:6579
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3192
std::integral_constant< bool, Value > bool_constant
Definition: json.hpp:4157
void concat_into(OutStringType &)
Definition: json.hpp:4266
typename T::key_type key_type_t
Definition: json.hpp:3500
constexpr bool value_in_range_of(T val)
Definition: json.hpp:4151
value_t
the JSON type enumeration
Definition: json.hpp:2873
@ null
null value
@ 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:4074
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6522
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:5005
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:9059
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:300
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:6023
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition: json.hpp:4282
typename T::iterator_category iterator_category_t
Definition: json.hpp:3515
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:6005
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:2902
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:9077
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:17971
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:4029
error_handler_t
how to treat decoding errors
Definition: json.hpp:18051
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
std::size_t concat_length()
Definition: json.hpp:4235
value_type_t< iterator_traits< iterator_t< T > >> range_value_t
Definition: json.hpp:3748
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:4665
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.hpp:3597
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5643
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:4679
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:9035
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3200
typename T::difference_type difference_type_t
Definition: json.hpp:3506
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:3082
typename T::is_transparent detect_is_transparent
Definition: json.hpp:3987
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:9055
typename std::conditional< std::is_same< T, void >::value, json_default_base, T >::type json_base_class
Definition: json.hpp:13794
typename T::reference reference_t
Definition: json.hpp:3512
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:9039
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:9070
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.hpp:4020
typename T::key_compare detect_key_compare
Definition: json.hpp:3581
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:9063
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition: json.hpp:4288
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:9047
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:294
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2991
void int_to_string(string_type &target, std::size_t value)
Definition: json.hpp:5180
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:4079
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:4001
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.hpp:4273
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)>>, index_sequence< Idx... >)
Definition: json.hpp:4905
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:9067
Definition: json.hpp:24461
Definition: json.hpp:5364
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:24536
namespace for Niels Lohmann
Definition: json.hpp:5834
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:5858
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:5848
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:5838
Definition: json.hpp:3589
typename BasicJsonType::object_t object_t
Definition: json.hpp:3590
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.hpp:3591
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition: json.hpp:3593
signed char char_type
Definition: json.hpp:3636
static constexpr int_type eof() noexcept
Definition: json.hpp:3650
uint64_t int_type
Definition: json.hpp:3637
static char_type to_char_type(int_type i) noexcept
Definition: json.hpp:3645
static int_type to_int_type(char_type c) noexcept
Definition: json.hpp:3640
static char_type to_char_type(int_type i) noexcept
Definition: json.hpp:3621
static constexpr int_type eof() noexcept
Definition: json.hpp:3626
unsigned char char_type
Definition: json.hpp:3612
uint64_t int_type
Definition: json.hpp:3613
static int_type to_int_type(char_type c) noexcept
Definition: json.hpp:3616
Definition: json.hpp:3606
Definition: json.hpp:3662
Definition: json.hpp:3661
decltype(input_adapter(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))) adapter_type
Definition: json.hpp:6545
Definition: json.hpp:281
std::false_type value_t
Definition: json.hpp:282
Default type
Definition: json.hpp:283
Definition: json.hpp:17082
diyfp w
Definition: json.hpp:17083
diyfp minus
Definition: json.hpp:17084
diyfp plus
Definition: json.hpp:17085
Definition: json.hpp:17221
std::uint64_t f
Definition: json.hpp:17222
int e
Definition: json.hpp:17223
int k
Definition: json.hpp:17224
Definition: json.hpp:16964
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:16988
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:17070
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:17053
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:16976
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:16970
static constexpr int kPrecision
Definition: json.hpp:16965
std::uint64_t f
Definition: json.hpp:16967
int e
Definition: json.hpp:16968
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:5568
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:5543
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:5533
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:5555
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:5584
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:5472
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:5481
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:5426
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:5494
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:5520
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:5507
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:5603
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:5624
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:5613
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:5448
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:5459
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:5439
Definition: json.hpp:5420
Definition: json.hpp:5100
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition: json.hpp:5102
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3543
Definition: json.hpp:3528
Definition: json.hpp:3584
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3558
Definition: json.hpp:3553
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3573
Definition: json.hpp:3568
Definition: json.hpp:4616
Definition: json.hpp:3124
T value_type
Definition: json.hpp:3125
static constexpr std::size_t size() noexcept
Definition: json.hpp:3126
an iterator value
Definition: json.hpp:12848
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:12852
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:12854
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:12850
Definition: json.hpp:3477
Definition: json.hpp:3464
Definition: json.hpp:4182
Definition: json.hpp:3978
Definition: json.hpp:3842
Definition: json.hpp:3861
Definition: json.hpp:3932
Definition: json.hpp:3782
Definition: json.hpp:3819
static constexpr auto value
Definition: json.hpp:3820
Definition: json.hpp:3935
Definition: json.hpp:3948
Definition: json.hpp:3755
Definition: json.hpp:3905
Definition: json.hpp:3815
Definition: json.hpp:3826
ConstructibleStringType laundered_type
Definition: json.hpp:3831
static constexpr auto value
Definition: json.hpp:3834
Definition: json.hpp:3951
Definition: json.hpp:3693
Definition: json.hpp:3674
Definition: json.hpp:297
Definition: json.hpp:3536
static constexpr bool value
Definition: json.hpp:3537
Definition: json.hpp:6498
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:6499
Definition: json.hpp:3708
Definition: json.hpp:3957
Definition: json.hpp:3487
Definition: json.hpp:4039
char x[2]
Definition: json.hpp:4040
Definition: json.hpp:4035
static one test(decltype(&C::capacity))
@ value
Definition: json.hpp:4046
char one
Definition: json.hpp:4036
static two test(...)
Definition: json.hpp:3727
static constexpr bool value
Definition: json.hpp:3741
Definition: json.hpp:9117
Definition: json.hpp:9086
static constexpr bool value
Definition: json.hpp:9099
Definition: json.hpp:3968
Definition: json.hpp:4204
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6510
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6514
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:6488
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6487
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6490
IteratorType iterator_type
Definition: json.hpp:6486
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3304
Definition: json.hpp:3292
Definition: json.hpp:3273
Default base class of the basic_json class.
Definition: json.hpp:13787
Definition: json.hpp:252
void type
Definition: json.hpp:253
Definition: json.hpp:3668
Definition: json.hpp:267
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:14944
output_adapter_protocol(const output_adapter_protocol &)=default
virtual ~output_adapter_protocol()=default
virtual void write_character(CharType c)=0
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
virtual void write_characters(const CharType *s, std::size_t length)=0
struct to capture the start position of the current token
Definition: json.hpp:3037
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:3041
std::size_t lines_read
the number of lines read
Definition: json.hpp:3043
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:3039
Definition: json.hpp:3208
Definition: json.hpp:3207
Definition: json.hpp:3213
static constexpr JSON_INLINE_VARIABLE T value
Definition: json.hpp:3214
Definition: json.hpp:5801
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:5803
Definition: json.hpp:3144
Definition: json.hpp:3163
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:3165
static constexpr bool test(T val)
Definition: json.hpp:4135
static constexpr bool test(T)
Definition: json.hpp:4144
Definition: json.hpp:4130
static constexpr bool test(T val)
Definition: json.hpp:4089
static constexpr bool test(T val)
Definition: json.hpp:4109
static constexpr bool test(T val)
Definition: json.hpp:4099
static constexpr bool test(T val)
Definition: json.hpp:4119
Definition: json.hpp:4084
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:6380
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:6322
Definition: json.hpp:6316
SAX interface.
Definition: json.hpp:6671
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:6672
typename BasicJsonType::string_t string_t
Definition: json.hpp:6675
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:6674
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6673
json_sax(json_sax &&) noexcept=default
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6676
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
a minimal map-like container that preserves insertion order
Definition: json.hpp:19033
const T & at(const key_type &key) const
Definition: json.hpp:19137
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:19036
const T & operator[](const key_type &key) const
Definition: json.hpp:19097
std::pair< iterator, bool > emplace(KeyType &&key, T &&t)
Definition: json.hpp:19072
typename Container::value_type value_type
Definition: json.hpp:19040
std::equal_to< Key > key_compare
Definition: json.hpp:19044
iterator erase(iterator pos)
Definition: json.hpp:19205
T mapped_type
Definition: json.hpp:19035
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.hpp:19050
typename Container::iterator iterator
Definition: json.hpp:19037
T & operator[](KeyType &&key)
Definition: json.hpp:19092
iterator find(const key_type &key)
Definition: json.hpp:19289
T & at(const key_type &key)
Definition: json.hpp:19109
iterator erase(iterator first, iterator last)
Definition: json.hpp:19210
const_iterator find(const key_type &key) const
Definition: json.hpp:19315
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:19332
size_type erase(KeyType &&key)
Definition: json.hpp:19186
typename Container::size_type size_type
Definition: json.hpp:19039
const T & at(KeyType &&key) const
Definition: json.hpp:19152
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:19057
ordered_map() noexcept(noexcept(Container()))
Definition: json.hpp:19049
void insert(InputIt first, InputIt last)
Definition: json.hpp:19350
T & operator[](const key_type &key)
Definition: json.hpp:19085
size_type count(const key_type &key) const
Definition: json.hpp:19263
size_type erase(const key_type &key)
Definition: json.hpp:19165
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:19327
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.hpp:19054
size_type count(KeyType &&key) const
Definition: json.hpp:19277
Key key_type
Definition: json.hpp:19034
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:19052
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.hpp:19347
iterator find(KeyType &&key)
Definition: json.hpp:19303
T & at(KeyType &&key)
Definition: json.hpp:19124
typename Container::const_iterator const_iterator
Definition: json.hpp:19038
const T & operator[](KeyType &&key) const
Definition: json.hpp:19104
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.hpp:24505
bool operator()(::nlohmann::detail::value_t lhs, ::nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:24519