WCSim
json.hpp
Go to the documentation of this file.
1 // __ _____ _____ _____
2 // __| | __| | | | JSON for Modern C++
3 // | | |__ | | | | | | version 3.11.2
4 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5 //
6 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7 // SPDX-License-Identifier: MIT
8 
9 /****************************************************************************\
10  * Note on documentation: The source files contain links to the online *
11  * documentation of the public API at https://json.nlohmann.me. This URL *
12  * contains the most recent documentation and should also be applicable to *
13  * previous versions; documentation for deprecated functions is not *
14  * removed, but marked deprecated. See "Generate documentation" section in *
15  * file docs/README.md. *
16 \****************************************************************************/
17 
18 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
19 #define INCLUDE_NLOHMANN_JSON_HPP_
20 
21 #include <algorithm> // all_of, find, for_each
22 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
23 #include <functional> // hash, less
24 #include <initializer_list> // initializer_list
25 #ifndef JSON_NO_IO
26  #include <iosfwd> // istream, ostream
27 #endif // JSON_NO_IO
28 #include <iterator> // random_access_iterator_tag
29 #include <memory> // unique_ptr
30 #include <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.2
38 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
39 //
40 // SPDX-FileCopyrightText: 2013-2022 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.2
51 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
52 //
53 // SPDX-FileCopyrightText: 2013-2022 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 != 2
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 2 // 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.2
153 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
154 //
155 // SPDX-FileCopyrightText: 2013-2022 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.2
176 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
177 //
178 // SPDX-FileCopyrightText: 2013-2022 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.2
196 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
197 //
198 // SPDX-FileCopyrightText: 2013-2022 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.2
212 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
213 //
214 // SPDX-FileCopyrightText: 2013-2022 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.2
224 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
225 //
226 // SPDX-FileCopyrightText: 2013-2022 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.2
237 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
238 //
239 // SPDX-FileCopyrightText: 2013-2022 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.2
324 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
325 //
326 // SPDX-FileCopyrightText: 2013-2022 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 #ifdef JSON_HAS_CPP_17
2489  #define JSON_INLINE_VARIABLE inline
2490 #else
2491  #define JSON_INLINE_VARIABLE
2492 #endif
2493 
2494 #if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2495  #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2496 #else
2497  #define JSON_NO_UNIQUE_ADDRESS
2498 #endif
2499 
2500 // disable documentation warnings on clang
2501 #if defined(__clang__)
2502  #pragma clang diagnostic push
2503  #pragma clang diagnostic ignored "-Wdocumentation"
2504  #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2505 #endif
2506 
2507 // allow disabling exceptions
2508 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2509  #define JSON_THROW(exception) throw exception
2510  #define JSON_TRY try
2511  #define JSON_CATCH(exception) catch(exception)
2512  #define JSON_INTERNAL_CATCH(exception) catch(exception)
2513 #else
2514  #include <cstdlib>
2515  #define JSON_THROW(exception) std::abort()
2516  #define JSON_TRY if(true)
2517  #define JSON_CATCH(exception) if(false)
2518  #define JSON_INTERNAL_CATCH(exception) if(false)
2519 #endif
2520 
2521 // override exception macros
2522 #if defined(JSON_THROW_USER)
2523  #undef JSON_THROW
2524  #define JSON_THROW JSON_THROW_USER
2525 #endif
2526 #if defined(JSON_TRY_USER)
2527  #undef JSON_TRY
2528  #define JSON_TRY JSON_TRY_USER
2529 #endif
2530 #if defined(JSON_CATCH_USER)
2531  #undef JSON_CATCH
2532  #define JSON_CATCH JSON_CATCH_USER
2533  #undef JSON_INTERNAL_CATCH
2534  #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2535 #endif
2536 #if defined(JSON_INTERNAL_CATCH_USER)
2537  #undef JSON_INTERNAL_CATCH
2538  #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2539 #endif
2540 
2541 // allow overriding assert
2542 #if !defined(JSON_ASSERT)
2543  #include <cassert> // assert
2544  #define JSON_ASSERT(x) assert(x)
2545 #endif
2546 
2547 // allow to access some private functions (needed by the test suite)
2548 #if defined(JSON_TESTS_PRIVATE)
2549  #define JSON_PRIVATE_UNLESS_TESTED public
2550 #else
2551  #define JSON_PRIVATE_UNLESS_TESTED private
2552 #endif
2553 
2559 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2560  template<typename BasicJsonType> \
2561  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2562  { \
2563  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2564  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2565  auto it = std::find_if(std::begin(m), std::end(m), \
2566  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2567  { \
2568  return ej_pair.first == e; \
2569  }); \
2570  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2571  } \
2572  template<typename BasicJsonType> \
2573  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2574  { \
2575  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2576  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2577  auto it = std::find_if(std::begin(m), std::end(m), \
2578  [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2579  { \
2580  return ej_pair.second == j; \
2581  }); \
2582  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2583  }
2584 
2585 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2586 // may be removed in the future once the class is split.
2587 
2588 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2589  template<template<typename, typename, typename...> class ObjectType, \
2590  template<typename, typename...> class ArrayType, \
2591  class StringType, class BooleanType, class NumberIntegerType, \
2592  class NumberUnsignedType, class NumberFloatType, \
2593  template<typename> class AllocatorType, \
2594  template<typename, typename = void> class JSONSerializer, \
2595  class BinaryType, \
2596  class CustomBaseClass>
2597 
2598 #define NLOHMANN_BASIC_JSON_TPL \
2599  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2600  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2601  AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>
2602 
2603 // Macros to simplify conversion from/to types
2604 
2605 #define NLOHMANN_JSON_EXPAND( x ) x
2606 #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
2607 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2608  NLOHMANN_JSON_PASTE64, \
2609  NLOHMANN_JSON_PASTE63, \
2610  NLOHMANN_JSON_PASTE62, \
2611  NLOHMANN_JSON_PASTE61, \
2612  NLOHMANN_JSON_PASTE60, \
2613  NLOHMANN_JSON_PASTE59, \
2614  NLOHMANN_JSON_PASTE58, \
2615  NLOHMANN_JSON_PASTE57, \
2616  NLOHMANN_JSON_PASTE56, \
2617  NLOHMANN_JSON_PASTE55, \
2618  NLOHMANN_JSON_PASTE54, \
2619  NLOHMANN_JSON_PASTE53, \
2620  NLOHMANN_JSON_PASTE52, \
2621  NLOHMANN_JSON_PASTE51, \
2622  NLOHMANN_JSON_PASTE50, \
2623  NLOHMANN_JSON_PASTE49, \
2624  NLOHMANN_JSON_PASTE48, \
2625  NLOHMANN_JSON_PASTE47, \
2626  NLOHMANN_JSON_PASTE46, \
2627  NLOHMANN_JSON_PASTE45, \
2628  NLOHMANN_JSON_PASTE44, \
2629  NLOHMANN_JSON_PASTE43, \
2630  NLOHMANN_JSON_PASTE42, \
2631  NLOHMANN_JSON_PASTE41, \
2632  NLOHMANN_JSON_PASTE40, \
2633  NLOHMANN_JSON_PASTE39, \
2634  NLOHMANN_JSON_PASTE38, \
2635  NLOHMANN_JSON_PASTE37, \
2636  NLOHMANN_JSON_PASTE36, \
2637  NLOHMANN_JSON_PASTE35, \
2638  NLOHMANN_JSON_PASTE34, \
2639  NLOHMANN_JSON_PASTE33, \
2640  NLOHMANN_JSON_PASTE32, \
2641  NLOHMANN_JSON_PASTE31, \
2642  NLOHMANN_JSON_PASTE30, \
2643  NLOHMANN_JSON_PASTE29, \
2644  NLOHMANN_JSON_PASTE28, \
2645  NLOHMANN_JSON_PASTE27, \
2646  NLOHMANN_JSON_PASTE26, \
2647  NLOHMANN_JSON_PASTE25, \
2648  NLOHMANN_JSON_PASTE24, \
2649  NLOHMANN_JSON_PASTE23, \
2650  NLOHMANN_JSON_PASTE22, \
2651  NLOHMANN_JSON_PASTE21, \
2652  NLOHMANN_JSON_PASTE20, \
2653  NLOHMANN_JSON_PASTE19, \
2654  NLOHMANN_JSON_PASTE18, \
2655  NLOHMANN_JSON_PASTE17, \
2656  NLOHMANN_JSON_PASTE16, \
2657  NLOHMANN_JSON_PASTE15, \
2658  NLOHMANN_JSON_PASTE14, \
2659  NLOHMANN_JSON_PASTE13, \
2660  NLOHMANN_JSON_PASTE12, \
2661  NLOHMANN_JSON_PASTE11, \
2662  NLOHMANN_JSON_PASTE10, \
2663  NLOHMANN_JSON_PASTE9, \
2664  NLOHMANN_JSON_PASTE8, \
2665  NLOHMANN_JSON_PASTE7, \
2666  NLOHMANN_JSON_PASTE6, \
2667  NLOHMANN_JSON_PASTE5, \
2668  NLOHMANN_JSON_PASTE4, \
2669  NLOHMANN_JSON_PASTE3, \
2670  NLOHMANN_JSON_PASTE2, \
2671  NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2672 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2673 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2674 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2675 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2676 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2677 #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)
2678 #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)
2679 #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)
2680 #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)
2681 #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)
2682 #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)
2683 #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)
2684 #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)
2685 #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)
2686 #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)
2687 #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)
2688 #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)
2689 #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)
2690 #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)
2691 #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)
2692 #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)
2693 #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)
2694 #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)
2695 #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)
2696 #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)
2697 #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)
2698 #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)
2699 #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)
2700 #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)
2701 #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)
2702 #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)
2703 #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)
2704 #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)
2705 #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)
2706 #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)
2707 #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)
2708 #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)
2709 #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)
2710 #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)
2711 #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)
2712 #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)
2713 #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)
2714 #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)
2715 #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)
2716 #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)
2717 #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)
2718 #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)
2719 #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)
2720 #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)
2721 #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)
2722 #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)
2723 #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)
2724 #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)
2725 #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)
2726 #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)
2727 #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)
2728 #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)
2729 #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)
2730 #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)
2731 #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)
2732 #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)
2733 #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)
2734 #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)
2735 
2736 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2737 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2738 #define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2739 
2745 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2746  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__)) } \
2747  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__)) }
2748 
2749 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2750  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__)) } \
2751  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__)) }
2752 
2758 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2759  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__)) } \
2760  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__)) }
2761 
2762 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2763  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__)) } \
2764  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__)) }
2765 
2766 
2767 // inspired from https://stackoverflow.com/a/26745591
2768 // allows to call any std function as if (e.g. with begin):
2769 // using std::begin; begin(x);
2770 //
2771 // it allows using the detected idiom to retrieve the return type
2772 // of such an expression
2773 #define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2774  namespace detail { \
2775  using std::std_name; \
2776  \
2777  template<typename... T> \
2778  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2779  } \
2780  \
2781  namespace detail2 { \
2782  struct std_name##_tag \
2783  { \
2784  }; \
2785  \
2786  template<typename... T> \
2787  std_name##_tag std_name(T&&...); \
2788  \
2789  template<typename... T> \
2790  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2791  \
2792  template<typename... T> \
2793  struct would_call_std_##std_name \
2794  { \
2795  static constexpr auto const value = ::nlohmann::detail:: \
2796  is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2797  }; \
2798  } /* namespace detail2 */ \
2799  \
2800  template<typename... T> \
2801  struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2802  { \
2803  }
2804 
2805 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2806  #define JSON_USE_IMPLICIT_CONVERSIONS 1
2807 #endif
2808 
2809 #if JSON_USE_IMPLICIT_CONVERSIONS
2810  #define JSON_EXPLICIT
2811 #else
2812  #define JSON_EXPLICIT explicit
2813 #endif
2814 
2815 #ifndef JSON_DISABLE_ENUM_SERIALIZATION
2816  #define JSON_DISABLE_ENUM_SERIALIZATION 0
2817 #endif
2818 
2819 #ifndef JSON_USE_GLOBAL_UDLS
2820  #define JSON_USE_GLOBAL_UDLS 1
2821 #endif
2822 
2823 #if JSON_HAS_THREE_WAY_COMPARISON
2824  #include <compare> // partial_ordering
2825 #endif
2826 
2828 namespace detail
2829 {
2830 
2832 // JSON type enumeration //
2834 
2859 enum class value_t : std::uint8_t
2860 {
2861  null,
2862  object,
2863  array,
2864  string,
2865  boolean,
2866  number_integer,
2867  number_unsigned,
2868  number_float,
2869  binary,
2870  discarded
2871 };
2872 
2886 #if JSON_HAS_THREE_WAY_COMPARISON
2887  inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
2888 #else
2889  inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2890 #endif
2891 {
2892  static constexpr std::array<std::uint8_t, 9> order = {{
2893  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2894  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
2895  6 /* binary */
2896  }
2897  };
2898 
2899  const auto l_index = static_cast<std::size_t>(lhs);
2900  const auto r_index = static_cast<std::size_t>(rhs);
2901 #if JSON_HAS_THREE_WAY_COMPARISON
2902  if (l_index < order.size() && r_index < order.size())
2903  {
2904  return order[l_index] <=> order[r_index]; // *NOPAD*
2905  }
2906  return std::partial_ordering::unordered;
2907 #else
2908  return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
2909 #endif
2910 }
2911 
2912 // GCC selects the built-in operator< over an operator rewritten from
2913 // a user-defined spaceship operator
2914 // Clang, MSVC, and ICC select the rewritten candidate
2915 // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
2916 #if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
2917 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2918 {
2919  return std::is_lt(lhs <=> rhs); // *NOPAD*
2920 }
2921 #endif
2922 
2923 } // namespace detail
2925 
2926 // #include <nlohmann/detail/string_escape.hpp>
2927 // __ _____ _____ _____
2928 // __| | __| | | | JSON for Modern C++
2929 // | | |__ | | | | | | version 3.11.2
2930 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
2931 //
2932 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
2933 // SPDX-License-Identifier: MIT
2934 
2935 
2936 
2937 // #include <nlohmann/detail/abi_macros.hpp>
2938 
2939 
2941 namespace detail
2942 {
2943 
2957 template<typename StringType>
2958 inline void replace_substring(StringType& s, const StringType& f,
2959  const StringType& t)
2960 {
2961  JSON_ASSERT(!f.empty());
2962  for (auto pos = s.find(f); // find first occurrence of f
2963  pos != StringType::npos; // make sure f was found
2964  s.replace(pos, f.size(), t), // replace with t, and
2965  pos = s.find(f, pos + t.size())) // find next occurrence of f
2966  {}
2967 }
2968 
2976 template<typename StringType>
2977 inline StringType escape(StringType s)
2978 {
2979  replace_substring(s, StringType{"~"}, StringType{"~0"});
2980  replace_substring(s, StringType{"/"}, StringType{"~1"});
2981  return s;
2982 }
2983 
2991 template<typename StringType>
2992 static void unescape(StringType& s)
2993 {
2994  replace_substring(s, StringType{"~1"}, StringType{"/"});
2995  replace_substring(s, StringType{"~0"}, StringType{"~"});
2996 }
2997 
2998 } // namespace detail
3000 
3001 // #include <nlohmann/detail/input/position_t.hpp>
3002 // __ _____ _____ _____
3003 // __| | __| | | | JSON for Modern C++
3004 // | | |__ | | | | | | version 3.11.2
3005 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3006 //
3007 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3008 // SPDX-License-Identifier: MIT
3009 
3010 
3011 
3012 #include <cstddef> // size_t
3013 
3014 // #include <nlohmann/detail/abi_macros.hpp>
3015 
3016 
3018 namespace detail
3019 {
3020 
3023 {
3025  std::size_t chars_read_total = 0;
3027  std::size_t chars_read_current_line = 0;
3029  std::size_t lines_read = 0;
3030 
3032  constexpr operator size_t() const
3033  {
3034  return chars_read_total;
3035  }
3036 };
3037 
3038 } // namespace detail
3040 
3041 // #include <nlohmann/detail/macro_scope.hpp>
3042 
3043 // #include <nlohmann/detail/meta/cpp_future.hpp>
3044 // __ _____ _____ _____
3045 // __| | __| | | | JSON for Modern C++
3046 // | | |__ | | | | | | version 3.11.2
3047 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3048 //
3049 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3050 // SPDX-FileCopyrightText: 2018 The Abseil Authors
3051 // SPDX-License-Identifier: MIT
3052 
3053 
3054 
3055 #include <array> // array
3056 #include <cstddef> // size_t
3057 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3058 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3059 
3060 // #include <nlohmann/detail/macro_scope.hpp>
3061 
3062 
3064 namespace detail
3065 {
3066 
3067 template<typename T>
3069 
3070 #ifdef JSON_HAS_CPP_14
3071 
3072 // the following utilities are natively available in C++14
3073 using std::enable_if_t;
3074 using std::index_sequence;
3077 
3078 #else
3079 
3080 // alias templates to reduce boilerplate
3081 template<bool B, typename T = void>
3083 
3084 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3085 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3086 
3088 
3089 // integer_sequence
3090 //
3091 // Class template representing a compile-time integer sequence. An instantiation
3092 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3093 // type through its template arguments (which is a common need when
3094 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3095 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3096 //
3097 // Example:
3098 //
3099 // template< class T, T... Ints >
3100 // void user_function(integer_sequence<T, Ints...>);
3101 //
3102 // int main()
3103 // {
3104 // // user_function's `T` will be deduced to `int` and `Ints...`
3105 // // will be deduced to `0, 1, 2, 3, 4`.
3106 // user_function(make_integer_sequence<int, 5>());
3107 // }
3108 template <typename T, T... Ints>
3110 {
3111  using value_type = T;
3112  static constexpr std::size_t size() noexcept
3113  {
3114  return sizeof...(Ints);
3115  }
3116 };
3117 
3118 // index_sequence
3119 //
3120 // A helper template for an `integer_sequence` of `size_t`,
3121 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3122 // `std::index_sequence`.
3123 template <size_t... Ints>
3124 using index_sequence = integer_sequence<size_t, Ints...>;
3125 
3126 namespace utility_internal
3127 {
3128 
3129 template <typename Seq, size_t SeqSize, size_t Rem>
3130 struct Extend;
3131 
3132 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3133 template <typename T, T... Ints, size_t SeqSize>
3134 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3135 {
3136  using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3137 };
3138 
3139 template <typename T, T... Ints, size_t SeqSize>
3140 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3141 {
3142  using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3143 };
3144 
3145 // Recursion helper for 'make_integer_sequence<T, N>'.
3146 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3147 template <typename T, size_t N>
3148 struct Gen
3149 {
3150  using type =
3151  typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3152 };
3153 
3154 template <typename T>
3155 struct Gen<T, 0>
3156 {
3158 };
3159 
3160 } // namespace utility_internal
3161 
3162 // Compile-time sequences of integers
3163 
3164 // make_integer_sequence
3165 //
3166 // This template alias is equivalent to
3167 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3168 // replacement for C++14's `std::make_integer_sequence`.
3169 template <typename T, T N>
3171 
3172 // make_index_sequence
3173 //
3174 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3175 // and is designed to be a drop-in replacement for C++14's
3176 // `std::make_index_sequence`.
3177 template <size_t N>
3179 
3180 // index_sequence_for
3181 //
3182 // Converts a typename pack into an index sequence of the same length, and
3183 // is designed to be a drop-in replacement for C++14's
3184 // `std::index_sequence_for()`
3185 template <typename... Ts>
3187 
3189 
3190 #endif
3191 
3192 // dispatch utility (taken from ranges-v3)
3193 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3194 template<> struct priority_tag<0> {};
3195 
3196 // taken from ranges-v3
3197 template<typename T>
3199 {
3200  static JSON_INLINE_VARIABLE constexpr T value{};
3201 };
3202 
3203 #ifndef JSON_HAS_CPP_17
3204  template<typename T>
3205  constexpr T static_const<T>::value;
3206 #endif
3207 
3208 template<typename T, typename... Args>
3209 inline constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args)
3210 {
3211  return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}};
3212 }
3213 
3214 } // namespace detail
3216 
3217 // #include <nlohmann/detail/meta/type_traits.hpp>
3218 // __ _____ _____ _____
3219 // __| | __| | | | JSON for Modern C++
3220 // | | |__ | | | | | | version 3.11.2
3221 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3222 //
3223 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3224 // SPDX-License-Identifier: MIT
3225 
3226 
3227 
3228 #include <limits> // numeric_limits
3229 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3230 #include <utility> // declval
3231 #include <tuple> // tuple
3232 
3233 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3234 // __ _____ _____ _____
3235 // __| | __| | | | JSON for Modern C++
3236 // | | |__ | | | | | | version 3.11.2
3237 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3238 //
3239 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3240 // SPDX-License-Identifier: MIT
3241 
3242 
3243 
3244 #include <iterator> // random_access_iterator_tag
3245 
3246 // #include <nlohmann/detail/abi_macros.hpp>
3247 
3248 // #include <nlohmann/detail/meta/void_t.hpp>
3249 
3250 // #include <nlohmann/detail/meta/cpp_future.hpp>
3251 
3252 
3254 namespace detail
3255 {
3256 
3257 template<typename It, typename = void>
3258 struct iterator_types {};
3259 
3260 template<typename It>
3262  It,
3263  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3264  typename It::reference, typename It::iterator_category >>
3265 {
3266  using difference_type = typename It::difference_type;
3267  using value_type = typename It::value_type;
3268  using pointer = typename It::pointer;
3269  using reference = typename It::reference;
3270  using iterator_category = typename It::iterator_category;
3271 };
3272 
3273 // This is required as some compilers implement std::iterator_traits in a way that
3274 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3275 template<typename T, typename = void>
3277 {
3278 };
3279 
3280 template<typename T>
3281 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3282  : iterator_types<T>
3283 {
3284 };
3285 
3286 template<typename T>
3288 {
3289  using iterator_category = std::random_access_iterator_tag;
3290  using value_type = T;
3291  using difference_type = ptrdiff_t;
3292  using pointer = T*;
3293  using reference = T&;
3294 };
3295 
3296 } // namespace detail
3298 
3299 // #include <nlohmann/detail/macro_scope.hpp>
3300 
3301 // #include <nlohmann/detail/meta/call_std/begin.hpp>
3302 // __ _____ _____ _____
3303 // __| | __| | | | JSON for Modern C++
3304 // | | |__ | | | | | | version 3.11.2
3305 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3306 //
3307 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3308 // SPDX-License-Identifier: MIT
3309 
3310 
3311 
3312 // #include <nlohmann/detail/macro_scope.hpp>
3313 
3314 
3316 
3318 
3320 
3321 // #include <nlohmann/detail/meta/call_std/end.hpp>
3322 // __ _____ _____ _____
3323 // __| | __| | | | JSON for Modern C++
3324 // | | |__ | | | | | | version 3.11.2
3325 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3326 //
3327 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3328 // SPDX-License-Identifier: MIT
3329 
3330 
3331 
3332 // #include <nlohmann/detail/macro_scope.hpp>
3333 
3334 
3336 
3338 
3340 
3341 // #include <nlohmann/detail/meta/cpp_future.hpp>
3342 
3343 // #include <nlohmann/detail/meta/detected.hpp>
3344 
3345 // #include <nlohmann/json_fwd.hpp>
3346 // __ _____ _____ _____
3347 // __| | __| | | | JSON for Modern C++
3348 // | | |__ | | | | | | version 3.11.2
3349 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3350 //
3351 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3352 // SPDX-License-Identifier: MIT
3353 
3354 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3355  #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3356 
3357  #include <cstdint> // int64_t, uint64_t
3358  #include <map> // map
3359  #include <memory> // allocator
3360  #include <string> // string
3361  #include <vector> // vector
3362 
3363  // #include <nlohmann/detail/abi_macros.hpp>
3364 
3365 
3372 
3380  template<typename T = void, typename SFINAE = void>
3382 
3385  template<template<typename U, typename V, typename... Args> class ObjectType =
3386  std::map,
3387  template<typename U, typename... Args> class ArrayType = std::vector,
3388  class StringType = std::string, class BooleanType = bool,
3389  class NumberIntegerType = std::int64_t,
3390  class NumberUnsignedType = std::uint64_t,
3391  class NumberFloatType = double,
3392  template<typename U> class AllocatorType = std::allocator,
3393  template<typename T, typename SFINAE = void> class JSONSerializer =
3395  class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
3396  class CustomBaseClass = void>
3397  class basic_json;
3398 
3401  template<typename RefStringType>
3403 
3409 
3412  template<class Key, class T, class IgnoredLess, class Allocator>
3413  struct ordered_map;
3414 
3418 
3420 
3421 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3422 
3423 
3433 namespace detail
3434 {
3435 
3437 // helpers //
3439 
3440 // Note to maintainers:
3441 //
3442 // Every trait in this file expects a non CV-qualified type.
3443 // The only exceptions are in the 'aliases for detected' section
3444 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3445 //
3446 // In this case, T has to be properly CV-qualified to constraint the function arguments
3447 // (e.g. to_json(BasicJsonType&, const T&))
3448 
3449 template<typename> struct is_basic_json : std::false_type {};
3450 
3452 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3453 
3454 // used by exceptions create() member functions
3455 // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3456 // false_type otherwise
3457 template<typename BasicJsonContext>
3459  std::integral_constant < bool,
3460  is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3461  || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3462 {};
3463 
3465 // json_ref helpers //
3467 
3468 template<typename>
3469 class json_ref;
3470 
3471 template<typename>
3472 struct is_json_ref : std::false_type {};
3473 
3474 template<typename T>
3475 struct is_json_ref<json_ref<T>> : std::true_type {};
3476 
3478 // aliases for detected //
3480 
3481 template<typename T>
3482 using mapped_type_t = typename T::mapped_type;
3483 
3484 template<typename T>
3485 using key_type_t = typename T::key_type;
3486 
3487 template<typename T>
3488 using value_type_t = typename T::value_type;
3489 
3490 template<typename T>
3491 using difference_type_t = typename T::difference_type;
3492 
3493 template<typename T>
3494 using pointer_t = typename T::pointer;
3495 
3496 template<typename T>
3497 using reference_t = typename T::reference;
3498 
3499 template<typename T>
3500 using iterator_category_t = typename T::iterator_category;
3501 
3502 template<typename T, typename... Args>
3503 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3504 
3505 template<typename T, typename... Args>
3506 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3507 
3508 template<typename T, typename U>
3509 using get_template_function = decltype(std::declval<T>().template get<U>());
3510 
3511 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3512 template<typename BasicJsonType, typename T, typename = void>
3513 struct has_from_json : std::false_type {};
3514 
3515 // trait checking if j.get<T> is valid
3516 // use this trait instead of std::is_constructible or std::is_convertible,
3517 // both rely on, or make use of implicit conversions, and thus fail when T
3518 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3519 template <typename BasicJsonType, typename T>
3521 {
3523 };
3524 
3525 template<typename BasicJsonType, typename T>
3526 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3527 {
3528  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3529 
3530  static constexpr bool value =
3532  const BasicJsonType&, T&>::value;
3533 };
3534 
3535 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3536 // this overload is used for non-default-constructible user-defined-types
3537 template<typename BasicJsonType, typename T, typename = void>
3538 struct has_non_default_from_json : std::false_type {};
3539 
3540 template<typename BasicJsonType, typename T>
3541 struct has_non_default_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&>::value;
3548 };
3549 
3550 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3551 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3552 template<typename BasicJsonType, typename T, typename = void>
3553 struct has_to_json : std::false_type {};
3554 
3555 template<typename BasicJsonType, typename T>
3556 struct has_to_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  T>::value;
3563 };
3564 
3565 template<typename T>
3566 using detect_key_compare = typename T::key_compare;
3567 
3568 template<typename T>
3569 struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3570 
3571 // obtains the actual object key comparator
3572 template<typename BasicJsonType>
3574 {
3575  using object_t = typename BasicJsonType::object_t;
3576  using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3577  using type = typename std::conditional < has_key_compare<object_t>::value,
3578  typename object_t::key_compare, object_comparator_t>::type;
3579 };
3580 
3581 template<typename BasicJsonType>
3583 
3585 // is_ functions //
3587 
3588 // https://en.cppreference.com/w/cpp/types/conjunction
3589 template<class...> struct conjunction : std::true_type { };
3590 template<class B> struct conjunction<B> : B { };
3591 template<class B, class... Bn>
3592 struct conjunction<B, Bn...>
3593 : std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
3594 
3595 // https://en.cppreference.com/w/cpp/types/negation
3596 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3597 
3598 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3599 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3600 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3601 template <typename T>
3602 struct is_default_constructible : std::is_default_constructible<T> {};
3603 
3604 template <typename T1, typename T2>
3605 struct is_default_constructible<std::pair<T1, T2>>
3606  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3607 
3608 template <typename T1, typename T2>
3609 struct is_default_constructible<const std::pair<T1, T2>>
3610  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3611 
3612 template <typename... Ts>
3613 struct is_default_constructible<std::tuple<Ts...>>
3614  : conjunction<is_default_constructible<Ts>...> {};
3615 
3616 template <typename... Ts>
3617 struct is_default_constructible<const std::tuple<Ts...>>
3618  : conjunction<is_default_constructible<Ts>...> {};
3619 
3620 
3621 template <typename T, typename... Args>
3622 struct is_constructible : std::is_constructible<T, Args...> {};
3623 
3624 template <typename T1, typename T2>
3625 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3626 
3627 template <typename T1, typename T2>
3628 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3629 
3630 template <typename... Ts>
3631 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3632 
3633 template <typename... Ts>
3634 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3635 
3636 
3637 template<typename T, typename = void>
3638 struct is_iterator_traits : std::false_type {};
3639 
3640 template<typename T>
3642 {
3643  private:
3645 
3646  public:
3647  static constexpr auto value =
3653 };
3654 
3655 template<typename T>
3656 struct is_range
3657 {
3658  private:
3660 
3663 
3664  // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3665  // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3666  // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3667  static constexpr auto is_iterator_begin =
3669 
3670  public:
3671  static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3672 };
3673 
3674 template<typename R>
3675 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3676 
3677 template<typename T>
3679 
3680 // The following implementation of is_complete_type is taken from
3681 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3682 // and is written by Xiang Fan who agreed to using it in this library.
3683 
3684 template<typename T, typename = void>
3685 struct is_complete_type : std::false_type {};
3686 
3687 template<typename T>
3688 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3689 
3690 template<typename BasicJsonType, typename CompatibleObjectType,
3691  typename = void>
3692 struct is_compatible_object_type_impl : std::false_type {};
3693 
3694 template<typename BasicJsonType, typename CompatibleObjectType>
3696  BasicJsonType, CompatibleObjectType,
3697  enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3698  is_detected<key_type_t, CompatibleObjectType>::value >>
3699 {
3700  using object_t = typename BasicJsonType::object_t;
3701 
3702  // macOS's is_constructible does not play well with nonesuch...
3703  static constexpr bool value =
3704  is_constructible<typename object_t::key_type,
3705  typename CompatibleObjectType::key_type>::value &&
3706  is_constructible<typename object_t::mapped_type,
3707  typename CompatibleObjectType::mapped_type>::value;
3708 };
3709 
3710 template<typename BasicJsonType, typename CompatibleObjectType>
3712  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3713 
3714 template<typename BasicJsonType, typename ConstructibleObjectType,
3715  typename = void>
3716 struct is_constructible_object_type_impl : std::false_type {};
3717 
3718 template<typename BasicJsonType, typename ConstructibleObjectType>
3720  BasicJsonType, ConstructibleObjectType,
3721  enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3722  is_detected<key_type_t, ConstructibleObjectType>::value >>
3723 {
3724  using object_t = typename BasicJsonType::object_t;
3725 
3726  static constexpr bool value =
3728  (std::is_move_assignable<ConstructibleObjectType>::value ||
3729  std::is_copy_assignable<ConstructibleObjectType>::value) &&
3730  (is_constructible<typename ConstructibleObjectType::key_type,
3731  typename object_t::key_type>::value &&
3732  std::is_same <
3733  typename object_t::mapped_type,
3734  typename ConstructibleObjectType::mapped_type >::value)) ||
3735  (has_from_json<BasicJsonType,
3736  typename ConstructibleObjectType::mapped_type>::value ||
3738  BasicJsonType,
3739  typename ConstructibleObjectType::mapped_type >::value);
3740 };
3741 
3742 template<typename BasicJsonType, typename ConstructibleObjectType>
3744  : is_constructible_object_type_impl<BasicJsonType,
3745  ConstructibleObjectType> {};
3746 
3747 template<typename BasicJsonType, typename CompatibleStringType>
3749 {
3750  static constexpr auto value =
3752 };
3753 
3754 template<typename BasicJsonType, typename ConstructibleStringType>
3756 {
3757  // launder type through decltype() to fix compilation failure on ICPC
3758 #ifdef __INTEL_COMPILER
3759  using laundered_type = decltype(std::declval<ConstructibleStringType>());
3760 #else
3761  using laundered_type = ConstructibleStringType;
3762 #endif
3763 
3764  static constexpr auto value =
3765  conjunction <
3767  is_detected_exact<typename BasicJsonType::string_t::value_type,
3769 };
3770 
3771 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3772 struct is_compatible_array_type_impl : std::false_type {};
3773 
3774 template<typename BasicJsonType, typename CompatibleArrayType>
3776  BasicJsonType, CompatibleArrayType,
3777  enable_if_t <
3778  is_detected<iterator_t, CompatibleArrayType>::value&&
3779  is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3780 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3781 // c.f. https://github.com/nlohmann/json/pull/3073
3782  !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3783 {
3784  static constexpr bool value =
3785  is_constructible<BasicJsonType,
3787 };
3788 
3789 template<typename BasicJsonType, typename CompatibleArrayType>
3791  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3792 
3793 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3794 struct is_constructible_array_type_impl : std::false_type {};
3795 
3796 template<typename BasicJsonType, typename ConstructibleArrayType>
3798  BasicJsonType, ConstructibleArrayType,
3799  enable_if_t<std::is_same<ConstructibleArrayType,
3800  typename BasicJsonType::value_type>::value >>
3801  : std::true_type {};
3802 
3803 template<typename BasicJsonType, typename ConstructibleArrayType>
3805  BasicJsonType, ConstructibleArrayType,
3806  enable_if_t < !std::is_same<ConstructibleArrayType,
3807  typename BasicJsonType::value_type>::value&&
3808  !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3809  is_default_constructible<ConstructibleArrayType>::value&&
3810 (std::is_move_assignable<ConstructibleArrayType>::value ||
3811  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3812 is_detected<iterator_t, ConstructibleArrayType>::value&&
3813 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3814 is_detected<range_value_t, ConstructibleArrayType>::value&&
3815 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3816 // c.f. https://github.com/nlohmann/json/pull/3073
3817 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3819  detected_t<range_value_t, ConstructibleArrayType >>::value >>
3820 {
3822 
3823  static constexpr bool value =
3824  std::is_same<value_type,
3825  typename BasicJsonType::array_t::value_type>::value ||
3826  has_from_json<BasicJsonType,
3827  value_type>::value ||
3829  BasicJsonType,
3831 };
3832 
3833 template<typename BasicJsonType, typename ConstructibleArrayType>
3835  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3836 
3837 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3838  typename = void>
3839 struct is_compatible_integer_type_impl : std::false_type {};
3840 
3841 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3843  RealIntegerType, CompatibleNumberIntegerType,
3844  enable_if_t < std::is_integral<RealIntegerType>::value&&
3845  std::is_integral<CompatibleNumberIntegerType>::value&&
3846  !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3847 {
3848  // is there an assert somewhere on overflows?
3849  using RealLimits = std::numeric_limits<RealIntegerType>;
3850  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3851 
3852  static constexpr auto value =
3853  is_constructible<RealIntegerType,
3854  CompatibleNumberIntegerType>::value &&
3855  CompatibleLimits::is_integer &&
3856  RealLimits::is_signed == CompatibleLimits::is_signed;
3857 };
3858 
3859 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3861  : is_compatible_integer_type_impl<RealIntegerType,
3862  CompatibleNumberIntegerType> {};
3863 
3864 template<typename BasicJsonType, typename CompatibleType, typename = void>
3865 struct is_compatible_type_impl: std::false_type {};
3866 
3867 template<typename BasicJsonType, typename CompatibleType>
3869  BasicJsonType, CompatibleType,
3870  enable_if_t<is_complete_type<CompatibleType>::value >>
3871 {
3872  static constexpr bool value =
3874 };
3875 
3876 template<typename BasicJsonType, typename CompatibleType>
3878  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3879 
3880 template<typename T1, typename T2>
3881 struct is_constructible_tuple : std::false_type {};
3882 
3883 template<typename T1, typename... Args>
3884 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3885 
3886 template<typename BasicJsonType, typename T>
3887 struct is_json_iterator_of : std::false_type {};
3888 
3889 template<typename BasicJsonType>
3890 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3891 
3892 template<typename BasicJsonType>
3893 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3894 {};
3895 
3896 // checks if a given type T is a template specialization of Primary
3897 template<template <typename...> class Primary, typename T>
3898 struct is_specialization_of : std::false_type {};
3899 
3900 template<template <typename...> class Primary, typename... Args>
3901 struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3902 
3903 template<typename T>
3905 
3906 // checks if A and B are comparable using Compare functor
3907 template<typename Compare, typename A, typename B, typename = void>
3908 struct is_comparable : std::false_type {};
3909 
3910 template<typename Compare, typename A, typename B>
3911 struct is_comparable<Compare, A, B, void_t<
3912 decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3913 decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3914 >> : std::true_type {};
3915 
3916 template<typename T>
3918 
3919 // type trait to check if KeyType can be used as object key (without a BasicJsonType)
3920 // see is_usable_as_basic_json_key_type below
3921 template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3922  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3923 using is_usable_as_key_type = typename std::conditional <
3925  && !(ExcludeObjectKeyType && std::is_same<KeyType,
3926  ObjectKeyType>::value)
3927  && (!RequireTransparentComparator
3930  std::true_type,
3931  std::false_type >::type;
3932 
3933 // type trait to check if KeyType can be used as object key
3934 // true if:
3935 // - KeyType is comparable with BasicJsonType::object_t::key_type
3936 // - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
3937 // - the comparator is transparent or RequireTransparentComparator is false
3938 // - KeyType is not a JSON iterator or json_pointer
3939 template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3940  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3941 using is_usable_as_basic_json_key_type = typename std::conditional <
3942  is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
3943  typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
3944  RequireTransparentComparator, ExcludeObjectKeyType>::value
3946  std::true_type,
3947  std::false_type >::type;
3948 
3949 template<typename ObjectType, typename KeyType>
3950 using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
3951 
3952 // type trait to check if object_t has an erase() member functions accepting KeyType
3953 template<typename BasicJsonType, typename KeyType>
3954 using has_erase_with_key_type = typename std::conditional <
3955  is_detected <
3957  typename BasicJsonType::object_t, KeyType >::value,
3958  std::true_type,
3959  std::false_type >::type;
3960 
3961 // a naive helper to check if a type is an ordered_map (exploits the fact that
3962 // ordered_map inherits capacity() from std::vector)
3963 template <typename T>
3965 {
3966  using one = char;
3967 
3968  struct two
3969  {
3970  char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3971  };
3972 
3973  template <typename C> static one test( decltype(&C::capacity) ) ;
3974  template <typename C> static two test(...);
3975 
3976  enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3977 };
3978 
3979 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3980 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3982 {
3983  return static_cast<T>(value);
3984 }
3985 
3986 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3987 T conditional_static_cast(U value)
3988 {
3989  return value;
3990 }
3991 
3992 template<typename... Types>
3994 
3995 template<typename... Types>
3997 
3998 template<typename... Types>
4000 
4001 // there's a disjunction trait in another PR; replace when merged
4002 template<typename... Types>
4003 using same_sign = std::integral_constant < bool,
4004  all_signed<Types...>::value || all_unsigned<Types...>::value >;
4005 
4006 template<typename OfType, typename T>
4007 using never_out_of_range = std::integral_constant < bool,
4008  (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
4009  || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
4010 
4011 template<typename OfType, typename T,
4012  bool OfTypeSigned = std::is_signed<OfType>::value,
4013  bool TSigned = std::is_signed<T>::value>
4015 
4016 template<typename OfType, typename T>
4017 struct value_in_range_of_impl2<OfType, T, false, false>
4018 {
4019  static constexpr bool test(T val)
4020  {
4021  using CommonType = typename std::common_type<OfType, T>::type;
4022  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4023  }
4024 };
4025 
4026 template<typename OfType, typename T>
4027 struct value_in_range_of_impl2<OfType, T, true, false>
4028 {
4029  static constexpr bool test(T val)
4030  {
4031  using CommonType = typename std::common_type<OfType, T>::type;
4032  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4033  }
4034 };
4035 
4036 template<typename OfType, typename T>
4037 struct value_in_range_of_impl2<OfType, T, false, true>
4038 {
4039  static constexpr bool test(T val)
4040  {
4041  using CommonType = typename std::common_type<OfType, T>::type;
4042  return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4043  }
4044 };
4045 
4046 
4047 template<typename OfType, typename T>
4048 struct value_in_range_of_impl2<OfType, T, true, true>
4049 {
4050  static constexpr bool test(T val)
4051  {
4052  using CommonType = typename std::common_type<OfType, T>::type;
4053  return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
4054  && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4055  }
4056 };
4057 
4058 template<typename OfType, typename T,
4059  bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
4062 
4063 template<typename OfType, typename T>
4064 struct value_in_range_of_impl1<OfType, T, false>
4065 {
4066  static constexpr bool test(T val)
4067  {
4069  }
4070 };
4071 
4072 template<typename OfType, typename T>
4073 struct value_in_range_of_impl1<OfType, T, true>
4074 {
4075  static constexpr bool test(T /*val*/)
4076  {
4077  return true;
4078  }
4079 };
4080 
4081 template<typename OfType, typename T>
4082 inline constexpr bool value_in_range_of(T val)
4083 {
4085 }
4086 
4087 template<bool Value>
4088 using bool_constant = std::integral_constant<bool, Value>;
4089 
4091 // is_c_string
4093 
4094 namespace impl
4095 {
4096 
4097 template<typename T>
4098 inline constexpr bool is_c_string()
4099 {
4100  using TUnExt = typename std::remove_extent<T>::type;
4101  using TUnCVExt = typename std::remove_cv<TUnExt>::type;
4102  using TUnPtr = typename std::remove_pointer<T>::type;
4103  using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
4104  return
4105  (std::is_array<T>::value && std::is_same<TUnCVExt, char>::value)
4106  || (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
4107 }
4108 
4109 } // namespace impl
4110 
4111 // checks whether T is a [cv] char */[cv] char[] C string
4112 template<typename T>
4113 struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
4114 
4115 template<typename T>
4117 
4119 // is_transparent
4121 
4122 namespace impl
4123 {
4124 
4125 template<typename T>
4126 inline constexpr bool is_transparent()
4127 {
4129 }
4130 
4131 } // namespace impl
4132 
4133 // checks whether T has a member named is_transparent
4134 template<typename T>
4135 struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
4136 
4138 
4139 } // namespace detail
4141 
4142 // #include <nlohmann/detail/string_concat.hpp>
4143 // __ _____ _____ _____
4144 // __| | __| | | | JSON for Modern C++
4145 // | | |__ | | | | | | version 3.11.2
4146 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4147 //
4148 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4149 // SPDX-License-Identifier: MIT
4150 
4151 
4152 
4153 #include <cstring> // strlen
4154 #include <string> // string
4155 #include <utility> // forward
4156 
4157 // #include <nlohmann/detail/meta/cpp_future.hpp>
4158 
4159 // #include <nlohmann/detail/meta/detected.hpp>
4160 
4161 
4163 namespace detail
4164 {
4165 
4166 inline std::size_t concat_length()
4167 {
4168  return 0;
4169 }
4170 
4171 template<typename... Args>
4172 inline std::size_t concat_length(const char* cstr, const Args& ... rest);
4173 
4174 template<typename StringType, typename... Args>
4175 inline std::size_t concat_length(const StringType& str, const Args& ... rest);
4176 
4177 template<typename... Args>
4178 inline std::size_t concat_length(const char /*c*/, const Args& ... rest)
4179 {
4180  return 1 + concat_length(rest...);
4181 }
4182 
4183 template<typename... Args>
4184 inline std::size_t concat_length(const char* cstr, const Args& ... rest)
4185 {
4186  // cppcheck-suppress ignoredReturnValue
4187  return ::strlen(cstr) + concat_length(rest...);
4188 }
4189 
4190 template<typename StringType, typename... Args>
4191 inline std::size_t concat_length(const StringType& str, const Args& ... rest)
4192 {
4193  return str.size() + concat_length(rest...);
4194 }
4195 
4196 template<typename OutStringType>
4197 inline void concat_into(OutStringType& /*out*/)
4198 {}
4199 
4200 template<typename StringType, typename Arg>
4201 using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
4202 
4203 template<typename StringType, typename Arg>
4205 
4206 template<typename StringType, typename Arg>
4207 using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
4208 
4209 template<typename StringType, typename Arg>
4211 
4212 template<typename StringType, typename Arg>
4213 using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
4214 
4215 template<typename StringType, typename Arg>
4217 
4218 template<typename StringType, typename Arg>
4219 using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
4220 
4221 template<typename StringType, typename Arg>
4223 
4224 template < typename OutStringType, typename Arg, typename... Args,
4227 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
4228 
4229 template < typename OutStringType, typename Arg, typename... Args,
4233 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4234 
4235 template < typename OutStringType, typename Arg, typename... Args,
4240 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4241 
4242 template<typename OutStringType, typename Arg, typename... Args,
4244 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
4245 {
4246  out.append(std::forward<Arg>(arg));
4247  concat_into(out, std::forward<Args>(rest)...);
4248 }
4249 
4250 template < typename OutStringType, typename Arg, typename... Args,
4253 inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
4254 {
4255  out += std::forward<Arg>(arg);
4256  concat_into(out, std::forward<Args>(rest)...);
4257 }
4258 
4259 template < typename OutStringType, typename Arg, typename... Args,
4263 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4264 {
4265  out.append(arg.begin(), arg.end());
4266  concat_into(out, std::forward<Args>(rest)...);
4267 }
4268 
4269 template < typename OutStringType, typename Arg, typename... Args,
4274 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4275 {
4276  out.append(arg.data(), arg.size());
4277  concat_into(out, std::forward<Args>(rest)...);
4278 }
4279 
4280 template<typename OutStringType = std::string, typename... Args>
4281 inline OutStringType concat(Args && ... args)
4282 {
4283  OutStringType str;
4284  str.reserve(concat_length(args...));
4285  concat_into(str, std::forward<Args>(args)...);
4286  return str;
4287 }
4288 
4289 } // namespace detail
4291 
4292 
4293 
4295 namespace detail
4296 {
4297 
4299 // exceptions //
4301 
4304 class exception : public std::exception
4305 {
4306  public:
4308  const char* what() const noexcept override
4309  {
4310  return m.what();
4311  }
4312 
4314  const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4315 
4316  protected:
4318  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
4319 
4320  static std::string name(const std::string& ename, int id_)
4321  {
4322  return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
4323  }
4324 
4325  static std::string diagnostics(std::nullptr_t /*leaf_element*/)
4326  {
4327  return "";
4328  }
4329 
4330  template<typename BasicJsonType>
4331  static std::string diagnostics(const BasicJsonType* leaf_element)
4332  {
4333 #if JSON_DIAGNOSTICS
4334  std::vector<std::string> tokens;
4335  for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
4336  {
4337  switch (current->m_parent->type())
4338  {
4339  case value_t::array:
4340  {
4341  for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i)
4342  {
4343  if (&current->m_parent->m_data.m_value.array->operator[](i) == current)
4344  {
4345  tokens.emplace_back(std::to_string(i));
4346  break;
4347  }
4348  }
4349  break;
4350  }
4351 
4352  case value_t::object:
4353  {
4354  for (const auto& element : *current->m_parent->m_data.m_value.object)
4355  {
4356  if (&element.second == current)
4357  {
4358  tokens.emplace_back(element.first.c_str());
4359  break;
4360  }
4361  }
4362  break;
4363  }
4364 
4365  case value_t::null: // LCOV_EXCL_LINE
4366  case value_t::string: // LCOV_EXCL_LINE
4367  case value_t::boolean: // LCOV_EXCL_LINE
4368  case value_t::number_integer: // LCOV_EXCL_LINE
4369  case value_t::number_unsigned: // LCOV_EXCL_LINE
4370  case value_t::number_float: // LCOV_EXCL_LINE
4371  case value_t::binary: // LCOV_EXCL_LINE
4372  case value_t::discarded: // LCOV_EXCL_LINE
4373  default: // LCOV_EXCL_LINE
4374  break; // LCOV_EXCL_LINE
4375  }
4376  }
4377 
4378  if (tokens.empty())
4379  {
4380  return "";
4381  }
4382 
4383  auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4384  [](const std::string & a, const std::string & b)
4385  {
4386  return concat(a, '/', detail::escape(b));
4387  });
4388  return concat('(', str, ") ");
4389 #else
4390  static_cast<void>(leaf_element);
4391  return "";
4392 #endif
4393  }
4394 
4395  private:
4397  std::runtime_error m;
4398 };
4399 
4402 class parse_error : public exception
4403 {
4404  public:
4415  static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4416  {
4417  const std::string w = concat(exception::name("parse_error", id_), "parse error",
4418  position_string(pos), ": ", exception::diagnostics(context), what_arg);
4419  return {id_, pos.chars_read_total, w.c_str()};
4420  }
4421 
4423  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4424  {
4425  const std::string w = concat(exception::name("parse_error", id_), "parse error",
4426  (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4427  ": ", exception::diagnostics(context), what_arg);
4428  return {id_, byte_, w.c_str()};
4429  }
4430 
4440  const std::size_t byte;
4441 
4442  private:
4443  parse_error(int id_, std::size_t byte_, const char* what_arg)
4444  : exception(id_, what_arg), byte(byte_) {}
4445 
4447  {
4448  return concat(" at line ", std::to_string(pos.lines_read + 1),
4449  ", column ", std::to_string(pos.chars_read_current_line));
4450  }
4451 };
4452 
4456 {
4457  public:
4459  static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4460  {
4461  const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4462  return {id_, w.c_str()};
4463  }
4464 
4465  private:
4467  invalid_iterator(int id_, const char* what_arg)
4468  : exception(id_, what_arg) {}
4469 };
4470 
4473 class type_error : public exception
4474 {
4475  public:
4477  static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4478  {
4479  const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4480  return {id_, w.c_str()};
4481  }
4482 
4483  private:
4485  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4486 };
4487 
4490 class out_of_range : public exception
4491 {
4492  public:
4494  static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4495  {
4496  const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4497  return {id_, w.c_str()};
4498  }
4499 
4500  private:
4502  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4503 };
4504 
4507 class other_error : public exception
4508 {
4509  public:
4511  static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4512  {
4513  const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4514  return {id_, w.c_str()};
4515  }
4516 
4517  private:
4519  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4520 };
4521 
4522 } // namespace detail
4524 
4525 // #include <nlohmann/detail/macro_scope.hpp>
4526 
4527 // #include <nlohmann/detail/meta/cpp_future.hpp>
4528 
4529 // #include <nlohmann/detail/meta/identity_tag.hpp>
4530 // __ _____ _____ _____
4531 // __| | __| | | | JSON for Modern C++
4532 // | | |__ | | | | | | version 3.11.2
4533 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4534 //
4535 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4536 // SPDX-License-Identifier: MIT
4537 
4538 
4539 
4540 // #include <nlohmann/detail/abi_macros.hpp>
4541 
4542 
4544 namespace detail
4545 {
4546 
4547 // dispatching helper struct
4548 template <class T> struct identity_tag {};
4549 
4550 } // namespace detail
4552 
4553 // #include <nlohmann/detail/meta/std_fs.hpp>
4554 // __ _____ _____ _____
4555 // __| | __| | | | JSON for Modern C++
4556 // | | |__ | | | | | | version 3.11.2
4557 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4558 //
4559 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4560 // SPDX-License-Identifier: MIT
4561 
4562 
4563 
4564 // #include <nlohmann/detail/macro_scope.hpp>
4565 
4566 
4567 #if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4568 #include <experimental/filesystem>
4570 namespace detail
4571 {
4572 namespace std_fs = std::experimental::filesystem;
4573 } // namespace detail
4575 #elif JSON_HAS_FILESYSTEM
4576 #include <filesystem>
4578 namespace detail
4579 {
4580 namespace std_fs = std::filesystem;
4581 } // namespace detail
4583 #endif
4584 
4585 // #include <nlohmann/detail/meta/type_traits.hpp>
4586 
4587 // #include <nlohmann/detail/string_concat.hpp>
4588 
4589 // #include <nlohmann/detail/value_t.hpp>
4590 
4591 
4593 namespace detail
4594 {
4595 
4596 template<typename BasicJsonType>
4597 inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4598 {
4599  if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4600  {
4601  JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4602  }
4603  n = nullptr;
4604 }
4605 
4606 // overloads for basic_json template parameters
4607 template < typename BasicJsonType, typename ArithmeticType,
4608  enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
4609  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4610  int > = 0 >
4611 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4612 {
4613  switch (static_cast<value_t>(j))
4614  {
4616  {
4617  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4618  break;
4619  }
4621  {
4622  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4623  break;
4624  }
4625  case value_t::number_float:
4626  {
4627  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4628  break;
4629  }
4630 
4631  case value_t::null:
4632  case value_t::object:
4633  case value_t::array:
4634  case value_t::string:
4635  case value_t::boolean:
4636  case value_t::binary:
4637  case value_t::discarded:
4638  default:
4639  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4640  }
4641 }
4642 
4643 template<typename BasicJsonType>
4644 inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4645 {
4646  if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4647  {
4648  JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4649  }
4650  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4651 }
4652 
4653 template<typename BasicJsonType>
4654 inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4655 {
4656  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4657  {
4658  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4659  }
4660  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4661 }
4662 
4663 template <
4664  typename BasicJsonType, typename StringType,
4665  enable_if_t <
4666  std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4667  && is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value
4668  && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4669  && !is_json_ref<StringType>::value, int > = 0 >
4670 inline void from_json(const BasicJsonType& j, StringType& s)
4671 {
4672  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4673  {
4674  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4675  }
4676 
4677  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4678 }
4679 
4680 template<typename BasicJsonType>
4681 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4682 {
4683  get_arithmetic_value(j, val);
4684 }
4685 
4686 template<typename BasicJsonType>
4687 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4688 {
4689  get_arithmetic_value(j, val);
4690 }
4691 
4692 template<typename BasicJsonType>
4693 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4694 {
4695  get_arithmetic_value(j, val);
4696 }
4697 
4698 #if !JSON_DISABLE_ENUM_SERIALIZATION
4699 template<typename BasicJsonType, typename EnumType,
4700  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4701 inline void from_json(const BasicJsonType& j, EnumType& e)
4702 {
4704  get_arithmetic_value(j, val);
4705  e = static_cast<EnumType>(val);
4706 }
4707 #endif // JSON_DISABLE_ENUM_SERIALIZATION
4708 
4709 // forward_list doesn't have an insert method
4710 template<typename BasicJsonType, typename T, typename Allocator,
4712 inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4713 {
4714  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4715  {
4716  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4717  }
4718  l.clear();
4719  std::transform(j.rbegin(), j.rend(),
4720  std::front_inserter(l), [](const BasicJsonType & i)
4721  {
4722  return i.template get<T>();
4723  });
4724 }
4725 
4726 // valarray doesn't have an insert method
4727 template<typename BasicJsonType, typename T,
4729 inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
4730 {
4731  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4732  {
4733  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4734  }
4735  l.resize(j.size());
4736  std::transform(j.begin(), j.end(), std::begin(l),
4737  [](const BasicJsonType & elem)
4738  {
4739  return elem.template get<T>();
4740  });
4741 }
4742 
4743 template<typename BasicJsonType, typename T, std::size_t N>
4744 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4745 -> decltype(j.template get<T>(), void())
4746 {
4747  for (std::size_t i = 0; i < N; ++i)
4748  {
4749  arr[i] = j.at(i).template get<T>();
4750  }
4751 }
4752 
4753 template<typename BasicJsonType>
4754 inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4755 {
4756  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4757 }
4758 
4759 template<typename BasicJsonType, typename T, std::size_t N>
4760 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4761  priority_tag<2> /*unused*/)
4762 -> decltype(j.template get<T>(), void())
4763 {
4764  for (std::size_t i = 0; i < N; ++i)
4765  {
4766  arr[i] = j.at(i).template get<T>();
4767  }
4768 }
4769 
4770 template<typename BasicJsonType, typename ConstructibleArrayType,
4771  enable_if_t<
4772  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4773  int> = 0>
4774 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4775 -> decltype(
4776  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4777  j.template get<typename ConstructibleArrayType::value_type>(),
4778  void())
4779 {
4780  using std::end;
4781 
4782  ConstructibleArrayType ret;
4783  ret.reserve(j.size());
4784  std::transform(j.begin(), j.end(),
4785  std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4786  {
4787  // get<BasicJsonType>() returns *this, this won't call a from_json
4788  // method when value_type is BasicJsonType
4789  return i.template get<typename ConstructibleArrayType::value_type>();
4790  });
4791  arr = std::move(ret);
4792 }
4793 
4794 template<typename BasicJsonType, typename ConstructibleArrayType,
4795  enable_if_t<
4796  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4797  int> = 0>
4798 inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4799  priority_tag<0> /*unused*/)
4800 {
4801  using std::end;
4802 
4803  ConstructibleArrayType ret;
4804  std::transform(
4805  j.begin(), j.end(), std::inserter(ret, end(ret)),
4806  [](const BasicJsonType & i)
4807  {
4808  // get<BasicJsonType>() returns *this, this won't call a from_json
4809  // method when value_type is BasicJsonType
4810  return i.template get<typename ConstructibleArrayType::value_type>();
4811  });
4812  arr = std::move(ret);
4813 }
4814 
4815 template < typename BasicJsonType, typename ConstructibleArrayType,
4816  enable_if_t <
4820  !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4822  int > = 0 >
4823 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4824 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4825 j.template get<typename ConstructibleArrayType::value_type>(),
4826 void())
4827 {
4828  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4829  {
4830  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4831  }
4832 
4834 }
4835 
4836 template < typename BasicJsonType, typename T, std::size_t... Idx >
4837 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4838  identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4839 {
4840  return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4841 }
4842 
4843 template < typename BasicJsonType, typename T, std::size_t N >
4844 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4845 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4846 {
4847  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4848  {
4849  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4850  }
4851 
4852  return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4853 }
4854 
4855 template<typename BasicJsonType>
4856 inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4857 {
4858  if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4859  {
4860  JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4861  }
4862 
4863  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4864 }
4865 
4866 template<typename BasicJsonType, typename ConstructibleObjectType,
4868 inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4869 {
4870  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4871  {
4872  JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4873  }
4874 
4875  ConstructibleObjectType ret;
4876  const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4877  using value_type = typename ConstructibleObjectType::value_type;
4878  std::transform(
4879  inner_object->begin(), inner_object->end(),
4880  std::inserter(ret, ret.begin()),
4881  [](typename BasicJsonType::object_t::value_type const & p)
4882  {
4883  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4884  });
4885  obj = std::move(ret);
4886 }
4887 
4888 // overload for arithmetic types, not chosen for basic_json template arguments
4889 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4890 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4891 // an arithmetic type?
4892 template < typename BasicJsonType, typename ArithmeticType,
4893  enable_if_t <
4894  std::is_arithmetic<ArithmeticType>::value&&
4895  !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4896  !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4897  !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4898  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4899  int > = 0 >
4900 inline void from_json(const BasicJsonType& j, ArithmeticType& val)
4901 {
4902  switch (static_cast<value_t>(j))
4903  {
4905  {
4906  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4907  break;
4908  }
4910  {
4911  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4912  break;
4913  }
4914  case value_t::number_float:
4915  {
4916  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4917  break;
4918  }
4919  case value_t::boolean:
4920  {
4921  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4922  break;
4923  }
4924 
4925  case value_t::null:
4926  case value_t::object:
4927  case value_t::array:
4928  case value_t::string:
4929  case value_t::binary:
4930  case value_t::discarded:
4931  default:
4932  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4933  }
4934 }
4935 
4936 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4937 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4938 {
4939  return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4940 }
4941 
4942 template < typename BasicJsonType, class A1, class A2 >
4943 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4944 {
4945  return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4946  std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4947 }
4948 
4949 template<typename BasicJsonType, typename A1, typename A2>
4950 inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4951 {
4952  p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4953 }
4954 
4955 template<typename BasicJsonType, typename... Args>
4956 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4957 {
4958  return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4959 }
4960 
4961 template<typename BasicJsonType, typename... Args>
4962 inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4963 {
4964  t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4965 }
4966 
4967 template<typename BasicJsonType, typename TupleRelated>
4968 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4969 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4970 {
4971  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4972  {
4973  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4974  }
4975 
4976  return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4977 }
4978 
4979 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4980  typename = enable_if_t < !std::is_constructible <
4981  typename BasicJsonType::string_t, Key >::value >>
4982 inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4983 {
4984  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4985  {
4986  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4987  }
4988  m.clear();
4989  for (const auto& p : j)
4990  {
4991  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4992  {
4993  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4994  }
4995  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4996  }
4997 }
4998 
4999 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
5000  typename = enable_if_t < !std::is_constructible <
5001  typename BasicJsonType::string_t, Key >::value >>
5002 inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
5003 {
5004  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5005  {
5006  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5007  }
5008  m.clear();
5009  for (const auto& p : j)
5010  {
5011  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5012  {
5013  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5014  }
5015  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5016  }
5017 }
5018 
5019 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5020 template<typename BasicJsonType>
5021 inline void from_json(const BasicJsonType& j, std_fs::path& p)
5022 {
5023  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
5024  {
5025  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
5026  }
5027  p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
5028 }
5029 #endif
5030 
5032 {
5033  template<typename BasicJsonType, typename T>
5034  auto operator()(const BasicJsonType& j, T&& val) const
5035  noexcept(noexcept(from_json(j, std::forward<T>(val))))
5036  -> decltype(from_json(j, std::forward<T>(val)))
5037  {
5038  return from_json(j, std::forward<T>(val));
5039  }
5040 };
5041 
5042 } // namespace detail
5043 
5044 #ifndef JSON_HAS_CPP_17
5045 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5049 {
5050 #endif
5051 JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
5053 #ifndef JSON_HAS_CPP_17
5054 } // namespace
5055 #endif
5056 
5058 
5059 // #include <nlohmann/detail/conversions/to_json.hpp>
5060 // __ _____ _____ _____
5061 // __| | __| | | | JSON for Modern C++
5062 // | | |__ | | | | | | version 3.11.2
5063 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5064 //
5065 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5066 // SPDX-License-Identifier: MIT
5067 
5068 
5069 
5070 #include <algorithm> // copy
5071 #include <iterator> // begin, end
5072 #include <string> // string
5073 #include <tuple> // tuple, get
5074 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
5075 #include <utility> // move, forward, declval, pair
5076 #include <valarray> // valarray
5077 #include <vector> // vector
5078 
5079 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5080 // __ _____ _____ _____
5081 // __| | __| | | | JSON for Modern C++
5082 // | | |__ | | | | | | version 3.11.2
5083 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5084 //
5085 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5086 // SPDX-License-Identifier: MIT
5087 
5088 
5089 
5090 #include <cstddef> // size_t
5091 #include <iterator> // input_iterator_tag
5092 #include <string> // string, to_string
5093 #include <tuple> // tuple_size, get, tuple_element
5094 #include <utility> // move
5095 
5096 #if JSON_HAS_RANGES
5097  #include <ranges> // enable_borrowed_range
5098 #endif
5099 
5100 // #include <nlohmann/detail/abi_macros.hpp>
5101 
5102 // #include <nlohmann/detail/meta/type_traits.hpp>
5103 
5104 // #include <nlohmann/detail/value_t.hpp>
5105 
5106 
5108 namespace detail
5109 {
5110 
5111 template<typename string_type>
5112 void int_to_string( string_type& target, std::size_t value )
5113 {
5114  // For ADL
5115  using std::to_string;
5116  target = to_string(value);
5117 }
5118 template<typename IteratorType> class iteration_proxy_value
5119 {
5120  public:
5121  using difference_type = std::ptrdiff_t;
5123  using pointer = value_type *;
5125  using iterator_category = std::input_iterator_tag;
5126  using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
5127 
5128  private:
5130  IteratorType anchor{};
5132  std::size_t array_index = 0;
5134  mutable std::size_t array_index_last = 0;
5139 
5140  public:
5141  explicit iteration_proxy_value() = default;
5142  explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
5143  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5144  && std::is_nothrow_default_constructible<string_type>::value)
5145  : anchor(std::move(it))
5146  , array_index(array_index_)
5147  {}
5148 
5149  iteration_proxy_value(iteration_proxy_value const&) = default;
5151  // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
5153  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5154  && std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5156  noexcept(std::is_nothrow_move_assignable<IteratorType>::value
5157  && std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5159 
5161  const iteration_proxy_value& operator*() const
5162  {
5163  return *this;
5164  }
5165 
5168  {
5169  ++anchor;
5170  ++array_index;
5171 
5172  return *this;
5173  }
5174 
5175  iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
5176  {
5178  ++anchor;
5179  ++array_index;
5180  return tmp;
5181  }
5182 
5184  bool operator==(const iteration_proxy_value& o) const
5185  {
5186  return anchor == o.anchor;
5187  }
5188 
5190  bool operator!=(const iteration_proxy_value& o) const
5191  {
5192  return anchor != o.anchor;
5193  }
5194 
5196  const string_type& key() const
5197  {
5198  JSON_ASSERT(anchor.m_object != nullptr);
5199 
5200  switch (anchor.m_object->type())
5201  {
5202  // use integer array index as key
5203  case value_t::array:
5204  {
5206  {
5209  }
5210  return array_index_str;
5211  }
5212 
5213  // use key from the object
5214  case value_t::object:
5215  return anchor.key();
5216 
5217  // use an empty key for all primitive types
5218  case value_t::null:
5219  case value_t::string:
5220  case value_t::boolean:
5223  case value_t::number_float:
5224  case value_t::binary:
5225  case value_t::discarded:
5226  default:
5227  return empty_str;
5228  }
5229  }
5230 
5232  typename IteratorType::reference value() const
5233  {
5234  return anchor.value();
5235  }
5236 };
5237 
5239 template<typename IteratorType> class iteration_proxy
5240 {
5241  private:
5243  typename IteratorType::pointer container = nullptr;
5244 
5245  public:
5246  explicit iteration_proxy() = default;
5247 
5249  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
5250  : container(&cont) {}
5251 
5252  iteration_proxy(iteration_proxy const&) = default;
5253  iteration_proxy& operator=(iteration_proxy const&) = default;
5254  iteration_proxy(iteration_proxy&&) noexcept = default;
5255  iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
5256  ~iteration_proxy() = default;
5257 
5259  iteration_proxy_value<IteratorType> begin() const noexcept
5260  {
5262  }
5263 
5266  {
5268  }
5269 };
5270 
5271 // Structured Bindings Support
5272 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5273 // And see https://github.com/nlohmann/json/pull/1391
5274 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
5275 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
5276 {
5277  return i.key();
5278 }
5279 // Structured Bindings Support
5280 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5281 // And see https://github.com/nlohmann/json/pull/1391
5282 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
5283 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
5284 {
5285  return i.value();
5286 }
5287 
5288 } // namespace detail
5290 
5291 // The Addition to the STD Namespace is required to add
5292 // Structured Bindings Support to the iteration_proxy_value class
5293 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5294 // And see https://github.com/nlohmann/json/pull/1391
5295 namespace std
5296 {
5297 
5298 #if defined(__clang__)
5299  // Fix: https://github.com/nlohmann/json/issues/1401
5300  #pragma clang diagnostic push
5301  #pragma clang diagnostic ignored "-Wmismatched-tags"
5302 #endif
5303 template<typename IteratorType>
5304 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
5305  : public std::integral_constant<std::size_t, 2> {};
5306 
5307 template<std::size_t N, typename IteratorType>
5308 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)
5309 {
5310  public:
5311  using type = decltype(
5312  get<N>(std::declval <
5313  ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
5314 };
5315 #if defined(__clang__)
5316  #pragma clang diagnostic pop
5317 #endif
5318 
5319 } // namespace std
5320 
5321 #if JSON_HAS_RANGES
5322  template <typename IteratorType>
5323  inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
5324 #endif
5325 
5326 // #include <nlohmann/detail/macro_scope.hpp>
5327 
5328 // #include <nlohmann/detail/meta/cpp_future.hpp>
5329 
5330 // #include <nlohmann/detail/meta/std_fs.hpp>
5331 
5332 // #include <nlohmann/detail/meta/type_traits.hpp>
5333 
5334 // #include <nlohmann/detail/value_t.hpp>
5335 
5336 
5338 namespace detail
5339 {
5340 
5342 // constructors //
5344 
5345 /*
5346  * Note all external_constructor<>::construct functions need to call
5347  * j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an
5348  * allocated value (e.g., a string). See bug issue
5349  * https://github.com/nlohmann/json/issues/2865 for more information.
5350  */
5351 
5352 template<value_t> struct external_constructor;
5353 
5354 template<>
5356 {
5357  template<typename BasicJsonType>
5358  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
5359  {
5360  j.m_data.m_value.destroy(j.m_data.m_type);
5361  j.m_data.m_type = value_t::boolean;
5362  j.m_data.m_value = b;
5363  j.assert_invariant();
5364  }
5365 };
5366 
5367 template<>
5369 {
5370  template<typename BasicJsonType>
5371  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
5372  {
5373  j.m_data.m_value.destroy(j.m_data.m_type);
5374  j.m_data.m_type = value_t::string;
5375  j.m_data.m_value = s;
5376  j.assert_invariant();
5377  }
5378 
5379  template<typename BasicJsonType>
5380  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5381  {
5382  j.m_data.m_value.destroy(j.m_data.m_type);
5383  j.m_data.m_type = value_t::string;
5384  j.m_data.m_value = std::move(s);
5385  j.assert_invariant();
5386  }
5387 
5388  template < typename BasicJsonType, typename CompatibleStringType,
5390  int > = 0 >
5391  static void construct(BasicJsonType& j, const CompatibleStringType& str)
5392  {
5393  j.m_data.m_value.destroy(j.m_data.m_type);
5394  j.m_data.m_type = value_t::string;
5395  j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
5396  j.assert_invariant();
5397  }
5398 };
5399 
5400 template<>
5402 {
5403  template<typename BasicJsonType>
5404  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
5405  {
5406  j.m_data.m_value.destroy(j.m_data.m_type);
5407  j.m_data.m_type = value_t::binary;
5408  j.m_data.m_value = typename BasicJsonType::binary_t(b);
5409  j.assert_invariant();
5410  }
5411 
5412  template<typename BasicJsonType>
5413  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
5414  {
5415  j.m_data.m_value.destroy(j.m_data.m_type);
5416  j.m_data.m_type = value_t::binary;
5417  j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
5418  j.assert_invariant();
5419  }
5420 };
5421 
5422 template<>
5424 {
5425  template<typename BasicJsonType>
5426  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5427  {
5428  j.m_data.m_value.destroy(j.m_data.m_type);
5429  j.m_data.m_type = value_t::number_float;
5430  j.m_data.m_value = val;
5431  j.assert_invariant();
5432  }
5433 };
5434 
5435 template<>
5437 {
5438  template<typename BasicJsonType>
5439  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5440  {
5441  j.m_data.m_value.destroy(j.m_data.m_type);
5442  j.m_data.m_type = value_t::number_unsigned;
5443  j.m_data.m_value = val;
5444  j.assert_invariant();
5445  }
5446 };
5447 
5448 template<>
5450 {
5451  template<typename BasicJsonType>
5452  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5453  {
5454  j.m_data.m_value.destroy(j.m_data.m_type);
5455  j.m_data.m_type = value_t::number_integer;
5456  j.m_data.m_value = val;
5457  j.assert_invariant();
5458  }
5459 };
5460 
5461 template<>
5463 {
5464  template<typename BasicJsonType>
5465  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5466  {
5467  j.m_data.m_value.destroy(j.m_data.m_type);
5468  j.m_data.m_type = value_t::array;
5469  j.m_data.m_value = arr;
5470  j.set_parents();
5471  j.assert_invariant();
5472  }
5473 
5474  template<typename BasicJsonType>
5475  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5476  {
5477  j.m_data.m_value.destroy(j.m_data.m_type);
5478  j.m_data.m_type = value_t::array;
5479  j.m_data.m_value = std::move(arr);
5480  j.set_parents();
5481  j.assert_invariant();
5482  }
5483 
5484  template < typename BasicJsonType, typename CompatibleArrayType,
5486  int > = 0 >
5487  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5488  {
5489  using std::begin;
5490  using std::end;
5491 
5492  j.m_data.m_value.destroy(j.m_data.m_type);
5493  j.m_data.m_type = value_t::array;
5494  j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5495  j.set_parents();
5496  j.assert_invariant();
5497  }
5498 
5499  template<typename BasicJsonType>
5500  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5501  {
5502  j.m_data.m_value.destroy(j.m_data.m_type);
5503  j.m_data.m_type = value_t::array;
5504  j.m_data.m_value = value_t::array;
5505  j.m_data.m_value.array->reserve(arr.size());
5506  for (const bool x : arr)
5507  {
5508  j.m_data.m_value.array->push_back(x);
5509  j.set_parent(j.m_data.m_value.array->back());
5510  }
5511  j.assert_invariant();
5512  }
5513 
5514  template<typename BasicJsonType, typename T,
5516  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5517  {
5518  j.m_data.m_value.destroy(j.m_data.m_type);
5519  j.m_data.m_type = value_t::array;
5520  j.m_data.m_value = value_t::array;
5521  j.m_data.m_value.array->resize(arr.size());
5522  if (arr.size() > 0)
5523  {
5524  std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());
5525  }
5526  j.set_parents();
5527  j.assert_invariant();
5528  }
5529 };
5530 
5531 template<>
5533 {
5534  template<typename BasicJsonType>
5535  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5536  {
5537  j.m_data.m_value.destroy(j.m_data.m_type);
5538  j.m_data.m_type = value_t::object;
5539  j.m_data.m_value = obj;
5540  j.set_parents();
5541  j.assert_invariant();
5542  }
5543 
5544  template<typename BasicJsonType>
5545  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5546  {
5547  j.m_data.m_value.destroy(j.m_data.m_type);
5548  j.m_data.m_type = value_t::object;
5549  j.m_data.m_value = std::move(obj);
5550  j.set_parents();
5551  j.assert_invariant();
5552  }
5553 
5554  template < typename BasicJsonType, typename CompatibleObjectType,
5556  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5557  {
5558  using std::begin;
5559  using std::end;
5560 
5561  j.m_data.m_value.destroy(j.m_data.m_type);
5562  j.m_data.m_type = value_t::object;
5563  j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5564  j.set_parents();
5565  j.assert_invariant();
5566  }
5567 };
5568 
5570 // to_json //
5572 
5573 template<typename BasicJsonType, typename T,
5574  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5575 inline void to_json(BasicJsonType& j, T b) noexcept
5576 {
5578 }
5579 
5580 template < typename BasicJsonType, typename BoolRef,
5581  enable_if_t <
5582  ((std::is_same<std::vector<bool>::reference, BoolRef>::value
5583  && !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
5584  || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
5585  && !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
5586  typename BasicJsonType::boolean_t >::value))
5587  && std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 >
5588 inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
5589 {
5590  external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
5591 }
5592 
5593 template<typename BasicJsonType, typename CompatibleString,
5594  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5595 inline void to_json(BasicJsonType& j, const CompatibleString& s)
5596 {
5598 }
5599 
5600 template<typename BasicJsonType>
5601 inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5602 {
5604 }
5605 
5606 template<typename BasicJsonType, typename FloatType,
5607  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5608 inline void to_json(BasicJsonType& j, FloatType val) noexcept
5609 {
5610  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5611 }
5612 
5613 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5614  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5615 inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5616 {
5617  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5618 }
5619 
5620 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5621  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5622 inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5623 {
5624  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5625 }
5626 
5627 #if !JSON_DISABLE_ENUM_SERIALIZATION
5628 template<typename BasicJsonType, typename EnumType,
5629  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5630 inline void to_json(BasicJsonType& j, EnumType e) noexcept
5631 {
5632  using underlying_type = typename std::underlying_type<EnumType>::type;
5633  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5634 }
5635 #endif // JSON_DISABLE_ENUM_SERIALIZATION
5636 
5637 template<typename BasicJsonType>
5638 inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
5639 {
5641 }
5642 
5643 template < typename BasicJsonType, typename CompatibleArrayType,
5644  enable_if_t < is_compatible_array_type<BasicJsonType,
5645  CompatibleArrayType>::value&&
5648  !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
5650  int > = 0 >
5651 inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5652 {
5654 }
5655 
5656 template<typename BasicJsonType>
5657 inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5658 {
5660 }
5661 
5662 template<typename BasicJsonType, typename T,
5663  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
5664 inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5665 {
5667 }
5668 
5669 template<typename BasicJsonType>
5670 inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5671 {
5673 }
5674 
5675 template < typename BasicJsonType, typename CompatibleObjectType,
5677 inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5678 {
5680 }
5681 
5682 template<typename BasicJsonType>
5683 inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5684 {
5686 }
5687 
5688 template <
5689  typename BasicJsonType, typename T, std::size_t N,
5690  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5691  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5692  int > = 0 >
5693 inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5694 {
5696 }
5697 
5698 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
5699 inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5700 {
5701  j = { p.first, p.second };
5702 }
5703 
5704 // for https://github.com/nlohmann/json/pull/1134
5705 template<typename BasicJsonType, typename T,
5706  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
5707 inline void to_json(BasicJsonType& j, const T& b)
5708 {
5709  j = { {b.key(), b.value()} };
5710 }
5711 
5712 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5713 inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5714 {
5715  j = { std::get<Idx>(t)... };
5716 }
5717 
5719 inline void to_json(BasicJsonType& j, const T& t)
5720 {
5721  to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5722 }
5723 
5724 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5725 template<typename BasicJsonType>
5726 inline void to_json(BasicJsonType& j, const std_fs::path& p)
5727 {
5728  j = p.string();
5729 }
5730 #endif
5731 
5733 {
5734  template<typename BasicJsonType, typename T>
5735  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5736  -> decltype(to_json(j, std::forward<T>(val)), void())
5737  {
5738  return to_json(j, std::forward<T>(val));
5739  }
5740 };
5741 } // namespace detail
5742 
5743 #ifndef JSON_HAS_CPP_17
5744 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5748 {
5749 #endif
5750 JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
5752 #ifndef JSON_HAS_CPP_17
5753 } // namespace
5754 #endif
5755 
5757 
5758 // #include <nlohmann/detail/meta/identity_tag.hpp>
5759 
5760 
5762 
5764 template<typename ValueType, typename>
5765 struct adl_serializer
5766 {
5769  template<typename BasicJsonType, typename TargetType = ValueType>
5770  static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5771  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5772  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5773  {
5774  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5775  }
5776 
5779  template<typename BasicJsonType, typename TargetType = ValueType>
5780  static auto from_json(BasicJsonType && j) noexcept(
5781  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5782  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5783  {
5784  return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5785  }
5786 
5789  template<typename BasicJsonType, typename TargetType = ValueType>
5790  static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5791  noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5792  -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5793  {
5794  ::nlohmann::to_json(j, std::forward<TargetType>(val));
5795  }
5796 };
5797 
5799 
5800 // #include <nlohmann/byte_container_with_subtype.hpp>
5801 // __ _____ _____ _____
5802 // __| | __| | | | JSON for Modern C++
5803 // | | |__ | | | | | | version 3.11.2
5804 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5805 //
5806 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5807 // SPDX-License-Identifier: MIT
5808 
5809 
5810 
5811 #include <cstdint> // uint8_t, uint64_t
5812 #include <tuple> // tie
5813 #include <utility> // move
5814 
5815 // #include <nlohmann/detail/abi_macros.hpp>
5816 
5817 
5819 
5822 template<typename BinaryType>
5824 {
5825  public:
5827  using subtype_type = std::uint64_t;
5828 
5831  : container_type()
5832  {}
5833 
5836  : container_type(b)
5837  {}
5838 
5840  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5841  : container_type(std::move(b))
5842  {}
5843 
5845  byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5846  : container_type(b)
5847  , m_subtype(subtype_)
5848  , m_has_subtype(true)
5849  {}
5850 
5852  byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5853  : container_type(std::move(b))
5854  , m_subtype(subtype_)
5855  , m_has_subtype(true)
5856  {}
5857 
5859  {
5860  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5861  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5862  }
5863 
5865  {
5866  return !(rhs == *this);
5867  }
5868 
5871  void set_subtype(subtype_type subtype_) noexcept
5872  {
5873  m_subtype = subtype_;
5874  m_has_subtype = true;
5875  }
5876 
5879  constexpr subtype_type subtype() const noexcept
5880  {
5881  return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5882  }
5883 
5886  constexpr bool has_subtype() const noexcept
5887  {
5888  return m_has_subtype;
5889  }
5890 
5893  void clear_subtype() noexcept
5894  {
5895  m_subtype = 0;
5896  m_has_subtype = false;
5897  }
5898 
5899  private:
5901  bool m_has_subtype = false;
5902 };
5903 
5905 
5906 // #include <nlohmann/detail/conversions/from_json.hpp>
5907 
5908 // #include <nlohmann/detail/conversions/to_json.hpp>
5909 
5910 // #include <nlohmann/detail/exceptions.hpp>
5911 
5912 // #include <nlohmann/detail/hash.hpp>
5913 // __ _____ _____ _____
5914 // __| | __| | | | JSON for Modern C++
5915 // | | |__ | | | | | | version 3.11.2
5916 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5917 //
5918 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5919 // SPDX-License-Identifier: MIT
5920 
5921 
5922 
5923 #include <cstdint> // uint8_t
5924 #include <cstddef> // size_t
5925 #include <functional> // hash
5926 
5927 // #include <nlohmann/detail/abi_macros.hpp>
5928 
5929 // #include <nlohmann/detail/value_t.hpp>
5930 
5931 
5933 namespace detail
5934 {
5935 
5936 // boost::hash_combine
5937 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5938 {
5939  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5940  return seed;
5941 }
5942 
5954 template<typename BasicJsonType>
5955 std::size_t hash(const BasicJsonType& j)
5956 {
5957  using string_t = typename BasicJsonType::string_t;
5958  using number_integer_t = typename BasicJsonType::number_integer_t;
5959  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5960  using number_float_t = typename BasicJsonType::number_float_t;
5961 
5962  const auto type = static_cast<std::size_t>(j.type());
5963  switch (j.type())
5964  {
5965  case BasicJsonType::value_t::null:
5966  case BasicJsonType::value_t::discarded:
5967  {
5968  return combine(type, 0);
5969  }
5970 
5971  case BasicJsonType::value_t::object:
5972  {
5973  auto seed = combine(type, j.size());
5974  for (const auto& element : j.items())
5975  {
5976  const auto h = std::hash<string_t> {}(element.key());
5977  seed = combine(seed, h);
5978  seed = combine(seed, hash(element.value()));
5979  }
5980  return seed;
5981  }
5982 
5983  case BasicJsonType::value_t::array:
5984  {
5985  auto seed = combine(type, j.size());
5986  for (const auto& element : j)
5987  {
5988  seed = combine(seed, hash(element));
5989  }
5990  return seed;
5991  }
5992 
5993  case BasicJsonType::value_t::string:
5994  {
5995  const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5996  return combine(type, h);
5997  }
5998 
5999  case BasicJsonType::value_t::boolean:
6000  {
6001  const auto h = std::hash<bool> {}(j.template get<bool>());
6002  return combine(type, h);
6003  }
6004 
6005  case BasicJsonType::value_t::number_integer:
6006  {
6007  const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
6008  return combine(type, h);
6009  }
6010 
6011  case BasicJsonType::value_t::number_unsigned:
6012  {
6013  const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
6014  return combine(type, h);
6015  }
6016 
6017  case BasicJsonType::value_t::number_float:
6018  {
6019  const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
6020  return combine(type, h);
6021  }
6022 
6023  case BasicJsonType::value_t::binary:
6024  {
6025  auto seed = combine(type, j.get_binary().size());
6026  const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
6027  seed = combine(seed, h);
6028  seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
6029  for (const auto byte : j.get_binary())
6030  {
6031  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
6032  }
6033  return seed;
6034  }
6035 
6036  default: // LCOV_EXCL_LINE
6037  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
6038  return 0; // LCOV_EXCL_LINE
6039  }
6040 }
6041 
6042 } // namespace detail
6044 
6045 // #include <nlohmann/detail/input/binary_reader.hpp>
6046 // __ _____ _____ _____
6047 // __| | __| | | | JSON for Modern C++
6048 // | | |__ | | | | | | version 3.11.2
6049 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6050 //
6051 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6052 // SPDX-License-Identifier: MIT
6053 
6054 
6055 
6056 #include <algorithm> // generate_n
6057 #include <array> // array
6058 #include <cmath> // ldexp
6059 #include <cstddef> // size_t
6060 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6061 #include <cstdio> // snprintf
6062 #include <cstring> // memcpy
6063 #include <iterator> // back_inserter
6064 #include <limits> // numeric_limits
6065 #include <string> // char_traits, string
6066 #include <utility> // make_pair, move
6067 #include <vector> // vector
6068 
6069 // #include <nlohmann/detail/exceptions.hpp>
6070 
6071 // #include <nlohmann/detail/input/input_adapters.hpp>
6072 // __ _____ _____ _____
6073 // __| | __| | | | JSON for Modern C++
6074 // | | |__ | | | | | | version 3.11.2
6075 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6076 //
6077 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6078 // SPDX-License-Identifier: MIT
6079 
6080 
6081 
6082 #include <array> // array
6083 #include <cstddef> // size_t
6084 #include <cstring> // strlen
6085 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
6086 #include <memory> // shared_ptr, make_shared, addressof
6087 #include <numeric> // accumulate
6088 #include <string> // string, char_traits
6089 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
6090 #include <utility> // pair, declval
6091 
6092 #ifndef JSON_NO_IO
6093  #include <cstdio> // FILE *
6094  #include <istream> // istream
6095 #endif // JSON_NO_IO
6096 
6097 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
6098 
6099 // #include <nlohmann/detail/macro_scope.hpp>
6100 
6101 
6103 namespace detail
6104 {
6105 
6108 
6110 // input adapters //
6112 
6113 #ifndef JSON_NO_IO
6114 
6119 {
6120  public:
6121  using char_type = char;
6122 
6124  explicit file_input_adapter(std::FILE* f) noexcept
6125  : m_file(f)
6126  {
6127  JSON_ASSERT(m_file != nullptr);
6128  }
6129 
6130  // make class move-only
6131  file_input_adapter(const file_input_adapter&) = delete;
6133  file_input_adapter& operator=(const file_input_adapter&) = delete;
6134  file_input_adapter& operator=(file_input_adapter&&) = delete;
6136 
6137  std::char_traits<char>::int_type get_character() noexcept
6138  {
6139  return std::fgetc(m_file);
6140  }
6141 
6142  private:
6144  std::FILE* m_file;
6145 };
6146 
6147 
6158 {
6159  public:
6160  using char_type = char;
6161 
6163  {
6164  // clear stream flags; we use underlying streambuf I/O, do not
6165  // maintain ifstream flags, except eof
6166  if (is != nullptr)
6167  {
6168  is->clear(is->rdstate() & std::ios::eofbit);
6169  }
6170  }
6171 
6172  explicit input_stream_adapter(std::istream& i)
6173  : is(&i), sb(i.rdbuf())
6174  {}
6175 
6176  // delete because of pointer members
6177  input_stream_adapter(const input_stream_adapter&) = delete;
6180 
6182  : is(rhs.is), sb(rhs.sb)
6183  {
6184  rhs.is = nullptr;
6185  rhs.sb = nullptr;
6186  }
6187 
6188  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
6189  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
6190  // end up as the same value, e.g. 0xFFFFFFFF.
6191  std::char_traits<char>::int_type get_character()
6192  {
6193  auto res = sb->sbumpc();
6194  // set eof manually, as we don't use the istream interface.
6195  if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
6196  {
6197  is->clear(is->rdstate() | std::ios::eofbit);
6198  }
6199  return res;
6200  }
6201 
6202  private:
6204  std::istream* is = nullptr;
6205  std::streambuf* sb = nullptr;
6206 };
6207 #endif // JSON_NO_IO
6208 
6209 // General-purpose iterator-based adapter. It might not be as fast as
6210 // theoretically possible for some containers, but it is extremely versatile.
6211 template<typename IteratorType>
6213 {
6214  public:
6215  using char_type = typename std::iterator_traits<IteratorType>::value_type;
6216 
6217  iterator_input_adapter(IteratorType first, IteratorType last)
6218  : current(std::move(first)), end(std::move(last))
6219  {}
6220 
6221  typename std::char_traits<char_type>::int_type get_character()
6222  {
6223  if (JSON_HEDLEY_LIKELY(current != end))
6224  {
6225  auto result = std::char_traits<char_type>::to_int_type(*current);
6226  std::advance(current, 1);
6227  return result;
6228  }
6229 
6230  return std::char_traits<char_type>::eof();
6231  }
6232 
6233  private:
6234  IteratorType current;
6235  IteratorType end;
6236 
6237  template<typename BaseInputAdapter, size_t T>
6239 
6240  bool empty() const
6241  {
6242  return current == end;
6243  }
6244 };
6245 
6246 
6247 template<typename BaseInputAdapter, size_t T>
6249 
6250 template<typename BaseInputAdapter>
6251 struct wide_string_input_helper<BaseInputAdapter, 4>
6252 {
6253  // UTF-32
6254  static void fill_buffer(BaseInputAdapter& input,
6255  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6256  size_t& utf8_bytes_index,
6257  size_t& utf8_bytes_filled)
6258  {
6259  utf8_bytes_index = 0;
6260 
6261  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6262  {
6263  utf8_bytes[0] = std::char_traits<char>::eof();
6264  utf8_bytes_filled = 1;
6265  }
6266  else
6267  {
6268  // get the current character
6269  const auto wc = input.get_character();
6270 
6271  // UTF-32 to UTF-8 encoding
6272  if (wc < 0x80)
6273  {
6274  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6275  utf8_bytes_filled = 1;
6276  }
6277  else if (wc <= 0x7FF)
6278  {
6279  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
6280  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6281  utf8_bytes_filled = 2;
6282  }
6283  else if (wc <= 0xFFFF)
6284  {
6285  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
6286  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6287  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6288  utf8_bytes_filled = 3;
6289  }
6290  else if (wc <= 0x10FFFF)
6291  {
6292  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
6293  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
6294  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6295  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6296  utf8_bytes_filled = 4;
6297  }
6298  else
6299  {
6300  // unknown character
6301  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6302  utf8_bytes_filled = 1;
6303  }
6304  }
6305  }
6306 };
6307 
6308 template<typename BaseInputAdapter>
6309 struct wide_string_input_helper<BaseInputAdapter, 2>
6310 {
6311  // UTF-16
6312  static void fill_buffer(BaseInputAdapter& input,
6313  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6314  size_t& utf8_bytes_index,
6315  size_t& utf8_bytes_filled)
6316  {
6317  utf8_bytes_index = 0;
6318 
6319  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6320  {
6321  utf8_bytes[0] = std::char_traits<char>::eof();
6322  utf8_bytes_filled = 1;
6323  }
6324  else
6325  {
6326  // get the current character
6327  const auto wc = input.get_character();
6328 
6329  // UTF-16 to UTF-8 encoding
6330  if (wc < 0x80)
6331  {
6332  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6333  utf8_bytes_filled = 1;
6334  }
6335  else if (wc <= 0x7FF)
6336  {
6337  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
6338  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6339  utf8_bytes_filled = 2;
6340  }
6341  else if (0xD800 > wc || wc >= 0xE000)
6342  {
6343  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
6344  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6345  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6346  utf8_bytes_filled = 3;
6347  }
6348  else
6349  {
6350  if (JSON_HEDLEY_UNLIKELY(!input.empty()))
6351  {
6352  const auto wc2 = static_cast<unsigned int>(input.get_character());
6353  const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
6354  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
6355  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
6356  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
6357  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
6358  utf8_bytes_filled = 4;
6359  }
6360  else
6361  {
6362  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6363  utf8_bytes_filled = 1;
6364  }
6365  }
6366  }
6367  }
6368 };
6369 
6370 // Wraps another input apdater to convert wide character types into individual bytes.
6371 template<typename BaseInputAdapter, typename WideCharType>
6373 {
6374  public:
6375  using char_type = char;
6376 
6377  wide_string_input_adapter(BaseInputAdapter base)
6378  : base_adapter(base) {}
6379 
6380  typename std::char_traits<char>::int_type get_character() noexcept
6381  {
6382  // check if buffer needs to be filled
6384  {
6385  fill_buffer<sizeof(WideCharType)>();
6386 
6389  }
6390 
6391  // use buffer
6394  return utf8_bytes[utf8_bytes_index++];
6395  }
6396 
6397  private:
6398  BaseInputAdapter base_adapter;
6399 
6400  template<size_t T>
6402  {
6404  }
6405 
6407  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
6408 
6410  std::size_t utf8_bytes_index = 0;
6412  std::size_t utf8_bytes_filled = 0;
6413 };
6414 
6415 
6416 template<typename IteratorType, typename Enable = void>
6418 {
6419  using iterator_type = IteratorType;
6420  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6422 
6423  static adapter_type create(IteratorType first, IteratorType last)
6424  {
6425  return adapter_type(std::move(first), std::move(last));
6426  }
6427 };
6428 
6429 template<typename T>
6431 {
6432  using value_type = typename std::iterator_traits<T>::value_type;
6433  enum
6434  {
6435  value = sizeof(value_type) > 1
6436  };
6437 };
6438 
6439 template<typename IteratorType>
6441 {
6442  using iterator_type = IteratorType;
6443  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6446 
6447  static adapter_type create(IteratorType first, IteratorType last)
6448  {
6449  return adapter_type(base_adapter_type(std::move(first), std::move(last)));
6450  }
6451 };
6452 
6453 // General purpose iterator-based input
6454 template<typename IteratorType>
6455 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
6456 {
6457  using factory_type = iterator_input_adapter_factory<IteratorType>;
6458  return factory_type::create(first, last);
6459 }
6460 
6461 // Convenience shorthand from container to iterator
6462 // Enables ADL on begin(container) and end(container)
6463 // Encloses the using declarations in namespace for not to leak them to outside scope
6464 
6465 namespace container_input_adapter_factory_impl
6466 {
6467 
6468 using std::begin;
6469 using std::end;
6470 
6471 template<typename ContainerType, typename Enable = void>
6473 
6474 template<typename ContainerType>
6475 struct container_input_adapter_factory< ContainerType,
6476  void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6477  {
6478  using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6479 
6480  static adapter_type create(const ContainerType& container)
6481 {
6482  return input_adapter(begin(container), end(container));
6483 }
6484  };
6485 
6486 } // namespace container_input_adapter_factory_impl
6487 
6488 template<typename ContainerType>
6490 {
6492 }
6493 
6494 #ifndef JSON_NO_IO
6495 // Special cases with fast paths
6497 {
6498  return file_input_adapter(file);
6499 }
6500 
6501 inline input_stream_adapter input_adapter(std::istream& stream)
6502 {
6503  return input_stream_adapter(stream);
6504 }
6505 
6506 inline input_stream_adapter input_adapter(std::istream&& stream)
6507 {
6508  return input_stream_adapter(stream);
6509 }
6510 #endif // JSON_NO_IO
6511 
6512 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6513 
6514 // Null-delimited strings, and the like.
6515 template < typename CharT,
6516  typename std::enable_if <
6517  std::is_pointer<CharT>::value&&
6518  !std::is_array<CharT>::value&&
6520  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6521  int >::type = 0 >
6523 {
6524  auto length = std::strlen(reinterpret_cast<const char*>(b));
6525  const auto* ptr = reinterpret_cast<const char*>(b);
6526  return input_adapter(ptr, ptr + length);
6527 }
6528 
6529 template<typename T, std::size_t N>
6530 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)
6531 {
6532  return input_adapter(array, array + N);
6533 }
6534 
6535 // This class only handles inputs of input_buffer_adapter type.
6536 // It's required so that expressions like {ptr, len} can be implicitly cast
6537 // to the correct adapter.
6539 {
6540  public:
6541  template < typename CharT,
6542  typename std::enable_if <
6543  std::is_pointer<CharT>::value&&
6545  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6546  int >::type = 0 >
6547  span_input_adapter(CharT b, std::size_t l)
6548  : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
6549 
6550  template<class IteratorType,
6551  typename std::enable_if<
6552  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
6553  int>::type = 0>
6554  span_input_adapter(IteratorType first, IteratorType last)
6555  : ia(input_adapter(first, last)) {}
6556 
6558  {
6559  return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6560  }
6561 
6562  private:
6564 };
6565 
6566 } // namespace detail
6568 
6569 // #include <nlohmann/detail/input/json_sax.hpp>
6570 // __ _____ _____ _____
6571 // __| | __| | | | JSON for Modern C++
6572 // | | |__ | | | | | | version 3.11.2
6573 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6574 //
6575 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6576 // SPDX-License-Identifier: MIT
6577 
6578 
6579 
6580 #include <cstddef>
6581 #include <string> // string
6582 #include <utility> // move
6583 #include <vector> // vector
6584 
6585 // #include <nlohmann/detail/exceptions.hpp>
6586 
6587 // #include <nlohmann/detail/macro_scope.hpp>
6588 
6589 // #include <nlohmann/detail/string_concat.hpp>
6590 
6591 
6593 
6602 template<typename BasicJsonType>
6603 struct json_sax
6604 {
6605  using number_integer_t = typename BasicJsonType::number_integer_t;
6606  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6607  using number_float_t = typename BasicJsonType::number_float_t;
6608  using string_t = typename BasicJsonType::string_t;
6609  using binary_t = typename BasicJsonType::binary_t;
6610 
6615  virtual bool null() = 0;
6616 
6622  virtual bool boolean(bool val) = 0;
6623 
6629  virtual bool number_integer(number_integer_t val) = 0;
6630 
6636  virtual bool number_unsigned(number_unsigned_t val) = 0;
6637 
6644  virtual bool number_float(number_float_t val, const string_t& s) = 0;
6645 
6652  virtual bool string(string_t& val) = 0;
6653 
6660  virtual bool binary(binary_t& val) = 0;
6661 
6668  virtual bool start_object(std::size_t elements) = 0;
6669 
6676  virtual bool key(string_t& val) = 0;
6677 
6682  virtual bool end_object() = 0;
6683 
6690  virtual bool start_array(std::size_t elements) = 0;
6691 
6696  virtual bool end_array() = 0;
6697 
6705  virtual bool parse_error(std::size_t position,
6706  const std::string& last_token,
6707  const detail::exception& ex) = 0;
6708 
6709  json_sax() = default;
6710  json_sax(const json_sax&) = default;
6711  json_sax(json_sax&&) noexcept = default;
6712  json_sax& operator=(const json_sax&) = default;
6713  json_sax& operator=(json_sax&&) noexcept = default;
6714  virtual ~json_sax() = default;
6715 };
6716 
6717 
6718 namespace detail
6719 {
6733 template<typename BasicJsonType>
6735 {
6736  public:
6737  using number_integer_t = typename BasicJsonType::number_integer_t;
6738  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6739  using number_float_t = typename BasicJsonType::number_float_t;
6740  using string_t = typename BasicJsonType::string_t;
6741  using binary_t = typename BasicJsonType::binary_t;
6742 
6748  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6749  : root(r), allow_exceptions(allow_exceptions_)
6750  {}
6751 
6752  // make class move-only
6753  json_sax_dom_parser(const json_sax_dom_parser&) = delete;
6754  json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6756  json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6757  ~json_sax_dom_parser() = default;
6758 
6759  bool null()
6760  {
6761  handle_value(nullptr);
6762  return true;
6763  }
6764 
6765  bool boolean(bool val)
6766  {
6767  handle_value(val);
6768  return true;
6769  }
6770 
6772  {
6773  handle_value(val);
6774  return true;
6775  }
6776 
6778  {
6779  handle_value(val);
6780  return true;
6781  }
6782 
6783  bool number_float(number_float_t val, const string_t& /*unused*/)
6784  {
6785  handle_value(val);
6786  return true;
6787  }
6788 
6789  bool string(string_t& val)
6790  {
6791  handle_value(val);
6792  return true;
6793  }
6794 
6795  bool binary(binary_t& val)
6796  {
6797  handle_value(std::move(val));
6798  return true;
6799  }
6800 
6801  bool start_object(std::size_t len)
6802  {
6803  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6804 
6805  if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6806  {
6807  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6808  }
6809 
6810  return true;
6811  }
6812 
6813  bool key(string_t& val)
6814  {
6815  JSON_ASSERT(!ref_stack.empty());
6816  JSON_ASSERT(ref_stack.back()->is_object());
6817 
6818  // add null at given key and store the reference for later
6819  object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val));
6820  return true;
6821  }
6822 
6823  bool end_object()
6824  {
6825  JSON_ASSERT(!ref_stack.empty());
6826  JSON_ASSERT(ref_stack.back()->is_object());
6827 
6828  ref_stack.back()->set_parents();
6829  ref_stack.pop_back();
6830  return true;
6831  }
6832 
6833  bool start_array(std::size_t len)
6834  {
6835  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6836 
6837  if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6838  {
6839  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6840  }
6841 
6842  return true;
6843  }
6844 
6845  bool end_array()
6846  {
6847  JSON_ASSERT(!ref_stack.empty());
6848  JSON_ASSERT(ref_stack.back()->is_array());
6849 
6850  ref_stack.back()->set_parents();
6851  ref_stack.pop_back();
6852  return true;
6853  }
6854 
6855  template<class Exception>
6856  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6857  const Exception& ex)
6858  {
6859  errored = true;
6860  static_cast<void>(ex);
6861  if (allow_exceptions)
6862  {
6863  JSON_THROW(ex);
6864  }
6865  return false;
6866  }
6867 
6868  constexpr bool is_errored() const
6869  {
6870  return errored;
6871  }
6872 
6873  private:
6880  template<typename Value>
6882  BasicJsonType* handle_value(Value&& v)
6883  {
6884  if (ref_stack.empty())
6885  {
6886  root = BasicJsonType(std::forward<Value>(v));
6887  return &root;
6888  }
6889 
6890  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6891 
6892  if (ref_stack.back()->is_array())
6893  {
6894  ref_stack.back()->m_data.m_value.array->emplace_back(std::forward<Value>(v));
6895  return &(ref_stack.back()->m_data.m_value.array->back());
6896  }
6897 
6898  JSON_ASSERT(ref_stack.back()->is_object());
6899  JSON_ASSERT(object_element);
6900  *object_element = BasicJsonType(std::forward<Value>(v));
6901  return object_element;
6902  }
6903 
6905  BasicJsonType& root;
6907  std::vector<BasicJsonType*> ref_stack {};
6909  BasicJsonType* object_element = nullptr;
6911  bool errored = false;
6913  const bool allow_exceptions = true;
6914 };
6915 
6916 template<typename BasicJsonType>
6918 {
6919  public:
6920  using number_integer_t = typename BasicJsonType::number_integer_t;
6921  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6922  using number_float_t = typename BasicJsonType::number_float_t;
6923  using string_t = typename BasicJsonType::string_t;
6924  using binary_t = typename BasicJsonType::binary_t;
6927 
6929  const parser_callback_t cb,
6930  const bool allow_exceptions_ = true)
6931  : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6932  {
6933  keep_stack.push_back(true);
6934  }
6935 
6936  // make class move-only
6938  json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6940  json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6941  ~json_sax_dom_callback_parser() = default;
6942 
6943  bool null()
6944  {
6945  handle_value(nullptr);
6946  return true;
6947  }
6948 
6949  bool boolean(bool val)
6950  {
6951  handle_value(val);
6952  return true;
6953  }
6954 
6956  {
6957  handle_value(val);
6958  return true;
6959  }
6960 
6962  {
6963  handle_value(val);
6964  return true;
6965  }
6966 
6967  bool number_float(number_float_t val, const string_t& /*unused*/)
6968  {
6969  handle_value(val);
6970  return true;
6971  }
6972 
6973  bool string(string_t& val)
6974  {
6975  handle_value(val);
6976  return true;
6977  }
6978 
6979  bool binary(binary_t& val)
6980  {
6981  handle_value(std::move(val));
6982  return true;
6983  }
6984 
6985  bool start_object(std::size_t len)
6986  {
6987  // check callback for object start
6988  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6989  keep_stack.push_back(keep);
6990 
6991  auto val = handle_value(BasicJsonType::value_t::object, true);
6992  ref_stack.push_back(val.second);
6993 
6994  // check object limit
6995  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6996  {
6997  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6998  }
6999 
7000  return true;
7001  }
7002 
7003  bool key(string_t& val)
7004  {
7005  BasicJsonType k = BasicJsonType(val);
7006 
7007  // check callback for key
7008  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
7009  key_keep_stack.push_back(keep);
7010 
7011  // add discarded value at given key and store the reference for later
7012  if (keep && ref_stack.back())
7013  {
7014  object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded);
7015  }
7016 
7017  return true;
7018  }
7019 
7020  bool end_object()
7021  {
7022  if (ref_stack.back())
7023  {
7024  if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
7025  {
7026  // discard object
7027  *ref_stack.back() = discarded;
7028  }
7029  else
7030  {
7031  ref_stack.back()->set_parents();
7032  }
7033  }
7034 
7035  JSON_ASSERT(!ref_stack.empty());
7036  JSON_ASSERT(!keep_stack.empty());
7037  ref_stack.pop_back();
7038  keep_stack.pop_back();
7039 
7040  if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
7041  {
7042  // remove discarded value
7043  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
7044  {
7045  if (it->is_discarded())
7046  {
7047  ref_stack.back()->erase(it);
7048  break;
7049  }
7050  }
7051  }
7052 
7053  return true;
7054  }
7055 
7056  bool start_array(std::size_t len)
7057  {
7058  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
7059  keep_stack.push_back(keep);
7060 
7061  auto val = handle_value(BasicJsonType::value_t::array, true);
7062  ref_stack.push_back(val.second);
7063 
7064  // check array limit
7065  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
7066  {
7067  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
7068  }
7069 
7070  return true;
7071  }
7072 
7073  bool end_array()
7074  {
7075  bool keep = true;
7076 
7077  if (ref_stack.back())
7078  {
7079  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
7080  if (keep)
7081  {
7082  ref_stack.back()->set_parents();
7083  }
7084  else
7085  {
7086  // discard array
7087  *ref_stack.back() = discarded;
7088  }
7089  }
7090 
7091  JSON_ASSERT(!ref_stack.empty());
7092  JSON_ASSERT(!keep_stack.empty());
7093  ref_stack.pop_back();
7094  keep_stack.pop_back();
7095 
7096  // remove discarded value
7097  if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
7098  {
7099  ref_stack.back()->m_data.m_value.array->pop_back();
7100  }
7101 
7102  return true;
7103  }
7104 
7105  template<class Exception>
7106  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
7107  const Exception& ex)
7108  {
7109  errored = true;
7110  static_cast<void>(ex);
7111  if (allow_exceptions)
7112  {
7113  JSON_THROW(ex);
7114  }
7115  return false;
7116  }
7117 
7118  constexpr bool is_errored() const
7119  {
7120  return errored;
7121  }
7122 
7123  private:
7139  template<typename Value>
7140  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
7141  {
7142  JSON_ASSERT(!keep_stack.empty());
7143 
7144  // do not handle this value if we know it would be added to a discarded
7145  // container
7146  if (!keep_stack.back())
7147  {
7148  return {false, nullptr};
7149  }
7150 
7151  // create value
7152  auto value = BasicJsonType(std::forward<Value>(v));
7153 
7154  // check callback
7155  const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
7156 
7157  // do not handle this value if we just learnt it shall be discarded
7158  if (!keep)
7159  {
7160  return {false, nullptr};
7161  }
7162 
7163  if (ref_stack.empty())
7164  {
7165  root = std::move(value);
7166  return {true, &root};
7167  }
7168 
7169  // skip this value if we already decided to skip the parent
7170  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
7171  if (!ref_stack.back())
7172  {
7173  return {false, nullptr};
7174  }
7175 
7176  // we now only expect arrays and objects
7177  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
7178 
7179  // array
7180  if (ref_stack.back()->is_array())
7181  {
7182  ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));
7183  return {true, &(ref_stack.back()->m_data.m_value.array->back())};
7184  }
7185 
7186  // object
7187  JSON_ASSERT(ref_stack.back()->is_object());
7188  // check if we should store an element for the current key
7189  JSON_ASSERT(!key_keep_stack.empty());
7190  const bool store_element = key_keep_stack.back();
7191  key_keep_stack.pop_back();
7192 
7193  if (!store_element)
7194  {
7195  return {false, nullptr};
7196  }
7197 
7198  JSON_ASSERT(object_element);
7199  *object_element = std::move(value);
7200  return {true, object_element};
7201  }
7202 
7204  BasicJsonType& root;
7206  std::vector<BasicJsonType*> ref_stack {};
7208  std::vector<bool> keep_stack {};
7210  std::vector<bool> key_keep_stack {};
7212  BasicJsonType* object_element = nullptr;
7214  bool errored = false;
7216  const parser_callback_t callback = nullptr;
7218  const bool allow_exceptions = true;
7220  BasicJsonType discarded = BasicJsonType::value_t::discarded;
7221 };
7222 
7223 template<typename BasicJsonType>
7225 {
7226  public:
7227  using number_integer_t = typename BasicJsonType::number_integer_t;
7228  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7229  using number_float_t = typename BasicJsonType::number_float_t;
7230  using string_t = typename BasicJsonType::string_t;
7231  using binary_t = typename BasicJsonType::binary_t;
7232 
7233  bool null()
7234  {
7235  return true;
7236  }
7237 
7238  bool boolean(bool /*unused*/)
7239  {
7240  return true;
7241  }
7242 
7244  {
7245  return true;
7246  }
7247 
7249  {
7250  return true;
7251  }
7252 
7253  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
7254  {
7255  return true;
7256  }
7257 
7258  bool string(string_t& /*unused*/)
7259  {
7260  return true;
7261  }
7262 
7263  bool binary(binary_t& /*unused*/)
7264  {
7265  return true;
7266  }
7267 
7268  bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7269  {
7270  return true;
7271  }
7272 
7273  bool key(string_t& /*unused*/)
7274  {
7275  return true;
7276  }
7277 
7278  bool end_object()
7279  {
7280  return true;
7281  }
7282 
7283  bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7284  {
7285  return true;
7286  }
7287 
7288  bool end_array()
7289  {
7290  return true;
7291  }
7292 
7293  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
7294  {
7295  return false;
7296  }
7297 };
7298 
7299 } // namespace detail
7301 
7302 // #include <nlohmann/detail/input/lexer.hpp>
7303 // __ _____ _____ _____
7304 // __| | __| | | | JSON for Modern C++
7305 // | | |__ | | | | | | version 3.11.2
7306 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
7307 //
7308 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7309 // SPDX-License-Identifier: MIT
7310 
7311 
7312 
7313 #include <array> // array
7314 #include <clocale> // localeconv
7315 #include <cstddef> // size_t
7316 #include <cstdio> // snprintf
7317 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7318 #include <initializer_list> // initializer_list
7319 #include <string> // char_traits, string
7320 #include <utility> // move
7321 #include <vector> // vector
7322 
7323 // #include <nlohmann/detail/input/input_adapters.hpp>
7324 
7325 // #include <nlohmann/detail/input/position_t.hpp>
7326 
7327 // #include <nlohmann/detail/macro_scope.hpp>
7328 
7329 
7331 namespace detail
7332 {
7333 
7335 // lexer //
7337 
7338 template<typename BasicJsonType>
7340 {
7341  public:
7343  enum class token_type
7344  {
7345  uninitialized,
7346  literal_true,
7347  literal_false,
7348  literal_null,
7349  value_string,
7350  value_unsigned,
7351  value_integer,
7352  value_float,
7353  begin_array,
7354  begin_object,
7355  end_array,
7356  end_object,
7357  name_separator,
7358  value_separator,
7359  parse_error,
7360  end_of_input,
7361  literal_or_value
7362  };
7363 
7367  static const char* token_type_name(const token_type t) noexcept
7368  {
7369  switch (t)
7370  {
7371  case token_type::uninitialized:
7372  return "<uninitialized>";
7373  case token_type::literal_true:
7374  return "true literal";
7375  case token_type::literal_false:
7376  return "false literal";
7377  case token_type::literal_null:
7378  return "null literal";
7379  case token_type::value_string:
7380  return "string literal";
7381  case token_type::value_unsigned:
7382  case token_type::value_integer:
7383  case token_type::value_float:
7384  return "number literal";
7385  case token_type::begin_array:
7386  return "'['";
7387  case token_type::begin_object:
7388  return "'{'";
7389  case token_type::end_array:
7390  return "']'";
7391  case token_type::end_object:
7392  return "'}'";
7393  case token_type::name_separator:
7394  return "':'";
7395  case token_type::value_separator:
7396  return "','";
7397  case token_type::parse_error:
7398  return "<parse error>";
7399  case token_type::end_of_input:
7400  return "end of input";
7401  case token_type::literal_or_value:
7402  return "'[', '{', or a literal";
7403  // LCOV_EXCL_START
7404  default: // catch non-enum values
7405  return "unknown token";
7406  // LCOV_EXCL_STOP
7407  }
7408  }
7409 };
7415 template<typename BasicJsonType, typename InputAdapterType>
7416 class lexer : public lexer_base<BasicJsonType>
7417 {
7418  using number_integer_t = typename BasicJsonType::number_integer_t;
7419  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7420  using number_float_t = typename BasicJsonType::number_float_t;
7421  using string_t = typename BasicJsonType::string_t;
7422  using char_type = typename InputAdapterType::char_type;
7423  using char_int_type = typename std::char_traits<char_type>::int_type;
7424 
7425  public:
7427 
7428  explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
7429  : ia(std::move(adapter))
7430  , ignore_comments(ignore_comments_)
7431  , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
7432  {}
7433 
7434  // delete because of pointer members
7435  lexer(const lexer&) = delete;
7436  lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7437  lexer& operator=(lexer&) = delete;
7438  lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7439  ~lexer() = default;
7440 
7441  private:
7443  // locales
7445 
7448  static char get_decimal_point() noexcept
7449  {
7450  const auto* loc = localeconv();
7451  JSON_ASSERT(loc != nullptr);
7452  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7453  }
7454 
7456  // scan functions
7458 
7475  {
7476  // this function only makes sense after reading `\u`
7477  JSON_ASSERT(current == 'u');
7478  int codepoint = 0;
7479 
7480  const auto factors = { 12u, 8u, 4u, 0u };
7481  for (const auto factor : factors)
7482  {
7483  get();
7484 
7485  if (current >= '0' && current <= '9')
7486  {
7487  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7488  }
7489  else if (current >= 'A' && current <= 'F')
7490  {
7491  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7492  }
7493  else if (current >= 'a' && current <= 'f')
7494  {
7495  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7496  }
7497  else
7498  {
7499  return -1;
7500  }
7501  }
7502 
7503  JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7504  return codepoint;
7505  }
7506 
7522  bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7523  {
7524  JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7525  add(current);
7526 
7527  for (auto range = ranges.begin(); range != ranges.end(); ++range)
7528  {
7529  get();
7530  if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
7531  {
7532  add(current);
7533  }
7534  else
7535  {
7536  error_message = "invalid string: ill-formed UTF-8 byte";
7537  return false;
7538  }
7539  }
7540 
7541  return true;
7542  }
7543 
7560  {
7561  // reset token_buffer (ignore opening quote)
7562  reset();
7563 
7564  // we entered the function by reading an open quote
7565  JSON_ASSERT(current == '\"');
7566 
7567  while (true)
7568  {
7569  // get next character
7570  switch (get())
7571  {
7572  // end of file while parsing string
7573  case std::char_traits<char_type>::eof():
7574  {
7575  error_message = "invalid string: missing closing quote";
7576  return token_type::parse_error;
7577  }
7578 
7579  // closing quote
7580  case '\"':
7581  {
7582  return token_type::value_string;
7583  }
7584 
7585  // escapes
7586  case '\\':
7587  {
7588  switch (get())
7589  {
7590  // quotation mark
7591  case '\"':
7592  add('\"');
7593  break;
7594  // reverse solidus
7595  case '\\':
7596  add('\\');
7597  break;
7598  // solidus
7599  case '/':
7600  add('/');
7601  break;
7602  // backspace
7603  case 'b':
7604  add('\b');
7605  break;
7606  // form feed
7607  case 'f':
7608  add('\f');
7609  break;
7610  // line feed
7611  case 'n':
7612  add('\n');
7613  break;
7614  // carriage return
7615  case 'r':
7616  add('\r');
7617  break;
7618  // tab
7619  case 't':
7620  add('\t');
7621  break;
7622 
7623  // unicode escapes
7624  case 'u':
7625  {
7626  const int codepoint1 = get_codepoint();
7627  int codepoint = codepoint1; // start with codepoint1
7628 
7629  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7630  {
7631  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7632  return token_type::parse_error;
7633  }
7634 
7635  // check if code point is a high surrogate
7636  if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7637  {
7638  // expect next \uxxxx entry
7639  if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7640  {
7641  const int codepoint2 = get_codepoint();
7642 
7643  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7644  {
7645  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7646  return token_type::parse_error;
7647  }
7648 
7649  // check if codepoint2 is a low surrogate
7650  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7651  {
7652  // overwrite codepoint
7653  codepoint = static_cast<int>(
7654  // high surrogate occupies the most significant 22 bits
7655  (static_cast<unsigned int>(codepoint1) << 10u)
7656  // low surrogate occupies the least significant 15 bits
7657  + static_cast<unsigned int>(codepoint2)
7658  // there is still the 0xD800, 0xDC00 and 0x10000 noise
7659  // in the result, so we have to subtract with:
7660  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7661  - 0x35FDC00u);
7662  }
7663  else
7664  {
7665  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7666  return token_type::parse_error;
7667  }
7668  }
7669  else
7670  {
7671  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7672  return token_type::parse_error;
7673  }
7674  }
7675  else
7676  {
7677  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7678  {
7679  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7680  return token_type::parse_error;
7681  }
7682  }
7683 
7684  // result of the above calculation yields a proper codepoint
7685  JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7686 
7687  // translate codepoint into bytes
7688  if (codepoint < 0x80)
7689  {
7690  // 1-byte characters: 0xxxxxxx (ASCII)
7691  add(static_cast<char_int_type>(codepoint));
7692  }
7693  else if (codepoint <= 0x7FF)
7694  {
7695  // 2-byte characters: 110xxxxx 10xxxxxx
7696  add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7697  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7698  }
7699  else if (codepoint <= 0xFFFF)
7700  {
7701  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7702  add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7703  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7704  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7705  }
7706  else
7707  {
7708  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7709  add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7710  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7711  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7712  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7713  }
7714 
7715  break;
7716  }
7717 
7718  // other characters after escape
7719  default:
7720  error_message = "invalid string: forbidden character after backslash";
7721  return token_type::parse_error;
7722  }
7723 
7724  break;
7725  }
7726 
7727  // invalid control characters
7728  case 0x00:
7729  {
7730  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7731  return token_type::parse_error;
7732  }
7733 
7734  case 0x01:
7735  {
7736  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7737  return token_type::parse_error;
7738  }
7739 
7740  case 0x02:
7741  {
7742  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7743  return token_type::parse_error;
7744  }
7745 
7746  case 0x03:
7747  {
7748  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7749  return token_type::parse_error;
7750  }
7751 
7752  case 0x04:
7753  {
7754  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7755  return token_type::parse_error;
7756  }
7757 
7758  case 0x05:
7759  {
7760  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7761  return token_type::parse_error;
7762  }
7763 
7764  case 0x06:
7765  {
7766  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7767  return token_type::parse_error;
7768  }
7769 
7770  case 0x07:
7771  {
7772  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7773  return token_type::parse_error;
7774  }
7775 
7776  case 0x08:
7777  {
7778  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7779  return token_type::parse_error;
7780  }
7781 
7782  case 0x09:
7783  {
7784  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7785  return token_type::parse_error;
7786  }
7787 
7788  case 0x0A:
7789  {
7790  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7791  return token_type::parse_error;
7792  }
7793 
7794  case 0x0B:
7795  {
7796  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7797  return token_type::parse_error;
7798  }
7799 
7800  case 0x0C:
7801  {
7802  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7803  return token_type::parse_error;
7804  }
7805 
7806  case 0x0D:
7807  {
7808  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7809  return token_type::parse_error;
7810  }
7811 
7812  case 0x0E:
7813  {
7814  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7815  return token_type::parse_error;
7816  }
7817 
7818  case 0x0F:
7819  {
7820  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7821  return token_type::parse_error;
7822  }
7823 
7824  case 0x10:
7825  {
7826  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7827  return token_type::parse_error;
7828  }
7829 
7830  case 0x11:
7831  {
7832  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7833  return token_type::parse_error;
7834  }
7835 
7836  case 0x12:
7837  {
7838  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7839  return token_type::parse_error;
7840  }
7841 
7842  case 0x13:
7843  {
7844  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7845  return token_type::parse_error;
7846  }
7847 
7848  case 0x14:
7849  {
7850  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7851  return token_type::parse_error;
7852  }
7853 
7854  case 0x15:
7855  {
7856  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7857  return token_type::parse_error;
7858  }
7859 
7860  case 0x16:
7861  {
7862  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7863  return token_type::parse_error;
7864  }
7865 
7866  case 0x17:
7867  {
7868  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7869  return token_type::parse_error;
7870  }
7871 
7872  case 0x18:
7873  {
7874  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7875  return token_type::parse_error;
7876  }
7877 
7878  case 0x19:
7879  {
7880  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7881  return token_type::parse_error;
7882  }
7883 
7884  case 0x1A:
7885  {
7886  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7887  return token_type::parse_error;
7888  }
7889 
7890  case 0x1B:
7891  {
7892  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7893  return token_type::parse_error;
7894  }
7895 
7896  case 0x1C:
7897  {
7898  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7899  return token_type::parse_error;
7900  }
7901 
7902  case 0x1D:
7903  {
7904  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7905  return token_type::parse_error;
7906  }
7907 
7908  case 0x1E:
7909  {
7910  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7911  return token_type::parse_error;
7912  }
7913 
7914  case 0x1F:
7915  {
7916  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7917  return token_type::parse_error;
7918  }
7919 
7920  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7921  case 0x20:
7922  case 0x21:
7923  case 0x23:
7924  case 0x24:
7925  case 0x25:
7926  case 0x26:
7927  case 0x27:
7928  case 0x28:
7929  case 0x29:
7930  case 0x2A:
7931  case 0x2B:
7932  case 0x2C:
7933  case 0x2D:
7934  case 0x2E:
7935  case 0x2F:
7936  case 0x30:
7937  case 0x31:
7938  case 0x32:
7939  case 0x33:
7940  case 0x34:
7941  case 0x35:
7942  case 0x36:
7943  case 0x37:
7944  case 0x38:
7945  case 0x39:
7946  case 0x3A:
7947  case 0x3B:
7948  case 0x3C:
7949  case 0x3D:
7950  case 0x3E:
7951  case 0x3F:
7952  case 0x40:
7953  case 0x41:
7954  case 0x42:
7955  case 0x43:
7956  case 0x44:
7957  case 0x45:
7958  case 0x46:
7959  case 0x47:
7960  case 0x48:
7961  case 0x49:
7962  case 0x4A:
7963  case 0x4B:
7964  case 0x4C:
7965  case 0x4D:
7966  case 0x4E:
7967  case 0x4F:
7968  case 0x50:
7969  case 0x51:
7970  case 0x52:
7971  case 0x53:
7972  case 0x54:
7973  case 0x55:
7974  case 0x56:
7975  case 0x57:
7976  case 0x58:
7977  case 0x59:
7978  case 0x5A:
7979  case 0x5B:
7980  case 0x5D:
7981  case 0x5E:
7982  case 0x5F:
7983  case 0x60:
7984  case 0x61:
7985  case 0x62:
7986  case 0x63:
7987  case 0x64:
7988  case 0x65:
7989  case 0x66:
7990  case 0x67:
7991  case 0x68:
7992  case 0x69:
7993  case 0x6A:
7994  case 0x6B:
7995  case 0x6C:
7996  case 0x6D:
7997  case 0x6E:
7998  case 0x6F:
7999  case 0x70:
8000  case 0x71:
8001  case 0x72:
8002  case 0x73:
8003  case 0x74:
8004  case 0x75:
8005  case 0x76:
8006  case 0x77:
8007  case 0x78:
8008  case 0x79:
8009  case 0x7A:
8010  case 0x7B:
8011  case 0x7C:
8012  case 0x7D:
8013  case 0x7E:
8014  case 0x7F:
8015  {
8016  add(current);
8017  break;
8018  }
8019 
8020  // U+0080..U+07FF: bytes C2..DF 80..BF
8021  case 0xC2:
8022  case 0xC3:
8023  case 0xC4:
8024  case 0xC5:
8025  case 0xC6:
8026  case 0xC7:
8027  case 0xC8:
8028  case 0xC9:
8029  case 0xCA:
8030  case 0xCB:
8031  case 0xCC:
8032  case 0xCD:
8033  case 0xCE:
8034  case 0xCF:
8035  case 0xD0:
8036  case 0xD1:
8037  case 0xD2:
8038  case 0xD3:
8039  case 0xD4:
8040  case 0xD5:
8041  case 0xD6:
8042  case 0xD7:
8043  case 0xD8:
8044  case 0xD9:
8045  case 0xDA:
8046  case 0xDB:
8047  case 0xDC:
8048  case 0xDD:
8049  case 0xDE:
8050  case 0xDF:
8051  {
8052  if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
8053  {
8054  return token_type::parse_error;
8055  }
8056  break;
8057  }
8058 
8059  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
8060  case 0xE0:
8061  {
8062  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
8063  {
8064  return token_type::parse_error;
8065  }
8066  break;
8067  }
8068 
8069  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
8070  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
8071  case 0xE1:
8072  case 0xE2:
8073  case 0xE3:
8074  case 0xE4:
8075  case 0xE5:
8076  case 0xE6:
8077  case 0xE7:
8078  case 0xE8:
8079  case 0xE9:
8080  case 0xEA:
8081  case 0xEB:
8082  case 0xEC:
8083  case 0xEE:
8084  case 0xEF:
8085  {
8086  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
8087  {
8088  return token_type::parse_error;
8089  }
8090  break;
8091  }
8092 
8093  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
8094  case 0xED:
8095  {
8096  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
8097  {
8098  return token_type::parse_error;
8099  }
8100  break;
8101  }
8102 
8103  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
8104  case 0xF0:
8105  {
8106  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8107  {
8108  return token_type::parse_error;
8109  }
8110  break;
8111  }
8112 
8113  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
8114  case 0xF1:
8115  case 0xF2:
8116  case 0xF3:
8117  {
8118  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8119  {
8120  return token_type::parse_error;
8121  }
8122  break;
8123  }
8124 
8125  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
8126  case 0xF4:
8127  {
8128  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
8129  {
8130  return token_type::parse_error;
8131  }
8132  break;
8133  }
8134 
8135  // remaining bytes (80..C1 and F5..FF) are ill-formed
8136  default:
8137  {
8138  error_message = "invalid string: ill-formed UTF-8 byte";
8139  return token_type::parse_error;
8140  }
8141  }
8142  }
8143  }
8144 
8150  {
8151  switch (get())
8152  {
8153  // single-line comments skip input until a newline or EOF is read
8154  case '/':
8155  {
8156  while (true)
8157  {
8158  switch (get())
8159  {
8160  case '\n':
8161  case '\r':
8162  case std::char_traits<char_type>::eof():
8163  case '\0':
8164  return true;
8165 
8166  default:
8167  break;
8168  }
8169  }
8170  }
8171 
8172  // multi-line comments skip input until */ is read
8173  case '*':
8174  {
8175  while (true)
8176  {
8177  switch (get())
8178  {
8179  case std::char_traits<char_type>::eof():
8180  case '\0':
8181  {
8182  error_message = "invalid comment; missing closing '*/'";
8183  return false;
8184  }
8185 
8186  case '*':
8187  {
8188  switch (get())
8189  {
8190  case '/':
8191  return true;
8192 
8193  default:
8194  {
8195  unget();
8196  continue;
8197  }
8198  }
8199  }
8200 
8201  default:
8202  continue;
8203  }
8204  }
8205  }
8206 
8207  // unexpected character after reading '/'
8208  default:
8209  {
8210  error_message = "invalid comment; expecting '/' or '*' after '/'";
8211  return false;
8212  }
8213  }
8214  }
8215 
8217  static void strtof(float& f, const char* str, char** endptr) noexcept
8218  {
8219  f = std::strtof(str, endptr);
8220  }
8221 
8223  static void strtof(double& f, const char* str, char** endptr) noexcept
8224  {
8225  f = std::strtod(str, endptr);
8226  }
8227 
8229  static void strtof(long double& f, const char* str, char** endptr) noexcept
8230  {
8231  f = std::strtold(str, endptr);
8232  }
8233 
8274  token_type scan_number() // lgtm [cpp/use-of-goto]
8275  {
8276  // reset token_buffer to store the number's bytes
8277  reset();
8278 
8279  // the type of the parsed number; initially set to unsigned; will be
8280  // changed if minus sign, decimal point or exponent is read
8281  token_type number_type = token_type::value_unsigned;
8282 
8283  // state (init): we just found out we need to scan a number
8284  switch (current)
8285  {
8286  case '-':
8287  {
8288  add(current);
8289  goto scan_number_minus;
8290  }
8291 
8292  case '0':
8293  {
8294  add(current);
8295  goto scan_number_zero;
8296  }
8297 
8298  case '1':
8299  case '2':
8300  case '3':
8301  case '4':
8302  case '5':
8303  case '6':
8304  case '7':
8305  case '8':
8306  case '9':
8307  {
8308  add(current);
8309  goto scan_number_any1;
8310  }
8311 
8312  // all other characters are rejected outside scan_number()
8313  default: // LCOV_EXCL_LINE
8314  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8315  }
8316 
8317 scan_number_minus:
8318  // state: we just parsed a leading minus sign
8319  number_type = token_type::value_integer;
8320  switch (get())
8321  {
8322  case '0':
8323  {
8324  add(current);
8325  goto scan_number_zero;
8326  }
8327 
8328  case '1':
8329  case '2':
8330  case '3':
8331  case '4':
8332  case '5':
8333  case '6':
8334  case '7':
8335  case '8':
8336  case '9':
8337  {
8338  add(current);
8339  goto scan_number_any1;
8340  }
8341 
8342  default:
8343  {
8344  error_message = "invalid number; expected digit after '-'";
8345  return token_type::parse_error;
8346  }
8347  }
8348 
8349 scan_number_zero:
8350  // state: we just parse a zero (maybe with a leading minus sign)
8351  switch (get())
8352  {
8353  case '.':
8354  {
8355  add(decimal_point_char);
8356  goto scan_number_decimal1;
8357  }
8358 
8359  case 'e':
8360  case 'E':
8361  {
8362  add(current);
8363  goto scan_number_exponent;
8364  }
8365 
8366  default:
8367  goto scan_number_done;
8368  }
8369 
8370 scan_number_any1:
8371  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8372  switch (get())
8373  {
8374  case '0':
8375  case '1':
8376  case '2':
8377  case '3':
8378  case '4':
8379  case '5':
8380  case '6':
8381  case '7':
8382  case '8':
8383  case '9':
8384  {
8385  add(current);
8386  goto scan_number_any1;
8387  }
8388 
8389  case '.':
8390  {
8391  add(decimal_point_char);
8392  goto scan_number_decimal1;
8393  }
8394 
8395  case 'e':
8396  case 'E':
8397  {
8398  add(current);
8399  goto scan_number_exponent;
8400  }
8401 
8402  default:
8403  goto scan_number_done;
8404  }
8405 
8406 scan_number_decimal1:
8407  // state: we just parsed a decimal point
8408  number_type = token_type::value_float;
8409  switch (get())
8410  {
8411  case '0':
8412  case '1':
8413  case '2':
8414  case '3':
8415  case '4':
8416  case '5':
8417  case '6':
8418  case '7':
8419  case '8':
8420  case '9':
8421  {
8422  add(current);
8423  goto scan_number_decimal2;
8424  }
8425 
8426  default:
8427  {
8428  error_message = "invalid number; expected digit after '.'";
8429  return token_type::parse_error;
8430  }
8431  }
8432 
8433 scan_number_decimal2:
8434  // we just parsed at least one number after a decimal point
8435  switch (get())
8436  {
8437  case '0':
8438  case '1':
8439  case '2':
8440  case '3':
8441  case '4':
8442  case '5':
8443  case '6':
8444  case '7':
8445  case '8':
8446  case '9':
8447  {
8448  add(current);
8449  goto scan_number_decimal2;
8450  }
8451 
8452  case 'e':
8453  case 'E':
8454  {
8455  add(current);
8456  goto scan_number_exponent;
8457  }
8458 
8459  default:
8460  goto scan_number_done;
8461  }
8462 
8463 scan_number_exponent:
8464  // we just parsed an exponent
8465  number_type = token_type::value_float;
8466  switch (get())
8467  {
8468  case '+':
8469  case '-':
8470  {
8471  add(current);
8472  goto scan_number_sign;
8473  }
8474 
8475  case '0':
8476  case '1':
8477  case '2':
8478  case '3':
8479  case '4':
8480  case '5':
8481  case '6':
8482  case '7':
8483  case '8':
8484  case '9':
8485  {
8486  add(current);
8487  goto scan_number_any2;
8488  }
8489 
8490  default:
8491  {
8492  error_message =
8493  "invalid number; expected '+', '-', or digit after exponent";
8494  return token_type::parse_error;
8495  }
8496  }
8497 
8498 scan_number_sign:
8499  // we just parsed an exponent sign
8500  switch (get())
8501  {
8502  case '0':
8503  case '1':
8504  case '2':
8505  case '3':
8506  case '4':
8507  case '5':
8508  case '6':
8509  case '7':
8510  case '8':
8511  case '9':
8512  {
8513  add(current);
8514  goto scan_number_any2;
8515  }
8516 
8517  default:
8518  {
8519  error_message = "invalid number; expected digit after exponent sign";
8520  return token_type::parse_error;
8521  }
8522  }
8523 
8524 scan_number_any2:
8525  // we just parsed a number after the exponent or exponent sign
8526  switch (get())
8527  {
8528  case '0':
8529  case '1':
8530  case '2':
8531  case '3':
8532  case '4':
8533  case '5':
8534  case '6':
8535  case '7':
8536  case '8':
8537  case '9':
8538  {
8539  add(current);
8540  goto scan_number_any2;
8541  }
8542 
8543  default:
8544  goto scan_number_done;
8545  }
8546 
8547 scan_number_done:
8548  // unget the character after the number (we only read it to know that
8549  // we are done scanning a number)
8550  unget();
8551 
8552  char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8553  errno = 0;
8554 
8555  // try to parse integers first and fall back to floats
8556  if (number_type == token_type::value_unsigned)
8557  {
8558  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8559 
8560  // we checked the number format before
8561  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8562 
8563  if (errno == 0)
8564  {
8565  value_unsigned = static_cast<number_unsigned_t>(x);
8566  if (value_unsigned == x)
8567  {
8568  return token_type::value_unsigned;
8569  }
8570  }
8571  }
8572  else if (number_type == token_type::value_integer)
8573  {
8574  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8575 
8576  // we checked the number format before
8577  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8578 
8579  if (errno == 0)
8580  {
8581  value_integer = static_cast<number_integer_t>(x);
8582  if (value_integer == x)
8583  {
8584  return token_type::value_integer;
8585  }
8586  }
8587  }
8588 
8589  // this code is reached if we parse a floating-point number or if an
8590  // integer conversion above failed
8591  strtof(value_float, token_buffer.data(), &endptr);
8592 
8593  // we checked the number format before
8594  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8595 
8596  return token_type::value_float;
8597  }
8598 
8605  token_type scan_literal(const char_type* literal_text, const std::size_t length,
8606  token_type return_type)
8607  {
8608  JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
8609  for (std::size_t i = 1; i < length; ++i)
8610  {
8611  if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
8612  {
8613  error_message = "invalid literal";
8614  return token_type::parse_error;
8615  }
8616  }
8617  return return_type;
8618  }
8619 
8621  // input management
8623 
8625  void reset() noexcept
8626  {
8627  token_buffer.clear();
8628  token_string.clear();
8629  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8630  }
8631 
8632  /*
8633  @brief get next character from the input
8634 
8635  This function provides the interface to the used input adapter. It does
8636  not throw in case the input reached EOF, but returns a
8637  `std::char_traits<char>::eof()` in that case. Stores the scanned characters
8638  for use in error messages.
8639 
8640  @return character read from the input
8641  */
8643  {
8644  ++position.chars_read_total;
8645  ++position.chars_read_current_line;
8646 
8647  if (next_unget)
8648  {
8649  // just reset the next_unget variable and work with current
8650  next_unget = false;
8651  }
8652  else
8653  {
8654  current = ia.get_character();
8655  }
8656 
8657  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8658  {
8659  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8660  }
8661 
8662  if (current == '\n')
8663  {
8664  ++position.lines_read;
8665  position.chars_read_current_line = 0;
8666  }
8667 
8668  return current;
8669  }
8670 
8679  void unget()
8680  {
8681  next_unget = true;
8682 
8683  --position.chars_read_total;
8684 
8685  // in case we "unget" a newline, we have to also decrement the lines_read
8686  if (position.chars_read_current_line == 0)
8687  {
8688  if (position.lines_read > 0)
8689  {
8690  --position.lines_read;
8691  }
8692  }
8693  else
8694  {
8695  --position.chars_read_current_line;
8696  }
8697 
8698  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8699  {
8700  JSON_ASSERT(!token_string.empty());
8701  token_string.pop_back();
8702  }
8703  }
8704 
8707  {
8708  token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8709  }
8710 
8711  public:
8713  // value getters
8715 
8717  constexpr number_integer_t get_number_integer() const noexcept
8718  {
8719  return value_integer;
8720  }
8721 
8723  constexpr number_unsigned_t get_number_unsigned() const noexcept
8724  {
8725  return value_unsigned;
8726  }
8727 
8729  constexpr number_float_t get_number_float() const noexcept
8730  {
8731  return value_float;
8732  }
8733 
8736  {
8737  return token_buffer;
8738  }
8739 
8741  // diagnostics
8743 
8745  constexpr position_t get_position() const noexcept
8746  {
8747  return position;
8748  }
8749 
8753  std::string get_token_string() const
8754  {
8755  // escape control characters
8756  std::string result;
8757  for (const auto c : token_string)
8758  {
8759  if (static_cast<unsigned char>(c) <= '\x1F')
8760  {
8761  // escape control characters
8762  std::array<char, 9> cs{{}};
8763  static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8764  result += cs.data();
8765  }
8766  else
8767  {
8768  // add character as is
8769  result.push_back(static_cast<std::string::value_type>(c));
8770  }
8771  }
8772 
8773  return result;
8774  }
8775 
8778  constexpr const char* get_error_message() const noexcept
8779  {
8780  return error_message;
8781  }
8782 
8784  // actual scanner
8786 
8791  bool skip_bom()
8792  {
8793  if (get() == 0xEF)
8794  {
8795  // check if we completely parse the BOM
8796  return get() == 0xBB && get() == 0xBF;
8797  }
8798 
8799  // the first character is not the beginning of the BOM; unget it to
8800  // process is later
8801  unget();
8802  return true;
8803  }
8804 
8806  {
8807  do
8808  {
8809  get();
8810  }
8811  while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8812  }
8813 
8815  {
8816  // initially, skip the BOM
8817  if (position.chars_read_total == 0 && !skip_bom())
8818  {
8819  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8820  return token_type::parse_error;
8821  }
8822 
8823  // read next character and ignore whitespace
8824  skip_whitespace();
8825 
8826  // ignore comments
8827  while (ignore_comments && current == '/')
8828  {
8829  if (!scan_comment())
8830  {
8831  return token_type::parse_error;
8832  }
8833 
8834  // skip following whitespace
8835  skip_whitespace();
8836  }
8837 
8838  switch (current)
8839  {
8840  // structural characters
8841  case '[':
8842  return token_type::begin_array;
8843  case ']':
8844  return token_type::end_array;
8845  case '{':
8846  return token_type::begin_object;
8847  case '}':
8848  return token_type::end_object;
8849  case ':':
8850  return token_type::name_separator;
8851  case ',':
8852  return token_type::value_separator;
8853 
8854  // literals
8855  case 't':
8856  {
8857  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')}};
8858  return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8859  }
8860  case 'f':
8861  {
8862  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')}};
8863  return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8864  }
8865  case 'n':
8866  {
8867  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')}};
8868  return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8869  }
8870 
8871  // string
8872  case '\"':
8873  return scan_string();
8874 
8875  // number
8876  case '-':
8877  case '0':
8878  case '1':
8879  case '2':
8880  case '3':
8881  case '4':
8882  case '5':
8883  case '6':
8884  case '7':
8885  case '8':
8886  case '9':
8887  return scan_number();
8888 
8889  // end of input (the null byte is needed when parsing from
8890  // string literals)
8891  case '\0':
8892  case std::char_traits<char_type>::eof():
8893  return token_type::end_of_input;
8894 
8895  // error
8896  default:
8897  error_message = "invalid literal";
8898  return token_type::parse_error;
8899  }
8900  }
8901 
8902  private:
8904  InputAdapterType ia;
8905 
8907  const bool ignore_comments = false;
8908 
8910  char_int_type current = std::char_traits<char_type>::eof();
8911 
8913  bool next_unget = false;
8914 
8916  position_t position {};
8917 
8919  std::vector<char_type> token_string {};
8920 
8922  string_t token_buffer {};
8923 
8925  const char* error_message = "";
8926 
8927  // number values
8928  number_integer_t value_integer = 0;
8929  number_unsigned_t value_unsigned = 0;
8930  number_float_t value_float = 0;
8931 
8933  const char_int_type decimal_point_char = '.';
8934 };
8935 
8936 } // namespace detail
8938 
8939 // #include <nlohmann/detail/macro_scope.hpp>
8940 
8941 // #include <nlohmann/detail/meta/is_sax.hpp>
8942 // __ _____ _____ _____
8943 // __| | __| | | | JSON for Modern C++
8944 // | | |__ | | | | | | version 3.11.2
8945 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
8946 //
8947 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
8948 // SPDX-License-Identifier: MIT
8949 
8950 
8951 
8952 #include <cstdint> // size_t
8953 #include <utility> // declval
8954 #include <string> // string
8955 
8956 // #include <nlohmann/detail/abi_macros.hpp>
8957 
8958 // #include <nlohmann/detail/meta/detected.hpp>
8959 
8960 // #include <nlohmann/detail/meta/type_traits.hpp>
8961 
8962 
8964 namespace detail
8965 {
8966 
8967 template<typename T>
8968 using null_function_t = decltype(std::declval<T&>().null());
8969 
8970 template<typename T>
8971 using boolean_function_t =
8972  decltype(std::declval<T&>().boolean(std::declval<bool>()));
8973 
8974 template<typename T, typename Integer>
8976  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8977 
8978 template<typename T, typename Unsigned>
8980  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8981 
8982 template<typename T, typename Float, typename String>
8983 using number_float_function_t = decltype(std::declval<T&>().number_float(
8984  std::declval<Float>(), std::declval<const String&>()));
8985 
8986 template<typename T, typename String>
8987 using string_function_t =
8988  decltype(std::declval<T&>().string(std::declval<String&>()));
8989 
8990 template<typename T, typename Binary>
8991 using binary_function_t =
8992  decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8993 
8994 template<typename T>
8996  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8997 
8998 template<typename T, typename String>
8999 using key_function_t =
9000  decltype(std::declval<T&>().key(std::declval<String&>()));
9001 
9002 template<typename T>
9003 using end_object_function_t = decltype(std::declval<T&>().end_object());
9004 
9005 template<typename T>
9006 using start_array_function_t =
9007  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
9008 
9009 template<typename T>
9010 using end_array_function_t = decltype(std::declval<T&>().end_array());
9011 
9012 template<typename T, typename Exception>
9013 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
9014  std::declval<std::size_t>(), std::declval<const std::string&>(),
9015  std::declval<const Exception&>()));
9016 
9017 template<typename SAX, typename BasicJsonType>
9018 struct is_sax
9019 {
9020  private:
9022  "BasicJsonType must be of type basic_json<...>");
9023 
9024  using number_integer_t = typename BasicJsonType::number_integer_t;
9025  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9026  using number_float_t = typename BasicJsonType::number_float_t;
9027  using string_t = typename BasicJsonType::string_t;
9028  using binary_t = typename BasicJsonType::binary_t;
9029  using exception_t = typename BasicJsonType::exception;
9030 
9031  public:
9032  static constexpr bool value =
9046 };
9047 
9048 template<typename SAX, typename BasicJsonType>
9050 {
9051  private:
9053  "BasicJsonType must be of type basic_json<...>");
9054 
9055  using number_integer_t = typename BasicJsonType::number_integer_t;
9056  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9057  using number_float_t = typename BasicJsonType::number_float_t;
9058  using string_t = typename BasicJsonType::string_t;
9059  using binary_t = typename BasicJsonType::binary_t;
9060  using exception_t = typename BasicJsonType::exception;
9061 
9062  public:
9064  "Missing/invalid function: bool null()");
9066  "Missing/invalid function: bool boolean(bool)");
9068  "Missing/invalid function: bool boolean(bool)");
9069  static_assert(
9071  number_integer_t>::value,
9072  "Missing/invalid function: bool number_integer(number_integer_t)");
9073  static_assert(
9075  number_unsigned_t>::value,
9076  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
9077  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
9078  number_float_t, string_t>::value,
9079  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
9080  static_assert(
9082  "Missing/invalid function: bool string(string_t&)");
9083  static_assert(
9085  "Missing/invalid function: bool binary(binary_t&)");
9087  "Missing/invalid function: bool start_object(std::size_t)");
9089  "Missing/invalid function: bool key(string_t&)");
9091  "Missing/invalid function: bool end_object()");
9093  "Missing/invalid function: bool start_array(std::size_t)");
9095  "Missing/invalid function: bool end_array()");
9096  static_assert(
9098  "Missing/invalid function: bool parse_error(std::size_t, const "
9099  "std::string&, const exception&)");
9100 };
9101 
9102 } // namespace detail
9104 
9105 // #include <nlohmann/detail/meta/type_traits.hpp>
9106 
9107 // #include <nlohmann/detail/string_concat.hpp>
9108 
9109 // #include <nlohmann/detail/value_t.hpp>
9110 
9111 
9113 namespace detail
9114 {
9115 
9118 {
9119  error,
9120  ignore,
9121  store
9122 };
9123 
9131 static inline bool little_endianness(int num = 1) noexcept
9132 {
9133  return *reinterpret_cast<char*>(&num) == 1;
9134 }
9135 
9136 
9138 // binary reader //
9140 
9144 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
9146 {
9147  using number_integer_t = typename BasicJsonType::number_integer_t;
9148  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9149  using number_float_t = typename BasicJsonType::number_float_t;
9150  using string_t = typename BasicJsonType::string_t;
9151  using binary_t = typename BasicJsonType::binary_t;
9152  using json_sax_t = SAX;
9153  using char_type = typename InputAdapterType::char_type;
9154  using char_int_type = typename std::char_traits<char_type>::int_type;
9155 
9156  public:
9162  explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
9163  {
9165  }
9166 
9167  // make class move-only
9168  binary_reader(const binary_reader&) = delete;
9169  binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9170  binary_reader& operator=(const binary_reader&) = delete;
9171  binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9172  ~binary_reader() = default;
9173 
9183  bool sax_parse(const input_format_t format,
9184  json_sax_t* sax_,
9185  const bool strict = true,
9186  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
9187  {
9188  sax = sax_;
9189  bool result = false;
9190 
9191  switch (format)
9192  {
9193  case input_format_t::bson:
9194  result = parse_bson_internal();
9195  break;
9196 
9197  case input_format_t::cbor:
9198  result = parse_cbor_internal(true, tag_handler);
9199  break;
9200 
9201  case input_format_t::msgpack:
9202  result = parse_msgpack_internal();
9203  break;
9204 
9205  case input_format_t::ubjson:
9206  case input_format_t::bjdata:
9207  result = parse_ubjson_internal();
9208  break;
9209 
9210  case input_format_t::json: // LCOV_EXCL_LINE
9211  default: // LCOV_EXCL_LINE
9212  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9213  }
9214 
9215  // strict mode: next byte must be EOF
9216  if (result && strict)
9217  {
9218  if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
9219  {
9220  get_ignore_noop();
9221  }
9222  else
9223  {
9224  get();
9225  }
9226 
9227  if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
9228  {
9229  return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
9230  exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
9231  }
9232  }
9233 
9234  return result;
9235  }
9236 
9237  private:
9239  // BSON //
9241 
9247  {
9248  std::int32_t document_size{};
9249  get_number<std::int32_t, true>(input_format_t::bson, document_size);
9250 
9251  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
9252  {
9253  return false;
9254  }
9255 
9256  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
9257  {
9258  return false;
9259  }
9260 
9261  return sax->end_object();
9262  }
9263 
9271  bool get_bson_cstr(string_t& result)
9272  {
9273  auto out = std::back_inserter(result);
9274  while (true)
9275  {
9276  get();
9277  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
9278  {
9279  return false;
9280  }
9281  if (current == 0x00)
9282  {
9283  return true;
9284  }
9285  *out++ = static_cast<typename string_t::value_type>(current);
9286  }
9287  }
9288 
9300  template<typename NumberType>
9301  bool get_bson_string(const NumberType len, string_t& result)
9302  {
9303  if (JSON_HEDLEY_UNLIKELY(len < 1))
9304  {
9305  auto last_token = get_token_string();
9306  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9307  exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
9308  }
9309 
9310  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
9311  }
9312 
9322  template<typename NumberType>
9323  bool get_bson_binary(const NumberType len, binary_t& result)
9324  {
9325  if (JSON_HEDLEY_UNLIKELY(len < 0))
9326  {
9327  auto last_token = get_token_string();
9328  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9329  exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
9330  }
9331 
9332  // All BSON binary values have a subtype
9333  std::uint8_t subtype{};
9334  get_number<std::uint8_t>(input_format_t::bson, subtype);
9335  result.set_subtype(subtype);
9336 
9337  return get_binary(input_format_t::bson, len, result);
9338  }
9339 
9351  const std::size_t element_type_parse_position)
9352  {
9353  switch (element_type)
9354  {
9355  case 0x01: // double
9356  {
9357  double number{};
9358  return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9359  }
9360 
9361  case 0x02: // string
9362  {
9363  std::int32_t len{};
9364  string_t value;
9365  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
9366  }
9367 
9368  case 0x03: // object
9369  {
9370  return parse_bson_internal();
9371  }
9372 
9373  case 0x04: // array
9374  {
9375  return parse_bson_array();
9376  }
9377 
9378  case 0x05: // binary
9379  {
9380  std::int32_t len{};
9381  binary_t value;
9382  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
9383  }
9384 
9385  case 0x08: // boolean
9386  {
9387  return sax->boolean(get() != 0);
9388  }
9389 
9390  case 0x0A: // null
9391  {
9392  return sax->null();
9393  }
9394 
9395  case 0x10: // int32
9396  {
9397  std::int32_t value{};
9398  return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9399  }
9400 
9401  case 0x12: // int64
9402  {
9403  std::int64_t value{};
9404  return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9405  }
9406 
9407  default: // anything else not supported (yet)
9408  {
9409  std::array<char, 3> cr{{}};
9410  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
9411  const std::string cr_str{cr.data()};
9412  return sax->parse_error(element_type_parse_position, cr_str,
9413  parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
9414  }
9415  }
9416  }
9417 
9430  bool parse_bson_element_list(const bool is_array)
9431  {
9432  string_t key;
9433 
9434  while (auto element_type = get())
9435  {
9436  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
9437  {
9438  return false;
9439  }
9440 
9441  const std::size_t element_type_parse_position = chars_read;
9442  if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
9443  {
9444  return false;
9445  }
9446 
9447  if (!is_array && !sax->key(key))
9448  {
9449  return false;
9450  }
9451 
9452  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
9453  {
9454  return false;
9455  }
9456 
9457  // get_bson_cstr only appends
9458  key.clear();
9459  }
9460 
9461  return true;
9462  }
9463 
9469  {
9470  std::int32_t document_size{};
9471  get_number<std::int32_t, true>(input_format_t::bson, document_size);
9472 
9473  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
9474  {
9475  return false;
9476  }
9477 
9478  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
9479  {
9480  return false;
9481  }
9482 
9483  return sax->end_array();
9484  }
9485 
9487  // CBOR //
9489 
9498  bool parse_cbor_internal(const bool get_char,
9499  const cbor_tag_handler_t tag_handler)
9500  {
9501  switch (get_char ? get() : current)
9502  {
9503  // EOF
9504  case std::char_traits<char_type>::eof():
9505  return unexpect_eof(input_format_t::cbor, "value");
9506 
9507  // Integer 0x00..0x17 (0..23)
9508  case 0x00:
9509  case 0x01:
9510  case 0x02:
9511  case 0x03:
9512  case 0x04:
9513  case 0x05:
9514  case 0x06:
9515  case 0x07:
9516  case 0x08:
9517  case 0x09:
9518  case 0x0A:
9519  case 0x0B:
9520  case 0x0C:
9521  case 0x0D:
9522  case 0x0E:
9523  case 0x0F:
9524  case 0x10:
9525  case 0x11:
9526  case 0x12:
9527  case 0x13:
9528  case 0x14:
9529  case 0x15:
9530  case 0x16:
9531  case 0x17:
9532  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9533 
9534  case 0x18: // Unsigned integer (one-byte uint8_t follows)
9535  {
9536  std::uint8_t number{};
9537  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9538  }
9539 
9540  case 0x19: // Unsigned integer (two-byte uint16_t follows)
9541  {
9542  std::uint16_t number{};
9543  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9544  }
9545 
9546  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
9547  {
9548  std::uint32_t number{};
9549  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9550  }
9551 
9552  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
9553  {
9554  std::uint64_t number{};
9555  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9556  }
9557 
9558  // Negative integer -1-0x00..-1-0x17 (-1..-24)
9559  case 0x20:
9560  case 0x21:
9561  case 0x22:
9562  case 0x23:
9563  case 0x24:
9564  case 0x25:
9565  case 0x26:
9566  case 0x27:
9567  case 0x28:
9568  case 0x29:
9569  case 0x2A:
9570  case 0x2B:
9571  case 0x2C:
9572  case 0x2D:
9573  case 0x2E:
9574  case 0x2F:
9575  case 0x30:
9576  case 0x31:
9577  case 0x32:
9578  case 0x33:
9579  case 0x34:
9580  case 0x35:
9581  case 0x36:
9582  case 0x37:
9583  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
9584 
9585  case 0x38: // Negative integer (one-byte uint8_t follows)
9586  {
9587  std::uint8_t number{};
9588  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9589  }
9590 
9591  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
9592  {
9593  std::uint16_t number{};
9594  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9595  }
9596 
9597  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
9598  {
9599  std::uint32_t number{};
9600  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9601  }
9602 
9603  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
9604  {
9605  std::uint64_t number{};
9606  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
9607  - static_cast<number_integer_t>(number));
9608  }
9609 
9610  // Binary data (0x00..0x17 bytes follow)
9611  case 0x40:
9612  case 0x41:
9613  case 0x42:
9614  case 0x43:
9615  case 0x44:
9616  case 0x45:
9617  case 0x46:
9618  case 0x47:
9619  case 0x48:
9620  case 0x49:
9621  case 0x4A:
9622  case 0x4B:
9623  case 0x4C:
9624  case 0x4D:
9625  case 0x4E:
9626  case 0x4F:
9627  case 0x50:
9628  case 0x51:
9629  case 0x52:
9630  case 0x53:
9631  case 0x54:
9632  case 0x55:
9633  case 0x56:
9634  case 0x57:
9635  case 0x58: // Binary data (one-byte uint8_t for n follows)
9636  case 0x59: // Binary data (two-byte uint16_t for n follow)
9637  case 0x5A: // Binary data (four-byte uint32_t for n follow)
9638  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9639  case 0x5F: // Binary data (indefinite length)
9640  {
9641  binary_t b;
9642  return get_cbor_binary(b) && sax->binary(b);
9643  }
9644 
9645  // UTF-8 string (0x00..0x17 bytes follow)
9646  case 0x60:
9647  case 0x61:
9648  case 0x62:
9649  case 0x63:
9650  case 0x64:
9651  case 0x65:
9652  case 0x66:
9653  case 0x67:
9654  case 0x68:
9655  case 0x69:
9656  case 0x6A:
9657  case 0x6B:
9658  case 0x6C:
9659  case 0x6D:
9660  case 0x6E:
9661  case 0x6F:
9662  case 0x70:
9663  case 0x71:
9664  case 0x72:
9665  case 0x73:
9666  case 0x74:
9667  case 0x75:
9668  case 0x76:
9669  case 0x77:
9670  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9671  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9672  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9673  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9674  case 0x7F: // UTF-8 string (indefinite length)
9675  {
9676  string_t s;
9677  return get_cbor_string(s) && sax->string(s);
9678  }
9679 
9680  // array (0x00..0x17 data items follow)
9681  case 0x80:
9682  case 0x81:
9683  case 0x82:
9684  case 0x83:
9685  case 0x84:
9686  case 0x85:
9687  case 0x86:
9688  case 0x87:
9689  case 0x88:
9690  case 0x89:
9691  case 0x8A:
9692  case 0x8B:
9693  case 0x8C:
9694  case 0x8D:
9695  case 0x8E:
9696  case 0x8F:
9697  case 0x90:
9698  case 0x91:
9699  case 0x92:
9700  case 0x93:
9701  case 0x94:
9702  case 0x95:
9703  case 0x96:
9704  case 0x97:
9705  return get_cbor_array(
9706  conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9707 
9708  case 0x98: // array (one-byte uint8_t for n follows)
9709  {
9710  std::uint8_t len{};
9711  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9712  }
9713 
9714  case 0x99: // array (two-byte uint16_t for n follow)
9715  {
9716  std::uint16_t len{};
9717  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9718  }
9719 
9720  case 0x9A: // array (four-byte uint32_t for n follow)
9721  {
9722  std::uint32_t len{};
9723  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9724  }
9725 
9726  case 0x9B: // array (eight-byte uint64_t for n follow)
9727  {
9728  std::uint64_t len{};
9729  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9730  }
9731 
9732  case 0x9F: // array (indefinite length)
9733  return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9734 
9735  // map (0x00..0x17 pairs of data items follow)
9736  case 0xA0:
9737  case 0xA1:
9738  case 0xA2:
9739  case 0xA3:
9740  case 0xA4:
9741  case 0xA5:
9742  case 0xA6:
9743  case 0xA7:
9744  case 0xA8:
9745  case 0xA9:
9746  case 0xAA:
9747  case 0xAB:
9748  case 0xAC:
9749  case 0xAD:
9750  case 0xAE:
9751  case 0xAF:
9752  case 0xB0:
9753  case 0xB1:
9754  case 0xB2:
9755  case 0xB3:
9756  case 0xB4:
9757  case 0xB5:
9758  case 0xB6:
9759  case 0xB7:
9760  return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9761 
9762  case 0xB8: // map (one-byte uint8_t for n follows)
9763  {
9764  std::uint8_t len{};
9765  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9766  }
9767 
9768  case 0xB9: // map (two-byte uint16_t for n follow)
9769  {
9770  std::uint16_t len{};
9771  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9772  }
9773 
9774  case 0xBA: // map (four-byte uint32_t for n follow)
9775  {
9776  std::uint32_t len{};
9777  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9778  }
9779 
9780  case 0xBB: // map (eight-byte uint64_t for n follow)
9781  {
9782  std::uint64_t len{};
9783  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9784  }
9785 
9786  case 0xBF: // map (indefinite length)
9787  return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9788 
9789  case 0xC6: // tagged item
9790  case 0xC7:
9791  case 0xC8:
9792  case 0xC9:
9793  case 0xCA:
9794  case 0xCB:
9795  case 0xCC:
9796  case 0xCD:
9797  case 0xCE:
9798  case 0xCF:
9799  case 0xD0:
9800  case 0xD1:
9801  case 0xD2:
9802  case 0xD3:
9803  case 0xD4:
9804  case 0xD8: // tagged item (1 bytes follow)
9805  case 0xD9: // tagged item (2 bytes follow)
9806  case 0xDA: // tagged item (4 bytes follow)
9807  case 0xDB: // tagged item (8 bytes follow)
9808  {
9809  switch (tag_handler)
9810  {
9811  case cbor_tag_handler_t::error:
9812  {
9813  auto last_token = get_token_string();
9814  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9815  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9816  }
9817 
9818  case cbor_tag_handler_t::ignore:
9819  {
9820  // ignore binary subtype
9821  switch (current)
9822  {
9823  case 0xD8:
9824  {
9825  std::uint8_t subtype_to_ignore{};
9826  get_number(input_format_t::cbor, subtype_to_ignore);
9827  break;
9828  }
9829  case 0xD9:
9830  {
9831  std::uint16_t subtype_to_ignore{};
9832  get_number(input_format_t::cbor, subtype_to_ignore);
9833  break;
9834  }
9835  case 0xDA:
9836  {
9837  std::uint32_t subtype_to_ignore{};
9838  get_number(input_format_t::cbor, subtype_to_ignore);
9839  break;
9840  }
9841  case 0xDB:
9842  {
9843  std::uint64_t subtype_to_ignore{};
9844  get_number(input_format_t::cbor, subtype_to_ignore);
9845  break;
9846  }
9847  default:
9848  break;
9849  }
9850  return parse_cbor_internal(true, tag_handler);
9851  }
9852 
9853  case cbor_tag_handler_t::store:
9854  {
9855  binary_t b;
9856  // use binary subtype and store in binary container
9857  switch (current)
9858  {
9859  case 0xD8:
9860  {
9861  std::uint8_t subtype{};
9862  get_number(input_format_t::cbor, subtype);
9863  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9864  break;
9865  }
9866  case 0xD9:
9867  {
9868  std::uint16_t subtype{};
9869  get_number(input_format_t::cbor, subtype);
9870  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9871  break;
9872  }
9873  case 0xDA:
9874  {
9875  std::uint32_t subtype{};
9876  get_number(input_format_t::cbor, subtype);
9877  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9878  break;
9879  }
9880  case 0xDB:
9881  {
9882  std::uint64_t subtype{};
9883  get_number(input_format_t::cbor, subtype);
9884  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9885  break;
9886  }
9887  default:
9888  return parse_cbor_internal(true, tag_handler);
9889  }
9890  get();
9891  return get_cbor_binary(b) && sax->binary(b);
9892  }
9893 
9894  default: // LCOV_EXCL_LINE
9895  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9896  return false; // LCOV_EXCL_LINE
9897  }
9898  }
9899 
9900  case 0xF4: // false
9901  return sax->boolean(false);
9902 
9903  case 0xF5: // true
9904  return sax->boolean(true);
9905 
9906  case 0xF6: // null
9907  return sax->null();
9908 
9909  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9910  {
9911  const auto byte1_raw = get();
9912  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9913  {
9914  return false;
9915  }
9916  const auto byte2_raw = get();
9917  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9918  {
9919  return false;
9920  }
9921 
9922  const auto byte1 = static_cast<unsigned char>(byte1_raw);
9923  const auto byte2 = static_cast<unsigned char>(byte2_raw);
9924 
9925  // code from RFC 7049, Appendix D, Figure 3:
9926  // As half-precision floating-point numbers were only added
9927  // to IEEE 754 in 2008, today's programming platforms often
9928  // still only have limited support for them. It is very
9929  // easy to include at least decoding support for them even
9930  // without such support. An example of a small decoder for
9931  // half-precision floating-point numbers in the C language
9932  // is shown in Fig. 3.
9933  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9934  const double val = [&half]
9935  {
9936  const int exp = (half >> 10u) & 0x1Fu;
9937  const unsigned int mant = half & 0x3FFu;
9938  JSON_ASSERT(0 <= exp&& exp <= 32);
9939  JSON_ASSERT(mant <= 1024);
9940  switch (exp)
9941  {
9942  case 0:
9943  return std::ldexp(mant, -24);
9944  case 31:
9945  return (mant == 0)
9946  ? std::numeric_limits<double>::infinity()
9947  : std::numeric_limits<double>::quiet_NaN();
9948  default:
9949  return std::ldexp(mant + 1024, exp - 25);
9950  }
9951  }();
9952  return sax->number_float((half & 0x8000u) != 0
9953  ? static_cast<number_float_t>(-val)
9954  : static_cast<number_float_t>(val), "");
9955  }
9956 
9957  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9958  {
9959  float number{};
9960  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9961  }
9962 
9963  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9964  {
9965  double number{};
9966  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9967  }
9968 
9969  default: // anything else (0xFF is handled inside the other types)
9970  {
9971  auto last_token = get_token_string();
9972  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9973  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9974  }
9975  }
9976  }
9977 
9990  {
9991  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9992  {
9993  return false;
9994  }
9995 
9996  switch (current)
9997  {
9998  // UTF-8 string (0x00..0x17 bytes follow)
9999  case 0x60:
10000  case 0x61:
10001  case 0x62:
10002  case 0x63:
10003  case 0x64:
10004  case 0x65:
10005  case 0x66:
10006  case 0x67:
10007  case 0x68:
10008  case 0x69:
10009  case 0x6A:
10010  case 0x6B:
10011  case 0x6C:
10012  case 0x6D:
10013  case 0x6E:
10014  case 0x6F:
10015  case 0x70:
10016  case 0x71:
10017  case 0x72:
10018  case 0x73:
10019  case 0x74:
10020  case 0x75:
10021  case 0x76:
10022  case 0x77:
10023  {
10024  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10025  }
10026 
10027  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
10028  {
10029  std::uint8_t len{};
10030  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10031  }
10032 
10033  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
10034  {
10035  std::uint16_t len{};
10036  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10037  }
10038 
10039  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
10040  {
10041  std::uint32_t len{};
10042  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10043  }
10044 
10045  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
10046  {
10047  std::uint64_t len{};
10048  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10049  }
10050 
10051  case 0x7F: // UTF-8 string (indefinite length)
10052  {
10053  while (get() != 0xFF)
10054  {
10055  string_t chunk;
10056  if (!get_cbor_string(chunk))
10057  {
10058  return false;
10059  }
10060  result.append(chunk);
10061  }
10062  return true;
10063  }
10064 
10065  default:
10066  {
10067  auto last_token = get_token_string();
10068  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10069  exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
10070  }
10071  }
10072  }
10073 
10086  {
10087  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
10088  {
10089  return false;
10090  }
10091 
10092  switch (current)
10093  {
10094  // Binary data (0x00..0x17 bytes follow)
10095  case 0x40:
10096  case 0x41:
10097  case 0x42:
10098  case 0x43:
10099  case 0x44:
10100  case 0x45:
10101  case 0x46:
10102  case 0x47:
10103  case 0x48:
10104  case 0x49:
10105  case 0x4A:
10106  case 0x4B:
10107  case 0x4C:
10108  case 0x4D:
10109  case 0x4E:
10110  case 0x4F:
10111  case 0x50:
10112  case 0x51:
10113  case 0x52:
10114  case 0x53:
10115  case 0x54:
10116  case 0x55:
10117  case 0x56:
10118  case 0x57:
10119  {
10120  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10121  }
10122 
10123  case 0x58: // Binary data (one-byte uint8_t for n follows)
10124  {
10125  std::uint8_t len{};
10126  return get_number(input_format_t::cbor, len) &&
10127  get_binary(input_format_t::cbor, len, result);
10128  }
10129 
10130  case 0x59: // Binary data (two-byte uint16_t for n follow)
10131  {
10132  std::uint16_t len{};
10133  return get_number(input_format_t::cbor, len) &&
10134  get_binary(input_format_t::cbor, len, result);
10135  }
10136 
10137  case 0x5A: // Binary data (four-byte uint32_t for n follow)
10138  {
10139  std::uint32_t len{};
10140  return get_number(input_format_t::cbor, len) &&
10141  get_binary(input_format_t::cbor, len, result);
10142  }
10143 
10144  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10145  {
10146  std::uint64_t len{};
10147  return get_number(input_format_t::cbor, len) &&
10148  get_binary(input_format_t::cbor, len, result);
10149  }
10150 
10151  case 0x5F: // Binary data (indefinite length)
10152  {
10153  while (get() != 0xFF)
10154  {
10155  binary_t chunk;
10156  if (!get_cbor_binary(chunk))
10157  {
10158  return false;
10159  }
10160  result.insert(result.end(), chunk.begin(), chunk.end());
10161  }
10162  return true;
10163  }
10164 
10165  default:
10166  {
10167  auto last_token = get_token_string();
10168  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10169  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));
10170  }
10171  }
10172  }
10173 
10180  bool get_cbor_array(const std::size_t len,
10181  const cbor_tag_handler_t tag_handler)
10182  {
10183  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10184  {
10185  return false;
10186  }
10187 
10188  if (len != static_cast<std::size_t>(-1))
10189  {
10190  for (std::size_t i = 0; i < len; ++i)
10191  {
10192  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10193  {
10194  return false;
10195  }
10196  }
10197  }
10198  else
10199  {
10200  while (get() != 0xFF)
10201  {
10202  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
10203  {
10204  return false;
10205  }
10206  }
10207  }
10208 
10209  return sax->end_array();
10210  }
10211 
10218  bool get_cbor_object(const std::size_t len,
10219  const cbor_tag_handler_t tag_handler)
10220  {
10221  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10222  {
10223  return false;
10224  }
10225 
10226  if (len != 0)
10227  {
10228  string_t key;
10229  if (len != static_cast<std::size_t>(-1))
10230  {
10231  for (std::size_t i = 0; i < len; ++i)
10232  {
10233  get();
10234  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10235  {
10236  return false;
10237  }
10238 
10239  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10240  {
10241  return false;
10242  }
10243  key.clear();
10244  }
10245  }
10246  else
10247  {
10248  while (get() != 0xFF)
10249  {
10250  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10251  {
10252  return false;
10253  }
10254 
10255  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10256  {
10257  return false;
10258  }
10259  key.clear();
10260  }
10261  }
10262  }
10263 
10264  return sax->end_object();
10265  }
10266 
10268  // MsgPack //
10270 
10275  {
10276  switch (get())
10277  {
10278  // EOF
10279  case std::char_traits<char_type>::eof():
10280  return unexpect_eof(input_format_t::msgpack, "value");
10281 
10282  // positive fixint
10283  case 0x00:
10284  case 0x01:
10285  case 0x02:
10286  case 0x03:
10287  case 0x04:
10288  case 0x05:
10289  case 0x06:
10290  case 0x07:
10291  case 0x08:
10292  case 0x09:
10293  case 0x0A:
10294  case 0x0B:
10295  case 0x0C:
10296  case 0x0D:
10297  case 0x0E:
10298  case 0x0F:
10299  case 0x10:
10300  case 0x11:
10301  case 0x12:
10302  case 0x13:
10303  case 0x14:
10304  case 0x15:
10305  case 0x16:
10306  case 0x17:
10307  case 0x18:
10308  case 0x19:
10309  case 0x1A:
10310  case 0x1B:
10311  case 0x1C:
10312  case 0x1D:
10313  case 0x1E:
10314  case 0x1F:
10315  case 0x20:
10316  case 0x21:
10317  case 0x22:
10318  case 0x23:
10319  case 0x24:
10320  case 0x25:
10321  case 0x26:
10322  case 0x27:
10323  case 0x28:
10324  case 0x29:
10325  case 0x2A:
10326  case 0x2B:
10327  case 0x2C:
10328  case 0x2D:
10329  case 0x2E:
10330  case 0x2F:
10331  case 0x30:
10332  case 0x31:
10333  case 0x32:
10334  case 0x33:
10335  case 0x34:
10336  case 0x35:
10337  case 0x36:
10338  case 0x37:
10339  case 0x38:
10340  case 0x39:
10341  case 0x3A:
10342  case 0x3B:
10343  case 0x3C:
10344  case 0x3D:
10345  case 0x3E:
10346  case 0x3F:
10347  case 0x40:
10348  case 0x41:
10349  case 0x42:
10350  case 0x43:
10351  case 0x44:
10352  case 0x45:
10353  case 0x46:
10354  case 0x47:
10355  case 0x48:
10356  case 0x49:
10357  case 0x4A:
10358  case 0x4B:
10359  case 0x4C:
10360  case 0x4D:
10361  case 0x4E:
10362  case 0x4F:
10363  case 0x50:
10364  case 0x51:
10365  case 0x52:
10366  case 0x53:
10367  case 0x54:
10368  case 0x55:
10369  case 0x56:
10370  case 0x57:
10371  case 0x58:
10372  case 0x59:
10373  case 0x5A:
10374  case 0x5B:
10375  case 0x5C:
10376  case 0x5D:
10377  case 0x5E:
10378  case 0x5F:
10379  case 0x60:
10380  case 0x61:
10381  case 0x62:
10382  case 0x63:
10383  case 0x64:
10384  case 0x65:
10385  case 0x66:
10386  case 0x67:
10387  case 0x68:
10388  case 0x69:
10389  case 0x6A:
10390  case 0x6B:
10391  case 0x6C:
10392  case 0x6D:
10393  case 0x6E:
10394  case 0x6F:
10395  case 0x70:
10396  case 0x71:
10397  case 0x72:
10398  case 0x73:
10399  case 0x74:
10400  case 0x75:
10401  case 0x76:
10402  case 0x77:
10403  case 0x78:
10404  case 0x79:
10405  case 0x7A:
10406  case 0x7B:
10407  case 0x7C:
10408  case 0x7D:
10409  case 0x7E:
10410  case 0x7F:
10411  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
10412 
10413  // fixmap
10414  case 0x80:
10415  case 0x81:
10416  case 0x82:
10417  case 0x83:
10418  case 0x84:
10419  case 0x85:
10420  case 0x86:
10421  case 0x87:
10422  case 0x88:
10423  case 0x89:
10424  case 0x8A:
10425  case 0x8B:
10426  case 0x8C:
10427  case 0x8D:
10428  case 0x8E:
10429  case 0x8F:
10430  return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10431 
10432  // fixarray
10433  case 0x90:
10434  case 0x91:
10435  case 0x92:
10436  case 0x93:
10437  case 0x94:
10438  case 0x95:
10439  case 0x96:
10440  case 0x97:
10441  case 0x98:
10442  case 0x99:
10443  case 0x9A:
10444  case 0x9B:
10445  case 0x9C:
10446  case 0x9D:
10447  case 0x9E:
10448  case 0x9F:
10449  return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10450 
10451  // fixstr
10452  case 0xA0:
10453  case 0xA1:
10454  case 0xA2:
10455  case 0xA3:
10456  case 0xA4:
10457  case 0xA5:
10458  case 0xA6:
10459  case 0xA7:
10460  case 0xA8:
10461  case 0xA9:
10462  case 0xAA:
10463  case 0xAB:
10464  case 0xAC:
10465  case 0xAD:
10466  case 0xAE:
10467  case 0xAF:
10468  case 0xB0:
10469  case 0xB1:
10470  case 0xB2:
10471  case 0xB3:
10472  case 0xB4:
10473  case 0xB5:
10474  case 0xB6:
10475  case 0xB7:
10476  case 0xB8:
10477  case 0xB9:
10478  case 0xBA:
10479  case 0xBB:
10480  case 0xBC:
10481  case 0xBD:
10482  case 0xBE:
10483  case 0xBF:
10484  case 0xD9: // str 8
10485  case 0xDA: // str 16
10486  case 0xDB: // str 32
10487  {
10488  string_t s;
10489  return get_msgpack_string(s) && sax->string(s);
10490  }
10491 
10492  case 0xC0: // nil
10493  return sax->null();
10494 
10495  case 0xC2: // false
10496  return sax->boolean(false);
10497 
10498  case 0xC3: // true
10499  return sax->boolean(true);
10500 
10501  case 0xC4: // bin 8
10502  case 0xC5: // bin 16
10503  case 0xC6: // bin 32
10504  case 0xC7: // ext 8
10505  case 0xC8: // ext 16
10506  case 0xC9: // ext 32
10507  case 0xD4: // fixext 1
10508  case 0xD5: // fixext 2
10509  case 0xD6: // fixext 4
10510  case 0xD7: // fixext 8
10511  case 0xD8: // fixext 16
10512  {
10513  binary_t b;
10514  return get_msgpack_binary(b) && sax->binary(b);
10515  }
10516 
10517  case 0xCA: // float 32
10518  {
10519  float number{};
10520  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10521  }
10522 
10523  case 0xCB: // float 64
10524  {
10525  double number{};
10526  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10527  }
10528 
10529  case 0xCC: // uint 8
10530  {
10531  std::uint8_t number{};
10532  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10533  }
10534 
10535  case 0xCD: // uint 16
10536  {
10537  std::uint16_t number{};
10538  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10539  }
10540 
10541  case 0xCE: // uint 32
10542  {
10543  std::uint32_t number{};
10544  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10545  }
10546 
10547  case 0xCF: // uint 64
10548  {
10549  std::uint64_t number{};
10550  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10551  }
10552 
10553  case 0xD0: // int 8
10554  {
10555  std::int8_t number{};
10556  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10557  }
10558 
10559  case 0xD1: // int 16
10560  {
10561  std::int16_t number{};
10562  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10563  }
10564 
10565  case 0xD2: // int 32
10566  {
10567  std::int32_t number{};
10568  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10569  }
10570 
10571  case 0xD3: // int 64
10572  {
10573  std::int64_t number{};
10574  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10575  }
10576 
10577  case 0xDC: // array 16
10578  {
10579  std::uint16_t len{};
10580  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
10581  }
10582 
10583  case 0xDD: // array 32
10584  {
10585  std::uint32_t len{};
10586  return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));
10587  }
10588 
10589  case 0xDE: // map 16
10590  {
10591  std::uint16_t len{};
10592  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
10593  }
10594 
10595  case 0xDF: // map 32
10596  {
10597  std::uint32_t len{};
10598  return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));
10599  }
10600 
10601  // negative fixint
10602  case 0xE0:
10603  case 0xE1:
10604  case 0xE2:
10605  case 0xE3:
10606  case 0xE4:
10607  case 0xE5:
10608  case 0xE6:
10609  case 0xE7:
10610  case 0xE8:
10611  case 0xE9:
10612  case 0xEA:
10613  case 0xEB:
10614  case 0xEC:
10615  case 0xED:
10616  case 0xEE:
10617  case 0xEF:
10618  case 0xF0:
10619  case 0xF1:
10620  case 0xF2:
10621  case 0xF3:
10622  case 0xF4:
10623  case 0xF5:
10624  case 0xF6:
10625  case 0xF7:
10626  case 0xF8:
10627  case 0xF9:
10628  case 0xFA:
10629  case 0xFB:
10630  case 0xFC:
10631  case 0xFD:
10632  case 0xFE:
10633  case 0xFF:
10634  return sax->number_integer(static_cast<std::int8_t>(current));
10635 
10636  default: // anything else
10637  {
10638  auto last_token = get_token_string();
10639  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10640  exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10641  }
10642  }
10643  }
10644 
10656  {
10657  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
10658  {
10659  return false;
10660  }
10661 
10662  switch (current)
10663  {
10664  // fixstr
10665  case 0xA0:
10666  case 0xA1:
10667  case 0xA2:
10668  case 0xA3:
10669  case 0xA4:
10670  case 0xA5:
10671  case 0xA6:
10672  case 0xA7:
10673  case 0xA8:
10674  case 0xA9:
10675  case 0xAA:
10676  case 0xAB:
10677  case 0xAC:
10678  case 0xAD:
10679  case 0xAE:
10680  case 0xAF:
10681  case 0xB0:
10682  case 0xB1:
10683  case 0xB2:
10684  case 0xB3:
10685  case 0xB4:
10686  case 0xB5:
10687  case 0xB6:
10688  case 0xB7:
10689  case 0xB8:
10690  case 0xB9:
10691  case 0xBA:
10692  case 0xBB:
10693  case 0xBC:
10694  case 0xBD:
10695  case 0xBE:
10696  case 0xBF:
10697  {
10698  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10699  }
10700 
10701  case 0xD9: // str 8
10702  {
10703  std::uint8_t len{};
10704  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10705  }
10706 
10707  case 0xDA: // str 16
10708  {
10709  std::uint16_t len{};
10710  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10711  }
10712 
10713  case 0xDB: // str 32
10714  {
10715  std::uint32_t len{};
10716  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10717  }
10718 
10719  default:
10720  {
10721  auto last_token = get_token_string();
10722  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10723  exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10724  }
10725  }
10726  }
10727 
10739  {
10740  // helper function to set the subtype
10741  auto assign_and_return_true = [&result](std::int8_t subtype)
10742  {
10743  result.set_subtype(static_cast<std::uint8_t>(subtype));
10744  return true;
10745  };
10746 
10747  switch (current)
10748  {
10749  case 0xC4: // bin 8
10750  {
10751  std::uint8_t len{};
10752  return get_number(input_format_t::msgpack, len) &&
10753  get_binary(input_format_t::msgpack, len, result);
10754  }
10755 
10756  case 0xC5: // bin 16
10757  {
10758  std::uint16_t len{};
10759  return get_number(input_format_t::msgpack, len) &&
10760  get_binary(input_format_t::msgpack, len, result);
10761  }
10762 
10763  case 0xC6: // bin 32
10764  {
10765  std::uint32_t len{};
10766  return get_number(input_format_t::msgpack, len) &&
10767  get_binary(input_format_t::msgpack, len, result);
10768  }
10769 
10770  case 0xC7: // ext 8
10771  {
10772  std::uint8_t len{};
10773  std::int8_t subtype{};
10774  return get_number(input_format_t::msgpack, len) &&
10775  get_number(input_format_t::msgpack, subtype) &&
10776  get_binary(input_format_t::msgpack, len, result) &&
10777  assign_and_return_true(subtype);
10778  }
10779 
10780  case 0xC8: // ext 16
10781  {
10782  std::uint16_t len{};
10783  std::int8_t subtype{};
10784  return get_number(input_format_t::msgpack, len) &&
10785  get_number(input_format_t::msgpack, subtype) &&
10786  get_binary(input_format_t::msgpack, len, result) &&
10787  assign_and_return_true(subtype);
10788  }
10789 
10790  case 0xC9: // ext 32
10791  {
10792  std::uint32_t len{};
10793  std::int8_t subtype{};
10794  return get_number(input_format_t::msgpack, len) &&
10795  get_number(input_format_t::msgpack, subtype) &&
10796  get_binary(input_format_t::msgpack, len, result) &&
10797  assign_and_return_true(subtype);
10798  }
10799 
10800  case 0xD4: // fixext 1
10801  {
10802  std::int8_t subtype{};
10803  return get_number(input_format_t::msgpack, subtype) &&
10804  get_binary(input_format_t::msgpack, 1, result) &&
10805  assign_and_return_true(subtype);
10806  }
10807 
10808  case 0xD5: // fixext 2
10809  {
10810  std::int8_t subtype{};
10811  return get_number(input_format_t::msgpack, subtype) &&
10812  get_binary(input_format_t::msgpack, 2, result) &&
10813  assign_and_return_true(subtype);
10814  }
10815 
10816  case 0xD6: // fixext 4
10817  {
10818  std::int8_t subtype{};
10819  return get_number(input_format_t::msgpack, subtype) &&
10820  get_binary(input_format_t::msgpack, 4, result) &&
10821  assign_and_return_true(subtype);
10822  }
10823 
10824  case 0xD7: // fixext 8
10825  {
10826  std::int8_t subtype{};
10827  return get_number(input_format_t::msgpack, subtype) &&
10828  get_binary(input_format_t::msgpack, 8, result) &&
10829  assign_and_return_true(subtype);
10830  }
10831 
10832  case 0xD8: // fixext 16
10833  {
10834  std::int8_t subtype{};
10835  return get_number(input_format_t::msgpack, subtype) &&
10836  get_binary(input_format_t::msgpack, 16, result) &&
10837  assign_and_return_true(subtype);
10838  }
10839 
10840  default: // LCOV_EXCL_LINE
10841  return false; // LCOV_EXCL_LINE
10842  }
10843  }
10844 
10849  bool get_msgpack_array(const std::size_t len)
10850  {
10851  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10852  {
10853  return false;
10854  }
10855 
10856  for (std::size_t i = 0; i < len; ++i)
10857  {
10858  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10859  {
10860  return false;
10861  }
10862  }
10863 
10864  return sax->end_array();
10865  }
10866 
10871  bool get_msgpack_object(const std::size_t len)
10872  {
10873  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10874  {
10875  return false;
10876  }
10877 
10878  string_t key;
10879  for (std::size_t i = 0; i < len; ++i)
10880  {
10881  get();
10882  if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10883  {
10884  return false;
10885  }
10886 
10887  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10888  {
10889  return false;
10890  }
10891  key.clear();
10892  }
10893 
10894  return sax->end_object();
10895  }
10896 
10898  // UBJSON //
10900 
10908  bool parse_ubjson_internal(const bool get_char = true)
10909  {
10910  return get_ubjson_value(get_char ? get_ignore_noop() : current);
10911  }
10912 
10927  bool get_ubjson_string(string_t& result, const bool get_char = true)
10928  {
10929  if (get_char)
10930  {
10931  get(); // TODO(niels): may we ignore N here?
10932  }
10933 
10934  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10935  {
10936  return false;
10937  }
10938 
10939  switch (current)
10940  {
10941  case 'U':
10942  {
10943  std::uint8_t len{};
10944  return get_number(input_format, len) && get_string(input_format, len, result);
10945  }
10946 
10947  case 'i':
10948  {
10949  std::int8_t len{};
10950  return get_number(input_format, len) && get_string(input_format, len, result);
10951  }
10952 
10953  case 'I':
10954  {
10955  std::int16_t len{};
10956  return get_number(input_format, len) && get_string(input_format, len, result);
10957  }
10958 
10959  case 'l':
10960  {
10961  std::int32_t len{};
10962  return get_number(input_format, len) && get_string(input_format, len, result);
10963  }
10964 
10965  case 'L':
10966  {
10967  std::int64_t len{};
10968  return get_number(input_format, len) && get_string(input_format, len, result);
10969  }
10970 
10971  case 'u':
10972  {
10973  if (input_format != input_format_t::bjdata)
10974  {
10975  break;
10976  }
10977  std::uint16_t len{};
10978  return get_number(input_format, len) && get_string(input_format, len, result);
10979  }
10980 
10981  case 'm':
10982  {
10983  if (input_format != input_format_t::bjdata)
10984  {
10985  break;
10986  }
10987  std::uint32_t len{};
10988  return get_number(input_format, len) && get_string(input_format, len, result);
10989  }
10990 
10991  case 'M':
10992  {
10993  if (input_format != input_format_t::bjdata)
10994  {
10995  break;
10996  }
10997  std::uint64_t len{};
10998  return get_number(input_format, len) && get_string(input_format, len, result);
10999  }
11000 
11001  default:
11002  break;
11003  }
11004  auto last_token = get_token_string();
11005  std::string message;
11006 
11007  if (input_format != input_format_t::bjdata)
11008  {
11009  message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
11010  }
11011  else
11012  {
11013  message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
11014  }
11015  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
11016  }
11017 
11022  bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
11023  {
11024  std::pair<std::size_t, char_int_type> size_and_type;
11025  size_t dimlen = 0;
11026  bool no_ndarray = true;
11027 
11028  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
11029  {
11030  return false;
11031  }
11032 
11033  if (size_and_type.first != npos)
11034  {
11035  if (size_and_type.second != 0)
11036  {
11037  if (size_and_type.second != 'N')
11038  {
11039  for (std::size_t i = 0; i < size_and_type.first; ++i)
11040  {
11041  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
11042  {
11043  return false;
11044  }
11045  dim.push_back(dimlen);
11046  }
11047  }
11048  }
11049  else
11050  {
11051  for (std::size_t i = 0; i < size_and_type.first; ++i)
11052  {
11053  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
11054  {
11055  return false;
11056  }
11057  dim.push_back(dimlen);
11058  }
11059  }
11060  }
11061  else
11062  {
11063  while (current != ']')
11064  {
11065  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
11066  {
11067  return false;
11068  }
11069  dim.push_back(dimlen);
11070  get_ignore_noop();
11071  }
11072  }
11073  return true;
11074  }
11075 
11087  bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
11088  {
11089  if (prefix == 0)
11090  {
11091  prefix = get_ignore_noop();
11092  }
11093 
11094  switch (prefix)
11095  {
11096  case 'U':
11097  {
11098  std::uint8_t number{};
11099  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11100  {
11101  return false;
11102  }
11103  result = static_cast<std::size_t>(number);
11104  return true;
11105  }
11106 
11107  case 'i':
11108  {
11109  std::int8_t number{};
11110  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11111  {
11112  return false;
11113  }
11114  if (number < 0)
11115  {
11116  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11117  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11118  }
11119  result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
11120  return true;
11121  }
11122 
11123  case 'I':
11124  {
11125  std::int16_t number{};
11126  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11127  {
11128  return false;
11129  }
11130  if (number < 0)
11131  {
11132  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11133  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11134  }
11135  result = static_cast<std::size_t>(number);
11136  return true;
11137  }
11138 
11139  case 'l':
11140  {
11141  std::int32_t number{};
11142  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11143  {
11144  return false;
11145  }
11146  if (number < 0)
11147  {
11148  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11149  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11150  }
11151  result = static_cast<std::size_t>(number);
11152  return true;
11153  }
11154 
11155  case 'L':
11156  {
11157  std::int64_t number{};
11158  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11159  {
11160  return false;
11161  }
11162  if (number < 0)
11163  {
11164  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11165  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11166  }
11167  if (!value_in_range_of<std::size_t>(number))
11168  {
11169  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11170  exception_message(input_format, "integer value overflow", "size"), nullptr));
11171  }
11172  result = static_cast<std::size_t>(number);
11173  return true;
11174  }
11175 
11176  case 'u':
11177  {
11178  if (input_format != input_format_t::bjdata)
11179  {
11180  break;
11181  }
11182  std::uint16_t number{};
11183  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11184  {
11185  return false;
11186  }
11187  result = static_cast<std::size_t>(number);
11188  return true;
11189  }
11190 
11191  case 'm':
11192  {
11193  if (input_format != input_format_t::bjdata)
11194  {
11195  break;
11196  }
11197  std::uint32_t number{};
11198  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11199  {
11200  return false;
11201  }
11202  result = conditional_static_cast<std::size_t>(number);
11203  return true;
11204  }
11205 
11206  case 'M':
11207  {
11208  if (input_format != input_format_t::bjdata)
11209  {
11210  break;
11211  }
11212  std::uint64_t number{};
11213  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11214  {
11215  return false;
11216  }
11217  if (!value_in_range_of<std::size_t>(number))
11218  {
11219  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11220  exception_message(input_format, "integer value overflow", "size"), nullptr));
11221  }
11222  result = detail::conditional_static_cast<std::size_t>(number);
11223  return true;
11224  }
11225 
11226  case '[':
11227  {
11228  if (input_format != input_format_t::bjdata)
11229  {
11230  break;
11231  }
11232  if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
11233  {
11234  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));
11235  }
11236  std::vector<size_t> dim;
11237  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
11238  {
11239  return false;
11240  }
11241  if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
11242  {
11243  result = dim.at(dim.size() - 1);
11244  return true;
11245  }
11246  if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
11247  {
11248  for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
11249  {
11250  if ( i == 0 )
11251  {
11252  result = 0;
11253  return true;
11254  }
11255  }
11256 
11257  string_t key = "_ArraySize_";
11258  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
11259  {
11260  return false;
11261  }
11262  result = 1;
11263  for (auto i : dim)
11264  {
11265  result *= i;
11266  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()
11267  {
11268  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));
11269  }
11270  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
11271  {
11272  return false;
11273  }
11274  }
11275  is_ndarray = true;
11276  return sax->end_array();
11277  }
11278  result = 0;
11279  return true;
11280  }
11281 
11282  default:
11283  break;
11284  }
11285  auto last_token = get_token_string();
11286  std::string message;
11287 
11288  if (input_format != input_format_t::bjdata)
11289  {
11290  message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
11291  }
11292  else
11293  {
11294  message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
11295  }
11296  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
11297  }
11298 
11310  bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
11311  {
11312  result.first = npos; // size
11313  result.second = 0; // type
11314  bool is_ndarray = false;
11315 
11316  get_ignore_noop();
11317 
11318  if (current == '$')
11319  {
11320  result.second = get(); // must not ignore 'N', because 'N' maybe the type
11321  if (input_format == input_format_t::bjdata
11322  && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
11323  {
11324  auto last_token = get_token_string();
11325  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11326  exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
11327  }
11328 
11329  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
11330  {
11331  return false;
11332  }
11333 
11334  get_ignore_noop();
11335  if (JSON_HEDLEY_UNLIKELY(current != '#'))
11336  {
11337  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
11338  {
11339  return false;
11340  }
11341  auto last_token = get_token_string();
11342  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11343  exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
11344  }
11345 
11346  const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11347  if (input_format == input_format_t::bjdata && is_ndarray)
11348  {
11349  if (inside_ndarray)
11350  {
11351  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11352  exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
11353  }
11354  result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
11355  }
11356  return is_error;
11357  }
11358 
11359  if (current == '#')
11360  {
11361  const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11362  if (input_format == input_format_t::bjdata && is_ndarray)
11363  {
11364  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11365  exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
11366  }
11367  return is_error;
11368  }
11369 
11370  return true;
11371  }
11372 
11377  bool get_ubjson_value(const char_int_type prefix)
11378  {
11379  switch (prefix)
11380  {
11381  case std::char_traits<char_type>::eof(): // EOF
11382  return unexpect_eof(input_format, "value");
11383 
11384  case 'T': // true
11385  return sax->boolean(true);
11386  case 'F': // false
11387  return sax->boolean(false);
11388 
11389  case 'Z': // null
11390  return sax->null();
11391 
11392  case 'U':
11393  {
11394  std::uint8_t number{};
11395  return get_number(input_format, number) && sax->number_unsigned(number);
11396  }
11397 
11398  case 'i':
11399  {
11400  std::int8_t number{};
11401  return get_number(input_format, number) && sax->number_integer(number);
11402  }
11403 
11404  case 'I':
11405  {
11406  std::int16_t number{};
11407  return get_number(input_format, number) && sax->number_integer(number);
11408  }
11409 
11410  case 'l':
11411  {
11412  std::int32_t number{};
11413  return get_number(input_format, number) && sax->number_integer(number);
11414  }
11415 
11416  case 'L':
11417  {
11418  std::int64_t number{};
11419  return get_number(input_format, number) && sax->number_integer(number);
11420  }
11421 
11422  case 'u':
11423  {
11424  if (input_format != input_format_t::bjdata)
11425  {
11426  break;
11427  }
11428  std::uint16_t number{};
11429  return get_number(input_format, number) && sax->number_unsigned(number);
11430  }
11431 
11432  case 'm':
11433  {
11434  if (input_format != input_format_t::bjdata)
11435  {
11436  break;
11437  }
11438  std::uint32_t number{};
11439  return get_number(input_format, number) && sax->number_unsigned(number);
11440  }
11441 
11442  case 'M':
11443  {
11444  if (input_format != input_format_t::bjdata)
11445  {
11446  break;
11447  }
11448  std::uint64_t number{};
11449  return get_number(input_format, number) && sax->number_unsigned(number);
11450  }
11451 
11452  case 'h':
11453  {
11454  if (input_format != input_format_t::bjdata)
11455  {
11456  break;
11457  }
11458  const auto byte1_raw = get();
11459  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11460  {
11461  return false;
11462  }
11463  const auto byte2_raw = get();
11464  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11465  {
11466  return false;
11467  }
11468 
11469  const auto byte1 = static_cast<unsigned char>(byte1_raw);
11470  const auto byte2 = static_cast<unsigned char>(byte2_raw);
11471 
11472  // code from RFC 7049, Appendix D, Figure 3:
11473  // As half-precision floating-point numbers were only added
11474  // to IEEE 754 in 2008, today's programming platforms often
11475  // still only have limited support for them. It is very
11476  // easy to include at least decoding support for them even
11477  // without such support. An example of a small decoder for
11478  // half-precision floating-point numbers in the C language
11479  // is shown in Fig. 3.
11480  const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
11481  const double val = [&half]
11482  {
11483  const int exp = (half >> 10u) & 0x1Fu;
11484  const unsigned int mant = half & 0x3FFu;
11485  JSON_ASSERT(0 <= exp&& exp <= 32);
11486  JSON_ASSERT(mant <= 1024);
11487  switch (exp)
11488  {
11489  case 0:
11490  return std::ldexp(mant, -24);
11491  case 31:
11492  return (mant == 0)
11493  ? std::numeric_limits<double>::infinity()
11494  : std::numeric_limits<double>::quiet_NaN();
11495  default:
11496  return std::ldexp(mant + 1024, exp - 25);
11497  }
11498  }();
11499  return sax->number_float((half & 0x8000u) != 0
11500  ? static_cast<number_float_t>(-val)
11501  : static_cast<number_float_t>(val), "");
11502  }
11503 
11504  case 'd':
11505  {
11506  float number{};
11507  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11508  }
11509 
11510  case 'D':
11511  {
11512  double number{};
11513  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11514  }
11515 
11516  case 'H':
11517  {
11518  return get_ubjson_high_precision_number();
11519  }
11520 
11521  case 'C': // char
11522  {
11523  get();
11524  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
11525  {
11526  return false;
11527  }
11528  if (JSON_HEDLEY_UNLIKELY(current > 127))
11529  {
11530  auto last_token = get_token_string();
11531  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11532  exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
11533  }
11534  string_t s(1, static_cast<typename string_t::value_type>(current));
11535  return sax->string(s);
11536  }
11537 
11538  case 'S': // string
11539  {
11540  string_t s;
11541  return get_ubjson_string(s) && sax->string(s);
11542  }
11543 
11544  case '[': // array
11545  return get_ubjson_array();
11546 
11547  case '{': // object
11548  return get_ubjson_object();
11549 
11550  default: // anything else
11551  break;
11552  }
11553  auto last_token = get_token_string();
11554  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));
11555  }
11556 
11561  {
11562  std::pair<std::size_t, char_int_type> size_and_type;
11563  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11564  {
11565  return false;
11566  }
11567 
11568  // 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):
11569  // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
11570 
11571  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11572  {
11573  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
11574  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)
11575  {
11576  return p.first < t;
11577  });
11578  string_t key = "_ArrayType_";
11579  if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
11580  {
11581  auto last_token = get_token_string();
11582  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11583  exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
11584  }
11585 
11586  string_t type = it->second; // sax->string() takes a reference
11587  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type)))
11588  {
11589  return false;
11590  }
11591 
11592  if (size_and_type.second == 'C')
11593  {
11594  size_and_type.second = 'U';
11595  }
11596 
11597  key = "_ArrayData_";
11598  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) ))
11599  {
11600  return false;
11601  }
11602 
11603  for (std::size_t i = 0; i < size_and_type.first; ++i)
11604  {
11605  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11606  {
11607  return false;
11608  }
11609  }
11610 
11611  return (sax->end_array() && sax->end_object());
11612  }
11613 
11614  if (size_and_type.first != npos)
11615  {
11616  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
11617  {
11618  return false;
11619  }
11620 
11621  if (size_and_type.second != 0)
11622  {
11623  if (size_and_type.second != 'N')
11624  {
11625  for (std::size_t i = 0; i < size_and_type.first; ++i)
11626  {
11627  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11628  {
11629  return false;
11630  }
11631  }
11632  }
11633  }
11634  else
11635  {
11636  for (std::size_t i = 0; i < size_and_type.first; ++i)
11637  {
11638  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11639  {
11640  return false;
11641  }
11642  }
11643  }
11644  }
11645  else
11646  {
11647  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11648  {
11649  return false;
11650  }
11651 
11652  while (current != ']')
11653  {
11654  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
11655  {
11656  return false;
11657  }
11658  get_ignore_noop();
11659  }
11660  }
11661 
11662  return sax->end_array();
11663  }
11664 
11669  {
11670  std::pair<std::size_t, char_int_type> size_and_type;
11671  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11672  {
11673  return false;
11674  }
11675 
11676  // do not accept ND-array size in objects in BJData
11677  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11678  {
11679  auto last_token = get_token_string();
11680  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11681  exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
11682  }
11683 
11684  string_t key;
11685  if (size_and_type.first != npos)
11686  {
11687  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
11688  {
11689  return false;
11690  }
11691 
11692  if (size_and_type.second != 0)
11693  {
11694  for (std::size_t i = 0; i < size_and_type.first; ++i)
11695  {
11696  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11697  {
11698  return false;
11699  }
11700  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11701  {
11702  return false;
11703  }
11704  key.clear();
11705  }
11706  }
11707  else
11708  {
11709  for (std::size_t i = 0; i < size_and_type.first; ++i)
11710  {
11711  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11712  {
11713  return false;
11714  }
11715  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11716  {
11717  return false;
11718  }
11719  key.clear();
11720  }
11721  }
11722  }
11723  else
11724  {
11725  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11726  {
11727  return false;
11728  }
11729 
11730  while (current != '}')
11731  {
11732  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11733  {
11734  return false;
11735  }
11736  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11737  {
11738  return false;
11739  }
11740  get_ignore_noop();
11741  key.clear();
11742  }
11743  }
11744 
11745  return sax->end_object();
11746  }
11747 
11748  // Note, no reader for UBJSON binary types is implemented because they do
11749  // not exist
11750 
11752  {
11753  // get size of following number string
11754  std::size_t size{};
11755  bool no_ndarray = true;
11756  auto res = get_ubjson_size_value(size, no_ndarray);
11757  if (JSON_HEDLEY_UNLIKELY(!res))
11758  {
11759  return res;
11760  }
11761 
11762  // get number string
11763  std::vector<char> number_vector;
11764  for (std::size_t i = 0; i < size; ++i)
11765  {
11766  get();
11767  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11768  {
11769  return false;
11770  }
11771  number_vector.push_back(static_cast<char>(current));
11772  }
11773 
11774  // parse number string
11775  using ia_type = decltype(detail::input_adapter(number_vector));
11776  auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11777  const auto result_number = number_lexer.scan();
11778  const auto number_string = number_lexer.get_token_string();
11779  const auto result_remainder = number_lexer.scan();
11780 
11781  using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11782 
11783  if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11784  {
11785  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11786  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11787  }
11788 
11789  switch (result_number)
11790  {
11791  case token_type::value_integer:
11792  return sax->number_integer(number_lexer.get_number_integer());
11793  case token_type::value_unsigned:
11794  return sax->number_unsigned(number_lexer.get_number_unsigned());
11795  case token_type::value_float:
11796  return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11797  case token_type::uninitialized:
11798  case token_type::literal_true:
11799  case token_type::literal_false:
11800  case token_type::literal_null:
11801  case token_type::value_string:
11802  case token_type::begin_array:
11803  case token_type::begin_object:
11804  case token_type::end_array:
11805  case token_type::end_object:
11806  case token_type::name_separator:
11807  case token_type::value_separator:
11808  case token_type::parse_error:
11809  case token_type::end_of_input:
11810  case token_type::literal_or_value:
11811  default:
11812  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11813  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11814  }
11815  }
11816 
11818  // Utility functions //
11820 
11831  {
11832  ++chars_read;
11833  return current = ia.get_character();
11834  }
11835 
11840  {
11841  do
11842  {
11843  get();
11844  }
11845  while (current == 'N');
11846 
11847  return current;
11848  }
11849 
11850  /*
11851  @brief read a number from the input
11852 
11853  @tparam NumberType the type of the number
11854  @param[in] format the current format (for diagnostics)
11855  @param[out] result number of type @a NumberType
11856 
11857  @return whether conversion completed
11858 
11859  @note This function needs to respect the system's endianness, because
11860  bytes in CBOR, MessagePack, and UBJSON are stored in network order
11861  (big endian) and therefore need reordering on little endian systems.
11862  On the other hand, BSON and BJData use little endian and should reorder
11863  on big endian systems.
11864  */
11865  template<typename NumberType, bool InputIsLittleEndian = false>
11866  bool get_number(const input_format_t format, NumberType& result)
11867  {
11868  // step 1: read input into array with system's byte order
11869  std::array<std::uint8_t, sizeof(NumberType)> vec{};
11870  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11871  {
11872  get();
11873  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11874  {
11875  return false;
11876  }
11877 
11878  // reverse byte order prior to conversion if necessary
11879  if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11880  {
11881  vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11882  }
11883  else
11884  {
11885  vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11886  }
11887  }
11888 
11889  // step 2: convert array into number of type T and return
11890  std::memcpy(&result, vec.data(), sizeof(NumberType));
11891  return true;
11892  }
11893 
11908  template<typename NumberType>
11909  bool get_string(const input_format_t format,
11910  const NumberType len,
11911  string_t& result)
11912  {
11913  bool success = true;
11914  for (NumberType i = 0; i < len; i++)
11915  {
11916  get();
11917  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11918  {
11919  success = false;
11920  break;
11921  }
11922  result.push_back(static_cast<typename string_t::value_type>(current));
11923  }
11924  return success;
11925  }
11926 
11941  template<typename NumberType>
11942  bool get_binary(const input_format_t format,
11943  const NumberType len,
11944  binary_t& result)
11945  {
11946  bool success = true;
11947  for (NumberType i = 0; i < len; i++)
11948  {
11949  get();
11950  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
11951  {
11952  success = false;
11953  break;
11954  }
11955  result.push_back(static_cast<std::uint8_t>(current));
11956  }
11957  return success;
11958  }
11959 
11966  bool unexpect_eof(const input_format_t format, const char* context) const
11967  {
11968  if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
11969  {
11970  return sax->parse_error(chars_read, "<end of file>",
11971  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
11972  }
11973  return true;
11974  }
11975 
11979  std::string get_token_string() const
11980  {
11981  std::array<char, 3> cr{{}};
11982  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
11983  return std::string{cr.data()};
11984  }
11985 
11992  std::string exception_message(const input_format_t format,
11993  const std::string& detail,
11994  const std::string& context) const
11995  {
11996  std::string error_msg = "syntax error while parsing ";
11997 
11998  switch (format)
11999  {
12000  case input_format_t::cbor:
12001  error_msg += "CBOR";
12002  break;
12003 
12004  case input_format_t::msgpack:
12005  error_msg += "MessagePack";
12006  break;
12007 
12008  case input_format_t::ubjson:
12009  error_msg += "UBJSON";
12010  break;
12011 
12012  case input_format_t::bson:
12013  error_msg += "BSON";
12014  break;
12015 
12016  case input_format_t::bjdata:
12017  error_msg += "BJData";
12018  break;
12019 
12020  case input_format_t::json: // LCOV_EXCL_LINE
12021  default: // LCOV_EXCL_LINE
12022  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
12023  }
12024 
12025  return concat(error_msg, ' ', context, ": ", detail);
12026  }
12027 
12028  private:
12029  static JSON_INLINE_VARIABLE constexpr std::size_t npos = static_cast<std::size_t>(-1);
12030 
12032  InputAdapterType ia;
12033 
12035  char_int_type current = std::char_traits<char_type>::eof();
12036 
12038  std::size_t chars_read = 0;
12039 
12041  const bool is_little_endian = little_endianness();
12042 
12044  const input_format_t input_format = input_format_t::json;
12045 
12047  json_sax_t* sax = nullptr;
12048 
12049  // excluded markers in bjdata optimized type
12050 #define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \
12051  make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
12052 
12053 #define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
12054  make_array<bjd_type>( \
12055  bjd_type{'C', "char"}, \
12056  bjd_type{'D', "double"}, \
12057  bjd_type{'I', "int16"}, \
12058  bjd_type{'L', "int64"}, \
12059  bjd_type{'M', "uint64"}, \
12060  bjd_type{'U', "uint8"}, \
12061  bjd_type{'d', "single"}, \
12062  bjd_type{'i', "int8"}, \
12063  bjd_type{'l', "int32"}, \
12064  bjd_type{'m', "uint32"}, \
12065  bjd_type{'u', "uint16"})
12066 
12068  // lookup tables
12069  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12070  const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =
12072 
12073  using bjd_type = std::pair<char_int_type, string_t>;
12074  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12075  const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map =
12077 
12078 #undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
12079 #undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
12080 };
12081 
12082 #ifndef JSON_HAS_CPP_17
12083  template<typename BasicJsonType, typename InputAdapterType, typename SAX>
12085 #endif
12086 
12087 } // namespace detail
12089 
12090 // #include <nlohmann/detail/input/input_adapters.hpp>
12091 
12092 // #include <nlohmann/detail/input/lexer.hpp>
12093 
12094 // #include <nlohmann/detail/input/parser.hpp>
12095 // __ _____ _____ _____
12096 // __| | __| | | | JSON for Modern C++
12097 // | | |__ | | | | | | version 3.11.2
12098 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12099 //
12100 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12101 // SPDX-License-Identifier: MIT
12102 
12103 
12104 
12105 #include <cmath> // isfinite
12106 #include <cstdint> // uint8_t
12107 #include <functional> // function
12108 #include <string> // string
12109 #include <utility> // move
12110 #include <vector> // vector
12111 
12112 // #include <nlohmann/detail/exceptions.hpp>
12113 
12114 // #include <nlohmann/detail/input/input_adapters.hpp>
12115 
12116 // #include <nlohmann/detail/input/json_sax.hpp>
12117 
12118 // #include <nlohmann/detail/input/lexer.hpp>
12119 
12120 // #include <nlohmann/detail/macro_scope.hpp>
12121 
12122 // #include <nlohmann/detail/meta/is_sax.hpp>
12123 
12124 // #include <nlohmann/detail/string_concat.hpp>
12125 
12126 // #include <nlohmann/detail/value_t.hpp>
12127 
12128 
12130 namespace detail
12131 {
12133 // parser //
12135 
12136 enum class parse_event_t : std::uint8_t
12137 {
12139  object_start,
12141  object_end,
12143  array_start,
12145  array_end,
12147  key,
12149  value
12150 };
12151 
12152 template<typename BasicJsonType>
12153 using parser_callback_t =
12154  std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
12155 
12161 template<typename BasicJsonType, typename InputAdapterType>
12162 class parser
12163 {
12164  using number_integer_t = typename BasicJsonType::number_integer_t;
12165  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12166  using number_float_t = typename BasicJsonType::number_float_t;
12167  using string_t = typename BasicJsonType::string_t;
12170 
12171  public:
12173  explicit parser(InputAdapterType&& adapter,
12174  const parser_callback_t<BasicJsonType> cb = nullptr,
12175  const bool allow_exceptions_ = true,
12176  const bool skip_comments = false)
12177  : callback(cb)
12178  , m_lexer(std::move(adapter), skip_comments)
12179  , allow_exceptions(allow_exceptions_)
12180  {
12181  // read first token
12182  get_token();
12183  }
12184 
12195  void parse(const bool strict, BasicJsonType& result)
12196  {
12197  if (callback)
12198  {
12199  json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
12200  sax_parse_internal(&sdp);
12201 
12202  // in strict mode, input must be completely read
12203  if (strict && (get_token() != token_type::end_of_input))
12204  {
12205  sdp.parse_error(m_lexer.get_position(),
12206  m_lexer.get_token_string(),
12207  parse_error::create(101, m_lexer.get_position(),
12208  exception_message(token_type::end_of_input, "value"), nullptr));
12209  }
12210 
12211  // in case of an error, return discarded value
12212  if (sdp.is_errored())
12213  {
12214  result = value_t::discarded;
12215  return;
12216  }
12217 
12218  // set top-level value to null if it was discarded by the callback
12219  // function
12220  if (result.is_discarded())
12221  {
12222  result = nullptr;
12223  }
12224  }
12225  else
12226  {
12227  json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
12228  sax_parse_internal(&sdp);
12229 
12230  // in strict mode, input must be completely read
12231  if (strict && (get_token() != token_type::end_of_input))
12232  {
12233  sdp.parse_error(m_lexer.get_position(),
12234  m_lexer.get_token_string(),
12235  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12236  }
12237 
12238  // in case of an error, return discarded value
12239  if (sdp.is_errored())
12240  {
12241  result = value_t::discarded;
12242  return;
12243  }
12244  }
12245 
12246  result.assert_invariant();
12247  }
12248 
12255  bool accept(const bool strict = true)
12256  {
12257  json_sax_acceptor<BasicJsonType> sax_acceptor;
12258  return sax_parse(&sax_acceptor, strict);
12259  }
12260 
12261  template<typename SAX>
12263  bool sax_parse(SAX* sax, const bool strict = true)
12264  {
12266  const bool result = sax_parse_internal(sax);
12267 
12268  // strict mode: next byte must be EOF
12269  if (result && strict && (get_token() != token_type::end_of_input))
12270  {
12271  return sax->parse_error(m_lexer.get_position(),
12272  m_lexer.get_token_string(),
12273  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12274  }
12275 
12276  return result;
12277  }
12278 
12279  private:
12280  template<typename SAX>
12282  bool sax_parse_internal(SAX* sax)
12283  {
12284  // stack to remember the hierarchy of structured values we are parsing
12285  // true = array; false = object
12286  std::vector<bool> states;
12287  // value to avoid a goto (see comment where set to true)
12288  bool skip_to_state_evaluation = false;
12289 
12290  while (true)
12291  {
12292  if (!skip_to_state_evaluation)
12293  {
12294  // invariant: get_token() was called before each iteration
12295  switch (last_token)
12296  {
12297  case token_type::begin_object:
12298  {
12299  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
12300  {
12301  return false;
12302  }
12303 
12304  // closing } -> we are done
12305  if (get_token() == token_type::end_object)
12306  {
12307  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12308  {
12309  return false;
12310  }
12311  break;
12312  }
12313 
12314  // parse key
12315  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
12316  {
12317  return sax->parse_error(m_lexer.get_position(),
12318  m_lexer.get_token_string(),
12319  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12320  }
12321  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12322  {
12323  return false;
12324  }
12325 
12326  // parse separator (:)
12327  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12328  {
12329  return sax->parse_error(m_lexer.get_position(),
12330  m_lexer.get_token_string(),
12331  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12332  }
12333 
12334  // remember we are now inside an object
12335  states.push_back(false);
12336 
12337  // parse values
12338  get_token();
12339  continue;
12340  }
12341 
12342  case token_type::begin_array:
12343  {
12344  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
12345  {
12346  return false;
12347  }
12348 
12349  // closing ] -> we are done
12350  if (get_token() == token_type::end_array)
12351  {
12352  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12353  {
12354  return false;
12355  }
12356  break;
12357  }
12358 
12359  // remember we are now inside an array
12360  states.push_back(true);
12361 
12362  // parse values (no need to call get_token)
12363  continue;
12364  }
12365 
12366  case token_type::value_float:
12367  {
12368  const auto res = m_lexer.get_number_float();
12369 
12370  if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
12371  {
12372  return sax->parse_error(m_lexer.get_position(),
12373  m_lexer.get_token_string(),
12374  out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
12375  }
12376 
12377  if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
12378  {
12379  return false;
12380  }
12381 
12382  break;
12383  }
12384 
12385  case token_type::literal_false:
12386  {
12387  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
12388  {
12389  return false;
12390  }
12391  break;
12392  }
12393 
12394  case token_type::literal_null:
12395  {
12396  if (JSON_HEDLEY_UNLIKELY(!sax->null()))
12397  {
12398  return false;
12399  }
12400  break;
12401  }
12402 
12403  case token_type::literal_true:
12404  {
12405  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
12406  {
12407  return false;
12408  }
12409  break;
12410  }
12411 
12412  case token_type::value_integer:
12413  {
12414  if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
12415  {
12416  return false;
12417  }
12418  break;
12419  }
12420 
12421  case token_type::value_string:
12422  {
12423  if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
12424  {
12425  return false;
12426  }
12427  break;
12428  }
12429 
12430  case token_type::value_unsigned:
12431  {
12432  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
12433  {
12434  return false;
12435  }
12436  break;
12437  }
12438 
12439  case token_type::parse_error:
12440  {
12441  // using "uninitialized" to avoid "expected" message
12442  return sax->parse_error(m_lexer.get_position(),
12443  m_lexer.get_token_string(),
12444  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
12445  }
12446 
12447  case token_type::uninitialized:
12448  case token_type::end_array:
12449  case token_type::end_object:
12450  case token_type::name_separator:
12451  case token_type::value_separator:
12452  case token_type::end_of_input:
12453  case token_type::literal_or_value:
12454  default: // the last token was unexpected
12455  {
12456  return sax->parse_error(m_lexer.get_position(),
12457  m_lexer.get_token_string(),
12458  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12459  }
12460  }
12461  }
12462  else
12463  {
12464  skip_to_state_evaluation = false;
12465  }
12466 
12467  // we reached this line after we successfully parsed a value
12468  if (states.empty())
12469  {
12470  // empty stack: we reached the end of the hierarchy: done
12471  return true;
12472  }
12473 
12474  if (states.back()) // array
12475  {
12476  // comma -> next value
12477  if (get_token() == token_type::value_separator)
12478  {
12479  // parse a new value
12480  get_token();
12481  continue;
12482  }
12483 
12484  // closing ]
12485  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
12486  {
12487  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12488  {
12489  return false;
12490  }
12491 
12492  // We are done with this array. Before we can parse a
12493  // new value, we need to evaluate the new state first.
12494  // By setting skip_to_state_evaluation to false, we
12495  // are effectively jumping to the beginning of this if.
12496  JSON_ASSERT(!states.empty());
12497  states.pop_back();
12498  skip_to_state_evaluation = true;
12499  continue;
12500  }
12501 
12502  return sax->parse_error(m_lexer.get_position(),
12503  m_lexer.get_token_string(),
12504  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
12505  }
12506 
12507  // states.back() is false -> object
12508 
12509  // comma -> next value
12510  if (get_token() == token_type::value_separator)
12511  {
12512  // parse key
12513  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
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(), exception_message(token_type::value_string, "object key"), nullptr));
12518  }
12519 
12520  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12521  {
12522  return false;
12523  }
12524 
12525  // parse separator (:)
12526  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12527  {
12528  return sax->parse_error(m_lexer.get_position(),
12529  m_lexer.get_token_string(),
12530  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12531  }
12532 
12533  // parse values
12534  get_token();
12535  continue;
12536  }
12537 
12538  // closing }
12539  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
12540  {
12541  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12542  {
12543  return false;
12544  }
12545 
12546  // We are done with this object. Before we can parse a
12547  // new value, we need to evaluate the new state first.
12548  // By setting skip_to_state_evaluation to false, we
12549  // are effectively jumping to the beginning of this if.
12550  JSON_ASSERT(!states.empty());
12551  states.pop_back();
12552  skip_to_state_evaluation = true;
12553  continue;
12554  }
12555 
12556  return sax->parse_error(m_lexer.get_position(),
12557  m_lexer.get_token_string(),
12558  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
12559  }
12560  }
12561 
12564  {
12565  return last_token = m_lexer.scan();
12566  }
12567 
12568  std::string exception_message(const token_type expected, const std::string& context)
12569  {
12570  std::string error_msg = "syntax error ";
12571 
12572  if (!context.empty())
12573  {
12574  error_msg += concat("while parsing ", context, ' ');
12575  }
12576 
12577  error_msg += "- ";
12578 
12579  if (last_token == token_type::parse_error)
12580  {
12581  error_msg += concat(m_lexer.get_error_message(), "; last read: '",
12582  m_lexer.get_token_string(), '\'');
12583  }
12584  else
12585  {
12586  error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
12587  }
12588 
12589  if (expected != token_type::uninitialized)
12590  {
12591  error_msg += concat("; expected ", lexer_t::token_type_name(expected));
12592  }
12593 
12594  return error_msg;
12595  }
12596 
12597  private:
12599  const parser_callback_t<BasicJsonType> callback = nullptr;
12601  token_type last_token = token_type::uninitialized;
12605  const bool allow_exceptions = true;
12606 };
12607 
12608 } // namespace detail
12610 
12611 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
12612 // __ _____ _____ _____
12613 // __| | __| | | | JSON for Modern C++
12614 // | | |__ | | | | | | version 3.11.2
12615 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12616 //
12617 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12618 // SPDX-License-Identifier: MIT
12619 
12620 
12621 
12622 // #include <nlohmann/detail/abi_macros.hpp>
12623 
12624 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12625 // __ _____ _____ _____
12626 // __| | __| | | | JSON for Modern C++
12627 // | | |__ | | | | | | version 3.11.2
12628 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12629 //
12630 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12631 // SPDX-License-Identifier: MIT
12632 
12633 
12634 
12635 #include <cstddef> // ptrdiff_t
12636 #include <limits> // numeric_limits
12637 
12638 // #include <nlohmann/detail/macro_scope.hpp>
12639 
12640 
12642 namespace detail
12643 {
12644 
12645 /*
12646 @brief an iterator for primitive JSON types
12647 
12648 This class models an iterator for primitive JSON types (boolean, number,
12649 string). It's only purpose is to allow the iterator/const_iterator classes
12650 to "iterate" over primitive values. Internally, the iterator is modeled by
12651 a `difference_type` variable. Value begin_value (`0`) models the begin,
12652 end_value (`1`) models past the end.
12653 */
12655 {
12656  private:
12657  using difference_type = std::ptrdiff_t;
12658  static constexpr difference_type begin_value = 0;
12659  static constexpr difference_type end_value = begin_value + 1;
12660 
12663  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
12664 
12665  public:
12666  constexpr difference_type get_value() const noexcept
12667  {
12668  return m_it;
12669  }
12670 
12672  void set_begin() noexcept
12673  {
12674  m_it = begin_value;
12675  }
12676 
12678  void set_end() noexcept
12679  {
12680  m_it = end_value;
12681  }
12682 
12684  constexpr bool is_begin() const noexcept
12685  {
12686  return m_it == begin_value;
12687  }
12688 
12690  constexpr bool is_end() const noexcept
12691  {
12692  return m_it == end_value;
12693  }
12694 
12695  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12696  {
12697  return lhs.m_it == rhs.m_it;
12698  }
12699 
12700  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12701  {
12702  return lhs.m_it < rhs.m_it;
12703  }
12704 
12706  {
12707  auto result = *this;
12708  result += n;
12709  return result;
12710  }
12711 
12713  {
12714  return lhs.m_it - rhs.m_it;
12715  }
12716 
12718  {
12719  ++m_it;
12720  return *this;
12721  }
12722 
12723  primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
12724  {
12725  auto result = *this;
12726  ++m_it;
12727  return result;
12728  }
12729 
12731  {
12732  --m_it;
12733  return *this;
12734  }
12735 
12736  primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
12737  {
12738  auto result = *this;
12739  --m_it;
12740  return result;
12741  }
12742 
12744  {
12745  m_it += n;
12746  return *this;
12747  }
12748 
12750  {
12751  m_it -= n;
12752  return *this;
12753  }
12754 };
12755 
12756 } // namespace detail
12758 
12759 
12761 namespace detail
12762 {
12763 
12770 template<typename BasicJsonType> struct internal_iterator
12771 {
12773  typename BasicJsonType::object_t::iterator object_iterator {};
12775  typename BasicJsonType::array_t::iterator array_iterator {};
12777  primitive_iterator_t primitive_iterator {};
12778 };
12779 
12780 } // namespace detail
12782 
12783 // #include <nlohmann/detail/iterators/iter_impl.hpp>
12784 // __ _____ _____ _____
12785 // __| | __| | | | JSON for Modern C++
12786 // | | |__ | | | | | | version 3.11.2
12787 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12788 //
12789 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12790 // SPDX-License-Identifier: MIT
12791 
12792 
12793 
12794 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12795 #include <type_traits> // conditional, is_const, remove_const
12796 
12797 // #include <nlohmann/detail/exceptions.hpp>
12798 
12799 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
12800 
12801 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12802 
12803 // #include <nlohmann/detail/macro_scope.hpp>
12804 
12805 // #include <nlohmann/detail/meta/cpp_future.hpp>
12806 
12807 // #include <nlohmann/detail/meta/type_traits.hpp>
12808 
12809 // #include <nlohmann/detail/value_t.hpp>
12810 
12811 
12813 namespace detail
12814 {
12815 
12816 // forward declare, to be able to friend it later on
12817 template<typename IteratorType> class iteration_proxy;
12818 template<typename IteratorType> class iteration_proxy_value;
12819 
12836 template<typename BasicJsonType>
12837 class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12838 {
12846 
12847  using object_t = typename BasicJsonType::object_t;
12848  using array_t = typename BasicJsonType::array_t;
12849  // make sure BasicJsonType is basic_json or const basic_json
12850  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
12851  "iter_impl only accepts (const) basic_json");
12852  // superficial check for the LegacyBidirectionalIterator named requirement
12853  static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
12854  && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
12855  "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
12856 
12857  public:
12863  using iterator_category = std::bidirectional_iterator_tag;
12864 
12866  using value_type = typename BasicJsonType::value_type;
12868  using difference_type = typename BasicJsonType::difference_type;
12870  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12871  typename BasicJsonType::const_pointer,
12872  typename BasicJsonType::pointer>::type;
12874  using reference =
12875  typename std::conditional<std::is_const<BasicJsonType>::value,
12876  typename BasicJsonType::const_reference,
12877  typename BasicJsonType::reference>::type;
12878 
12879  iter_impl() = default;
12880  ~iter_impl() = default;
12881  iter_impl(iter_impl&&) noexcept = default;
12882  iter_impl& operator=(iter_impl&&) noexcept = default;
12883 
12890  explicit iter_impl(pointer object) noexcept : m_object(object)
12891  {
12892  JSON_ASSERT(m_object != nullptr);
12893 
12894  switch (m_object->m_data.m_type)
12895  {
12896  case value_t::object:
12897  {
12898  m_it.object_iterator = typename object_t::iterator();
12899  break;
12900  }
12901 
12902  case value_t::array:
12903  {
12904  m_it.array_iterator = typename array_t::iterator();
12905  break;
12906  }
12907 
12908  case value_t::null:
12909  case value_t::string:
12910  case value_t::boolean:
12911  case value_t::number_integer:
12912  case value_t::number_unsigned:
12913  case value_t::number_float:
12914  case value_t::binary:
12915  case value_t::discarded:
12916  default:
12917  {
12918  m_it.primitive_iterator = primitive_iterator_t();
12919  break;
12920  }
12921  }
12922  }
12923 
12941  : m_object(other.m_object), m_it(other.m_it)
12942  {}
12943 
12951  {
12952  if (&other != this)
12953  {
12954  m_object = other.m_object;
12955  m_it = other.m_it;
12956  }
12957  return *this;
12958  }
12959 
12966  : m_object(other.m_object), m_it(other.m_it)
12967  {}
12968 
12975  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
12976  {
12977  m_object = other.m_object;
12978  m_it = other.m_it;
12979  return *this;
12980  }
12981 
12987  void set_begin() noexcept
12988  {
12989  JSON_ASSERT(m_object != nullptr);
12990 
12991  switch (m_object->m_data.m_type)
12992  {
12993  case value_t::object:
12994  {
12995  m_it.object_iterator = m_object->m_data.m_value.object->begin();
12996  break;
12997  }
12998 
12999  case value_t::array:
13000  {
13001  m_it.array_iterator = m_object->m_data.m_value.array->begin();
13002  break;
13003  }
13004 
13005  case value_t::null:
13006  {
13007  // set to end so begin()==end() is true: null is empty
13008  m_it.primitive_iterator.set_end();
13009  break;
13010  }
13011 
13012  case value_t::string:
13013  case value_t::boolean:
13014  case value_t::number_integer:
13015  case value_t::number_unsigned:
13016  case value_t::number_float:
13017  case value_t::binary:
13018  case value_t::discarded:
13019  default:
13020  {
13021  m_it.primitive_iterator.set_begin();
13022  break;
13023  }
13024  }
13025  }
13026 
13031  void set_end() noexcept
13032  {
13033  JSON_ASSERT(m_object != nullptr);
13034 
13035  switch (m_object->m_data.m_type)
13036  {
13037  case value_t::object:
13038  {
13039  m_it.object_iterator = m_object->m_data.m_value.object->end();
13040  break;
13041  }
13042 
13043  case value_t::array:
13044  {
13045  m_it.array_iterator = m_object->m_data.m_value.array->end();
13046  break;
13047  }
13048 
13049  case value_t::null:
13050  case value_t::string:
13051  case value_t::boolean:
13052  case value_t::number_integer:
13053  case value_t::number_unsigned:
13054  case value_t::number_float:
13055  case value_t::binary:
13056  case value_t::discarded:
13057  default:
13058  {
13059  m_it.primitive_iterator.set_end();
13060  break;
13061  }
13062  }
13063  }
13064 
13065  public:
13071  {
13072  JSON_ASSERT(m_object != nullptr);
13073 
13074  switch (m_object->m_data.m_type)
13075  {
13076  case value_t::object:
13077  {
13078  JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13079  return m_it.object_iterator->second;
13080  }
13081 
13082  case value_t::array:
13083  {
13084  JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13085  return *m_it.array_iterator;
13086  }
13087 
13088  case value_t::null:
13089  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13090 
13091  case value_t::string:
13092  case value_t::boolean:
13093  case value_t::number_integer:
13094  case value_t::number_unsigned:
13095  case value_t::number_float:
13096  case value_t::binary:
13097  case value_t::discarded:
13098  default:
13099  {
13100  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13101  {
13102  return *m_object;
13103  }
13104 
13105  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13106  }
13107  }
13108  }
13109 
13115  {
13116  JSON_ASSERT(m_object != nullptr);
13117 
13118  switch (m_object->m_data.m_type)
13119  {
13120  case value_t::object:
13121  {
13122  JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13123  return &(m_it.object_iterator->second);
13124  }
13125 
13126  case value_t::array:
13127  {
13128  JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13129  return &*m_it.array_iterator;
13130  }
13131 
13132  case value_t::null:
13133  case value_t::string:
13134  case value_t::boolean:
13135  case value_t::number_integer:
13136  case value_t::number_unsigned:
13137  case value_t::number_float:
13138  case value_t::binary:
13139  case value_t::discarded:
13140  default:
13141  {
13142  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13143  {
13144  return m_object;
13145  }
13146 
13147  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13148  }
13149  }
13150  }
13151 
13156  iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
13157  {
13158  auto result = *this;
13159  ++(*this);
13160  return result;
13161  }
13162 
13168  {
13169  JSON_ASSERT(m_object != nullptr);
13170 
13171  switch (m_object->m_data.m_type)
13172  {
13173  case value_t::object:
13174  {
13175  std::advance(m_it.object_iterator, 1);
13176  break;
13177  }
13178 
13179  case value_t::array:
13180  {
13181  std::advance(m_it.array_iterator, 1);
13182  break;
13183  }
13184 
13185  case value_t::null:
13186  case value_t::string:
13187  case value_t::boolean:
13188  case value_t::number_integer:
13189  case value_t::number_unsigned:
13190  case value_t::number_float:
13191  case value_t::binary:
13192  case value_t::discarded:
13193  default:
13194  {
13195  ++m_it.primitive_iterator;
13196  break;
13197  }
13198  }
13199 
13200  return *this;
13201  }
13202 
13207  iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
13208  {
13209  auto result = *this;
13210  --(*this);
13211  return result;
13212  }
13213 
13219  {
13220  JSON_ASSERT(m_object != nullptr);
13221 
13222  switch (m_object->m_data.m_type)
13223  {
13224  case value_t::object:
13225  {
13226  std::advance(m_it.object_iterator, -1);
13227  break;
13228  }
13229 
13230  case value_t::array:
13231  {
13232  std::advance(m_it.array_iterator, -1);
13233  break;
13234  }
13235 
13236  case value_t::null:
13237  case value_t::string:
13238  case value_t::boolean:
13239  case value_t::number_integer:
13240  case value_t::number_unsigned:
13241  case value_t::number_float:
13242  case value_t::binary:
13243  case value_t::discarded:
13244  default:
13245  {
13246  --m_it.primitive_iterator;
13247  break;
13248  }
13249  }
13250 
13251  return *this;
13252  }
13253 
13258  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 >
13259  bool operator==(const IterImpl& other) const
13260  {
13261  // if objects are not the same, the comparison is undefined
13262  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13263  {
13264  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13265  }
13266 
13267  JSON_ASSERT(m_object != nullptr);
13268 
13269  switch (m_object->m_data.m_type)
13270  {
13271  case value_t::object:
13272  return (m_it.object_iterator == other.m_it.object_iterator);
13273 
13274  case value_t::array:
13275  return (m_it.array_iterator == other.m_it.array_iterator);
13276 
13277  case value_t::null:
13278  case value_t::string:
13279  case value_t::boolean:
13280  case value_t::number_integer:
13281  case value_t::number_unsigned:
13282  case value_t::number_float:
13283  case value_t::binary:
13284  case value_t::discarded:
13285  default:
13286  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
13287  }
13288  }
13289 
13294  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 >
13295  bool operator!=(const IterImpl& other) const
13296  {
13297  return !operator==(other);
13298  }
13299 
13304  bool operator<(const iter_impl& other) const
13305  {
13306  // if objects are not the same, the comparison is undefined
13307  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13308  {
13309  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13310  }
13311 
13312  JSON_ASSERT(m_object != nullptr);
13313 
13314  switch (m_object->m_data.m_type)
13315  {
13316  case value_t::object:
13317  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
13318 
13319  case value_t::array:
13320  return (m_it.array_iterator < other.m_it.array_iterator);
13321 
13322  case value_t::null:
13323  case value_t::string:
13324  case value_t::boolean:
13325  case value_t::number_integer:
13326  case value_t::number_unsigned:
13327  case value_t::number_float:
13328  case value_t::binary:
13329  case value_t::discarded:
13330  default:
13331  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
13332  }
13333  }
13334 
13339  bool operator<=(const iter_impl& other) const
13340  {
13341  return !other.operator < (*this);
13342  }
13343 
13348  bool operator>(const iter_impl& other) const
13349  {
13350  return !operator<=(other);
13351  }
13352 
13357  bool operator>=(const iter_impl& other) const
13358  {
13359  return !operator<(other);
13360  }
13361 
13367  {
13368  JSON_ASSERT(m_object != nullptr);
13369 
13370  switch (m_object->m_data.m_type)
13371  {
13372  case value_t::object:
13373  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13374 
13375  case value_t::array:
13376  {
13377  std::advance(m_it.array_iterator, i);
13378  break;
13379  }
13380 
13381  case value_t::null:
13382  case value_t::string:
13383  case value_t::boolean:
13384  case value_t::number_integer:
13385  case value_t::number_unsigned:
13386  case value_t::number_float:
13387  case value_t::binary:
13388  case value_t::discarded:
13389  default:
13390  {
13391  m_it.primitive_iterator += i;
13392  break;
13393  }
13394  }
13395 
13396  return *this;
13397  }
13398 
13404  {
13405  return operator+=(-i);
13406  }
13407 
13413  {
13414  auto result = *this;
13415  result += i;
13416  return result;
13417  }
13418 
13424  {
13425  auto result = it;
13426  result += i;
13427  return result;
13428  }
13429 
13435  {
13436  auto result = *this;
13437  result -= i;
13438  return result;
13439  }
13440 
13446  {
13447  JSON_ASSERT(m_object != nullptr);
13448 
13449  switch (m_object->m_data.m_type)
13450  {
13451  case value_t::object:
13452  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13453 
13454  case value_t::array:
13455  return m_it.array_iterator - other.m_it.array_iterator;
13456 
13457  case value_t::null:
13458  case value_t::string:
13459  case value_t::boolean:
13460  case value_t::number_integer:
13461  case value_t::number_unsigned:
13462  case value_t::number_float:
13463  case value_t::binary:
13464  case value_t::discarded:
13465  default:
13466  return m_it.primitive_iterator - other.m_it.primitive_iterator;
13467  }
13468  }
13469 
13475  {
13476  JSON_ASSERT(m_object != nullptr);
13477 
13478  switch (m_object->m_data.m_type)
13479  {
13480  case value_t::object:
13481  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
13482 
13483  case value_t::array:
13484  return *std::next(m_it.array_iterator, n);
13485 
13486  case value_t::null:
13487  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13488 
13489  case value_t::string:
13490  case value_t::boolean:
13491  case value_t::number_integer:
13492  case value_t::number_unsigned:
13493  case value_t::number_float:
13494  case value_t::binary:
13495  case value_t::discarded:
13496  default:
13497  {
13498  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
13499  {
13500  return *m_object;
13501  }
13502 
13503  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13504  }
13505  }
13506  }
13507 
13512  const typename object_t::key_type& key() const
13513  {
13514  JSON_ASSERT(m_object != nullptr);
13515 
13516  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
13517  {
13518  return m_it.object_iterator->first;
13519  }
13520 
13521  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
13522  }
13523 
13529  {
13530  return operator*();
13531  }
13532 
13535  pointer m_object = nullptr;
13538 };
13539 
13540 } // namespace detail
13542 
13543 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
13544 
13545 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
13546 // __ _____ _____ _____
13547 // __| | __| | | | JSON for Modern C++
13548 // | | |__ | | | | | | version 3.11.2
13549 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13550 //
13551 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
13552 // SPDX-License-Identifier: MIT
13553 
13554 
13555 
13556 #include <cstddef> // ptrdiff_t
13557 #include <iterator> // reverse_iterator
13558 #include <utility> // declval
13559 
13560 // #include <nlohmann/detail/abi_macros.hpp>
13561 
13562 
13564 namespace detail
13565 {
13566 
13568 // reverse_iterator //
13570 
13589 template<typename Base>
13590 class json_reverse_iterator : public std::reverse_iterator<Base>
13591 {
13592  public:
13593  using difference_type = std::ptrdiff_t;
13595  using base_iterator = std::reverse_iterator<Base>;
13597  using reference = typename Base::reference;
13598 
13600  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
13601  : base_iterator(it) {}
13602 
13604  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
13605 
13607  json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
13608  {
13609  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
13610  }
13611 
13614  {
13615  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
13616  }
13617 
13619  json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
13620  {
13621  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
13622  }
13623 
13626  {
13627  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
13628  }
13629 
13632  {
13633  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
13634  }
13635 
13638  {
13639  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
13640  }
13641 
13644  {
13645  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
13646  }
13647 
13650  {
13651  return base_iterator(*this) - base_iterator(other);
13652  }
13653 
13656  {
13657  return *(this->operator+(n));
13658  }
13659 
13661  auto key() const -> decltype(std::declval<Base>().key())
13662  {
13663  auto it = --this->base();
13664  return it.key();
13665  }
13666 
13669  {
13670  auto it = --this->base();
13671  return it.operator * ();
13672  }
13673 };
13674 
13675 } // namespace detail
13677 
13678 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13679 
13680 // #include <nlohmann/detail/json_custom_base_class.hpp>
13681 
13682 
13683 #include <type_traits> // conditional, is_same
13684 
13685 // #include <nlohmann/detail/abi_macros.hpp>
13686 
13687 
13689 namespace detail
13690 {
13691 
13703 
13704 template<class T>
13705 using json_base_class = typename std::conditional <
13706  std::is_same<T, void>::value,
13708  T
13710 
13711 } // namespace detail
13713 
13714 // #include <nlohmann/detail/json_pointer.hpp>
13715 // __ _____ _____ _____
13716 // __| | __| | | | JSON for Modern C++
13717 // | | |__ | | | | | | version 3.11.2
13718 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13719 //
13720 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
13721 // SPDX-License-Identifier: MIT
13722 
13723 
13724 
13725 #include <algorithm> // all_of
13726 #include <cctype> // isdigit
13727 #include <cerrno> // errno, ERANGE
13728 #include <cstdlib> // strtoull
13729 #ifndef JSON_NO_IO
13730  #include <iosfwd> // ostream
13731 #endif // JSON_NO_IO
13732 #include <limits> // max
13733 #include <numeric> // accumulate
13734 #include <string> // string
13735 #include <utility> // move
13736 #include <vector> // vector
13737 
13738 // #include <nlohmann/detail/exceptions.hpp>
13739 
13740 // #include <nlohmann/detail/macro_scope.hpp>
13741 
13742 // #include <nlohmann/detail/string_concat.hpp>
13743 
13744 // #include <nlohmann/detail/string_escape.hpp>
13745 
13746 // #include <nlohmann/detail/value_t.hpp>
13747 
13748 
13750 
13753 template<typename RefStringType>
13754 class json_pointer
13755 {
13756  // allow basic_json to access private members
13758  friend class basic_json;
13759 
13760  template<typename>
13761  friend class json_pointer;
13762 
13763  template<typename T>
13765  {
13766  using type = T;
13767  };
13768 
13771  {
13772  using type = StringType;
13773  };
13774 
13775  public:
13776  // for backwards compatibility accept BasicJsonType
13778 
13781  explicit json_pointer(const string_t& s = "")
13782  : reference_tokens(split(s))
13783  {}
13784 
13788  {
13789  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
13790  string_t{},
13791  [](const string_t& a, const string_t& b)
13792  {
13793  return detail::concat(a, '/', detail::escape(b));
13794  });
13795  }
13796 
13800  operator string_t() const
13801  {
13802  return to_string();
13803  }
13804 
13805 #ifndef JSON_NO_IO
13806  friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
13809  {
13810  o << ptr.to_string();
13811  return o;
13812  }
13813 #endif
13814 
13818  {
13819  reference_tokens.insert(reference_tokens.end(),
13820  ptr.reference_tokens.begin(),
13821  ptr.reference_tokens.end());
13822  return *this;
13823  }
13824 
13828  {
13829  push_back(std::move(token));
13830  return *this;
13831  }
13832 
13835  json_pointer& operator/=(std::size_t array_idx)
13836  {
13837  return *this /= std::to_string(array_idx);
13838  }
13839 
13843  const json_pointer& rhs)
13844  {
13845  return json_pointer(lhs) /= rhs;
13846  }
13847 
13850  friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
13851  {
13852  return json_pointer(lhs) /= std::move(token);
13853  }
13854 
13857  friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13858  {
13859  return json_pointer(lhs) /= array_idx;
13860  }
13861 
13865  {
13866  if (empty())
13867  {
13868  return *this;
13869  }
13870 
13871  json_pointer res = *this;
13872  res.pop_back();
13873  return res;
13874  }
13875 
13878  void pop_back()
13879  {
13880  if (JSON_HEDLEY_UNLIKELY(empty()))
13881  {
13882  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13883  }
13884 
13885  reference_tokens.pop_back();
13886  }
13887 
13890  const string_t& back() const
13891  {
13892  if (JSON_HEDLEY_UNLIKELY(empty()))
13893  {
13894  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13895  }
13896 
13897  return reference_tokens.back();
13898  }
13899 
13902  void push_back(const string_t& token)
13903  {
13904  reference_tokens.push_back(token);
13905  }
13906 
13909  void push_back(string_t&& token)
13910  {
13911  reference_tokens.push_back(std::move(token));
13912  }
13913 
13916  bool empty() const noexcept
13917  {
13918  return reference_tokens.empty();
13919  }
13920 
13921  private:
13932  template<typename BasicJsonType>
13933  static typename BasicJsonType::size_type array_index(const string_t& s)
13934  {
13935  using size_type = typename BasicJsonType::size_type;
13936 
13937  // error condition (cf. RFC 6901, Sect. 4)
13938  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
13939  {
13940  JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
13941  }
13942 
13943  // error condition (cf. RFC 6901, Sect. 4)
13944  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
13945  {
13946  JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
13947  }
13948 
13949  const char* p = s.c_str();
13950  char* p_end = nullptr;
13951  errno = 0; // strtoull doesn't reset errno
13952  const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
13953  if (p == p_end // invalid input or empty string
13954  || errno == ERANGE // out of range
13955  || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
13956  {
13957  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
13958  }
13959 
13960  // only triggered on special platforms (like 32bit), see also
13961  // https://github.com/nlohmann/json/pull/2203
13962  if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
13963  {
13964  JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
13965  }
13966 
13967  return static_cast<size_type>(res);
13968  }
13969 
13971  json_pointer top() const
13972  {
13973  if (JSON_HEDLEY_UNLIKELY(empty()))
13974  {
13975  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13976  }
13977 
13978  json_pointer result = *this;
13979  result.reference_tokens = {reference_tokens[0]};
13980  return result;
13981  }
13982 
13983  private:
13992  template<typename BasicJsonType>
13993  BasicJsonType& get_and_create(BasicJsonType& j) const
13994  {
13995  auto* result = &j;
13996 
13997  // in case no reference tokens exist, return a reference to the JSON value
13998  // j which will be overwritten by a primitive value
13999  for (const auto& reference_token : reference_tokens)
14000  {
14001  switch (result->type())
14002  {
14003  case detail::value_t::null:
14004  {
14005  if (reference_token == "0")
14006  {
14007  // start a new array if reference token is 0
14008  result = &result->operator[](0);
14009  }
14010  else
14011  {
14012  // start a new object otherwise
14013  result = &result->operator[](reference_token);
14014  }
14015  break;
14016  }
14017 
14019  {
14020  // create an entry in the object
14021  result = &result->operator[](reference_token);
14022  break;
14023  }
14024 
14026  {
14027  // create an entry in the array
14028  result = &result->operator[](array_index<BasicJsonType>(reference_token));
14029  break;
14030  }
14031 
14032  /*
14033  The following code is only reached if there exists a reference
14034  token _and_ the current value is primitive. In this case, we have
14035  an error situation, because primitive values may only occur as
14036  single value; that is, with an empty list of reference tokens.
14037  */
14045  default:
14046  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
14047  }
14048  }
14049 
14050  return *result;
14051  }
14052 
14072  template<typename BasicJsonType>
14073  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
14074  {
14075  for (const auto& reference_token : reference_tokens)
14076  {
14077  // convert null values to arrays or objects before continuing
14078  if (ptr->is_null())
14079  {
14080  // check if reference token is a number
14081  const bool nums =
14082  std::all_of(reference_token.begin(), reference_token.end(),
14083  [](const unsigned char x)
14084  {
14085  return std::isdigit(x);
14086  });
14087 
14088  // change value to array for numbers or "-" or to object otherwise
14089  *ptr = (nums || reference_token == "-")
14092  }
14093 
14094  switch (ptr->type())
14095  {
14097  {
14098  // use unchecked object access
14099  ptr = &ptr->operator[](reference_token);
14100  break;
14101  }
14102 
14104  {
14105  if (reference_token == "-")
14106  {
14107  // explicitly treat "-" as index beyond the end
14108  ptr = &ptr->operator[](ptr->m_data.m_value.array->size());
14109  }
14110  else
14111  {
14112  // convert array index to number; unchecked access
14113  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14114  }
14115  break;
14116  }
14117 
14118  case detail::value_t::null:
14126  default:
14127  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14128  }
14129  }
14130 
14131  return *ptr;
14132  }
14133 
14140  template<typename BasicJsonType>
14141  BasicJsonType& get_checked(BasicJsonType* ptr) const
14142  {
14143  for (const auto& reference_token : reference_tokens)
14144  {
14145  switch (ptr->type())
14146  {
14148  {
14149  // note: at performs range check
14150  ptr = &ptr->at(reference_token);
14151  break;
14152  }
14153 
14155  {
14156  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14157  {
14158  // "-" always fails the range check
14160  "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
14161  ") is out of range"), ptr));
14162  }
14163 
14164  // note: at performs range check
14165  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14166  break;
14167  }
14168 
14169  case detail::value_t::null:
14177  default:
14178  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14179  }
14180  }
14181 
14182  return *ptr;
14183  }
14184 
14198  template<typename BasicJsonType>
14199  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
14200  {
14201  for (const auto& reference_token : reference_tokens)
14202  {
14203  switch (ptr->type())
14204  {
14206  {
14207  // use unchecked object access
14208  ptr = &ptr->operator[](reference_token);
14209  break;
14210  }
14211 
14213  {
14214  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14215  {
14216  // "-" cannot be used for const access
14217  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));
14218  }
14219 
14220  // use unchecked array access
14221  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14222  break;
14223  }
14224 
14225  case detail::value_t::null:
14233  default:
14234  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14235  }
14236  }
14237 
14238  return *ptr;
14239  }
14240 
14247  template<typename BasicJsonType>
14248  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
14249  {
14250  for (const auto& reference_token : reference_tokens)
14251  {
14252  switch (ptr->type())
14253  {
14255  {
14256  // note: at performs range check
14257  ptr = &ptr->at(reference_token);
14258  break;
14259  }
14260 
14262  {
14263  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14264  {
14265  // "-" always fails the range check
14267  "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
14268  ") is out of range"), ptr));
14269  }
14270 
14271  // note: at performs range check
14272  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14273  break;
14274  }
14275 
14276  case detail::value_t::null:
14284  default:
14285  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14286  }
14287  }
14288 
14289  return *ptr;
14290  }
14291 
14296  template<typename BasicJsonType>
14297  bool contains(const BasicJsonType* ptr) const
14298  {
14299  for (const auto& reference_token : reference_tokens)
14300  {
14301  switch (ptr->type())
14302  {
14304  {
14305  if (!ptr->contains(reference_token))
14306  {
14307  // we did not find the key in the object
14308  return false;
14309  }
14310 
14311  ptr = &ptr->operator[](reference_token);
14312  break;
14313  }
14314 
14316  {
14317  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14318  {
14319  // "-" always fails the range check
14320  return false;
14321  }
14322  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
14323  {
14324  // invalid char
14325  return false;
14326  }
14327  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
14328  {
14329  if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
14330  {
14331  // first char should be between '1' and '9'
14332  return false;
14333  }
14334  for (std::size_t i = 1; i < reference_token.size(); i++)
14335  {
14336  if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
14337  {
14338  // other char should be between '0' and '9'
14339  return false;
14340  }
14341  }
14342  }
14343 
14344  const auto idx = array_index<BasicJsonType>(reference_token);
14345  if (idx >= ptr->size())
14346  {
14347  // index out of range
14348  return false;
14349  }
14350 
14351  ptr = &ptr->operator[](idx);
14352  break;
14353  }
14354 
14355  case detail::value_t::null:
14363  default:
14364  {
14365  // we do not expect primitive values if there is still a
14366  // reference token to process
14367  return false;
14368  }
14369  }
14370  }
14371 
14372  // no reference token left means we found a primitive value
14373  return true;
14374  }
14375 
14385  static std::vector<string_t> split(const string_t& reference_string)
14386  {
14387  std::vector<string_t> result;
14388 
14389  // special case: empty reference string -> no reference tokens
14390  if (reference_string.empty())
14391  {
14392  return result;
14393  }
14394 
14395  // check if nonempty reference string begins with slash
14396  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
14397  {
14398  JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
14399  }
14400 
14401  // extract the reference tokens:
14402  // - slash: position of the last read slash (or end of string)
14403  // - start: position after the previous slash
14404  for (
14405  // search for the first slash after the first character
14406  std::size_t slash = reference_string.find_first_of('/', 1),
14407  // set the beginning of the first reference token
14408  start = 1;
14409  // we can stop if start == 0 (if slash == string_t::npos)
14410  start != 0;
14411  // set the beginning of the next reference token
14412  // (will eventually be 0 if slash == string_t::npos)
14413  start = (slash == string_t::npos) ? 0 : slash + 1,
14414  // find next slash
14415  slash = reference_string.find_first_of('/', start))
14416  {
14417  // use the text between the beginning of the reference token
14418  // (start) and the last slash (slash).
14419  auto reference_token = reference_string.substr(start, slash - start);
14420 
14421  // check reference tokens are properly escaped
14422  for (std::size_t pos = reference_token.find_first_of('~');
14423  pos != string_t::npos;
14424  pos = reference_token.find_first_of('~', pos + 1))
14425  {
14426  JSON_ASSERT(reference_token[pos] == '~');
14427 
14428  // ~ must be followed by 0 or 1
14429  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
14430  (reference_token[pos + 1] != '0' &&
14431  reference_token[pos + 1] != '1')))
14432  {
14433  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
14434  }
14435  }
14436 
14437  // finally, store the reference token
14438  detail::unescape(reference_token);
14439  result.push_back(reference_token);
14440  }
14441 
14442  return result;
14443  }
14444 
14445  private:
14453  template<typename BasicJsonType>
14454  static void flatten(const string_t& reference_string,
14455  const BasicJsonType& value,
14456  BasicJsonType& result)
14457  {
14458  switch (value.type())
14459  {
14461  {
14462  if (value.m_data.m_value.array->empty())
14463  {
14464  // flatten empty array as null
14465  result[reference_string] = nullptr;
14466  }
14467  else
14468  {
14469  // iterate array and use index as reference string
14470  for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)
14471  {
14472  flatten(detail::concat(reference_string, '/', std::to_string(i)),
14473  value.m_data.m_value.array->operator[](i), result);
14474  }
14475  }
14476  break;
14477  }
14478 
14480  {
14481  if (value.m_data.m_value.object->empty())
14482  {
14483  // flatten empty object as null
14484  result[reference_string] = nullptr;
14485  }
14486  else
14487  {
14488  // iterate object and use keys as reference string
14489  for (const auto& element : *value.m_data.m_value.object)
14490  {
14491  flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
14492  }
14493  }
14494  break;
14495  }
14496 
14497  case detail::value_t::null:
14505  default:
14506  {
14507  // add primitive value with its reference string
14508  result[reference_string] = value;
14509  break;
14510  }
14511  }
14512  }
14513 
14524  template<typename BasicJsonType>
14525  static BasicJsonType
14526  unflatten(const BasicJsonType& value)
14527  {
14528  if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
14529  {
14530  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
14531  }
14532 
14533  BasicJsonType result;
14534 
14535  // iterate the JSON object values
14536  for (const auto& element : *value.m_data.m_value.object)
14537  {
14538  if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
14539  {
14540  JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
14541  }
14542 
14543  // assign value to reference pointed to by JSON pointer; Note that if
14544  // the JSON pointer is "" (i.e., points to the whole value), function
14545  // get_and_create returns a reference to result itself. An assignment
14546  // will then create a primitive value.
14547  json_pointer(element.first).get_and_create(result) = element.second;
14548  }
14549 
14550  return result;
14551  }
14552 
14553  // can't use conversion operator because of ambiguity
14555  {
14556  json_pointer<string_t> result;
14557  result.reference_tokens = reference_tokens;
14558  return result;
14559  }
14560 
14562  {
14563  json_pointer<string_t> result;
14564  result.reference_tokens = std::move(reference_tokens);
14565  return result;
14566  }
14567 
14568  public:
14569 #if JSON_HAS_THREE_WAY_COMPARISON
14570  template<typename RefStringTypeRhs>
14573  bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept
14574  {
14575  return reference_tokens == rhs.reference_tokens;
14576  }
14577 
14580  JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))
14581  bool operator==(const string_t& rhs) const
14582  {
14583  return *this == json_pointer(rhs);
14584  }
14585 
14587  template<typename RefStringTypeRhs>
14588  std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
14589  {
14590  return reference_tokens <=> rhs.reference_tokens; // *NOPAD*
14591  }
14592 #else
14593  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14596  // NOLINTNEXTLINE(readability-redundant-declaration)
14597  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14598  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14599 
14602  template<typename RefStringTypeLhs, typename StringType>
14603  // NOLINTNEXTLINE(readability-redundant-declaration)
14604  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14605  const StringType& rhs);
14606 
14609  template<typename RefStringTypeRhs, typename StringType>
14610  // NOLINTNEXTLINE(readability-redundant-declaration)
14611  friend bool operator==(const StringType& lhs,
14612  const json_pointer<RefStringTypeRhs>& rhs);
14613 
14616  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14617  // NOLINTNEXTLINE(readability-redundant-declaration)
14618  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14619  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14620 
14623  template<typename RefStringTypeLhs, typename StringType>
14624  // NOLINTNEXTLINE(readability-redundant-declaration)
14625  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14626  const StringType& rhs);
14627 
14630  template<typename RefStringTypeRhs, typename StringType>
14631  // NOLINTNEXTLINE(readability-redundant-declaration)
14632  friend bool operator!=(const StringType& lhs,
14633  const json_pointer<RefStringTypeRhs>& rhs);
14634 
14636  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14637  // NOLINTNEXTLINE(readability-redundant-declaration)
14638  friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
14639  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14640 #endif
14641 
14642  private:
14644  std::vector<string_t> reference_tokens;
14645 };
14646 
14647 #if !JSON_HAS_THREE_WAY_COMPARISON
14648 // functions cannot be defined inside class due to ODR violations
14649 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14651  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14652 {
14653  return lhs.reference_tokens == rhs.reference_tokens;
14654 }
14655 
14656 template<typename RefStringTypeLhs,
14657  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14659 inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14660  const StringType& rhs)
14661 {
14662  return lhs == json_pointer<RefStringTypeLhs>(rhs);
14663 }
14664 
14665 template<typename RefStringTypeRhs,
14666  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14668 inline bool operator==(const StringType& lhs,
14669  const json_pointer<RefStringTypeRhs>& rhs)
14670 {
14671  return json_pointer<RefStringTypeRhs>(lhs) == rhs;
14672 }
14673 
14674 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14676  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14677 {
14678  return !(lhs == rhs);
14679 }
14680 
14681 template<typename RefStringTypeLhs,
14682  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14684 inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14685  const StringType& rhs)
14686 {
14687  return !(lhs == rhs);
14688 }
14689 
14690 template<typename RefStringTypeRhs,
14691  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14693 inline bool operator!=(const StringType& lhs,
14694  const json_pointer<RefStringTypeRhs>& rhs)
14695 {
14696  return !(lhs == rhs);
14697 }
14698 
14699 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14700 inline bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
14701  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14702 {
14703  return lhs.reference_tokens < rhs.reference_tokens;
14704 }
14705 #endif
14706 
14708 
14709 // #include <nlohmann/detail/json_ref.hpp>
14710 // __ _____ _____ _____
14711 // __| | __| | | | JSON for Modern C++
14712 // | | |__ | | | | | | version 3.11.2
14713 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14714 //
14715 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14716 // SPDX-License-Identifier: MIT
14717 
14718 
14719 
14720 #include <initializer_list>
14721 #include <utility>
14722 
14723 // #include <nlohmann/detail/abi_macros.hpp>
14724 
14725 // #include <nlohmann/detail/meta/type_traits.hpp>
14726 
14727 
14729 namespace detail
14730 {
14731 
14732 template<typename BasicJsonType>
14733 class json_ref
14734 {
14735  public:
14736  using value_type = BasicJsonType;
14737 
14739  : owned_value(std::move(value))
14740  {}
14741 
14742  json_ref(const value_type& value)
14743  : value_ref(&value)
14744  {}
14745 
14746  json_ref(std::initializer_list<json_ref> init)
14747  : owned_value(init)
14748  {}
14749 
14750  template <
14751  class... Args,
14752  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
14753  json_ref(Args && ... args)
14754  : owned_value(std::forward<Args>(args)...)
14755  {}
14756 
14757  // class should be movable only
14758  json_ref(json_ref&&) noexcept = default;
14759  json_ref(const json_ref&) = delete;
14760  json_ref& operator=(const json_ref&) = delete;
14761  json_ref& operator=(json_ref&&) = delete;
14762  ~json_ref() = default;
14763 
14764  value_type moved_or_copied() const
14765  {
14766  if (value_ref == nullptr)
14767  {
14768  return std::move(owned_value);
14769  }
14770  return *value_ref;
14771  }
14772 
14773  value_type const& operator*() const
14774  {
14775  return value_ref ? *value_ref : owned_value;
14776  }
14777 
14778  value_type const* operator->() const
14779  {
14780  return &** this;
14781  }
14782 
14783  private:
14784  mutable value_type owned_value = nullptr;
14785  value_type const* value_ref = nullptr;
14786 };
14787 
14788 } // namespace detail
14790 
14791 // #include <nlohmann/detail/macro_scope.hpp>
14792 
14793 // #include <nlohmann/detail/string_concat.hpp>
14794 
14795 // #include <nlohmann/detail/string_escape.hpp>
14796 
14797 // #include <nlohmann/detail/meta/cpp_future.hpp>
14798 
14799 // #include <nlohmann/detail/meta/type_traits.hpp>
14800 
14801 // #include <nlohmann/detail/output/binary_writer.hpp>
14802 // __ _____ _____ _____
14803 // __| | __| | | | JSON for Modern C++
14804 // | | |__ | | | | | | version 3.11.2
14805 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14806 //
14807 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14808 // SPDX-License-Identifier: MIT
14809 
14810 
14811 
14812 #include <algorithm> // reverse
14813 #include <array> // array
14814 #include <map> // map
14815 #include <cmath> // isnan, isinf
14816 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
14817 #include <cstring> // memcpy
14818 #include <limits> // numeric_limits
14819 #include <string> // string
14820 #include <utility> // move
14821 #include <vector> // vector
14822 
14823 // #include <nlohmann/detail/input/binary_reader.hpp>
14824 
14825 // #include <nlohmann/detail/macro_scope.hpp>
14826 
14827 // #include <nlohmann/detail/output/output_adapters.hpp>
14828 // __ _____ _____ _____
14829 // __| | __| | | | JSON for Modern C++
14830 // | | |__ | | | | | | version 3.11.2
14831 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14832 //
14833 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14834 // SPDX-License-Identifier: MIT
14835 
14836 
14837 
14838 #include <algorithm> // copy
14839 #include <cstddef> // size_t
14840 #include <iterator> // back_inserter
14841 #include <memory> // shared_ptr, make_shared
14842 #include <string> // basic_string
14843 #include <vector> // vector
14844 
14845 #ifndef JSON_NO_IO
14846  #include <ios> // streamsize
14847  #include <ostream> // basic_ostream
14848 #endif // JSON_NO_IO
14849 
14850 // #include <nlohmann/detail/macro_scope.hpp>
14851 
14852 
14854 namespace detail
14855 {
14856 
14858 template<typename CharType> struct output_adapter_protocol
14859 {
14860  virtual void write_character(CharType c) = 0;
14861  virtual void write_characters(const CharType* s, std::size_t length) = 0;
14862  virtual ~output_adapter_protocol() = default;
14863 
14864  output_adapter_protocol() = default;
14866  output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
14869 };
14870 
14872 template<typename CharType>
14873 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
14874 
14876 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
14878 {
14879  public:
14880  explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
14881  : v(vec)
14882  {}
14883 
14884  void write_character(CharType c) override
14885  {
14886  v.push_back(c);
14887  }
14888 
14890  void write_characters(const CharType* s, std::size_t length) override
14891  {
14892  v.insert(v.end(), s, s + length);
14893  }
14894 
14895  private:
14896  std::vector<CharType, AllocatorType>& v;
14897 };
14898 
14899 #ifndef JSON_NO_IO
14900 template<typename CharType>
14903 {
14904  public:
14905  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
14906  : stream(s)
14907  {}
14908 
14909  void write_character(CharType c) override
14910  {
14911  stream.put(c);
14912  }
14913 
14915  void write_characters(const CharType* s, std::size_t length) override
14916  {
14917  stream.write(s, static_cast<std::streamsize>(length));
14918  }
14919 
14920  private:
14921  std::basic_ostream<CharType>& stream;
14922 };
14923 #endif // JSON_NO_IO
14924 
14926 template<typename CharType, typename StringType = std::basic_string<CharType>>
14928 {
14929  public:
14930  explicit output_string_adapter(StringType& s) noexcept
14931  : str(s)
14932  {}
14933 
14934  void write_character(CharType c) override
14935  {
14936  str.push_back(c);
14937  }
14938 
14940  void write_characters(const CharType* s, std::size_t length) override
14941  {
14942  str.append(s, length);
14943  }
14944 
14945  private:
14946  StringType& str;
14947 };
14948 
14949 template<typename CharType, typename StringType = std::basic_string<CharType>>
14951 {
14952  public:
14953  template<typename AllocatorType = std::allocator<CharType>>
14954  output_adapter(std::vector<CharType, AllocatorType>& vec)
14955  : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
14956 
14957 #ifndef JSON_NO_IO
14958  output_adapter(std::basic_ostream<CharType>& s)
14959  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
14960 #endif // JSON_NO_IO
14961 
14962  output_adapter(StringType& s)
14963  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
14964 
14966  {
14967  return oa;
14968  }
14969 
14970  private:
14972 };
14973 
14974 } // namespace detail
14976 
14977 // #include <nlohmann/detail/string_concat.hpp>
14978 
14979 
14981 namespace detail
14982 {
14983 
14985 // binary writer //
14987 
14991 template<typename BasicJsonType, typename CharType>
14993 {
14994  using string_t = typename BasicJsonType::string_t;
14995  using binary_t = typename BasicJsonType::binary_t;
14996  using number_float_t = typename BasicJsonType::number_float_t;
14997 
14998  public:
15004  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
15005  {
15006  JSON_ASSERT(oa);
15007  }
15008 
15013  void write_bson(const BasicJsonType& j)
15014  {
15015  switch (j.type())
15016  {
15017  case value_t::object:
15018  {
15019  write_bson_object(*j.m_data.m_value.object);
15020  break;
15021  }
15022 
15023  case value_t::null:
15024  case value_t::array:
15025  case value_t::string:
15026  case value_t::boolean:
15027  case value_t::number_integer:
15028  case value_t::number_unsigned:
15029  case value_t::number_float:
15030  case value_t::binary:
15031  case value_t::discarded:
15032  default:
15033  {
15034  JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
15035  }
15036  }
15037  }
15038 
15042  void write_cbor(const BasicJsonType& j)
15043  {
15044  switch (j.type())
15045  {
15046  case value_t::null:
15047  {
15048  oa->write_character(to_char_type(0xF6));
15049  break;
15050  }
15051 
15052  case value_t::boolean:
15053  {
15054  oa->write_character(j.m_data.m_value.boolean
15055  ? to_char_type(0xF5)
15056  : to_char_type(0xF4));
15057  break;
15058  }
15059 
15060  case value_t::number_integer:
15061  {
15062  if (j.m_data.m_value.number_integer >= 0)
15063  {
15064  // CBOR does not differentiate between positive signed
15065  // integers and unsigned integers. Therefore, we used the
15066  // code from the value_t::number_unsigned case here.
15067  if (j.m_data.m_value.number_integer <= 0x17)
15068  {
15069  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15070  }
15071  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15072  {
15073  oa->write_character(to_char_type(0x18));
15074  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15075  }
15076  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
15077  {
15078  oa->write_character(to_char_type(0x19));
15079  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15080  }
15081  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
15082  {
15083  oa->write_character(to_char_type(0x1A));
15084  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15085  }
15086  else
15087  {
15088  oa->write_character(to_char_type(0x1B));
15089  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15090  }
15091  }
15092  else
15093  {
15094  // The conversions below encode the sign in the first
15095  // byte, and the value is converted to a positive number.
15096  const auto positive_number = -1 - j.m_data.m_value.number_integer;
15097  if (j.m_data.m_value.number_integer >= -24)
15098  {
15099  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
15100  }
15101  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
15102  {
15103  oa->write_character(to_char_type(0x38));
15104  write_number(static_cast<std::uint8_t>(positive_number));
15105  }
15106  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
15107  {
15108  oa->write_character(to_char_type(0x39));
15109  write_number(static_cast<std::uint16_t>(positive_number));
15110  }
15111  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
15112  {
15113  oa->write_character(to_char_type(0x3A));
15114  write_number(static_cast<std::uint32_t>(positive_number));
15115  }
15116  else
15117  {
15118  oa->write_character(to_char_type(0x3B));
15119  write_number(static_cast<std::uint64_t>(positive_number));
15120  }
15121  }
15122  break;
15123  }
15124 
15125  case value_t::number_unsigned:
15126  {
15127  if (j.m_data.m_value.number_unsigned <= 0x17)
15128  {
15129  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15130  }
15131  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15132  {
15133  oa->write_character(to_char_type(0x18));
15134  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15135  }
15136  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15137  {
15138  oa->write_character(to_char_type(0x19));
15139  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
15140  }
15141  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15142  {
15143  oa->write_character(to_char_type(0x1A));
15144  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
15145  }
15146  else
15147  {
15148  oa->write_character(to_char_type(0x1B));
15149  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
15150  }
15151  break;
15152  }
15153 
15154  case value_t::number_float:
15155  {
15156  if (std::isnan(j.m_data.m_value.number_float))
15157  {
15158  // NaN is 0xf97e00 in CBOR
15159  oa->write_character(to_char_type(0xF9));
15160  oa->write_character(to_char_type(0x7E));
15161  oa->write_character(to_char_type(0x00));
15162  }
15163  else if (std::isinf(j.m_data.m_value.number_float))
15164  {
15165  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
15166  oa->write_character(to_char_type(0xf9));
15167  oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
15168  oa->write_character(to_char_type(0x00));
15169  }
15170  else
15171  {
15172  write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::cbor);
15173  }
15174  break;
15175  }
15176 
15177  case value_t::string:
15178  {
15179  // step 1: write control byte and the string length
15180  const auto N = j.m_data.m_value.string->size();
15181  if (N <= 0x17)
15182  {
15183  write_number(static_cast<std::uint8_t>(0x60 + N));
15184  }
15185  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15186  {
15187  oa->write_character(to_char_type(0x78));
15188  write_number(static_cast<std::uint8_t>(N));
15189  }
15190  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15191  {
15192  oa->write_character(to_char_type(0x79));
15193  write_number(static_cast<std::uint16_t>(N));
15194  }
15195  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15196  {
15197  oa->write_character(to_char_type(0x7A));
15198  write_number(static_cast<std::uint32_t>(N));
15199  }
15200  // LCOV_EXCL_START
15201  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15202  {
15203  oa->write_character(to_char_type(0x7B));
15204  write_number(static_cast<std::uint64_t>(N));
15205  }
15206  // LCOV_EXCL_STOP
15207 
15208  // step 2: write the string
15209  oa->write_characters(
15210  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15211  j.m_data.m_value.string->size());
15212  break;
15213  }
15214 
15215  case value_t::array:
15216  {
15217  // step 1: write control byte and the array size
15218  const auto N = j.m_data.m_value.array->size();
15219  if (N <= 0x17)
15220  {
15221  write_number(static_cast<std::uint8_t>(0x80 + N));
15222  }
15223  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15224  {
15225  oa->write_character(to_char_type(0x98));
15226  write_number(static_cast<std::uint8_t>(N));
15227  }
15228  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15229  {
15230  oa->write_character(to_char_type(0x99));
15231  write_number(static_cast<std::uint16_t>(N));
15232  }
15233  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15234  {
15235  oa->write_character(to_char_type(0x9A));
15236  write_number(static_cast<std::uint32_t>(N));
15237  }
15238  // LCOV_EXCL_START
15239  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15240  {
15241  oa->write_character(to_char_type(0x9B));
15242  write_number(static_cast<std::uint64_t>(N));
15243  }
15244  // LCOV_EXCL_STOP
15245 
15246  // step 2: write each element
15247  for (const auto& el : *j.m_data.m_value.array)
15248  {
15249  write_cbor(el);
15250  }
15251  break;
15252  }
15253 
15254  case value_t::binary:
15255  {
15256  if (j.m_data.m_value.binary->has_subtype())
15257  {
15258  if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
15259  {
15260  write_number(static_cast<std::uint8_t>(0xd8));
15261  write_number(static_cast<std::uint8_t>(j.m_data.m_value.binary->subtype()));
15262  }
15263  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
15264  {
15265  write_number(static_cast<std::uint8_t>(0xd9));
15266  write_number(static_cast<std::uint16_t>(j.m_data.m_value.binary->subtype()));
15267  }
15268  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
15269  {
15270  write_number(static_cast<std::uint8_t>(0xda));
15271  write_number(static_cast<std::uint32_t>(j.m_data.m_value.binary->subtype()));
15272  }
15273  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
15274  {
15275  write_number(static_cast<std::uint8_t>(0xdb));
15276  write_number(static_cast<std::uint64_t>(j.m_data.m_value.binary->subtype()));
15277  }
15278  }
15279 
15280  // step 1: write control byte and the binary array size
15281  const auto N = j.m_data.m_value.binary->size();
15282  if (N <= 0x17)
15283  {
15284  write_number(static_cast<std::uint8_t>(0x40 + N));
15285  }
15286  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15287  {
15288  oa->write_character(to_char_type(0x58));
15289  write_number(static_cast<std::uint8_t>(N));
15290  }
15291  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15292  {
15293  oa->write_character(to_char_type(0x59));
15294  write_number(static_cast<std::uint16_t>(N));
15295  }
15296  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15297  {
15298  oa->write_character(to_char_type(0x5A));
15299  write_number(static_cast<std::uint32_t>(N));
15300  }
15301  // LCOV_EXCL_START
15302  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15303  {
15304  oa->write_character(to_char_type(0x5B));
15305  write_number(static_cast<std::uint64_t>(N));
15306  }
15307  // LCOV_EXCL_STOP
15308 
15309  // step 2: write each element
15310  oa->write_characters(
15311  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15312  N);
15313 
15314  break;
15315  }
15316 
15317  case value_t::object:
15318  {
15319  // step 1: write control byte and the object size
15320  const auto N = j.m_data.m_value.object->size();
15321  if (N <= 0x17)
15322  {
15323  write_number(static_cast<std::uint8_t>(0xA0 + N));
15324  }
15325  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15326  {
15327  oa->write_character(to_char_type(0xB8));
15328  write_number(static_cast<std::uint8_t>(N));
15329  }
15330  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15331  {
15332  oa->write_character(to_char_type(0xB9));
15333  write_number(static_cast<std::uint16_t>(N));
15334  }
15335  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15336  {
15337  oa->write_character(to_char_type(0xBA));
15338  write_number(static_cast<std::uint32_t>(N));
15339  }
15340  // LCOV_EXCL_START
15341  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15342  {
15343  oa->write_character(to_char_type(0xBB));
15344  write_number(static_cast<std::uint64_t>(N));
15345  }
15346  // LCOV_EXCL_STOP
15347 
15348  // step 2: write each element
15349  for (const auto& el : *j.m_data.m_value.object)
15350  {
15351  write_cbor(el.first);
15352  write_cbor(el.second);
15353  }
15354  break;
15355  }
15356 
15357  case value_t::discarded:
15358  default:
15359  break;
15360  }
15361  }
15362 
15366  void write_msgpack(const BasicJsonType& j)
15367  {
15368  switch (j.type())
15369  {
15370  case value_t::null: // nil
15371  {
15372  oa->write_character(to_char_type(0xC0));
15373  break;
15374  }
15375 
15376  case value_t::boolean: // true and false
15377  {
15378  oa->write_character(j.m_data.m_value.boolean
15379  ? to_char_type(0xC3)
15380  : to_char_type(0xC2));
15381  break;
15382  }
15383 
15384  case value_t::number_integer:
15385  {
15386  if (j.m_data.m_value.number_integer >= 0)
15387  {
15388  // MessagePack does not differentiate between positive
15389  // signed integers and unsigned integers. Therefore, we used
15390  // the code from the value_t::number_unsigned case here.
15391  if (j.m_data.m_value.number_unsigned < 128)
15392  {
15393  // positive fixnum
15394  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15395  }
15396  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15397  {
15398  // uint 8
15399  oa->write_character(to_char_type(0xCC));
15400  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15401  }
15402  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15403  {
15404  // uint 16
15405  oa->write_character(to_char_type(0xCD));
15406  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15407  }
15408  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15409  {
15410  // uint 32
15411  oa->write_character(to_char_type(0xCE));
15412  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15413  }
15414  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15415  {
15416  // uint 64
15417  oa->write_character(to_char_type(0xCF));
15418  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15419  }
15420  }
15421  else
15422  {
15423  if (j.m_data.m_value.number_integer >= -32)
15424  {
15425  // negative fixnum
15426  write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
15427  }
15428  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
15429  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15430  {
15431  // int 8
15432  oa->write_character(to_char_type(0xD0));
15433  write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
15434  }
15435  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
15436  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15437  {
15438  // int 16
15439  oa->write_character(to_char_type(0xD1));
15440  write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));
15441  }
15442  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
15443  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15444  {
15445  // int 32
15446  oa->write_character(to_char_type(0xD2));
15447  write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));
15448  }
15449  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
15450  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15451  {
15452  // int 64
15453  oa->write_character(to_char_type(0xD3));
15454  write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
15455  }
15456  }
15457  break;
15458  }
15459 
15460  case value_t::number_unsigned:
15461  {
15462  if (j.m_data.m_value.number_unsigned < 128)
15463  {
15464  // positive fixnum
15465  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15466  }
15467  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15468  {
15469  // uint 8
15470  oa->write_character(to_char_type(0xCC));
15471  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15472  }
15473  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15474  {
15475  // uint 16
15476  oa->write_character(to_char_type(0xCD));
15477  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15478  }
15479  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15480  {
15481  // uint 32
15482  oa->write_character(to_char_type(0xCE));
15483  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15484  }
15485  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15486  {
15487  // uint 64
15488  oa->write_character(to_char_type(0xCF));
15489  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15490  }
15491  break;
15492  }
15493 
15494  case value_t::number_float:
15495  {
15496  write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::msgpack);
15497  break;
15498  }
15499 
15500  case value_t::string:
15501  {
15502  // step 1: write control byte and the string length
15503  const auto N = j.m_data.m_value.string->size();
15504  if (N <= 31)
15505  {
15506  // fixstr
15507  write_number(static_cast<std::uint8_t>(0xA0 | N));
15508  }
15509  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15510  {
15511  // str 8
15512  oa->write_character(to_char_type(0xD9));
15513  write_number(static_cast<std::uint8_t>(N));
15514  }
15515  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15516  {
15517  // str 16
15518  oa->write_character(to_char_type(0xDA));
15519  write_number(static_cast<std::uint16_t>(N));
15520  }
15521  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15522  {
15523  // str 32
15524  oa->write_character(to_char_type(0xDB));
15525  write_number(static_cast<std::uint32_t>(N));
15526  }
15527 
15528  // step 2: write the string
15529  oa->write_characters(
15530  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15531  j.m_data.m_value.string->size());
15532  break;
15533  }
15534 
15535  case value_t::array:
15536  {
15537  // step 1: write control byte and the array size
15538  const auto N = j.m_data.m_value.array->size();
15539  if (N <= 15)
15540  {
15541  // fixarray
15542  write_number(static_cast<std::uint8_t>(0x90 | N));
15543  }
15544  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15545  {
15546  // array 16
15547  oa->write_character(to_char_type(0xDC));
15548  write_number(static_cast<std::uint16_t>(N));
15549  }
15550  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15551  {
15552  // array 32
15553  oa->write_character(to_char_type(0xDD));
15554  write_number(static_cast<std::uint32_t>(N));
15555  }
15556 
15557  // step 2: write each element
15558  for (const auto& el : *j.m_data.m_value.array)
15559  {
15560  write_msgpack(el);
15561  }
15562  break;
15563  }
15564 
15565  case value_t::binary:
15566  {
15567  // step 0: determine if the binary type has a set subtype to
15568  // determine whether or not to use the ext or fixext types
15569  const bool use_ext = j.m_data.m_value.binary->has_subtype();
15570 
15571  // step 1: write control byte and the byte string length
15572  const auto N = j.m_data.m_value.binary->size();
15573  if (N <= (std::numeric_limits<std::uint8_t>::max)())
15574  {
15575  std::uint8_t output_type{};
15576  bool fixed = true;
15577  if (use_ext)
15578  {
15579  switch (N)
15580  {
15581  case 1:
15582  output_type = 0xD4; // fixext 1
15583  break;
15584  case 2:
15585  output_type = 0xD5; // fixext 2
15586  break;
15587  case 4:
15588  output_type = 0xD6; // fixext 4
15589  break;
15590  case 8:
15591  output_type = 0xD7; // fixext 8
15592  break;
15593  case 16:
15594  output_type = 0xD8; // fixext 16
15595  break;
15596  default:
15597  output_type = 0xC7; // ext 8
15598  fixed = false;
15599  break;
15600  }
15601 
15602  }
15603  else
15604  {
15605  output_type = 0xC4; // bin 8
15606  fixed = false;
15607  }
15608 
15609  oa->write_character(to_char_type(output_type));
15610  if (!fixed)
15611  {
15612  write_number(static_cast<std::uint8_t>(N));
15613  }
15614  }
15615  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15616  {
15617  const std::uint8_t output_type = use_ext
15618  ? 0xC8 // ext 16
15619  : 0xC5; // bin 16
15620 
15621  oa->write_character(to_char_type(output_type));
15622  write_number(static_cast<std::uint16_t>(N));
15623  }
15624  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15625  {
15626  const std::uint8_t output_type = use_ext
15627  ? 0xC9 // ext 32
15628  : 0xC6; // bin 32
15629 
15630  oa->write_character(to_char_type(output_type));
15631  write_number(static_cast<std::uint32_t>(N));
15632  }
15633 
15634  // step 1.5: if this is an ext type, write the subtype
15635  if (use_ext)
15636  {
15637  write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));
15638  }
15639 
15640  // step 2: write the byte string
15641  oa->write_characters(
15642  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15643  N);
15644 
15645  break;
15646  }
15647 
15648  case value_t::object:
15649  {
15650  // step 1: write control byte and the object size
15651  const auto N = j.m_data.m_value.object->size();
15652  if (N <= 15)
15653  {
15654  // fixmap
15655  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
15656  }
15657  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15658  {
15659  // map 16
15660  oa->write_character(to_char_type(0xDE));
15661  write_number(static_cast<std::uint16_t>(N));
15662  }
15663  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15664  {
15665  // map 32
15666  oa->write_character(to_char_type(0xDF));
15667  write_number(static_cast<std::uint32_t>(N));
15668  }
15669 
15670  // step 2: write each element
15671  for (const auto& el : *j.m_data.m_value.object)
15672  {
15673  write_msgpack(el.first);
15674  write_msgpack(el.second);
15675  }
15676  break;
15677  }
15678 
15679  case value_t::discarded:
15680  default:
15681  break;
15682  }
15683  }
15684 
15692  void write_ubjson(const BasicJsonType& j, const bool use_count,
15693  const bool use_type, const bool add_prefix = true,
15694  const bool use_bjdata = false)
15695  {
15696  switch (j.type())
15697  {
15698  case value_t::null:
15699  {
15700  if (add_prefix)
15701  {
15702  oa->write_character(to_char_type('Z'));
15703  }
15704  break;
15705  }
15706 
15707  case value_t::boolean:
15708  {
15709  if (add_prefix)
15710  {
15711  oa->write_character(j.m_data.m_value.boolean
15712  ? to_char_type('T')
15713  : to_char_type('F'));
15714  }
15715  break;
15716  }
15717 
15718  case value_t::number_integer:
15719  {
15720  write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);
15721  break;
15722  }
15723 
15724  case value_t::number_unsigned:
15725  {
15726  write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);
15727  break;
15728  }
15729 
15730  case value_t::number_float:
15731  {
15732  write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);
15733  break;
15734  }
15735 
15736  case value_t::string:
15737  {
15738  if (add_prefix)
15739  {
15740  oa->write_character(to_char_type('S'));
15741  }
15742  write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
15743  oa->write_characters(
15744  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15745  j.m_data.m_value.string->size());
15746  break;
15747  }
15748 
15749  case value_t::array:
15750  {
15751  if (add_prefix)
15752  {
15753  oa->write_character(to_char_type('['));
15754  }
15755 
15756  bool prefix_required = true;
15757  if (use_type && !j.m_data.m_value.array->empty())
15758  {
15759  JSON_ASSERT(use_count);
15760  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15761  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
15762  [this, first_prefix, use_bjdata](const BasicJsonType & v)
15763  {
15764  return ubjson_prefix(v, use_bjdata) == first_prefix;
15765  });
15766 
15767  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15768 
15769  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15770  {
15771  prefix_required = false;
15772  oa->write_character(to_char_type('$'));
15773  oa->write_character(first_prefix);
15774  }
15775  }
15776 
15777  if (use_count)
15778  {
15779  oa->write_character(to_char_type('#'));
15780  write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
15781  }
15782 
15783  for (const auto& el : *j.m_data.m_value.array)
15784  {
15785  write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
15786  }
15787 
15788  if (!use_count)
15789  {
15790  oa->write_character(to_char_type(']'));
15791  }
15792 
15793  break;
15794  }
15795 
15796  case value_t::binary:
15797  {
15798  if (add_prefix)
15799  {
15800  oa->write_character(to_char_type('['));
15801  }
15802 
15803  if (use_type && !j.m_data.m_value.binary->empty())
15804  {
15805  JSON_ASSERT(use_count);
15806  oa->write_character(to_char_type('$'));
15807  oa->write_character('U');
15808  }
15809 
15810  if (use_count)
15811  {
15812  oa->write_character(to_char_type('#'));
15813  write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);
15814  }
15815 
15816  if (use_type)
15817  {
15818  oa->write_characters(
15819  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15820  j.m_data.m_value.binary->size());
15821  }
15822  else
15823  {
15824  for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
15825  {
15826  oa->write_character(to_char_type('U'));
15827  oa->write_character(j.m_data.m_value.binary->data()[i]);
15828  }
15829  }
15830 
15831  if (!use_count)
15832  {
15833  oa->write_character(to_char_type(']'));
15834  }
15835 
15836  break;
15837  }
15838 
15839  case value_t::object:
15840  {
15841  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())
15842  {
15843  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)
15844  {
15845  break;
15846  }
15847  }
15848 
15849  if (add_prefix)
15850  {
15851  oa->write_character(to_char_type('{'));
15852  }
15853 
15854  bool prefix_required = true;
15855  if (use_type && !j.m_data.m_value.object->empty())
15856  {
15857  JSON_ASSERT(use_count);
15858  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15859  const bool same_prefix = std::all_of(j.begin(), j.end(),
15860  [this, first_prefix, use_bjdata](const BasicJsonType & v)
15861  {
15862  return ubjson_prefix(v, use_bjdata) == first_prefix;
15863  });
15864 
15865  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15866 
15867  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15868  {
15869  prefix_required = false;
15870  oa->write_character(to_char_type('$'));
15871  oa->write_character(first_prefix);
15872  }
15873  }
15874 
15875  if (use_count)
15876  {
15877  oa->write_character(to_char_type('#'));
15878  write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
15879  }
15880 
15881  for (const auto& el : *j.m_data.m_value.object)
15882  {
15883  write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
15884  oa->write_characters(
15885  reinterpret_cast<const CharType*>(el.first.c_str()),
15886  el.first.size());
15887  write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
15888  }
15889 
15890  if (!use_count)
15891  {
15892  oa->write_character(to_char_type('}'));
15893  }
15894 
15895  break;
15896  }
15897 
15898  case value_t::discarded:
15899  default:
15900  break;
15901  }
15902  }
15903 
15904  private:
15906  // BSON //
15908 
15913  static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
15914  {
15915  const auto it = name.find(static_cast<typename string_t::value_type>(0));
15916  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
15917  {
15918  JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
15919  static_cast<void>(j);
15920  }
15921 
15922  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
15923  }
15924 
15929  const std::uint8_t element_type)
15930  {
15931  oa->write_character(to_char_type(element_type)); // boolean
15932  oa->write_characters(
15933  reinterpret_cast<const CharType*>(name.c_str()),
15934  name.size() + 1u);
15935  }
15936 
15940  void write_bson_boolean(const string_t& name,
15941  const bool value)
15942  {
15943  write_bson_entry_header(name, 0x08);
15944  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
15945  }
15946 
15950  void write_bson_double(const string_t& name,
15951  const double value)
15952  {
15953  write_bson_entry_header(name, 0x01);
15954  write_number<double>(value, true);
15955  }
15956 
15960  static std::size_t calc_bson_string_size(const string_t& value)
15961  {
15962  return sizeof(std::int32_t) + value.size() + 1ul;
15963  }
15964 
15968  void write_bson_string(const string_t& name,
15969  const string_t& value)
15970  {
15971  write_bson_entry_header(name, 0x02);
15972 
15973  write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
15974  oa->write_characters(
15975  reinterpret_cast<const CharType*>(value.c_str()),
15976  value.size() + 1);
15977  }
15978 
15982  void write_bson_null(const string_t& name)
15983  {
15984  write_bson_entry_header(name, 0x0A);
15985  }
15986 
15990  static std::size_t calc_bson_integer_size(const std::int64_t value)
15991  {
15992  return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
15993  ? sizeof(std::int32_t)
15994  : sizeof(std::int64_t);
15995  }
15996 
16000  void write_bson_integer(const string_t& name,
16001  const std::int64_t value)
16002  {
16003  if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
16004  {
16005  write_bson_entry_header(name, 0x10); // int32
16006  write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
16007  }
16008  else
16009  {
16010  write_bson_entry_header(name, 0x12); // int64
16011  write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
16012  }
16013  }
16014 
16018  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
16019  {
16020  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16021  ? sizeof(std::int32_t)
16022  : sizeof(std::int64_t);
16023  }
16024 
16028  void write_bson_unsigned(const string_t& name,
16029  const BasicJsonType& j)
16030  {
16031  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16032  {
16033  write_bson_entry_header(name, 0x10 /* int32 */);
16034  write_number<std::int32_t>(static_cast<std::int32_t>(j.m_data.m_value.number_unsigned), true);
16035  }
16036  else if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16037  {
16038  write_bson_entry_header(name, 0x12 /* int64 */);
16039  write_number<std::int64_t>(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned), true);
16040  }
16041  else
16042  {
16043  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));
16044  }
16045  }
16046 
16051  const typename BasicJsonType::object_t& value)
16052  {
16053  write_bson_entry_header(name, 0x03); // object
16054  write_bson_object(value);
16055  }
16056 
16060  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
16061  {
16062  std::size_t array_index = 0ul;
16063 
16064  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)
16065  {
16066  return result + calc_bson_element_size(std::to_string(array_index++), el);
16067  });
16068 
16069  return sizeof(std::int32_t) + embedded_document_size + 1ul;
16070  }
16071 
16075  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
16076  {
16077  return sizeof(std::int32_t) + value.size() + 1ul;
16078  }
16079 
16083  void write_bson_array(const string_t& name,
16084  const typename BasicJsonType::array_t& value)
16085  {
16086  write_bson_entry_header(name, 0x04); // array
16087  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
16088 
16089  std::size_t array_index = 0ul;
16090 
16091  for (const auto& el : value)
16092  {
16093  write_bson_element(std::to_string(array_index++), el);
16094  }
16095 
16096  oa->write_character(to_char_type(0x00));
16097  }
16098 
16102  void write_bson_binary(const string_t& name,
16103  const binary_t& value)
16104  {
16105  write_bson_entry_header(name, 0x05);
16106 
16107  write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
16108  write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
16109 
16110  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
16111  }
16112 
16117  static std::size_t calc_bson_element_size(const string_t& name,
16118  const BasicJsonType& j)
16119  {
16120  const auto header_size = calc_bson_entry_header_size(name, j);
16121  switch (j.type())
16122  {
16123  case value_t::object:
16124  return header_size + calc_bson_object_size(*j.m_data.m_value.object);
16125 
16126  case value_t::array:
16127  return header_size + calc_bson_array_size(*j.m_data.m_value.array);
16128 
16129  case value_t::binary:
16130  return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);
16131 
16132  case value_t::boolean:
16133  return header_size + 1ul;
16134 
16135  case value_t::number_float:
16136  return header_size + 8ul;
16137 
16138  case value_t::number_integer:
16139  return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);
16140 
16141  case value_t::number_unsigned:
16142  return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);
16143 
16144  case value_t::string:
16145  return header_size + calc_bson_string_size(*j.m_data.m_value.string);
16146 
16147  case value_t::null:
16148  return header_size + 0ul;
16149 
16150  // LCOV_EXCL_START
16151  case value_t::discarded:
16152  default:
16153  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16154  return 0ul;
16155  // LCOV_EXCL_STOP
16156  }
16157  }
16158 
16165  void write_bson_element(const string_t& name,
16166  const BasicJsonType& j)
16167  {
16168  switch (j.type())
16169  {
16170  case value_t::object:
16171  return write_bson_object_entry(name, *j.m_data.m_value.object);
16172 
16173  case value_t::array:
16174  return write_bson_array(name, *j.m_data.m_value.array);
16175 
16176  case value_t::binary:
16177  return write_bson_binary(name, *j.m_data.m_value.binary);
16178 
16179  case value_t::boolean:
16180  return write_bson_boolean(name, j.m_data.m_value.boolean);
16181 
16182  case value_t::number_float:
16183  return write_bson_double(name, j.m_data.m_value.number_float);
16184 
16185  case value_t::number_integer:
16186  return write_bson_integer(name, j.m_data.m_value.number_integer);
16187 
16188  case value_t::number_unsigned:
16189  return write_bson_unsigned(name, j);
16190 
16191  case value_t::string:
16192  return write_bson_string(name, *j.m_data.m_value.string);
16193 
16194  case value_t::null:
16195  return write_bson_null(name);
16196 
16197  // LCOV_EXCL_START
16198  case value_t::discarded:
16199  default:
16200  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16201  return;
16202  // LCOV_EXCL_STOP
16203  }
16204  }
16205 
16212  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
16213  {
16214  const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
16215  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
16216  {
16217  return result += calc_bson_element_size(el.first, el.second);
16218  });
16219 
16220  return sizeof(std::int32_t) + document_size + 1ul;
16221  }
16222 
16227  void write_bson_object(const typename BasicJsonType::object_t& value)
16228  {
16229  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
16230 
16231  for (const auto& el : value)
16232  {
16233  write_bson_element(el.first, el.second);
16234  }
16235 
16236  oa->write_character(to_char_type(0x00));
16237  }
16238 
16240  // CBOR //
16242 
16243  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
16244  {
16245  return to_char_type(0xFA); // Single-Precision Float
16246  }
16247 
16248  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
16249  {
16250  return to_char_type(0xFB); // Double-Precision Float
16251  }
16252 
16254  // MsgPack //
16256 
16257  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
16258  {
16259  return to_char_type(0xCA); // float 32
16260  }
16261 
16262  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
16263  {
16264  return to_char_type(0xCB); // float 64
16265  }
16266 
16268  // UBJSON //
16270 
16271  // UBJSON: write number (floating point)
16272  template<typename NumberType, typename std::enable_if<
16273  std::is_floating_point<NumberType>::value, int>::type = 0>
16274  void write_number_with_ubjson_prefix(const NumberType n,
16275  const bool add_prefix,
16276  const bool use_bjdata)
16277  {
16278  if (add_prefix)
16279  {
16280  oa->write_character(get_ubjson_float_prefix(n));
16281  }
16282  write_number(n, use_bjdata);
16283  }
16284 
16285  // UBJSON: write number (unsigned integer)
16286  template<typename NumberType, typename std::enable_if<
16287  std::is_unsigned<NumberType>::value, int>::type = 0>
16288  void write_number_with_ubjson_prefix(const NumberType n,
16289  const bool add_prefix,
16290  const bool use_bjdata)
16291  {
16292  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16293  {
16294  if (add_prefix)
16295  {
16296  oa->write_character(to_char_type('i')); // int8
16297  }
16298  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16299  }
16300  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
16301  {
16302  if (add_prefix)
16303  {
16304  oa->write_character(to_char_type('U')); // uint8
16305  }
16306  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16307  }
16308  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16309  {
16310  if (add_prefix)
16311  {
16312  oa->write_character(to_char_type('I')); // int16
16313  }
16314  write_number(static_cast<std::int16_t>(n), use_bjdata);
16315  }
16316  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
16317  {
16318  if (add_prefix)
16319  {
16320  oa->write_character(to_char_type('u')); // uint16 - bjdata only
16321  }
16322  write_number(static_cast<std::uint16_t>(n), use_bjdata);
16323  }
16324  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16325  {
16326  if (add_prefix)
16327  {
16328  oa->write_character(to_char_type('l')); // int32
16329  }
16330  write_number(static_cast<std::int32_t>(n), use_bjdata);
16331  }
16332  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
16333  {
16334  if (add_prefix)
16335  {
16336  oa->write_character(to_char_type('m')); // uint32 - bjdata only
16337  }
16338  write_number(static_cast<std::uint32_t>(n), use_bjdata);
16339  }
16340  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16341  {
16342  if (add_prefix)
16343  {
16344  oa->write_character(to_char_type('L')); // int64
16345  }
16346  write_number(static_cast<std::int64_t>(n), use_bjdata);
16347  }
16348  else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
16349  {
16350  if (add_prefix)
16351  {
16352  oa->write_character(to_char_type('M')); // uint64 - bjdata only
16353  }
16354  write_number(static_cast<std::uint64_t>(n), use_bjdata);
16355  }
16356  else
16357  {
16358  if (add_prefix)
16359  {
16360  oa->write_character(to_char_type('H')); // high-precision number
16361  }
16362 
16363  const auto number = BasicJsonType(n).dump();
16364  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16365  for (std::size_t i = 0; i < number.size(); ++i)
16366  {
16367  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16368  }
16369  }
16370  }
16371 
16372  // UBJSON: write number (signed integer)
16373  template < typename NumberType, typename std::enable_if <
16374  std::is_signed<NumberType>::value&&
16375  !std::is_floating_point<NumberType>::value, int >::type = 0 >
16376  void write_number_with_ubjson_prefix(const NumberType n,
16377  const bool add_prefix,
16378  const bool use_bjdata)
16379  {
16380  if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
16381  {
16382  if (add_prefix)
16383  {
16384  oa->write_character(to_char_type('i')); // int8
16385  }
16386  write_number(static_cast<std::int8_t>(n), use_bjdata);
16387  }
16388  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)()))
16389  {
16390  if (add_prefix)
16391  {
16392  oa->write_character(to_char_type('U')); // uint8
16393  }
16394  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16395  }
16396  else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
16397  {
16398  if (add_prefix)
16399  {
16400  oa->write_character(to_char_type('I')); // int16
16401  }
16402  write_number(static_cast<std::int16_t>(n), use_bjdata);
16403  }
16404  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)())))
16405  {
16406  if (add_prefix)
16407  {
16408  oa->write_character(to_char_type('u')); // uint16 - bjdata only
16409  }
16410  write_number(static_cast<uint16_t>(n), use_bjdata);
16411  }
16412  else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
16413  {
16414  if (add_prefix)
16415  {
16416  oa->write_character(to_char_type('l')); // int32
16417  }
16418  write_number(static_cast<std::int32_t>(n), use_bjdata);
16419  }
16420  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)())))
16421  {
16422  if (add_prefix)
16423  {
16424  oa->write_character(to_char_type('m')); // uint32 - bjdata only
16425  }
16426  write_number(static_cast<uint32_t>(n), use_bjdata);
16427  }
16428  else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
16429  {
16430  if (add_prefix)
16431  {
16432  oa->write_character(to_char_type('L')); // int64
16433  }
16434  write_number(static_cast<std::int64_t>(n), use_bjdata);
16435  }
16436  // LCOV_EXCL_START
16437  else
16438  {
16439  if (add_prefix)
16440  {
16441  oa->write_character(to_char_type('H')); // high-precision number
16442  }
16443 
16444  const auto number = BasicJsonType(n).dump();
16445  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16446  for (std::size_t i = 0; i < number.size(); ++i)
16447  {
16448  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16449  }
16450  }
16451  // LCOV_EXCL_STOP
16452  }
16453 
16457  CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
16458  {
16459  switch (j.type())
16460  {
16461  case value_t::null:
16462  return 'Z';
16463 
16464  case value_t::boolean:
16465  return j.m_data.m_value.boolean ? 'T' : 'F';
16466 
16467  case value_t::number_integer:
16468  {
16469  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)())
16470  {
16471  return 'i';
16472  }
16473  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)())
16474  {
16475  return 'U';
16476  }
16477  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)())
16478  {
16479  return 'I';
16480  }
16481  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)()))
16482  {
16483  return 'u';
16484  }
16485  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)())
16486  {
16487  return 'l';
16488  }
16489  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)()))
16490  {
16491  return 'm';
16492  }
16493  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)())
16494  {
16495  return 'L';
16496  }
16497  // anything else is treated as high-precision number
16498  return 'H'; // LCOV_EXCL_LINE
16499  }
16500 
16501  case value_t::number_unsigned:
16502  {
16503  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16504  {
16505  return 'i';
16506  }
16507  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
16508  {
16509  return 'U';
16510  }
16511  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16512  {
16513  return 'I';
16514  }
16515  if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
16516  {
16517  return 'u';
16518  }
16519  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16520  {
16521  return 'l';
16522  }
16523  if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
16524  {
16525  return 'm';
16526  }
16527  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16528  {
16529  return 'L';
16530  }
16531  if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16532  {
16533  return 'M';
16534  }
16535  // anything else is treated as high-precision number
16536  return 'H'; // LCOV_EXCL_LINE
16537  }
16538 
16539  case value_t::number_float:
16540  return get_ubjson_float_prefix(j.m_data.m_value.number_float);
16541 
16542  case value_t::string:
16543  return 'S';
16544 
16545  case value_t::array: // fallthrough
16546  case value_t::binary:
16547  return '[';
16548 
16549  case value_t::object:
16550  return '{';
16551 
16552  case value_t::discarded:
16553  default: // discarded values
16554  return 'N';
16555  }
16556  }
16557 
16558  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
16559  {
16560  return 'd'; // float 32
16561  }
16562 
16563  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
16564  {
16565  return 'D'; // float 64
16566  }
16567 
16571  bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
16572  {
16573  std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
16574  {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
16575  };
16576 
16577  string_t key = "_ArrayType_";
16578  auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
16579  if (it == bjdtype.end())
16580  {
16581  return true;
16582  }
16583  CharType dtype = it->second;
16584 
16585  key = "_ArraySize_";
16586  std::size_t len = (value.at(key).empty() ? 0 : 1);
16587  for (const auto& el : value.at(key))
16588  {
16589  len *= static_cast<std::size_t>(el.m_data.m_value.number_unsigned);
16590  }
16591 
16592  key = "_ArrayData_";
16593  if (value.at(key).size() != len)
16594  {
16595  return true;
16596  }
16597 
16598  oa->write_character('[');
16599  oa->write_character('$');
16600  oa->write_character(dtype);
16601  oa->write_character('#');
16602 
16603  key = "_ArraySize_";
16604  write_ubjson(value.at(key), use_count, use_type, true, true);
16605 
16606  key = "_ArrayData_";
16607  if (dtype == 'U' || dtype == 'C')
16608  {
16609  for (const auto& el : value.at(key))
16610  {
16611  write_number(static_cast<std::uint8_t>(el.m_data.m_value.number_unsigned), true);
16612  }
16613  }
16614  else if (dtype == 'i')
16615  {
16616  for (const auto& el : value.at(key))
16617  {
16618  write_number(static_cast<std::int8_t>(el.m_data.m_value.number_integer), true);
16619  }
16620  }
16621  else if (dtype == 'u')
16622  {
16623  for (const auto& el : value.at(key))
16624  {
16625  write_number(static_cast<std::uint16_t>(el.m_data.m_value.number_unsigned), true);
16626  }
16627  }
16628  else if (dtype == 'I')
16629  {
16630  for (const auto& el : value.at(key))
16631  {
16632  write_number(static_cast<std::int16_t>(el.m_data.m_value.number_integer), true);
16633  }
16634  }
16635  else if (dtype == 'm')
16636  {
16637  for (const auto& el : value.at(key))
16638  {
16639  write_number(static_cast<std::uint32_t>(el.m_data.m_value.number_unsigned), true);
16640  }
16641  }
16642  else if (dtype == 'l')
16643  {
16644  for (const auto& el : value.at(key))
16645  {
16646  write_number(static_cast<std::int32_t>(el.m_data.m_value.number_integer), true);
16647  }
16648  }
16649  else if (dtype == 'M')
16650  {
16651  for (const auto& el : value.at(key))
16652  {
16653  write_number(static_cast<std::uint64_t>(el.m_data.m_value.number_unsigned), true);
16654  }
16655  }
16656  else if (dtype == 'L')
16657  {
16658  for (const auto& el : value.at(key))
16659  {
16660  write_number(static_cast<std::int64_t>(el.m_data.m_value.number_integer), true);
16661  }
16662  }
16663  else if (dtype == 'd')
16664  {
16665  for (const auto& el : value.at(key))
16666  {
16667  write_number(static_cast<float>(el.m_data.m_value.number_float), true);
16668  }
16669  }
16670  else if (dtype == 'D')
16671  {
16672  for (const auto& el : value.at(key))
16673  {
16674  write_number(static_cast<double>(el.m_data.m_value.number_float), true);
16675  }
16676  }
16677  return false;
16678  }
16679 
16681  // Utility functions //
16683 
16684  /*
16685  @brief write a number to output input
16686  @param[in] n number of type @a NumberType
16687  @param[in] OutputIsLittleEndian Set to true if output data is
16688  required to be little endian
16689  @tparam NumberType the type of the number
16690 
16691  @note This function needs to respect the system's endianness, because bytes
16692  in CBOR, MessagePack, and UBJSON are stored in network order (big
16693  endian) and therefore need reordering on little endian systems.
16694  On the other hand, BSON and BJData use little endian and should reorder
16695  on big endian systems.
16696  */
16697  template<typename NumberType>
16698  void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
16699  {
16700  // step 1: write number to array of length NumberType
16701  std::array<CharType, sizeof(NumberType)> vec{};
16702  std::memcpy(vec.data(), &n, sizeof(NumberType));
16703 
16704  // step 2: write array to output (with possible reordering)
16705  if (is_little_endian != OutputIsLittleEndian)
16706  {
16707  // reverse byte order prior to conversion if necessary
16708  std::reverse(vec.begin(), vec.end());
16709  }
16710 
16711  oa->write_characters(vec.data(), sizeof(NumberType));
16712  }
16713 
16715  {
16716 #ifdef __GNUC__
16717 #pragma GCC diagnostic push
16718 #pragma GCC diagnostic ignored "-Wfloat-equal"
16719 #endif
16720  if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
16721  static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
16722  static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
16723  {
16724  oa->write_character(format == detail::input_format_t::cbor
16725  ? get_cbor_float_prefix(static_cast<float>(n))
16726  : get_msgpack_float_prefix(static_cast<float>(n)));
16727  write_number(static_cast<float>(n));
16728  }
16729  else
16730  {
16731  oa->write_character(format == detail::input_format_t::cbor
16732  ? get_cbor_float_prefix(n)
16733  : get_msgpack_float_prefix(n));
16734  write_number(n);
16735  }
16736 #ifdef __GNUC__
16737 #pragma GCC diagnostic pop
16738 #endif
16739  }
16740 
16741  public:
16742  // The following to_char_type functions are implement the conversion
16743  // between uint8_t and CharType. In case CharType is not unsigned,
16744  // such a conversion is required to allow values greater than 128.
16745  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
16746  template < typename C = CharType,
16747  enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
16748  static constexpr CharType to_char_type(std::uint8_t x) noexcept
16749  {
16750  return *reinterpret_cast<char*>(&x);
16751  }
16752 
16753  template < typename C = CharType,
16754  enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
16755  static CharType to_char_type(std::uint8_t x) noexcept
16756  {
16757  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
16758  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
16759  CharType result;
16760  std::memcpy(&result, &x, sizeof(x));
16761  return result;
16762  }
16763 
16764  template<typename C = CharType,
16766  static constexpr CharType to_char_type(std::uint8_t x) noexcept
16767  {
16768  return x;
16769  }
16770 
16771  template < typename InputCharType, typename C = CharType,
16772  enable_if_t <
16773  std::is_signed<C>::value &&
16774  std::is_signed<char>::value &&
16776  > * = nullptr >
16777  static constexpr CharType to_char_type(InputCharType x) noexcept
16778  {
16779  return x;
16780  }
16781 
16782  private:
16784  const bool is_little_endian = little_endianness();
16785 
16788 };
16789 
16790 } // namespace detail
16792 
16793 // #include <nlohmann/detail/output/output_adapters.hpp>
16794 
16795 // #include <nlohmann/detail/output/serializer.hpp>
16796 // __ _____ _____ _____
16797 // __| | __| | | | JSON for Modern C++
16798 // | | |__ | | | | | | version 3.11.2
16799 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
16800 //
16801 // SPDX-FileCopyrightText: 2008-2009 Björn Hoehrmann <bjoern@hoehrmann.de>
16802 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
16803 // SPDX-License-Identifier: MIT
16804 
16805 
16806 
16807 #include <algorithm> // reverse, remove, fill, find, none_of
16808 #include <array> // array
16809 #include <clocale> // localeconv, lconv
16810 #include <cmath> // labs, isfinite, isnan, signbit
16811 #include <cstddef> // size_t, ptrdiff_t
16812 #include <cstdint> // uint8_t
16813 #include <cstdio> // snprintf
16814 #include <limits> // numeric_limits
16815 #include <string> // string, char_traits
16816 #include <iomanip> // setfill, setw
16817 #include <type_traits> // is_same
16818 #include <utility> // move
16819 
16820 // #include <nlohmann/detail/conversions/to_chars.hpp>
16821 // __ _____ _____ _____
16822 // __| | __| | | | JSON for Modern C++
16823 // | | |__ | | | | | | version 3.11.2
16824 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
16825 //
16826 // SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>
16827 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
16828 // SPDX-License-Identifier: MIT
16829 
16830 
16831 
16832 #include <array> // array
16833 #include <cmath> // signbit, isfinite
16834 #include <cstdint> // intN_t, uintN_t
16835 #include <cstring> // memcpy, memmove
16836 #include <limits> // numeric_limits
16837 #include <type_traits> // conditional
16838 
16839 // #include <nlohmann/detail/macro_scope.hpp>
16840 
16841 
16843 namespace detail
16844 {
16845 
16865 namespace dtoa_impl
16866 {
16867 
16868 template<typename Target, typename Source>
16869 Target reinterpret_bits(const Source source)
16870 {
16871  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
16872 
16873  Target target;
16874  std::memcpy(&target, &source, sizeof(Source));
16875  return target;
16876 }
16877 
16878 struct diyfp // f * 2^e
16879 {
16880  static constexpr int kPrecision = 64; // = q
16881 
16882  std::uint64_t f = 0;
16883  int e = 0;
16884 
16885  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
16886 
16891  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
16892  {
16893  JSON_ASSERT(x.e == y.e);
16894  JSON_ASSERT(x.f >= y.f);
16895 
16896  return {x.f - y.f, x.e};
16897  }
16898 
16903  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
16904  {
16905  static_assert(kPrecision == 64, "internal error");
16906 
16907  // Computes:
16908  // f = round((x.f * y.f) / 2^q)
16909  // e = x.e + y.e + q
16910 
16911  // Emulate the 64-bit * 64-bit multiplication:
16912  //
16913  // p = u * v
16914  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
16915  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
16916  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
16917  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
16918  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
16919  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
16920  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
16921  //
16922  // (Since Q might be larger than 2^32 - 1)
16923  //
16924  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
16925  //
16926  // (Q_hi + H does not overflow a 64-bit int)
16927  //
16928  // = p_lo + 2^64 p_hi
16929 
16930  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
16931  const std::uint64_t u_hi = x.f >> 32u;
16932  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
16933  const std::uint64_t v_hi = y.f >> 32u;
16934 
16935  const std::uint64_t p0 = u_lo * v_lo;
16936  const std::uint64_t p1 = u_lo * v_hi;
16937  const std::uint64_t p2 = u_hi * v_lo;
16938  const std::uint64_t p3 = u_hi * v_hi;
16939 
16940  const std::uint64_t p0_hi = p0 >> 32u;
16941  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
16942  const std::uint64_t p1_hi = p1 >> 32u;
16943  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
16944  const std::uint64_t p2_hi = p2 >> 32u;
16945 
16946  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
16947 
16948  // The full product might now be computed as
16949  //
16950  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
16951  // p_lo = p0_lo + (Q << 32)
16952  //
16953  // But in this particular case here, the full p_lo is not required.
16954  // Effectively we only need to add the highest bit in p_lo to p_hi (and
16955  // Q_hi + 1 does not overflow).
16956 
16957  Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
16958 
16959  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
16960 
16961  return {h, x.e + y.e + 64};
16962  }
16963 
16968  static diyfp normalize(diyfp x) noexcept
16969  {
16970  JSON_ASSERT(x.f != 0);
16971 
16972  while ((x.f >> 63u) == 0)
16973  {
16974  x.f <<= 1u;
16975  x.e--;
16976  }
16977 
16978  return x;
16979  }
16980 
16985  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
16986  {
16987  const int delta = x.e - target_exponent;
16988 
16989  JSON_ASSERT(delta >= 0);
16990  JSON_ASSERT(((x.f << delta) >> delta) == x.f);
16991 
16992  return {x.f << delta, target_exponent};
16993  }
16994 };
16995 
16997 {
17001 };
17002 
17009 template<typename FloatType>
17011 {
17012  JSON_ASSERT(std::isfinite(value));
17013  JSON_ASSERT(value > 0);
17014 
17015  // Convert the IEEE representation into a diyfp.
17016  //
17017  // If v is denormal:
17018  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
17019  // If v is normalized:
17020  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
17021 
17022  static_assert(std::numeric_limits<FloatType>::is_iec559,
17023  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
17024 
17025  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
17026  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
17027  constexpr int kMinExp = 1 - kBias;
17028  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
17029 
17031 
17032  const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
17033  const std::uint64_t E = bits >> (kPrecision - 1);
17034  const std::uint64_t F = bits & (kHiddenBit - 1);
17035 
17036  const bool is_denormal = E == 0;
17037  const diyfp v = is_denormal
17038  ? diyfp(F, kMinExp)
17039  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
17040 
17041  // Compute the boundaries m- and m+ of the floating-point value
17042  // v = f * 2^e.
17043  //
17044  // Determine v- and v+, the floating-point predecessor and successor if v,
17045  // respectively.
17046  //
17047  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
17048  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
17049  //
17050  // v+ = v + 2^e
17051  //
17052  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
17053  // between m- and m+ round to v, regardless of how the input rounding
17054  // algorithm breaks ties.
17055  //
17056  // ---+-------------+-------------+-------------+-------------+--- (A)
17057  // v- m- v m+ v+
17058  //
17059  // -----------------+------+------+-------------+-------------+--- (B)
17060  // v- m- v m+ v+
17061 
17062  const bool lower_boundary_is_closer = F == 0 && E > 1;
17063  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
17064  const diyfp m_minus = lower_boundary_is_closer
17065  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
17066  : diyfp(2 * v.f - 1, v.e - 1); // (A)
17067 
17068  // Determine the normalized w+ = m+.
17069  const diyfp w_plus = diyfp::normalize(m_plus);
17070 
17071  // Determine w- = m- such that e_(w-) = e_(w+).
17072  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
17073 
17074  return {diyfp::normalize(v), w_minus, w_plus};
17075 }
17076 
17077 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
17078 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
17079 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
17080 //
17081 // alpha <= e = e_c + e_w + q <= gamma
17082 //
17083 // or
17084 //
17085 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
17086 // <= f_c * f_w * 2^gamma
17087 //
17088 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
17089 //
17090 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
17091 //
17092 // or
17093 //
17094 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
17095 //
17096 // The choice of (alpha,gamma) determines the size of the table and the form of
17097 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
17098 // in practice:
17099 //
17100 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
17101 // processed independently: An integral part p1, and a fractional part p2:
17102 //
17103 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
17104 // = (f div 2^-e) + (f mod 2^-e) * 2^e
17105 // = p1 + p2 * 2^e
17106 //
17107 // The conversion of p1 into decimal form requires a series of divisions and
17108 // modulos by (a power of) 10. These operations are faster for 32-bit than for
17109 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
17110 // achieved by choosing
17111 //
17112 // -e >= 32 or e <= -32 := gamma
17113 //
17114 // In order to convert the fractional part
17115 //
17116 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
17117 //
17118 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
17119 // d[-i] are extracted in order:
17120 //
17121 // (10 * p2) div 2^-e = d[-1]
17122 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
17123 //
17124 // The multiplication by 10 must not overflow. It is sufficient to choose
17125 //
17126 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
17127 //
17128 // Since p2 = f mod 2^-e < 2^-e,
17129 //
17130 // -e <= 60 or e >= -60 := alpha
17131 
17132 constexpr int kAlpha = -60;
17133 constexpr int kGamma = -32;
17134 
17135 struct cached_power // c = f * 2^e ~= 10^k
17136 {
17137  std::uint64_t f;
17138  int e;
17139  int k;
17140 };
17141 
17150 {
17151  // Now
17152  //
17153  // alpha <= e_c + e + q <= gamma (1)
17154  // ==> f_c * 2^alpha <= c * 2^e * 2^q
17155  //
17156  // and since the c's are normalized, 2^(q-1) <= f_c,
17157  //
17158  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
17159  // ==> 2^(alpha - e - 1) <= c
17160  //
17161  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
17162  //
17163  // k = ceil( log_10( 2^(alpha - e - 1) ) )
17164  // = ceil( (alpha - e - 1) * log_10(2) )
17165  //
17166  // From the paper:
17167  // "In theory the result of the procedure could be wrong since c is rounded,
17168  // and the computation itself is approximated [...]. In practice, however,
17169  // this simple function is sufficient."
17170  //
17171  // For IEEE double precision floating-point numbers converted into
17172  // normalized diyfp's w = f * 2^e, with q = 64,
17173  //
17174  // e >= -1022 (min IEEE exponent)
17175  // -52 (p - 1)
17176  // -52 (p - 1, possibly normalize denormal IEEE numbers)
17177  // -11 (normalize the diyfp)
17178  // = -1137
17179  //
17180  // and
17181  //
17182  // e <= +1023 (max IEEE exponent)
17183  // -52 (p - 1)
17184  // -11 (normalize the diyfp)
17185  // = 960
17186  //
17187  // This binary exponent range [-1137,960] results in a decimal exponent
17188  // range [-307,324]. One does not need to store a cached power for each
17189  // k in this range. For each such k it suffices to find a cached power
17190  // such that the exponent of the product lies in [alpha,gamma].
17191  // This implies that the difference of the decimal exponents of adjacent
17192  // table entries must be less than or equal to
17193  //
17194  // floor( (gamma - alpha) * log_10(2) ) = 8.
17195  //
17196  // (A smaller distance gamma-alpha would require a larger table.)
17197 
17198  // NB:
17199  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
17200 
17201  constexpr int kCachedPowersMinDecExp = -300;
17202  constexpr int kCachedPowersDecStep = 8;
17203 
17204  static constexpr std::array<cached_power, 79> kCachedPowers =
17205  {
17206  {
17207  { 0xAB70FE17C79AC6CA, -1060, -300 },
17208  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
17209  { 0xBE5691EF416BD60C, -1007, -284 },
17210  { 0x8DD01FAD907FFC3C, -980, -276 },
17211  { 0xD3515C2831559A83, -954, -268 },
17212  { 0x9D71AC8FADA6C9B5, -927, -260 },
17213  { 0xEA9C227723EE8BCB, -901, -252 },
17214  { 0xAECC49914078536D, -874, -244 },
17215  { 0x823C12795DB6CE57, -847, -236 },
17216  { 0xC21094364DFB5637, -821, -228 },
17217  { 0x9096EA6F3848984F, -794, -220 },
17218  { 0xD77485CB25823AC7, -768, -212 },
17219  { 0xA086CFCD97BF97F4, -741, -204 },
17220  { 0xEF340A98172AACE5, -715, -196 },
17221  { 0xB23867FB2A35B28E, -688, -188 },
17222  { 0x84C8D4DFD2C63F3B, -661, -180 },
17223  { 0xC5DD44271AD3CDBA, -635, -172 },
17224  { 0x936B9FCEBB25C996, -608, -164 },
17225  { 0xDBAC6C247D62A584, -582, -156 },
17226  { 0xA3AB66580D5FDAF6, -555, -148 },
17227  { 0xF3E2F893DEC3F126, -529, -140 },
17228  { 0xB5B5ADA8AAFF80B8, -502, -132 },
17229  { 0x87625F056C7C4A8B, -475, -124 },
17230  { 0xC9BCFF6034C13053, -449, -116 },
17231  { 0x964E858C91BA2655, -422, -108 },
17232  { 0xDFF9772470297EBD, -396, -100 },
17233  { 0xA6DFBD9FB8E5B88F, -369, -92 },
17234  { 0xF8A95FCF88747D94, -343, -84 },
17235  { 0xB94470938FA89BCF, -316, -76 },
17236  { 0x8A08F0F8BF0F156B, -289, -68 },
17237  { 0xCDB02555653131B6, -263, -60 },
17238  { 0x993FE2C6D07B7FAC, -236, -52 },
17239  { 0xE45C10C42A2B3B06, -210, -44 },
17240  { 0xAA242499697392D3, -183, -36 },
17241  { 0xFD87B5F28300CA0E, -157, -28 },
17242  { 0xBCE5086492111AEB, -130, -20 },
17243  { 0x8CBCCC096F5088CC, -103, -12 },
17244  { 0xD1B71758E219652C, -77, -4 },
17245  { 0x9C40000000000000, -50, 4 },
17246  { 0xE8D4A51000000000, -24, 12 },
17247  { 0xAD78EBC5AC620000, 3, 20 },
17248  { 0x813F3978F8940984, 30, 28 },
17249  { 0xC097CE7BC90715B3, 56, 36 },
17250  { 0x8F7E32CE7BEA5C70, 83, 44 },
17251  { 0xD5D238A4ABE98068, 109, 52 },
17252  { 0x9F4F2726179A2245, 136, 60 },
17253  { 0xED63A231D4C4FB27, 162, 68 },
17254  { 0xB0DE65388CC8ADA8, 189, 76 },
17255  { 0x83C7088E1AAB65DB, 216, 84 },
17256  { 0xC45D1DF942711D9A, 242, 92 },
17257  { 0x924D692CA61BE758, 269, 100 },
17258  { 0xDA01EE641A708DEA, 295, 108 },
17259  { 0xA26DA3999AEF774A, 322, 116 },
17260  { 0xF209787BB47D6B85, 348, 124 },
17261  { 0xB454E4A179DD1877, 375, 132 },
17262  { 0x865B86925B9BC5C2, 402, 140 },
17263  { 0xC83553C5C8965D3D, 428, 148 },
17264  { 0x952AB45CFA97A0B3, 455, 156 },
17265  { 0xDE469FBD99A05FE3, 481, 164 },
17266  { 0xA59BC234DB398C25, 508, 172 },
17267  { 0xF6C69A72A3989F5C, 534, 180 },
17268  { 0xB7DCBF5354E9BECE, 561, 188 },
17269  { 0x88FCF317F22241E2, 588, 196 },
17270  { 0xCC20CE9BD35C78A5, 614, 204 },
17271  { 0x98165AF37B2153DF, 641, 212 },
17272  { 0xE2A0B5DC971F303A, 667, 220 },
17273  { 0xA8D9D1535CE3B396, 694, 228 },
17274  { 0xFB9B7CD9A4A7443C, 720, 236 },
17275  { 0xBB764C4CA7A44410, 747, 244 },
17276  { 0x8BAB8EEFB6409C1A, 774, 252 },
17277  { 0xD01FEF10A657842C, 800, 260 },
17278  { 0x9B10A4E5E9913129, 827, 268 },
17279  { 0xE7109BFBA19C0C9D, 853, 276 },
17280  { 0xAC2820D9623BF429, 880, 284 },
17281  { 0x80444B5E7AA7CF85, 907, 292 },
17282  { 0xBF21E44003ACDD2D, 933, 300 },
17283  { 0x8E679C2F5E44FF8F, 960, 308 },
17284  { 0xD433179D9C8CB841, 986, 316 },
17285  { 0x9E19DB92B4E31BA9, 1013, 324 },
17286  }
17287  };
17288 
17289  // This computation gives exactly the same results for k as
17290  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
17291  // for |e| <= 1500, but doesn't require floating-point operations.
17292  // NB: log_10(2) ~= 78913 / 2^18
17293  JSON_ASSERT(e >= -1500);
17294  JSON_ASSERT(e <= 1500);
17295  const int f = kAlpha - e - 1;
17296  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
17297 
17298  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
17299  JSON_ASSERT(index >= 0);
17300  JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
17301 
17302  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
17303  JSON_ASSERT(kAlpha <= cached.e + e + 64);
17304  JSON_ASSERT(kGamma >= cached.e + e + 64);
17305 
17306  return cached;
17307 }
17308 
17313 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
17314 {
17315  // LCOV_EXCL_START
17316  if (n >= 1000000000)
17317  {
17318  pow10 = 1000000000;
17319  return 10;
17320  }
17321  // LCOV_EXCL_STOP
17322  if (n >= 100000000)
17323  {
17324  pow10 = 100000000;
17325  return 9;
17326  }
17327  if (n >= 10000000)
17328  {
17329  pow10 = 10000000;
17330  return 8;
17331  }
17332  if (n >= 1000000)
17333  {
17334  pow10 = 1000000;
17335  return 7;
17336  }
17337  if (n >= 100000)
17338  {
17339  pow10 = 100000;
17340  return 6;
17341  }
17342  if (n >= 10000)
17343  {
17344  pow10 = 10000;
17345  return 5;
17346  }
17347  if (n >= 1000)
17348  {
17349  pow10 = 1000;
17350  return 4;
17351  }
17352  if (n >= 100)
17353  {
17354  pow10 = 100;
17355  return 3;
17356  }
17357  if (n >= 10)
17358  {
17359  pow10 = 10;
17360  return 2;
17361  }
17362 
17363  pow10 = 1;
17364  return 1;
17365 }
17366 
17367 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
17368  std::uint64_t rest, std::uint64_t ten_k)
17369 {
17370  JSON_ASSERT(len >= 1);
17371  JSON_ASSERT(dist <= delta);
17372  JSON_ASSERT(rest <= delta);
17373  JSON_ASSERT(ten_k > 0);
17374 
17375  // <--------------------------- delta ---->
17376  // <---- dist --------->
17377  // --------------[------------------+-------------------]--------------
17378  // M- w M+
17379  //
17380  // ten_k
17381  // <------>
17382  // <---- rest ---->
17383  // --------------[------------------+----+--------------]--------------
17384  // w V
17385  // = buf * 10^k
17386  //
17387  // ten_k represents a unit-in-the-last-place in the decimal representation
17388  // stored in buf.
17389  // Decrement buf by ten_k while this takes buf closer to w.
17390 
17391  // The tests are written in this order to avoid overflow in unsigned
17392  // integer arithmetic.
17393 
17394  while (rest < dist
17395  && delta - rest >= ten_k
17396  && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
17397  {
17398  JSON_ASSERT(buf[len - 1] != '0');
17399  buf[len - 1]--;
17400  rest += ten_k;
17401  }
17402 }
17403 
17408 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
17409  diyfp M_minus, diyfp w, diyfp M_plus)
17410 {
17411  static_assert(kAlpha >= -60, "internal error");
17412  static_assert(kGamma <= -32, "internal error");
17413 
17414  // Generates the digits (and the exponent) of a decimal floating-point
17415  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
17416  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
17417  //
17418  // <--------------------------- delta ---->
17419  // <---- dist --------->
17420  // --------------[------------------+-------------------]--------------
17421  // M- w M+
17422  //
17423  // Grisu2 generates the digits of M+ from left to right and stops as soon as
17424  // V is in [M-,M+].
17425 
17426  JSON_ASSERT(M_plus.e >= kAlpha);
17427  JSON_ASSERT(M_plus.e <= kGamma);
17428 
17429  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
17430  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
17431 
17432  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
17433  //
17434  // M+ = f * 2^e
17435  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
17436  // = ((p1 ) * 2^-e + (p2 )) * 2^e
17437  // = p1 + p2 * 2^e
17438 
17439  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
17440 
17441  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.)
17442  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
17443 
17444  // 1)
17445  //
17446  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
17447 
17448  JSON_ASSERT(p1 > 0);
17449 
17450  std::uint32_t pow10{};
17451  const int k = find_largest_pow10(p1, pow10);
17452 
17453  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
17454  //
17455  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
17456  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
17457  //
17458  // M+ = p1 + p2 * 2^e
17459  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
17460  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
17461  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
17462  //
17463  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
17464  //
17465  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
17466  //
17467  // but stop as soon as
17468  //
17469  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
17470 
17471  int n = k;
17472  while (n > 0)
17473  {
17474  // Invariants:
17475  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
17476  // pow10 = 10^(n-1) <= p1 < 10^n
17477  //
17478  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
17479  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
17480  //
17481  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
17482  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
17483  //
17484  JSON_ASSERT(d <= 9);
17485  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17486  //
17487  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
17488  //
17489  p1 = r;
17490  n--;
17491  //
17492  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
17493  // pow10 = 10^n
17494  //
17495 
17496  // Now check if enough digits have been generated.
17497  // Compute
17498  //
17499  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
17500  //
17501  // Note:
17502  // Since rest and delta share the same exponent e, it suffices to
17503  // compare the significands.
17504  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
17505  if (rest <= delta)
17506  {
17507  // V = buffer * 10^n, with M- <= V <= M+.
17508 
17509  decimal_exponent += n;
17510 
17511  // We may now just stop. But instead look if the buffer could be
17512  // decremented to bring V closer to w.
17513  //
17514  // pow10 = 10^n is now 1 ulp in the decimal representation V.
17515  // The rounding procedure works with diyfp's with an implicit
17516  // exponent of e.
17517  //
17518  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
17519  //
17520  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
17521  grisu2_round(buffer, length, dist, delta, rest, ten_n);
17522 
17523  return;
17524  }
17525 
17526  pow10 /= 10;
17527  //
17528  // pow10 = 10^(n-1) <= p1 < 10^n
17529  // Invariants restored.
17530  }
17531 
17532  // 2)
17533  //
17534  // The digits of the integral part have been generated:
17535  //
17536  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
17537  // = buffer + p2 * 2^e
17538  //
17539  // Now generate the digits of the fractional part p2 * 2^e.
17540  //
17541  // Note:
17542  // No decimal point is generated: the exponent is adjusted instead.
17543  //
17544  // p2 actually represents the fraction
17545  //
17546  // p2 * 2^e
17547  // = p2 / 2^-e
17548  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
17549  //
17550  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
17551  //
17552  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
17553  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
17554  //
17555  // using
17556  //
17557  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
17558  // = ( d) * 2^-e + ( r)
17559  //
17560  // or
17561  // 10^m * p2 * 2^e = d + r * 2^e
17562  //
17563  // i.e.
17564  //
17565  // M+ = buffer + p2 * 2^e
17566  // = buffer + 10^-m * (d + r * 2^e)
17567  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
17568  //
17569  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
17570 
17571  JSON_ASSERT(p2 > delta);
17572 
17573  int m = 0;
17574  for (;;)
17575  {
17576  // Invariant:
17577  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
17578  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
17579  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
17580  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
17581  //
17582  JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
17583  p2 *= 10;
17584  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
17585  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
17586  //
17587  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
17588  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
17589  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
17590  //
17591  JSON_ASSERT(d <= 9);
17592  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17593  //
17594  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
17595  //
17596  p2 = r;
17597  m++;
17598  //
17599  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
17600  // Invariant restored.
17601 
17602  // Check if enough digits have been generated.
17603  //
17604  // 10^-m * p2 * 2^e <= delta * 2^e
17605  // p2 * 2^e <= 10^m * delta * 2^e
17606  // p2 <= 10^m * delta
17607  delta *= 10;
17608  dist *= 10;
17609  if (p2 <= delta)
17610  {
17611  break;
17612  }
17613  }
17614 
17615  // V = buffer * 10^-m, with M- <= V <= M+.
17616 
17617  decimal_exponent -= m;
17618 
17619  // 1 ulp in the decimal representation is now 10^-m.
17620  // Since delta and dist are now scaled by 10^m, we need to do the
17621  // same with ulp in order to keep the units in sync.
17622  //
17623  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
17624  //
17625  const std::uint64_t ten_m = one.f;
17626  grisu2_round(buffer, length, dist, delta, p2, ten_m);
17627 
17628  // By construction this algorithm generates the shortest possible decimal
17629  // number (Loitsch, Theorem 6.2) which rounds back to w.
17630  // For an input number of precision p, at least
17631  //
17632  // N = 1 + ceil(p * log_10(2))
17633  //
17634  // decimal digits are sufficient to identify all binary floating-point
17635  // numbers (Matula, "In-and-Out conversions").
17636  // This implies that the algorithm does not produce more than N decimal
17637  // digits.
17638  //
17639  // N = 17 for p = 53 (IEEE double precision)
17640  // N = 9 for p = 24 (IEEE single precision)
17641 }
17642 
17649 inline void grisu2(char* buf, int& len, int& decimal_exponent,
17650  diyfp m_minus, diyfp v, diyfp m_plus)
17651 {
17652  JSON_ASSERT(m_plus.e == m_minus.e);
17653  JSON_ASSERT(m_plus.e == v.e);
17654 
17655  // --------(-----------------------+-----------------------)-------- (A)
17656  // m- v m+
17657  //
17658  // --------------------(-----------+-----------------------)-------- (B)
17659  // m- v m+
17660  //
17661  // First scale v (and m- and m+) such that the exponent is in the range
17662  // [alpha, gamma].
17663 
17664  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
17665 
17666  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
17667 
17668  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
17669  const diyfp w = diyfp::mul(v, c_minus_k);
17670  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
17671  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
17672 
17673  // ----(---+---)---------------(---+---)---------------(---+---)----
17674  // w- w w+
17675  // = c*m- = c*v = c*m+
17676  //
17677  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
17678  // w+ are now off by a small amount.
17679  // In fact:
17680  //
17681  // w - v * 10^k < 1 ulp
17682  //
17683  // To account for this inaccuracy, add resp. subtract 1 ulp.
17684  //
17685  // --------+---[---------------(---+---)---------------]---+--------
17686  // w- M- w M+ w+
17687  //
17688  // Now any number in [M-, M+] (bounds included) will round to w when input,
17689  // regardless of how the input rounding algorithm breaks ties.
17690  //
17691  // And digit_gen generates the shortest possible such number in [M-, M+].
17692  // Note that this does not mean that Grisu2 always generates the shortest
17693  // possible number in the interval (m-, m+).
17694  const diyfp M_minus(w_minus.f + 1, w_minus.e);
17695  const diyfp M_plus (w_plus.f - 1, w_plus.e );
17696 
17697  decimal_exponent = -cached.k; // = -(-k) = k
17698 
17699  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
17700 }
17701 
17707 template<typename FloatType>
17709 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
17710 {
17711  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
17712  "internal error: not enough precision");
17713 
17714  JSON_ASSERT(std::isfinite(value));
17715  JSON_ASSERT(value > 0);
17716 
17717  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
17718  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
17719  // decimal representations are not exactly "short".
17720  //
17721  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
17722  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
17723  // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
17724  // does.
17725  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
17726  // representation using the corresponding std::from_chars function recovers value exactly". That
17727  // indicates that single precision floating-point numbers should be recovered using
17728  // 'std::strtof'.
17729  //
17730  // NB: If the neighbors are computed for single-precision numbers, there is a single float
17731  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
17732  // value is off by 1 ulp.
17733 #if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)
17734  const boundaries w = compute_boundaries(static_cast<double>(value));
17735 #else
17736  const boundaries w = compute_boundaries(value);
17737 #endif
17738 
17739  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
17740 }
17741 
17749 inline char* append_exponent(char* buf, int e)
17750 {
17751  JSON_ASSERT(e > -1000);
17752  JSON_ASSERT(e < 1000);
17753 
17754  if (e < 0)
17755  {
17756  e = -e;
17757  *buf++ = '-';
17758  }
17759  else
17760  {
17761  *buf++ = '+';
17762  }
17763 
17764  auto k = static_cast<std::uint32_t>(e);
17765  if (k < 10)
17766  {
17767  // Always print at least two digits in the exponent.
17768  // This is for compatibility with printf("%g").
17769  *buf++ = '0';
17770  *buf++ = static_cast<char>('0' + k);
17771  }
17772  else if (k < 100)
17773  {
17774  *buf++ = static_cast<char>('0' + k / 10);
17775  k %= 10;
17776  *buf++ = static_cast<char>('0' + k);
17777  }
17778  else
17779  {
17780  *buf++ = static_cast<char>('0' + k / 100);
17781  k %= 100;
17782  *buf++ = static_cast<char>('0' + k / 10);
17783  k %= 10;
17784  *buf++ = static_cast<char>('0' + k);
17785  }
17786 
17787  return buf;
17788 }
17789 
17801 inline char* format_buffer(char* buf, int len, int decimal_exponent,
17802  int min_exp, int max_exp)
17803 {
17804  JSON_ASSERT(min_exp < 0);
17805  JSON_ASSERT(max_exp > 0);
17806 
17807  const int k = len;
17808  const int n = len + decimal_exponent;
17809 
17810  // v = buf * 10^(n-k)
17811  // k is the length of the buffer (number of decimal digits)
17812  // n is the position of the decimal point relative to the start of the buffer.
17813 
17814  if (k <= n && n <= max_exp)
17815  {
17816  // digits[000]
17817  // len <= max_exp + 2
17818 
17819  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
17820  // Make it look like a floating-point number (#362, #378)
17821  buf[n + 0] = '.';
17822  buf[n + 1] = '0';
17823  return buf + (static_cast<size_t>(n) + 2);
17824  }
17825 
17826  if (0 < n && n <= max_exp)
17827  {
17828  // dig.its
17829  // len <= max_digits10 + 1
17830 
17831  JSON_ASSERT(k > n);
17832 
17833  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
17834  buf[n] = '.';
17835  return buf + (static_cast<size_t>(k) + 1U);
17836  }
17837 
17838  if (min_exp < n && n <= 0)
17839  {
17840  // 0.[000]digits
17841  // len <= 2 + (-min_exp - 1) + max_digits10
17842 
17843  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
17844  buf[0] = '0';
17845  buf[1] = '.';
17846  std::memset(buf + 2, '0', static_cast<size_t>(-n));
17847  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
17848  }
17849 
17850  if (k == 1)
17851  {
17852  // dE+123
17853  // len <= 1 + 5
17854 
17855  buf += 1;
17856  }
17857  else
17858  {
17859  // d.igitsE+123
17860  // len <= max_digits10 + 1 + 5
17861 
17862  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
17863  buf[1] = '.';
17864  buf += 1 + static_cast<size_t>(k);
17865  }
17866 
17867  *buf++ = 'e';
17868  return append_exponent(buf, n - 1);
17869 }
17870 
17871 } // namespace dtoa_impl
17872 
17883 template<typename FloatType>
17886 char* to_chars(char* first, const char* last, FloatType value)
17887 {
17888  static_cast<void>(last); // maybe unused - fix warning
17889  JSON_ASSERT(std::isfinite(value));
17890 
17891  // Use signbit(value) instead of (value < 0) since signbit works for -0.
17892  if (std::signbit(value))
17893  {
17894  value = -value;
17895  *first++ = '-';
17896  }
17897 
17898 #ifdef __GNUC__
17899 #pragma GCC diagnostic push
17900 #pragma GCC diagnostic ignored "-Wfloat-equal"
17901 #endif
17902  if (value == 0) // +-0
17903  {
17904  *first++ = '0';
17905  // Make it look like a floating-point number (#362, #378)
17906  *first++ = '.';
17907  *first++ = '0';
17908  return first;
17909  }
17910 #ifdef __GNUC__
17911 #pragma GCC diagnostic pop
17912 #endif
17913 
17914  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
17915 
17916  // Compute v = buffer * 10^decimal_exponent.
17917  // The decimal digits are stored in the buffer, which needs to be interpreted
17918  // as an unsigned decimal integer.
17919  // len is the length of the buffer, i.e. the number of decimal digits.
17920  int len = 0;
17921  int decimal_exponent = 0;
17922  dtoa_impl::grisu2(first, len, decimal_exponent, value);
17923 
17924  JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
17925 
17926  // Format the buffer like printf("%.*g", prec, value)
17927  constexpr int kMinExp = -4;
17928  // Use digits10 here to increase compatibility with version 2.
17929  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
17930 
17931  JSON_ASSERT(last - first >= kMaxExp + 2);
17932  JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
17933  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
17934 
17935  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
17936 }
17937 
17938 } // namespace detail
17940 
17941 // #include <nlohmann/detail/exceptions.hpp>
17942 
17943 // #include <nlohmann/detail/macro_scope.hpp>
17944 
17945 // #include <nlohmann/detail/meta/cpp_future.hpp>
17946 
17947 // #include <nlohmann/detail/output/binary_writer.hpp>
17948 
17949 // #include <nlohmann/detail/output/output_adapters.hpp>
17950 
17951 // #include <nlohmann/detail/string_concat.hpp>
17952 
17953 // #include <nlohmann/detail/value_t.hpp>
17954 
17955 
17957 namespace detail
17958 {
17959 
17961 // serialization //
17963 
17966 {
17967  strict,
17968  replace,
17969  ignore
17970 };
17971 
17972 template<typename BasicJsonType>
17974 {
17975  using string_t = typename BasicJsonType::string_t;
17976  using number_float_t = typename BasicJsonType::number_float_t;
17977  using number_integer_t = typename BasicJsonType::number_integer_t;
17978  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17979  using binary_char_t = typename BasicJsonType::binary_t::value_type;
17980  static constexpr std::uint8_t UTF8_ACCEPT = 0;
17981  static constexpr std::uint8_t UTF8_REJECT = 1;
17982 
17983  public:
17989  serializer(output_adapter_t<char> s, const char ichar,
17990  error_handler_t error_handler_ = error_handler_t::strict)
17991  : o(std::move(s))
17992  , loc(std::localeconv())
17993  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
17994  , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
17995  , indent_char(ichar)
17996  , indent_string(512, indent_char)
17997  , error_handler(error_handler_)
17998  {}
17999 
18000  // delete because of pointer members
18001  serializer(const serializer&) = delete;
18002  serializer& operator=(const serializer&) = delete;
18003  serializer(serializer&&) = delete;
18004  serializer& operator=(serializer&&) = delete;
18005  ~serializer() = default;
18006 
18029  void dump(const BasicJsonType& val,
18030  const bool pretty_print,
18031  const bool ensure_ascii,
18032  const unsigned int indent_step,
18033  const unsigned int current_indent = 0)
18034  {
18035  switch (val.m_data.m_type)
18036  {
18037  case value_t::object:
18038  {
18039  if (val.m_data.m_value.object->empty())
18040  {
18041  o->write_characters("{}", 2);
18042  return;
18043  }
18044 
18045  if (pretty_print)
18046  {
18047  o->write_characters("{\n", 2);
18048 
18049  // variable to hold indentation for recursive calls
18050  const auto new_indent = current_indent + indent_step;
18051  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18052  {
18053  indent_string.resize(indent_string.size() * 2, ' ');
18054  }
18055 
18056  // first n-1 elements
18057  auto i = val.m_data.m_value.object->cbegin();
18058  for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18059  {
18060  o->write_characters(indent_string.c_str(), new_indent);
18061  o->write_character('\"');
18062  dump_escaped(i->first, ensure_ascii);
18063  o->write_characters("\": ", 3);
18064  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18065  o->write_characters(",\n", 2);
18066  }
18067 
18068  // last element
18069  JSON_ASSERT(i != val.m_data.m_value.object->cend());
18070  JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18071  o->write_characters(indent_string.c_str(), new_indent);
18072  o->write_character('\"');
18073  dump_escaped(i->first, ensure_ascii);
18074  o->write_characters("\": ", 3);
18075  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18076 
18077  o->write_character('\n');
18078  o->write_characters(indent_string.c_str(), current_indent);
18079  o->write_character('}');
18080  }
18081  else
18082  {
18083  o->write_character('{');
18084 
18085  // first n-1 elements
18086  auto i = val.m_data.m_value.object->cbegin();
18087  for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18088  {
18089  o->write_character('\"');
18090  dump_escaped(i->first, ensure_ascii);
18091  o->write_characters("\":", 2);
18092  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18093  o->write_character(',');
18094  }
18095 
18096  // last element
18097  JSON_ASSERT(i != val.m_data.m_value.object->cend());
18098  JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18099  o->write_character('\"');
18100  dump_escaped(i->first, ensure_ascii);
18101  o->write_characters("\":", 2);
18102  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18103 
18104  o->write_character('}');
18105  }
18106 
18107  return;
18108  }
18109 
18110  case value_t::array:
18111  {
18112  if (val.m_data.m_value.array->empty())
18113  {
18114  o->write_characters("[]", 2);
18115  return;
18116  }
18117 
18118  if (pretty_print)
18119  {
18120  o->write_characters("[\n", 2);
18121 
18122  // variable to hold indentation for recursive calls
18123  const auto new_indent = current_indent + indent_step;
18124  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18125  {
18126  indent_string.resize(indent_string.size() * 2, ' ');
18127  }
18128 
18129  // first n-1 elements
18130  for (auto i = val.m_data.m_value.array->cbegin();
18131  i != val.m_data.m_value.array->cend() - 1; ++i)
18132  {
18133  o->write_characters(indent_string.c_str(), new_indent);
18134  dump(*i, true, ensure_ascii, indent_step, new_indent);
18135  o->write_characters(",\n", 2);
18136  }
18137 
18138  // last element
18139  JSON_ASSERT(!val.m_data.m_value.array->empty());
18140  o->write_characters(indent_string.c_str(), new_indent);
18141  dump(val.m_data.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
18142 
18143  o->write_character('\n');
18144  o->write_characters(indent_string.c_str(), current_indent);
18145  o->write_character(']');
18146  }
18147  else
18148  {
18149  o->write_character('[');
18150 
18151  // first n-1 elements
18152  for (auto i = val.m_data.m_value.array->cbegin();
18153  i != val.m_data.m_value.array->cend() - 1; ++i)
18154  {
18155  dump(*i, false, ensure_ascii, indent_step, current_indent);
18156  o->write_character(',');
18157  }
18158 
18159  // last element
18160  JSON_ASSERT(!val.m_data.m_value.array->empty());
18161  dump(val.m_data.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
18162 
18163  o->write_character(']');
18164  }
18165 
18166  return;
18167  }
18168 
18169  case value_t::string:
18170  {
18171  o->write_character('\"');
18172  dump_escaped(*val.m_data.m_value.string, ensure_ascii);
18173  o->write_character('\"');
18174  return;
18175  }
18176 
18177  case value_t::binary:
18178  {
18179  if (pretty_print)
18180  {
18181  o->write_characters("{\n", 2);
18182 
18183  // variable to hold indentation for recursive calls
18184  const auto new_indent = current_indent + indent_step;
18185  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18186  {
18187  indent_string.resize(indent_string.size() * 2, ' ');
18188  }
18189 
18190  o->write_characters(indent_string.c_str(), new_indent);
18191 
18192  o->write_characters("\"bytes\": [", 10);
18193 
18194  if (!val.m_data.m_value.binary->empty())
18195  {
18196  for (auto i = val.m_data.m_value.binary->cbegin();
18197  i != val.m_data.m_value.binary->cend() - 1; ++i)
18198  {
18199  dump_integer(*i);
18200  o->write_characters(", ", 2);
18201  }
18202  dump_integer(val.m_data.m_value.binary->back());
18203  }
18204 
18205  o->write_characters("],\n", 3);
18206  o->write_characters(indent_string.c_str(), new_indent);
18207 
18208  o->write_characters("\"subtype\": ", 11);
18209  if (val.m_data.m_value.binary->has_subtype())
18210  {
18211  dump_integer(val.m_data.m_value.binary->subtype());
18212  }
18213  else
18214  {
18215  o->write_characters("null", 4);
18216  }
18217  o->write_character('\n');
18218  o->write_characters(indent_string.c_str(), current_indent);
18219  o->write_character('}');
18220  }
18221  else
18222  {
18223  o->write_characters("{\"bytes\":[", 10);
18224 
18225  if (!val.m_data.m_value.binary->empty())
18226  {
18227  for (auto i = val.m_data.m_value.binary->cbegin();
18228  i != val.m_data.m_value.binary->cend() - 1; ++i)
18229  {
18230  dump_integer(*i);
18231  o->write_character(',');
18232  }
18233  dump_integer(val.m_data.m_value.binary->back());
18234  }
18235 
18236  o->write_characters("],\"subtype\":", 12);
18237  if (val.m_data.m_value.binary->has_subtype())
18238  {
18239  dump_integer(val.m_data.m_value.binary->subtype());
18240  o->write_character('}');
18241  }
18242  else
18243  {
18244  o->write_characters("null}", 5);
18245  }
18246  }
18247  return;
18248  }
18249 
18250  case value_t::boolean:
18251  {
18252  if (val.m_data.m_value.boolean)
18253  {
18254  o->write_characters("true", 4);
18255  }
18256  else
18257  {
18258  o->write_characters("false", 5);
18259  }
18260  return;
18261  }
18262 
18263  case value_t::number_integer:
18264  {
18265  dump_integer(val.m_data.m_value.number_integer);
18266  return;
18267  }
18268 
18269  case value_t::number_unsigned:
18270  {
18271  dump_integer(val.m_data.m_value.number_unsigned);
18272  return;
18273  }
18274 
18275  case value_t::number_float:
18276  {
18277  dump_float(val.m_data.m_value.number_float);
18278  return;
18279  }
18280 
18281  case value_t::discarded:
18282  {
18283  o->write_characters("<discarded>", 11);
18284  return;
18285  }
18286 
18287  case value_t::null:
18288  {
18289  o->write_characters("null", 4);
18290  return;
18291  }
18292 
18293  default: // LCOV_EXCL_LINE
18294  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18295  }
18296  }
18297 
18313  void dump_escaped(const string_t& s, const bool ensure_ascii)
18314  {
18315  std::uint32_t codepoint{};
18316  std::uint8_t state = UTF8_ACCEPT;
18317  std::size_t bytes = 0; // number of bytes written to string_buffer
18318 
18319  // number of bytes written at the point of the last valid byte
18320  std::size_t bytes_after_last_accept = 0;
18321  std::size_t undumped_chars = 0;
18322 
18323  for (std::size_t i = 0; i < s.size(); ++i)
18324  {
18325  const auto byte = static_cast<std::uint8_t>(s[i]);
18326 
18327  switch (decode(state, codepoint, byte))
18328  {
18329  case UTF8_ACCEPT: // decode found a new code point
18330  {
18331  switch (codepoint)
18332  {
18333  case 0x08: // backspace
18334  {
18335  string_buffer[bytes++] = '\\';
18336  string_buffer[bytes++] = 'b';
18337  break;
18338  }
18339 
18340  case 0x09: // horizontal tab
18341  {
18342  string_buffer[bytes++] = '\\';
18343  string_buffer[bytes++] = 't';
18344  break;
18345  }
18346 
18347  case 0x0A: // newline
18348  {
18349  string_buffer[bytes++] = '\\';
18350  string_buffer[bytes++] = 'n';
18351  break;
18352  }
18353 
18354  case 0x0C: // formfeed
18355  {
18356  string_buffer[bytes++] = '\\';
18357  string_buffer[bytes++] = 'f';
18358  break;
18359  }
18360 
18361  case 0x0D: // carriage return
18362  {
18363  string_buffer[bytes++] = '\\';
18364  string_buffer[bytes++] = 'r';
18365  break;
18366  }
18367 
18368  case 0x22: // quotation mark
18369  {
18370  string_buffer[bytes++] = '\\';
18371  string_buffer[bytes++] = '\"';
18372  break;
18373  }
18374 
18375  case 0x5C: // reverse solidus
18376  {
18377  string_buffer[bytes++] = '\\';
18378  string_buffer[bytes++] = '\\';
18379  break;
18380  }
18381 
18382  default:
18383  {
18384  // escape control characters (0x00..0x1F) or, if
18385  // ensure_ascii parameter is used, non-ASCII characters
18386  if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
18387  {
18388  if (codepoint <= 0xFFFF)
18389  {
18390  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18391  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
18392  static_cast<std::uint16_t>(codepoint)));
18393  bytes += 6;
18394  }
18395  else
18396  {
18397  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18398  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
18399  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
18400  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
18401  bytes += 12;
18402  }
18403  }
18404  else
18405  {
18406  // copy byte to buffer (all previous bytes
18407  // been copied have in default case above)
18408  string_buffer[bytes++] = s[i];
18409  }
18410  break;
18411  }
18412  }
18413 
18414  // write buffer and reset index; there must be 13 bytes
18415  // left, as this is the maximal number of bytes to be
18416  // written ("\uxxxx\uxxxx\0") for one code point
18417  if (string_buffer.size() - bytes < 13)
18418  {
18419  o->write_characters(string_buffer.data(), bytes);
18420  bytes = 0;
18421  }
18422 
18423  // remember the byte position of this accept
18424  bytes_after_last_accept = bytes;
18425  undumped_chars = 0;
18426  break;
18427  }
18428 
18429  case UTF8_REJECT: // decode found invalid UTF-8 byte
18430  {
18431  switch (error_handler)
18432  {
18433  case error_handler_t::strict:
18434  {
18435  JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
18436  }
18437 
18438  case error_handler_t::ignore:
18439  case error_handler_t::replace:
18440  {
18441  // in case we saw this character the first time, we
18442  // would like to read it again, because the byte
18443  // may be OK for itself, but just not OK for the
18444  // previous sequence
18445  if (undumped_chars > 0)
18446  {
18447  --i;
18448  }
18449 
18450  // reset length buffer to the last accepted index;
18451  // thus removing/ignoring the invalid characters
18452  bytes = bytes_after_last_accept;
18453 
18454  if (error_handler == error_handler_t::replace)
18455  {
18456  // add a replacement character
18457  if (ensure_ascii)
18458  {
18459  string_buffer[bytes++] = '\\';
18460  string_buffer[bytes++] = 'u';
18461  string_buffer[bytes++] = 'f';
18462  string_buffer[bytes++] = 'f';
18463  string_buffer[bytes++] = 'f';
18464  string_buffer[bytes++] = 'd';
18465  }
18466  else
18467  {
18468  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
18469  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
18470  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
18471  }
18472 
18473  // write buffer and reset index; there must be 13 bytes
18474  // left, as this is the maximal number of bytes to be
18475  // written ("\uxxxx\uxxxx\0") for one code point
18476  if (string_buffer.size() - bytes < 13)
18477  {
18478  o->write_characters(string_buffer.data(), bytes);
18479  bytes = 0;
18480  }
18481 
18482  bytes_after_last_accept = bytes;
18483  }
18484 
18485  undumped_chars = 0;
18486 
18487  // continue processing the string
18488  state = UTF8_ACCEPT;
18489  break;
18490  }
18491 
18492  default: // LCOV_EXCL_LINE
18493  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18494  }
18495  break;
18496  }
18497 
18498  default: // decode found yet incomplete multi-byte code point
18499  {
18500  if (!ensure_ascii)
18501  {
18502  // code point will not be escaped - copy byte to buffer
18503  string_buffer[bytes++] = s[i];
18504  }
18505  ++undumped_chars;
18506  break;
18507  }
18508  }
18509  }
18510 
18511  // we finished processing the string
18512  if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
18513  {
18514  // write buffer
18515  if (bytes > 0)
18516  {
18517  o->write_characters(string_buffer.data(), bytes);
18518  }
18519  }
18520  else
18521  {
18522  // we finish reading, but do not accept: string was incomplete
18523  switch (error_handler)
18524  {
18525  case error_handler_t::strict:
18526  {
18527  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));
18528  }
18529 
18530  case error_handler_t::ignore:
18531  {
18532  // write all accepted bytes
18533  o->write_characters(string_buffer.data(), bytes_after_last_accept);
18534  break;
18535  }
18536 
18537  case error_handler_t::replace:
18538  {
18539  // write all accepted bytes
18540  o->write_characters(string_buffer.data(), bytes_after_last_accept);
18541  // add a replacement character
18542  if (ensure_ascii)
18543  {
18544  o->write_characters("\\ufffd", 6);
18545  }
18546  else
18547  {
18548  o->write_characters("\xEF\xBF\xBD", 3);
18549  }
18550  break;
18551  }
18552 
18553  default: // LCOV_EXCL_LINE
18554  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18555  }
18556  }
18557  }
18558 
18559  private:
18568  inline unsigned int count_digits(number_unsigned_t x) noexcept
18569  {
18570  unsigned int n_digits = 1;
18571  for (;;)
18572  {
18573  if (x < 10)
18574  {
18575  return n_digits;
18576  }
18577  if (x < 100)
18578  {
18579  return n_digits + 1;
18580  }
18581  if (x < 1000)
18582  {
18583  return n_digits + 2;
18584  }
18585  if (x < 10000)
18586  {
18587  return n_digits + 3;
18588  }
18589  x = x / 10000u;
18590  n_digits += 4;
18591  }
18592  }
18593 
18599  static std::string hex_bytes(std::uint8_t byte)
18600  {
18601  std::string result = "FF";
18602  constexpr const char* nibble_to_hex = "0123456789ABCDEF";
18603  result[0] = nibble_to_hex[byte / 16];
18604  result[1] = nibble_to_hex[byte % 16];
18605  return result;
18606  }
18607 
18608  // templates to avoid warnings about useless casts
18609  template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
18610  bool is_negative_number(NumberType x)
18611  {
18612  return x < 0;
18613  }
18614 
18615  template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
18616  bool is_negative_number(NumberType /*unused*/)
18617  {
18618  return false;
18619  }
18620 
18630  template < typename NumberType, detail::enable_if_t <
18631  std::is_integral<NumberType>::value ||
18632  std::is_same<NumberType, number_unsigned_t>::value ||
18633  std::is_same<NumberType, number_integer_t>::value ||
18634  std::is_same<NumberType, binary_char_t>::value,
18635  int > = 0 >
18636  void dump_integer(NumberType x)
18637  {
18638  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
18639  {
18640  {
18641  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
18642  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
18643  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
18644  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
18645  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
18646  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
18647  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
18648  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
18649  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
18650  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
18651  }
18652  };
18653 
18654  // special case for "0"
18655  if (x == 0)
18656  {
18657  o->write_character('0');
18658  return;
18659  }
18660 
18661  // use a pointer to fill the buffer
18662  auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18663 
18664  number_unsigned_t abs_value;
18665 
18666  unsigned int n_chars{};
18667 
18668  if (is_negative_number(x))
18669  {
18670  *buffer_ptr = '-';
18671  abs_value = remove_sign(static_cast<number_integer_t>(x));
18672 
18673  // account one more byte for the minus sign
18674  n_chars = 1 + count_digits(abs_value);
18675  }
18676  else
18677  {
18678  abs_value = static_cast<number_unsigned_t>(x);
18679  n_chars = count_digits(abs_value);
18680  }
18681 
18682  // spare 1 byte for '\0'
18683  JSON_ASSERT(n_chars < number_buffer.size() - 1);
18684 
18685  // jump to the end to generate the string from backward,
18686  // so we later avoid reversing the result
18687  buffer_ptr += n_chars;
18688 
18689  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
18690  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
18691  while (abs_value >= 100)
18692  {
18693  const auto digits_index = static_cast<unsigned>((abs_value % 100));
18694  abs_value /= 100;
18695  *(--buffer_ptr) = digits_to_99[digits_index][1];
18696  *(--buffer_ptr) = digits_to_99[digits_index][0];
18697  }
18698 
18699  if (abs_value >= 10)
18700  {
18701  const auto digits_index = static_cast<unsigned>(abs_value);
18702  *(--buffer_ptr) = digits_to_99[digits_index][1];
18703  *(--buffer_ptr) = digits_to_99[digits_index][0];
18704  }
18705  else
18706  {
18707  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
18708  }
18709 
18710  o->write_characters(number_buffer.data(), n_chars);
18711  }
18712 
18721  void dump_float(number_float_t x)
18722  {
18723  // NaN / inf
18724  if (!std::isfinite(x))
18725  {
18726  o->write_characters("null", 4);
18727  return;
18728  }
18729 
18730  // If number_float_t is an IEEE-754 single or double precision number,
18731  // use the Grisu2 algorithm to produce short numbers which are
18732  // guaranteed to round-trip, using strtof and strtod, resp.
18733  //
18734  // NB: The test below works if <long double> == <double>.
18735  static constexpr bool is_ieee_single_or_double
18736  = (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) ||
18737  (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);
18738 
18739  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
18740  }
18741 
18742  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
18743  {
18744  auto* begin = number_buffer.data();
18745  auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
18746 
18747  o->write_characters(begin, static_cast<size_t>(end - begin));
18748  }
18749 
18750  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
18751  {
18752  // get number of digits for a float -> text -> float round-trip
18753  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
18754 
18755  // the actual conversion
18756  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18757  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
18758 
18759  // negative value indicates an error
18760  JSON_ASSERT(len > 0);
18761  // check if buffer was large enough
18762  JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
18763 
18764  // erase thousands separator
18765  if (thousands_sep != '\0')
18766  {
18767  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
18768  const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
18769  std::fill(end, number_buffer.end(), '\0');
18770  JSON_ASSERT((end - number_buffer.begin()) <= len);
18771  len = (end - number_buffer.begin());
18772  }
18773 
18774  // convert decimal point to '.'
18775  if (decimal_point != '\0' && decimal_point != '.')
18776  {
18777  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
18778  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
18779  if (dec_pos != number_buffer.end())
18780  {
18781  *dec_pos = '.';
18782  }
18783  }
18784 
18785  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
18786 
18787  // determine if we need to append ".0"
18788  const bool value_is_int_like =
18789  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
18790  [](char c)
18791  {
18792  return c == '.' || c == 'e';
18793  });
18794 
18795  if (value_is_int_like)
18796  {
18797  o->write_characters(".0", 2);
18798  }
18799  }
18800 
18822  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
18823  {
18824  static const std::array<std::uint8_t, 400> utf8d =
18825  {
18826  {
18827  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
18828  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
18829  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
18830  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
18831  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
18832  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
18833  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
18834  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
18835  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
18836  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
18837  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
18838  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
18839  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
18840  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
18841  }
18842  };
18843 
18844  JSON_ASSERT(byte < utf8d.size());
18845  const std::uint8_t type = utf8d[byte];
18846 
18847  codep = (state != UTF8_ACCEPT)
18848  ? (byte & 0x3fu) | (codep << 6u)
18849  : (0xFFu >> type) & (byte);
18850 
18851  const std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
18852  JSON_ASSERT(index < utf8d.size());
18853  state = utf8d[index];
18854  return state;
18855  }
18856 
18857  /*
18858  * Overload to make the compiler happy while it is instantiating
18859  * dump_integer for number_unsigned_t.
18860  * Must never be called.
18861  */
18862  number_unsigned_t remove_sign(number_unsigned_t x)
18863  {
18864  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18865  return x; // LCOV_EXCL_LINE
18866  }
18867 
18868  /*
18869  * Helper function for dump_integer
18870  *
18871  * This function takes a negative signed integer and returns its absolute
18872  * value as unsigned integer. The plus/minus shuffling is necessary as we can
18873  * not directly remove the sign of an arbitrary signed integer as the
18874  * absolute values of INT_MIN and INT_MAX are usually not the same. See
18875  * #1708 for details.
18876  */
18877  inline number_unsigned_t remove_sign(number_integer_t x) noexcept
18878  {
18879  JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
18880  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
18881  }
18882 
18883  private:
18885  output_adapter_t<char> o = nullptr;
18886 
18888  std::array<char, 64> number_buffer{{}};
18889 
18891  const std::lconv* loc = nullptr;
18893  const char thousands_sep = '\0';
18895  const char decimal_point = '\0';
18896 
18898  std::array<char, 512> string_buffer{{}};
18899 
18901  const char indent_char;
18904 
18907 };
18908 
18909 } // namespace detail
18911 
18912 // #include <nlohmann/detail/value_t.hpp>
18913 
18914 // #include <nlohmann/json_fwd.hpp>
18915 
18916 // #include <nlohmann/ordered_map.hpp>
18917 // __ _____ _____ _____
18918 // __| | __| | | | JSON for Modern C++
18919 // | | |__ | | | | | | version 3.11.2
18920 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
18921 //
18922 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
18923 // SPDX-License-Identifier: MIT
18924 
18925 
18926 
18927 #include <functional> // equal_to, less
18928 #include <initializer_list> // initializer_list
18929 #include <iterator> // input_iterator_tag, iterator_traits
18930 #include <memory> // allocator
18931 #include <stdexcept> // for out_of_range
18932 #include <type_traits> // enable_if, is_convertible
18933 #include <utility> // pair
18934 #include <vector> // vector
18935 
18936 // #include <nlohmann/detail/macro_scope.hpp>
18937 
18938 // #include <nlohmann/detail/meta/type_traits.hpp>
18939 
18940 
18942 
18945 template <class Key, class T, class IgnoredLess = std::less<Key>,
18946  class Allocator = std::allocator<std::pair<const Key, T>>>
18947  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
18948 {
18949  using key_type = Key;
18950  using mapped_type = T;
18951  using Container = std::vector<std::pair<const Key, T>, Allocator>;
18952  using iterator = typename Container::iterator;
18953  using const_iterator = typename Container::const_iterator;
18954  using size_type = typename Container::size_type;
18955  using value_type = typename Container::value_type;
18956 #ifdef JSON_HAS_CPP_14
18957  using key_compare = std::equal_to<>;
18958 #else
18959  using key_compare = std::equal_to<Key>;
18960 #endif
18961 
18962  // Explicit constructors instead of `using Container::Container`
18963  // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
18964  ordered_map() noexcept(noexcept(Container())) : Container{} {}
18965  explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
18966  template <class It>
18967  ordered_map(It first, It last, const Allocator& alloc = Allocator())
18968  : Container{first, last, alloc} {}
18969  ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
18970  : Container{init, alloc} {}
18971 
18972  std::pair<iterator, bool> emplace(const key_type& key, T&& t)
18973  {
18974  for (auto it = this->begin(); it != this->end(); ++it)
18975  {
18976  if (m_compare(it->first, key))
18977  {
18978  return {it, false};
18979  }
18980  }
18981  Container::emplace_back(key, std::forward<T>(t));
18982  return {std::prev(this->end()), true};
18983  }
18984 
18985  template<class KeyType, detail::enable_if_t<
18987  std::pair<iterator, bool> emplace(KeyType && key, T && t)
18988  {
18989  for (auto it = this->begin(); it != this->end(); ++it)
18990  {
18991  if (m_compare(it->first, key))
18992  {
18993  return {it, false};
18994  }
18995  }
18996  Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
18997  return {std::prev(this->end()), true};
18998  }
18999 
19001  {
19002  return emplace(key, T{}).first->second;
19003  }
19004 
19005  template<class KeyType, detail::enable_if_t<
19007  T & operator[](KeyType && key)
19008  {
19009  return emplace(std::forward<KeyType>(key), T{}).first->second;
19010  }
19011 
19012  const T& operator[](const key_type& key) const
19013  {
19014  return at(key);
19015  }
19016 
19017  template<class KeyType, detail::enable_if_t<
19019  const T & operator[](KeyType && key) const
19020  {
19021  return at(std::forward<KeyType>(key));
19022  }
19023 
19024  T& at(const key_type& key)
19025  {
19026  for (auto it = this->begin(); it != this->end(); ++it)
19027  {
19028  if (m_compare(it->first, key))
19029  {
19030  return it->second;
19031  }
19032  }
19033 
19034  JSON_THROW(std::out_of_range("key not found"));
19035  }
19036 
19037  template<class KeyType, detail::enable_if_t<
19039  T & at(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
19040  {
19041  for (auto it = this->begin(); it != this->end(); ++it)
19042  {
19043  if (m_compare(it->first, key))
19044  {
19045  return it->second;
19046  }
19047  }
19048 
19049  JSON_THROW(std::out_of_range("key not found"));
19050  }
19051 
19052  const T& at(const key_type& key) const
19053  {
19054  for (auto it = this->begin(); it != this->end(); ++it)
19055  {
19056  if (m_compare(it->first, key))
19057  {
19058  return it->second;
19059  }
19060  }
19061 
19062  JSON_THROW(std::out_of_range("key not found"));
19063  }
19064 
19065  template<class KeyType, detail::enable_if_t<
19067  const T & at(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)
19068  {
19069  for (auto it = this->begin(); it != this->end(); ++it)
19070  {
19071  if (m_compare(it->first, key))
19072  {
19073  return it->second;
19074  }
19075  }
19076 
19077  JSON_THROW(std::out_of_range("key not found"));
19078  }
19079 
19081  {
19082  for (auto it = this->begin(); it != this->end(); ++it)
19083  {
19084  if (m_compare(it->first, key))
19085  {
19086  // Since we cannot move const Keys, re-construct them in place
19087  for (auto next = it; ++next != this->end(); ++it)
19088  {
19089  it->~value_type(); // Destroy but keep allocation
19090  new (&*it) value_type{std::move(*next)};
19091  }
19092  Container::pop_back();
19093  return 1;
19094  }
19095  }
19096  return 0;
19097  }
19098 
19099  template<class KeyType, detail::enable_if_t<
19101  size_type erase(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
19102  {
19103  for (auto it = this->begin(); it != this->end(); ++it)
19104  {
19105  if (m_compare(it->first, key))
19106  {
19107  // Since we cannot move const Keys, re-construct them in place
19108  for (auto next = it; ++next != this->end(); ++it)
19109  {
19110  it->~value_type(); // Destroy but keep allocation
19111  new (&*it) value_type{std::move(*next)};
19112  }
19113  Container::pop_back();
19114  return 1;
19115  }
19116  }
19117  return 0;
19118  }
19119 
19121  {
19122  return erase(pos, std::next(pos));
19123  }
19124 
19126  {
19127  if (first == last)
19128  {
19129  return first;
19130  }
19131 
19132  const auto elements_affected = std::distance(first, last);
19133  const auto offset = std::distance(Container::begin(), first);
19134 
19135  // This is the start situation. We need to delete elements_affected
19136  // elements (3 in this example: e, f, g), and need to return an
19137  // iterator past the last deleted element (h in this example).
19138  // Note that offset is the distance from the start of the vector
19139  // to first. We will need this later.
19140 
19141  // [ a, b, c, d, e, f, g, h, i, j ]
19142  // ^ ^
19143  // first last
19144 
19145  // Since we cannot move const Keys, we re-construct them in place.
19146  // We start at first and re-construct (viz. copy) the elements from
19147  // the back of the vector. Example for first iteration:
19148 
19149  // ,--------.
19150  // v | destroy e and re-construct with h
19151  // [ a, b, c, d, e, f, g, h, i, j ]
19152  // ^ ^
19153  // it it + elements_affected
19154 
19155  for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
19156  {
19157  it->~value_type(); // destroy but keep allocation
19158  new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
19159  }
19160 
19161  // [ a, b, c, d, h, i, j, h, i, j ]
19162  // ^ ^
19163  // first last
19164 
19165  // remove the unneeded elements at the end of the vector
19166  Container::resize(this->size() - static_cast<size_type>(elements_affected));
19167 
19168  // [ a, b, c, d, h, i, j ]
19169  // ^ ^
19170  // first last
19171 
19172  // first is now pointing past the last deleted element, but we cannot
19173  // use this iterator, because it may have been invalidated by the
19174  // resize call. Instead, we can return begin() + offset.
19175  return Container::begin() + offset;
19176  }
19177 
19178  size_type count(const key_type& key) const
19179  {
19180  for (auto it = this->begin(); it != this->end(); ++it)
19181  {
19182  if (m_compare(it->first, key))
19183  {
19184  return 1;
19185  }
19186  }
19187  return 0;
19188  }
19189 
19190  template<class KeyType, detail::enable_if_t<
19192  size_type count(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)
19193  {
19194  for (auto it = this->begin(); it != this->end(); ++it)
19195  {
19196  if (m_compare(it->first, key))
19197  {
19198  return 1;
19199  }
19200  }
19201  return 0;
19202  }
19203 
19205  {
19206  for (auto it = this->begin(); it != this->end(); ++it)
19207  {
19208  if (m_compare(it->first, key))
19209  {
19210  return it;
19211  }
19212  }
19213  return Container::end();
19214  }
19215 
19216  template<class KeyType, detail::enable_if_t<
19218  iterator find(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
19219  {
19220  for (auto it = this->begin(); it != this->end(); ++it)
19221  {
19222  if (m_compare(it->first, key))
19223  {
19224  return it;
19225  }
19226  }
19227  return Container::end();
19228  }
19229 
19231  {
19232  for (auto it = this->begin(); it != this->end(); ++it)
19233  {
19234  if (m_compare(it->first, key))
19235  {
19236  return it;
19237  }
19238  }
19239  return Container::end();
19240  }
19241 
19242  std::pair<iterator, bool> insert( value_type&& value )
19243  {
19244  return emplace(value.first, std::move(value.second));
19245  }
19246 
19247  std::pair<iterator, bool> insert( const value_type& value )
19248  {
19249  for (auto it = this->begin(); it != this->end(); ++it)
19250  {
19251  if (m_compare(it->first, value.first))
19252  {
19253  return {it, false};
19254  }
19255  }
19256  Container::push_back(value);
19257  return {--this->end(), true};
19258  }
19259 
19260  template<typename InputIt>
19261  using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
19262  std::input_iterator_tag>::value>::type;
19263 
19264  template<typename InputIt, typename = require_input_iter<InputIt>>
19265  void insert(InputIt first, InputIt last)
19266  {
19267  for (auto it = first; it != last; ++it)
19268  {
19269  insert(*it);
19270  }
19271  }
19272 
19273 private:
19275 };
19276 
19278 
19279 
19280 #if defined(JSON_HAS_CPP_17)
19281  #include <any>
19282  #include <string_view>
19283 #endif
19284 
19291 
19311 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
19312  : public ::nlohmann::detail::json_base_class<CustomBaseClass>
19313 {
19314  private:
19315  template<detail::value_t> friend struct detail::external_constructor;
19316 
19317  template<typename>
19318  friend class ::nlohmann::json_pointer;
19319  // can be restored when json_pointer backwards compatibility is removed
19320  // friend ::nlohmann::json_pointer<StringType>;
19321 
19322  template<typename BasicJsonType, typename InputType>
19324  friend ::nlohmann::detail::serializer<basic_json>;
19325  template<typename BasicJsonType>
19326  friend class ::nlohmann::detail::iter_impl;
19327  template<typename BasicJsonType, typename CharType>
19328  friend class ::nlohmann::detail::binary_writer;
19329  template<typename BasicJsonType, typename InputType, typename SAX>
19330  friend class ::nlohmann::detail::binary_reader;
19331  template<typename BasicJsonType>
19332  friend class ::nlohmann::detail::json_sax_dom_parser;
19333  template<typename BasicJsonType>
19334  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
19335  friend class ::nlohmann::detail::exception;
19336 
19339  using json_base_class_t = ::nlohmann::detail::json_base_class<CustomBaseClass>;
19340 
19342  // convenience aliases for types residing in namespace detail;
19343  using lexer = ::nlohmann::detail::lexer_base<basic_json>;
19344 
19345  template<typename InputAdapterType>
19346  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
19347  InputAdapterType adapter,
19349  const bool allow_exceptions = true,
19350  const bool ignore_comments = false
19351  )
19352  {
19353  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
19354  std::move(cb), allow_exceptions, ignore_comments);
19355  }
19356 
19357  private:
19358  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
19359  template<typename BasicJsonType>
19360  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
19361  template<typename BasicJsonType>
19362  using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
19363  template<typename Iterator>
19364  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
19365  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
19366 
19367  template<typename CharType>
19368  using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
19369 
19370  template<typename InputType>
19371  using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
19372  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
19373 
19375  using serializer = ::nlohmann::detail::serializer<basic_json>;
19376 
19377  public:
19380  using json_pointer = ::nlohmann::json_pointer<StringType>;
19381  template<typename T, typename SFINAE>
19382  using json_serializer = JSONSerializer<T, SFINAE>;
19388  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
19389 
19393 
19395  // exceptions //
19397 
19401 
19408 
19410 
19411 
19413  // container types //
19415 
19420 
19423 
19427  using const_reference = const value_type&;
19428 
19430  using difference_type = std::ptrdiff_t;
19432  using size_type = std::size_t;
19433 
19435  using allocator_type = AllocatorType<basic_json>;
19436 
19438  using pointer = typename std::allocator_traits<allocator_type>::pointer;
19440  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
19441 
19450 
19452 
19453 
19457  {
19458  return allocator_type();
19459  }
19460 
19464  static basic_json meta()
19465  {
19466  basic_json result;
19467 
19468  result["copyright"] = "(C) 2013-2022 Niels Lohmann";
19469  result["name"] = "JSON for Modern C++";
19470  result["url"] = "https://github.com/nlohmann/json";
19471  result["version"]["string"] =
19475  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
19476  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
19477  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
19478 
19479 #ifdef _WIN32
19480  result["platform"] = "win32";
19481 #elif defined __linux__
19482  result["platform"] = "linux";
19483 #elif defined __APPLE__
19484  result["platform"] = "apple";
19485 #elif defined __unix__
19486  result["platform"] = "unix";
19487 #else
19488  result["platform"] = "unknown";
19489 #endif
19490 
19491 #if defined(__ICC) || defined(__INTEL_COMPILER)
19492  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
19493 #elif defined(__clang__)
19494  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
19495 #elif defined(__GNUC__) || defined(__GNUG__)
19496  result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
19497  std::to_string(__GNUC__), '.',
19498  std::to_string(__GNUC_MINOR__), '.',
19499  std::to_string(__GNUC_PATCHLEVEL__))
19500  }
19501  };
19502 #elif defined(__HP_cc) || defined(__HP_aCC)
19503  result["compiler"] = "hp"
19504 #elif defined(__IBMCPP__)
19505  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
19506 #elif defined(_MSC_VER)
19507  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
19508 #elif defined(__PGI)
19509  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
19510 #elif defined(__SUNPRO_CC)
19511  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
19512 #else
19513  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
19514 #endif
19515 
19516 
19517 #if defined(_MSVC_LANG)
19518  result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
19519 #elif defined(__cplusplus)
19520  result["compiler"]["c++"] = std::to_string(__cplusplus);
19521 #else
19522  result["compiler"]["c++"] = "unknown";
19523 #endif
19524  return result;
19525  }
19526 
19527 
19529  // JSON value data types //
19531 
19536 
19541 #if defined(JSON_HAS_CPP_14)
19542  // use of transparent comparator avoids unnecessary repeated construction of temporaries
19543  // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
19544  using default_object_comparator_t = std::less<>;
19545 #else
19546  using default_object_comparator_t = std::less<StringType>;
19547 #endif
19548 
19551  using object_t = ObjectType<StringType,
19552  basic_json,
19554  AllocatorType<std::pair<const StringType,
19556 
19559  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
19560 
19563  using string_t = StringType;
19564 
19567  using boolean_t = BooleanType;
19568 
19571  using number_integer_t = NumberIntegerType;
19572 
19575  using number_unsigned_t = NumberUnsignedType;
19576 
19579  using number_float_t = NumberFloatType;
19580 
19583  using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
19584 
19588 
19590 
19591  private:
19592 
19594  template<typename T, typename... Args>
19596  static T* create(Args&& ... args)
19597  {
19598  AllocatorType<T> alloc;
19599  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
19600 
19601  auto deleter = [&](T * obj)
19602  {
19603  AllocatorTraits::deallocate(alloc, obj, 1);
19604  };
19605  std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
19606  AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
19607  JSON_ASSERT(obj != nullptr);
19608  return obj.release();
19609  }
19610 
19612  // JSON value storage //
19614 
19641  union json_value
19642  {
19644  object_t* object;
19659 
19661  json_value() = default;
19663  json_value(boolean_t v) noexcept : boolean(v) {}
19672  {
19673  switch (t)
19674  {
19675  case value_t::object:
19676  {
19677  object = create<object_t>();
19678  break;
19679  }
19680 
19681  case value_t::array:
19682  {
19683  array = create<array_t>();
19684  break;
19685  }
19686 
19687  case value_t::string:
19688  {
19689  string = create<string_t>("");
19690  break;
19691  }
19692 
19693  case value_t::binary:
19694  {
19695  binary = create<binary_t>();
19696  break;
19697  }
19698 
19699  case value_t::boolean:
19700  {
19701  boolean = static_cast<boolean_t>(false);
19702  break;
19703  }
19704 
19705  case value_t::number_integer:
19706  {
19707  number_integer = static_cast<number_integer_t>(0);
19708  break;
19709  }
19710 
19711  case value_t::number_unsigned:
19712  {
19713  number_unsigned = static_cast<number_unsigned_t>(0);
19714  break;
19715  }
19716 
19717  case value_t::number_float:
19718  {
19719  number_float = static_cast<number_float_t>(0.0);
19720  break;
19721  }
19722 
19723  case value_t::null:
19724  {
19725  object = nullptr; // silence warning, see #821
19726  break;
19727  }
19728 
19729  case value_t::discarded:
19730  default:
19731  {
19732  object = nullptr; // silence warning, see #821
19733  if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
19734  {
19735  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.2", nullptr)); // LCOV_EXCL_LINE
19736  }
19737  break;
19738  }
19739  }
19740  }
19741 
19743  json_value(const string_t& value) : string(create<string_t>(value)) {}
19744 
19746  json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
19747 
19749  json_value(const object_t& value) : object(create<object_t>(value)) {}
19750 
19752  json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
19753 
19755  json_value(const array_t& value) : array(create<array_t>(value)) {}
19756 
19758  json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
19759 
19761  json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
19762 
19764  json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
19765 
19767  json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
19768 
19770  json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
19771 
19773  {
19774  if (
19775  (t == value_t::object && object == nullptr) ||
19776  (t == value_t::array && array == nullptr) ||
19777  (t == value_t::string && string == nullptr) ||
19778  (t == value_t::binary && binary == nullptr)
19779  )
19780  {
19781  //not initialized (e.g. due to exception in the ctor)
19782  return;
19783  }
19784  if (t == value_t::array || t == value_t::object)
19785  {
19786  // flatten the current json_value to a heap-allocated stack
19787  std::vector<basic_json> stack;
19788 
19789  // move the top-level items to stack
19790  if (t == value_t::array)
19791  {
19792  stack.reserve(array->size());
19793  std::move(array->begin(), array->end(), std::back_inserter(stack));
19794  }
19795  else
19796  {
19797  stack.reserve(object->size());
19798  for (auto&& it : *object)
19799  {
19800  stack.push_back(std::move(it.second));
19801  }
19802  }
19803 
19804  while (!stack.empty())
19805  {
19806  // move the last item to local variable to be processed
19807  basic_json current_item(std::move(stack.back()));
19808  stack.pop_back();
19809 
19810  // if current_item is array/object, move
19811  // its children to the stack to be processed later
19812  if (current_item.is_array())
19813  {
19814  std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
19815 
19816  current_item.m_data.m_value.array->clear();
19817  }
19818  else if (current_item.is_object())
19819  {
19820  for (auto&& it : *current_item.m_data.m_value.object)
19821  {
19822  stack.push_back(std::move(it.second));
19823  }
19824 
19825  current_item.m_data.m_value.object->clear();
19826  }
19827 
19828  // it's now safe that current_item get destructed
19829  // since it doesn't have any children
19830  }
19831  }
19832 
19833  switch (t)
19834  {
19835  case value_t::object:
19836  {
19837  AllocatorType<object_t> alloc;
19838  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
19839  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
19840  break;
19841  }
19842 
19843  case value_t::array:
19844  {
19845  AllocatorType<array_t> alloc;
19846  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
19847  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
19848  break;
19849  }
19850 
19851  case value_t::string:
19852  {
19853  AllocatorType<string_t> alloc;
19854  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
19855  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
19856  break;
19857  }
19858 
19859  case value_t::binary:
19860  {
19861  AllocatorType<binary_t> alloc;
19862  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
19863  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
19864  break;
19865  }
19866 
19867  case value_t::null:
19868  case value_t::boolean:
19869  case value_t::number_integer:
19870  case value_t::number_unsigned:
19871  case value_t::number_float:
19872  case value_t::discarded:
19873  default:
19874  {
19875  break;
19876  }
19877  }
19878  }
19879  };
19880 
19881  private:
19900  void assert_invariant(bool check_parents = true) const noexcept
19901  {
19902  JSON_ASSERT(m_data.m_type != value_t::object || m_data.m_value.object != nullptr);
19903  JSON_ASSERT(m_data.m_type != value_t::array || m_data.m_value.array != nullptr);
19904  JSON_ASSERT(m_data.m_type != value_t::string || m_data.m_value.string != nullptr);
19905  JSON_ASSERT(m_data.m_type != value_t::binary || m_data.m_value.binary != nullptr);
19906 
19907 #if JSON_DIAGNOSTICS
19908  JSON_TRY
19909  {
19910  // cppcheck-suppress assertWithSideEffect
19911  JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
19912  {
19913  return j.m_parent == this;
19914  }));
19915  }
19916  JSON_CATCH(...) {} // LCOV_EXCL_LINE
19917 #endif
19918  static_cast<void>(check_parents);
19919  }
19920 
19922  {
19923 #if JSON_DIAGNOSTICS
19924  switch (m_data.m_type)
19925  {
19926  case value_t::array:
19927  {
19928  for (auto& element : *m_data.m_value.array)
19929  {
19930  element.m_parent = this;
19931  }
19932  break;
19933  }
19934 
19935  case value_t::object:
19936  {
19937  for (auto& element : *m_data.m_value.object)
19938  {
19939  element.second.m_parent = this;
19940  }
19941  break;
19942  }
19943 
19944  case value_t::null:
19945  case value_t::string:
19946  case value_t::boolean:
19947  case value_t::number_integer:
19948  case value_t::number_unsigned:
19949  case value_t::number_float:
19950  case value_t::binary:
19951  case value_t::discarded:
19952  default:
19953  break;
19954  }
19955 #endif
19956  }
19957 
19958  iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
19959  {
19960 #if JSON_DIAGNOSTICS
19961  for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
19962  {
19963  (it + i)->m_parent = this;
19964  }
19965 #else
19966  static_cast<void>(count_set_parents);
19967 #endif
19968  return it;
19969  }
19970 
19971  reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
19972  {
19973 #if JSON_DIAGNOSTICS
19974  if (old_capacity != static_cast<std::size_t>(-1))
19975  {
19976  // see https://github.com/nlohmann/json/issues/2838
19977  JSON_ASSERT(type() == value_t::array);
19978  if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
19979  {
19980  // capacity has changed: update all parents
19981  set_parents();
19982  return j;
19983  }
19984  }
19985 
19986  // ordered_json uses a vector internally, so pointers could have
19987  // been invalidated; see https://github.com/nlohmann/json/issues/2962
19988 #ifdef JSON_HEDLEY_MSVC_VERSION
19989 #pragma warning(push )
19990 #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
19991 #endif
19993  {
19994  set_parents();
19995  return j;
19996  }
19997 #ifdef JSON_HEDLEY_MSVC_VERSION
19998 #pragma warning( pop )
19999 #endif
20000 
20001  j.m_parent = this;
20002 #else
20003  static_cast<void>(j);
20004  static_cast<void>(old_capacity);
20005 #endif
20006  return j;
20007  }
20008 
20009  public:
20011  // JSON parser callback //
20013 
20017 
20021 
20023  // constructors //
20025 
20030 
20034  : m_data(v)
20035  {
20036  assert_invariant();
20037  }
20038 
20041  basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
20042  : basic_json(value_t::null)
20043  {
20044  assert_invariant();
20045  }
20046 
20049  template < typename CompatibleType,
20050  typename U = detail::uncvref_t<CompatibleType>,
20053  basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
20054  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
20055  std::forward<CompatibleType>(val))))
20056  {
20057  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
20058  set_parents();
20059  assert_invariant();
20060  }
20061 
20064  template < typename BasicJsonType,
20066  detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
20067  basic_json(const BasicJsonType& val)
20068  {
20069  using other_boolean_t = typename BasicJsonType::boolean_t;
20070  using other_number_float_t = typename BasicJsonType::number_float_t;
20071  using other_number_integer_t = typename BasicJsonType::number_integer_t;
20072  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
20073  using other_string_t = typename BasicJsonType::string_t;
20074  using other_object_t = typename BasicJsonType::object_t;
20075  using other_array_t = typename BasicJsonType::array_t;
20076  using other_binary_t = typename BasicJsonType::binary_t;
20077 
20078  switch (val.type())
20079  {
20080  case value_t::boolean:
20081  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
20082  break;
20083  case value_t::number_float:
20084  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
20085  break;
20086  case value_t::number_integer:
20087  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
20088  break;
20089  case value_t::number_unsigned:
20090  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
20091  break;
20092  case value_t::string:
20093  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
20094  break;
20095  case value_t::object:
20096  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
20097  break;
20098  case value_t::array:
20099  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
20100  break;
20101  case value_t::binary:
20102  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
20103  break;
20104  case value_t::null:
20105  *this = nullptr;
20106  break;
20107  case value_t::discarded:
20108  m_data.m_type = value_t::discarded;
20109  break;
20110  default: // LCOV_EXCL_LINE
20111  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
20112  }
20113  JSON_ASSERT(m_data.m_type == val.type());
20114  set_parents();
20115  assert_invariant();
20116  }
20117 
20121  bool type_deduction = true,
20122  value_t manual_type = value_t::array)
20123  {
20124  // check if each element is an array with two elements whose first
20125  // element is a string
20126  bool is_an_object = std::all_of(init.begin(), init.end(),
20127  [](const detail::json_ref<basic_json>& element_ref)
20128  {
20129  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
20130  });
20131 
20132  // adjust type if type deduction is not wanted
20133  if (!type_deduction)
20134  {
20135  // if array is wanted, do not create an object though possible
20136  if (manual_type == value_t::array)
20137  {
20138  is_an_object = false;
20139  }
20140 
20141  // if object is wanted but impossible, throw an exception
20142  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
20143  {
20144  JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
20145  }
20146  }
20147 
20148  if (is_an_object)
20149  {
20150  // the initializer list is a list of pairs -> create object
20151  m_data.m_type = value_t::object;
20152  m_data.m_value = value_t::object;
20153 
20154  for (auto& element_ref : init)
20155  {
20156  auto element = element_ref.moved_or_copied();
20157  m_data.m_value.object->emplace(
20158  std::move(*((*element.m_data.m_value.array)[0].m_data.m_value.string)),
20159  std::move((*element.m_data.m_value.array)[1]));
20160  }
20161  }
20162  else
20163  {
20164  // the initializer list describes an array -> create array
20165  m_data.m_type = value_t::array;
20166  m_data.m_value.array = create<array_t>(init.begin(), init.end());
20167  }
20168 
20169  set_parents();
20170  assert_invariant();
20171  }
20172 
20176  static basic_json binary(const typename binary_t::container_type& init)
20177  {
20178  auto res = basic_json();
20179  res.m_data.m_type = value_t::binary;
20180  res.m_data.m_value = init;
20181  return res;
20182  }
20183 
20187  static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
20188  {
20189  auto res = basic_json();
20190  res.m_data.m_type = value_t::binary;
20191  res.m_data.m_value = binary_t(init, subtype);
20192  return res;
20193  }
20194 
20198  static basic_json binary(typename binary_t::container_type&& init)
20199  {
20200  auto res = basic_json();
20201  res.m_data.m_type = value_t::binary;
20202  res.m_data.m_value = std::move(init);
20203  return res;
20204  }
20205 
20209  static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
20210  {
20211  auto res = basic_json();
20212  res.m_data.m_type = value_t::binary;
20213  res.m_data.m_value = binary_t(std::move(init), subtype);
20214  return res;
20215  }
20216 
20221  {
20222  return basic_json(init, false, value_t::array);
20223  }
20224 
20229  {
20230  return basic_json(init, false, value_t::object);
20231  }
20232 
20235  basic_json(size_type cnt, const basic_json& val):
20236  m_data{cnt, val}
20237  {
20238  set_parents();
20239  assert_invariant();
20240  }
20241 
20244  template < class InputIT, typename std::enable_if <
20245  std::is_same<InputIT, typename basic_json_t::iterator>::value ||
20246  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
20247  basic_json(InputIT first, InputIT last)
20248  {
20249  JSON_ASSERT(first.m_object != nullptr);
20250  JSON_ASSERT(last.m_object != nullptr);
20251 
20252  // make sure iterator fits the current value
20253  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20254  {
20255  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
20256  }
20257 
20258  // copy type from first iterator
20259  m_data.m_type = first.m_object->m_data.m_type;
20260 
20261  // check if iterator range is complete for primitive values
20262  switch (m_data.m_type)
20263  {
20264  case value_t::boolean:
20265  case value_t::number_float:
20266  case value_t::number_integer:
20267  case value_t::number_unsigned:
20268  case value_t::string:
20269  {
20270  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
20271  || !last.m_it.primitive_iterator.is_end()))
20272  {
20273  JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
20274  }
20275  break;
20276  }
20277 
20278  case value_t::null:
20279  case value_t::object:
20280  case value_t::array:
20281  case value_t::binary:
20282  case value_t::discarded:
20283  default:
20284  break;
20285  }
20286 
20287  switch (m_data.m_type)
20288  {
20289  case value_t::number_integer:
20290  {
20291  m_data.m_value.number_integer = first.m_object->m_data.m_value.number_integer;
20292  break;
20293  }
20294 
20295  case value_t::number_unsigned:
20296  {
20297  m_data.m_value.number_unsigned = first.m_object->m_data.m_value.number_unsigned;
20298  break;
20299  }
20300 
20301  case value_t::number_float:
20302  {
20303  m_data.m_value.number_float = first.m_object->m_data.m_value.number_float;
20304  break;
20305  }
20306 
20307  case value_t::boolean:
20308  {
20309  m_data.m_value.boolean = first.m_object->m_data.m_value.boolean;
20310  break;
20311  }
20312 
20313  case value_t::string:
20314  {
20315  m_data.m_value = *first.m_object->m_data.m_value.string;
20316  break;
20317  }
20318 
20319  case value_t::object:
20320  {
20321  m_data.m_value.object = create<object_t>(first.m_it.object_iterator,
20322  last.m_it.object_iterator);
20323  break;
20324  }
20325 
20326  case value_t::array:
20327  {
20328  m_data.m_value.array = create<array_t>(first.m_it.array_iterator,
20329  last.m_it.array_iterator);
20330  break;
20331  }
20332 
20333  case value_t::binary:
20334  {
20335  m_data.m_value = *first.m_object->m_data.m_value.binary;
20336  break;
20337  }
20338 
20339  case value_t::null:
20340  case value_t::discarded:
20341  default:
20342  JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
20343  }
20344 
20345  set_parents();
20346  assert_invariant();
20347  }
20348 
20349 
20351  // other constructors and destructor //
20353 
20354  template<typename JsonRef,
20356  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
20357  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
20358 
20361  basic_json(const basic_json& other)
20362  : json_base_class_t(other)
20363  {
20364  m_data.m_type = other.m_data.m_type;
20365  // check of passed value is valid
20366  other.assert_invariant();
20367 
20368  switch (m_data.m_type)
20369  {
20370  case value_t::object:
20371  {
20372  m_data.m_value = *other.m_data.m_value.object;
20373  break;
20374  }
20375 
20376  case value_t::array:
20377  {
20378  m_data.m_value = *other.m_data.m_value.array;
20379  break;
20380  }
20381 
20382  case value_t::string:
20383  {
20384  m_data.m_value = *other.m_data.m_value.string;
20385  break;
20386  }
20387 
20388  case value_t::boolean:
20389  {
20390  m_data.m_value = other.m_data.m_value.boolean;
20391  break;
20392  }
20393 
20394  case value_t::number_integer:
20395  {
20396  m_data.m_value = other.m_data.m_value.number_integer;
20397  break;
20398  }
20399 
20400  case value_t::number_unsigned:
20401  {
20402  m_data.m_value = other.m_data.m_value.number_unsigned;
20403  break;
20404  }
20405 
20406  case value_t::number_float:
20407  {
20408  m_data.m_value = other.m_data.m_value.number_float;
20409  break;
20410  }
20411 
20412  case value_t::binary:
20413  {
20414  m_data.m_value = *other.m_data.m_value.binary;
20415  break;
20416  }
20417 
20418  case value_t::null:
20419  case value_t::discarded:
20420  default:
20421  break;
20422  }
20423 
20424  set_parents();
20425  assert_invariant();
20426  }
20427 
20430  basic_json(basic_json&& other) noexcept
20431  : json_base_class_t(std::forward<json_base_class_t>(other)),
20432  m_data(std::move(other.m_data))
20433  {
20434  // check that passed value is valid
20435  other.assert_invariant(false);
20436 
20437  // invalidate payload
20438  other.m_data.m_type = value_t::null;
20439  other.m_data.m_value = {};
20440 
20441  set_parents();
20442  assert_invariant();
20443  }
20444 
20447  basic_json& operator=(basic_json other) noexcept (
20448  std::is_nothrow_move_constructible<value_t>::value&&
20449  std::is_nothrow_move_assignable<value_t>::value&&
20450  std::is_nothrow_move_constructible<json_value>::value&&
20451  std::is_nothrow_move_assignable<json_value>::value&&
20452  std::is_nothrow_move_assignable<json_base_class_t>::value
20453  )
20454  {
20455  // check that passed value is valid
20456  other.assert_invariant();
20457 
20458  using std::swap;
20459  swap(m_data.m_type, other.m_data.m_type);
20460  swap(m_data.m_value, other.m_data.m_value);
20461  json_base_class_t::operator=(std::move(other));
20462 
20463  set_parents();
20464  assert_invariant();
20465  return *this;
20466  }
20467 
20470  ~basic_json() noexcept
20471  {
20472  assert_invariant(false);
20473  }
20474 
20476 
20477  public:
20479  // object inspection //
20481 
20485 
20488  string_t dump(const int indent = -1,
20489  const char indent_char = ' ',
20490  const bool ensure_ascii = false,
20491  const error_handler_t error_handler = error_handler_t::strict) const
20492  {
20493  string_t result;
20494  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
20495 
20496  if (indent >= 0)
20497  {
20498  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
20499  }
20500  else
20501  {
20502  s.dump(*this, false, ensure_ascii, 0);
20503  }
20504 
20505  return result;
20506  }
20507 
20510  constexpr value_t type() const noexcept
20511  {
20512  return m_data.m_type;
20513  }
20514 
20517  constexpr bool is_primitive() const noexcept
20518  {
20519  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20520  }
20521 
20524  constexpr bool is_structured() const noexcept
20525  {
20526  return is_array() || is_object();
20527  }
20528 
20531  constexpr bool is_null() const noexcept
20532  {
20533  return m_data.m_type == value_t::null;
20534  }
20535 
20538  constexpr bool is_boolean() const noexcept
20539  {
20540  return m_data.m_type == value_t::boolean;
20541  }
20542 
20545  constexpr bool is_number() const noexcept
20546  {
20547  return is_number_integer() || is_number_float();
20548  }
20549 
20552  constexpr bool is_number_integer() const noexcept
20553  {
20554  return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
20555  }
20556 
20559  constexpr bool is_number_unsigned() const noexcept
20560  {
20561  return m_data.m_type == value_t::number_unsigned;
20562  }
20563 
20566  constexpr bool is_number_float() const noexcept
20567  {
20568  return m_data.m_type == value_t::number_float;
20569  }
20570 
20573  constexpr bool is_object() const noexcept
20574  {
20575  return m_data.m_type == value_t::object;
20576  }
20577 
20580  constexpr bool is_array() const noexcept
20581  {
20582  return m_data.m_type == value_t::array;
20583  }
20584 
20587  constexpr bool is_string() const noexcept
20588  {
20589  return m_data.m_type == value_t::string;
20590  }
20591 
20594  constexpr bool is_binary() const noexcept
20595  {
20596  return m_data.m_type == value_t::binary;
20597  }
20598 
20601  constexpr bool is_discarded() const noexcept
20602  {
20603  return m_data.m_type == value_t::discarded;
20604  }
20605 
20608  constexpr operator value_t() const noexcept
20609  {
20610  return m_data.m_type;
20611  }
20612 
20614 
20615  private:
20617  // value access //
20619 
20621  boolean_t get_impl(boolean_t* /*unused*/) const
20622  {
20623  if (JSON_HEDLEY_LIKELY(is_boolean()))
20624  {
20625  return m_data.m_value.boolean;
20626  }
20627 
20628  JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
20629  }
20630 
20632  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20633  {
20634  return is_object() ? m_data.m_value.object : nullptr;
20635  }
20636 
20638  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20639  {
20640  return is_object() ? m_data.m_value.object : nullptr;
20641  }
20642 
20644  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20645  {
20646  return is_array() ? m_data.m_value.array : nullptr;
20647  }
20648 
20650  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20651  {
20652  return is_array() ? m_data.m_value.array : nullptr;
20653  }
20654 
20656  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20657  {
20658  return is_string() ? m_data.m_value.string : nullptr;
20659  }
20660 
20662  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20663  {
20664  return is_string() ? m_data.m_value.string : nullptr;
20665  }
20666 
20668  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20669  {
20670  return is_boolean() ? &m_data.m_value.boolean : nullptr;
20671  }
20672 
20674  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20675  {
20676  return is_boolean() ? &m_data.m_value.boolean : nullptr;
20677  }
20678 
20681  {
20682  return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
20683  }
20684 
20686  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20687  {
20688  return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
20689  }
20690 
20693  {
20694  return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
20695  }
20696 
20698  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20699  {
20700  return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
20701  }
20702 
20705  {
20706  return is_number_float() ? &m_data.m_value.number_float : nullptr;
20707  }
20708 
20710  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20711  {
20712  return is_number_float() ? &m_data.m_value.number_float : nullptr;
20713  }
20714 
20716  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20717  {
20718  return is_binary() ? m_data.m_value.binary : nullptr;
20719  }
20720 
20722  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20723  {
20724  return is_binary() ? m_data.m_value.binary : nullptr;
20725  }
20726 
20738  template<typename ReferenceType, typename ThisType>
20739  static ReferenceType get_ref_impl(ThisType& obj)
20740  {
20741  // delegate the call to get_ptr<>()
20742  auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20743 
20744  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20745  {
20746  return *ptr;
20747  }
20748 
20749  JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
20750  }
20751 
20752  public:
20756 
20759  template<typename PointerType, typename std::enable_if<
20760  std::is_pointer<PointerType>::value, int>::type = 0>
20761  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20762  {
20763  // delegate the call to get_impl_ptr<>()
20764  return get_impl_ptr(static_cast<PointerType>(nullptr));
20765  }
20766 
20769  template < typename PointerType, typename std::enable_if <
20770  std::is_pointer<PointerType>::value&&
20772  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20773  {
20774  // delegate the call to get_impl_ptr<>() const
20775  return get_impl_ptr(static_cast<PointerType>(nullptr));
20776  }
20777 
20778  private:
20817  template < typename ValueType,
20821  int > = 0 >
20822  ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20823  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20824  {
20825  auto ret = ValueType();
20827  return ret;
20828  }
20829 
20860  template < typename ValueType,
20863  int > = 0 >
20864  ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20865  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20866  {
20868  }
20869 
20885  template < typename BasicJsonType,
20888  int > = 0 >
20889  BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20890  {
20891  return *this;
20892  }
20893 
20908  template<typename BasicJsonType,
20910  std::is_same<BasicJsonType, basic_json_t>::value,
20911  int> = 0>
20913  {
20914  return *this;
20915  }
20916 
20921  template<typename PointerType,
20923  std::is_pointer<PointerType>::value,
20924  int> = 0>
20925  constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20926  -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20927  {
20928  // delegate the call to get_ptr
20929  return get_ptr<PointerType>();
20930  }
20931 
20932  public:
20956  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20957 #if defined(JSON_HAS_CPP_14)
20958  constexpr
20959 #endif
20960  auto get() const noexcept(
20961  noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20962  -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20963  {
20964  // we cannot static_assert on ValueTypeCV being non-const, because
20965  // there is support for get<const basic_json_t>(), which is why we
20966  // still need the uncvref
20967  static_assert(!std::is_reference<ValueTypeCV>::value,
20968  "get() cannot be used with reference types, you might want to use get_ref()");
20969  return get_impl<ValueType>(detail::priority_tag<4> {});
20970  }
20971 
20999  template<typename PointerType, typename std::enable_if<
21000  std::is_pointer<PointerType>::value, int>::type = 0>
21001  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
21002  {
21003  // delegate the call to get_ptr
21004  return get_ptr<PointerType>();
21005  }
21006 
21009  template < typename ValueType,
21013  int > = 0 >
21014  ValueType & get_to(ValueType& v) const noexcept(noexcept(
21015  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
21016  {
21018  return v;
21019  }
21020 
21021  // specialization to allow calling get_to with a basic_json value
21022  // see https://github.com/nlohmann/json/issues/2175
21023  template<typename ValueType,
21026  int> = 0>
21027  ValueType & get_to(ValueType& v) const
21028  {
21029  v = *this;
21030  return v;
21031  }
21032 
21033  template <
21034  typename T, std::size_t N,
21035  typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21038  Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21039  noexcept(noexcept(JSONSerializer<Array>::from_json(
21040  std::declval<const basic_json_t&>(), v)))
21041  {
21043  return v;
21044  }
21045 
21048  template<typename ReferenceType, typename std::enable_if<
21049  std::is_reference<ReferenceType>::value, int>::type = 0>
21050  ReferenceType get_ref()
21051  {
21052  // delegate call to get_ref_impl
21053  return get_ref_impl<ReferenceType>(*this);
21054  }
21055 
21058  template < typename ReferenceType, typename std::enable_if <
21059  std::is_reference<ReferenceType>::value&&
21061  ReferenceType get_ref() const
21062  {
21063  // delegate call to get_ref_impl
21064  return get_ref_impl<ReferenceType>(*this);
21065  }
21066 
21096  template < typename ValueType, typename std::enable_if <
21104 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
21106 #endif
21107 #if defined(JSON_HAS_CPP_17)
21109 #endif
21111  >::value, int >::type = 0 >
21112  JSON_EXPLICIT operator ValueType() const
21113  {
21114  // delegate the call to get<>() const
21115  return get<ValueType>();
21116  }
21117 
21121  {
21122  if (!is_binary())
21123  {
21124  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21125  }
21126 
21127  return *get_ptr<binary_t*>();
21128  }
21129 
21132  const binary_t& get_binary() const
21133  {
21134  if (!is_binary())
21135  {
21136  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21137  }
21138 
21139  return *get_ptr<const binary_t*>();
21140  }
21141 
21143 
21144 
21146  // element access //
21148 
21152 
21156  {
21157  // at only works for arrays
21158  if (JSON_HEDLEY_LIKELY(is_array()))
21159  {
21160  JSON_TRY
21161  {
21162  return set_parent(m_data.m_value.array->at(idx));
21163  }
21164  JSON_CATCH (std::out_of_range&)
21165  {
21166  // create better exception explanation
21167  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21168  }
21169  }
21170  else
21171  {
21172  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21173  }
21174  }
21175 
21179  {
21180  // at only works for arrays
21181  if (JSON_HEDLEY_LIKELY(is_array()))
21182  {
21183  JSON_TRY
21184  {
21185  return m_data.m_value.array->at(idx);
21186  }
21187  JSON_CATCH (std::out_of_range&)
21188  {
21189  // create better exception explanation
21190  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21191  }
21192  }
21193  else
21194  {
21195  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21196  }
21197  }
21198 
21201  reference at(const typename object_t::key_type& key)
21202  {
21203  // at only works for objects
21204  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21205  {
21206  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21207  }
21208 
21209  auto it = m_data.m_value.object->find(key);
21210  if (it == m_data.m_value.object->end())
21211  {
21212  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21213  }
21214  return set_parent(it->second);
21215  }
21216 
21219  template<class KeyType, detail::enable_if_t<
21221  reference at(KeyType && key)
21222  {
21223  // at only works for objects
21224  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21225  {
21226  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21227  }
21228 
21229  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21230  if (it == m_data.m_value.object->end())
21231  {
21232  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21233  }
21234  return set_parent(it->second);
21235  }
21236 
21239  const_reference at(const typename object_t::key_type& key) const
21240  {
21241  // at only works for objects
21242  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21243  {
21244  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21245  }
21246 
21247  auto it = m_data.m_value.object->find(key);
21248  if (it == m_data.m_value.object->end())
21249  {
21250  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21251  }
21252  return it->second;
21253  }
21254 
21257  template<class KeyType, detail::enable_if_t<
21259  const_reference at(KeyType && key) const
21260  {
21261  // at only works for objects
21262  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21263  {
21264  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21265  }
21266 
21267  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21268  if (it == m_data.m_value.object->end())
21269  {
21270  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21271  }
21272  return it->second;
21273  }
21274 
21278  {
21279  // implicitly convert null value to an empty array
21280  if (is_null())
21281  {
21282  m_data.m_type = value_t::array;
21283  m_data.m_value.array = create<array_t>();
21284  assert_invariant();
21285  }
21286 
21287  // operator[] only works for arrays
21288  if (JSON_HEDLEY_LIKELY(is_array()))
21289  {
21290  // fill up array with null values if given idx is outside range
21291  if (idx >= m_data.m_value.array->size())
21292  {
21293 #if JSON_DIAGNOSTICS
21294  // remember array size & capacity before resizing
21295  const auto old_size = m_data.m_value.array->size();
21296  const auto old_capacity = m_data.m_value.array->capacity();
21297 #endif
21298  m_data.m_value.array->resize(idx + 1);
21299 
21300 #if JSON_DIAGNOSTICS
21301  if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
21302  {
21303  // capacity has changed: update all parents
21304  set_parents();
21305  }
21306  else
21307  {
21308  // set parent for values added above
21309  set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21310  }
21311 #endif
21312  assert_invariant();
21313  }
21314 
21315  return m_data.m_value.array->operator[](idx);
21316  }
21317 
21318  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21319  }
21320 
21324  {
21325  // const operator[] only works for arrays
21326  if (JSON_HEDLEY_LIKELY(is_array()))
21327  {
21328  return m_data.m_value.array->operator[](idx);
21329  }
21330 
21331  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21332  }
21333 
21336  reference operator[](typename object_t::key_type key)
21337  {
21338  // implicitly convert null value to an empty object
21339  if (is_null())
21340  {
21341  m_data.m_type = value_t::object;
21342  m_data.m_value.object = create<object_t>();
21343  assert_invariant();
21344  }
21345 
21346  // operator[] only works for objects
21347  if (JSON_HEDLEY_LIKELY(is_object()))
21348  {
21349  auto result = m_data.m_value.object->emplace(std::move(key), nullptr);
21350  return set_parent(result.first->second);
21351  }
21352 
21353  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21354  }
21355 
21358  const_reference operator[](const typename object_t::key_type& key) const
21359  {
21360  // const operator[] only works for objects
21361  if (JSON_HEDLEY_LIKELY(is_object()))
21362  {
21363  auto it = m_data.m_value.object->find(key);
21364  JSON_ASSERT(it != m_data.m_value.object->end());
21365  return it->second;
21366  }
21367 
21368  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21369  }
21370 
21371  // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
21372  // (they seemingly cannot be constrained to resolve the ambiguity)
21373  template<typename T>
21375  {
21376  return operator[](typename object_t::key_type(key));
21377  }
21378 
21379  template<typename T>
21381  {
21382  return operator[](typename object_t::key_type(key));
21383  }
21384 
21387  template<class KeyType, detail::enable_if_t<
21390  {
21391  // implicitly convert null value to an empty object
21392  if (is_null())
21393  {
21394  m_data.m_type = value_t::object;
21395  m_data.m_value.object = create<object_t>();
21396  assert_invariant();
21397  }
21398 
21399  // operator[] only works for objects
21400  if (JSON_HEDLEY_LIKELY(is_object()))
21401  {
21402  auto result = m_data.m_value.object->emplace(std::forward<KeyType>(key), nullptr);
21403  return set_parent(result.first->second);
21404  }
21405 
21406  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21407  }
21408 
21411  template<class KeyType, detail::enable_if_t<
21413  const_reference operator[](KeyType && key) const
21414  {
21415  // const operator[] only works for objects
21416  if (JSON_HEDLEY_LIKELY(is_object()))
21417  {
21418  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21419  JSON_ASSERT(it != m_data.m_value.object->end());
21420  return it->second;
21421  }
21422 
21423  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21424  }
21425 
21426  private:
21427  template<typename KeyType>
21428  using is_comparable_with_object_key = detail::is_comparable <
21429  object_comparator_t, const typename object_t::key_type&, KeyType >;
21430 
21431  template<typename ValueType>
21432  using value_return_type = std::conditional <
21435 
21436  public:
21439  template < class ValueType, detail::enable_if_t <
21442  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21443  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21444  {
21445  // value only works for objects
21446  if (JSON_HEDLEY_LIKELY(is_object()))
21447  {
21448  // if key is found, return value and given default value otherwise
21449  const auto it = find(key);
21450  if (it != end())
21451  {
21452  return it->template get<ValueType>();
21453  }
21454 
21455  return default_value;
21456  }
21457 
21458  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21459  }
21460 
21467  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21468  ReturnType value(const typename object_t::key_type& key, ValueType && default_value) const
21469  {
21470  // value only works for objects
21471  if (JSON_HEDLEY_LIKELY(is_object()))
21472  {
21473  // if key is found, return value and given default value otherwise
21474  const auto it = find(key);
21475  if (it != end())
21476  {
21477  return it->template get<ReturnType>();
21478  }
21479 
21480  return std::forward<ValueType>(default_value);
21481  }
21482 
21483  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21484  }
21485 
21488  template < class ValueType, class KeyType, detail::enable_if_t <
21491  && is_comparable_with_object_key<KeyType>::value
21493  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21494  ValueType value(KeyType && key, const ValueType& default_value) const
21495  {
21496  // value only works for objects
21497  if (JSON_HEDLEY_LIKELY(is_object()))
21498  {
21499  // if key is found, return value and given default value otherwise
21500  const auto it = find(std::forward<KeyType>(key));
21501  if (it != end())
21502  {
21503  return it->template get<ValueType>();
21504  }
21505 
21506  return default_value;
21507  }
21508 
21509  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21510  }
21511 
21518  && is_comparable_with_object_key<KeyType>::value
21520  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21521  ReturnType value(KeyType && key, ValueType && default_value) const
21522  {
21523  // value only works for objects
21524  if (JSON_HEDLEY_LIKELY(is_object()))
21525  {
21526  // if key is found, return value and given default value otherwise
21527  const auto it = find(std::forward<KeyType>(key));
21528  if (it != end())
21529  {
21530  return it->template get<ReturnType>();
21531  }
21532 
21533  return std::forward<ValueType>(default_value);
21534  }
21535 
21536  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21537  }
21538 
21541  template < class ValueType, detail::enable_if_t <
21543  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21544  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21545  {
21546  // value only works for objects
21547  if (JSON_HEDLEY_LIKELY(is_object()))
21548  {
21549  // if pointer resolves a value, return it or use default value
21550  JSON_TRY
21551  {
21552  return ptr.get_checked(this).template get<ValueType>();
21553  }
21555  {
21556  return default_value;
21557  }
21558  }
21559 
21560  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21561  }
21562 
21568  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21569  ReturnType value(const json_pointer& ptr, ValueType && default_value) const
21570  {
21571  // value only works for objects
21572  if (JSON_HEDLEY_LIKELY(is_object()))
21573  {
21574  // if pointer resolves a value, return it or use default value
21575  JSON_TRY
21576  {
21577  return ptr.get_checked(this).template get<ReturnType>();
21578  }
21580  {
21581  return std::forward<ValueType>(default_value);
21582  }
21583  }
21584 
21585  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21586  }
21587 
21588  template < class ValueType, class BasicJsonType, detail::enable_if_t <
21591  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21592  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21593  ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
21594  {
21595  return value(ptr.convert(), default_value);
21596  }
21597 
21602  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21603  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21604  ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const
21605  {
21606  return value(ptr.convert(), std::forward<ValueType>(default_value));
21607  }
21608 
21611  reference front()
21612  {
21613  return *begin();
21614  }
21615 
21619  {
21620  return *cbegin();
21621  }
21622 
21626  {
21627  auto tmp = end();
21628  --tmp;
21629  return *tmp;
21630  }
21631 
21635  {
21636  auto tmp = cend();
21637  --tmp;
21638  return *tmp;
21639  }
21640 
21643  template < class IteratorType, detail::enable_if_t <
21644  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21645  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21646  IteratorType erase(IteratorType pos)
21647  {
21648  // make sure iterator fits the current value
21649  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21650  {
21651  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21652  }
21653 
21654  IteratorType result = end();
21655 
21656  switch (m_data.m_type)
21657  {
21658  case value_t::boolean:
21659  case value_t::number_float:
21660  case value_t::number_integer:
21661  case value_t::number_unsigned:
21662  case value_t::string:
21663  case value_t::binary:
21664  {
21665  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21666  {
21667  JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
21668  }
21669 
21670  if (is_string())
21671  {
21672  AllocatorType<string_t> alloc;
21673  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
21674  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
21675  m_data.m_value.string = nullptr;
21676  }
21677  else if (is_binary())
21678  {
21679  AllocatorType<binary_t> alloc;
21680  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
21681  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
21682  m_data.m_value.binary = nullptr;
21683  }
21684 
21685  m_data.m_type = value_t::null;
21686  assert_invariant();
21687  break;
21688  }
21689 
21690  case value_t::object:
21691  {
21692  result.m_it.object_iterator = m_data.m_value.object->erase(pos.m_it.object_iterator);
21693  break;
21694  }
21695 
21696  case value_t::array:
21697  {
21698  result.m_it.array_iterator = m_data.m_value.array->erase(pos.m_it.array_iterator);
21699  break;
21700  }
21701 
21702  case value_t::null:
21703  case value_t::discarded:
21704  default:
21705  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21706  }
21707 
21708  return result;
21709  }
21710 
21713  template < class IteratorType, detail::enable_if_t <
21714  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21715  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21716  IteratorType erase(IteratorType first, IteratorType last)
21717  {
21718  // make sure iterator fits the current value
21719  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21720  {
21721  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
21722  }
21723 
21724  IteratorType result = end();
21725 
21726  switch (m_data.m_type)
21727  {
21728  case value_t::boolean:
21729  case value_t::number_float:
21730  case value_t::number_integer:
21731  case value_t::number_unsigned:
21732  case value_t::string:
21733  case value_t::binary:
21734  {
21735  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21736  || !last.m_it.primitive_iterator.is_end()))
21737  {
21738  JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
21739  }
21740 
21741  if (is_string())
21742  {
21743  AllocatorType<string_t> alloc;
21744  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
21745  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
21746  m_data.m_value.string = nullptr;
21747  }
21748  else if (is_binary())
21749  {
21750  AllocatorType<binary_t> alloc;
21751  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
21752  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
21753  m_data.m_value.binary = nullptr;
21754  }
21755 
21756  m_data.m_type = value_t::null;
21757  assert_invariant();
21758  break;
21759  }
21760 
21761  case value_t::object:
21762  {
21763  result.m_it.object_iterator = m_data.m_value.object->erase(first.m_it.object_iterator,
21764  last.m_it.object_iterator);
21765  break;
21766  }
21767 
21768  case value_t::array:
21769  {
21770  result.m_it.array_iterator = m_data.m_value.array->erase(first.m_it.array_iterator,
21771  last.m_it.array_iterator);
21772  break;
21773  }
21774 
21775  case value_t::null:
21776  case value_t::discarded:
21777  default:
21778  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21779  }
21780 
21781  return result;
21782  }
21783 
21784  private:
21785  template < typename KeyType, detail::enable_if_t <
21788  {
21789  // this erase only works for objects
21790  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21791  {
21792  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21793  }
21794 
21795  return m_data.m_value.object->erase(std::forward<KeyType>(key));
21796  }
21797 
21798  template < typename KeyType, detail::enable_if_t <
21801  {
21802  // this erase only works for objects
21803  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21804  {
21805  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21806  }
21807 
21808  const auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21809  if (it != m_data.m_value.object->end())
21810  {
21811  m_data.m_value.object->erase(it);
21812  return 1;
21813  }
21814  return 0;
21815  }
21816 
21817  public:
21818 
21821  size_type erase(const typename object_t::key_type& key)
21822  {
21823  // the indirection via erase_internal() is added to avoid making this
21824  // function a template and thus de-rank it during overload resolution
21825  return erase_internal(key);
21826  }
21827 
21830  template<class KeyType, detail::enable_if_t<
21832  size_type erase(KeyType && key)
21833  {
21834  return erase_internal(std::forward<KeyType>(key));
21835  }
21836 
21839  void erase(const size_type idx)
21840  {
21841  // this erase only works for arrays
21842  if (JSON_HEDLEY_LIKELY(is_array()))
21843  {
21844  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21845  {
21846  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21847  }
21848 
21849  m_data.m_value.array->erase(m_data.m_value.array->begin() + static_cast<difference_type>(idx));
21850  }
21851  else
21852  {
21853  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21854  }
21855  }
21856 
21858 
21859 
21861  // lookup //
21863 
21866 
21869  iterator find(const typename object_t::key_type& key)
21870  {
21871  auto result = end();
21872 
21873  if (is_object())
21874  {
21875  result.m_it.object_iterator = m_data.m_value.object->find(key);
21876  }
21877 
21878  return result;
21879  }
21880 
21883  const_iterator find(const typename object_t::key_type& key) const
21884  {
21885  auto result = cend();
21886 
21887  if (is_object())
21888  {
21889  result.m_it.object_iterator = m_data.m_value.object->find(key);
21890  }
21891 
21892  return result;
21893  }
21894 
21897  template<class KeyType, detail::enable_if_t<
21899  iterator find(KeyType && key)
21900  {
21901  auto result = end();
21902 
21903  if (is_object())
21904  {
21905  result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
21906  }
21907 
21908  return result;
21909  }
21910 
21913  template<class KeyType, detail::enable_if_t<
21915  const_iterator find(KeyType && key) const
21916  {
21917  auto result = cend();
21918 
21919  if (is_object())
21920  {
21921  result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
21922  }
21923 
21924  return result;
21925  }
21926 
21929  size_type count(const typename object_t::key_type& key) const
21930  {
21931  // return 0 for all nonobject types
21932  return is_object() ? m_data.m_value.object->count(key) : 0;
21933  }
21934 
21937  template<class KeyType, detail::enable_if_t<
21939  size_type count(KeyType && key) const
21940  {
21941  // return 0 for all nonobject types
21942  return is_object() ? m_data.m_value.object->count(std::forward<KeyType>(key)) : 0;
21943  }
21944 
21947  bool contains(const typename object_t::key_type& key) const
21948  {
21949  return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
21950  }
21951 
21954  template<class KeyType, detail::enable_if_t<
21956  bool contains(KeyType && key) const
21957  {
21958  return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
21959  }
21960 
21963  bool contains(const json_pointer& ptr) const
21964  {
21965  return ptr.contains(this);
21966  }
21967 
21968  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
21969  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21970  bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
21971  {
21972  return ptr.contains(this);
21973  }
21974 
21976 
21977 
21979  // iterators //
21981 
21984 
21987  iterator begin() noexcept
21988  {
21989  iterator result(this);
21990  result.set_begin();
21991  return result;
21992  }
21993 
21996  const_iterator begin() const noexcept
21997  {
21998  return cbegin();
21999  }
22000 
22003  const_iterator cbegin() const noexcept
22004  {
22005  const_iterator result(this);
22006  result.set_begin();
22007  return result;
22008  }
22009 
22012  iterator end() noexcept
22013  {
22014  iterator result(this);
22015  result.set_end();
22016  return result;
22017  }
22018 
22021  const_iterator end() const noexcept
22022  {
22023  return cend();
22024  }
22025 
22028  const_iterator cend() const noexcept
22029  {
22030  const_iterator result(this);
22031  result.set_end();
22032  return result;
22033  }
22034 
22037  reverse_iterator rbegin() noexcept
22038  {
22039  return reverse_iterator(end());
22040  }
22041 
22044  const_reverse_iterator rbegin() const noexcept
22045  {
22046  return crbegin();
22047  }
22048 
22051  reverse_iterator rend() noexcept
22052  {
22053  return reverse_iterator(begin());
22054  }
22055 
22058  const_reverse_iterator rend() const noexcept
22059  {
22060  return crend();
22061  }
22062 
22065  const_reverse_iterator crbegin() const noexcept
22066  {
22067  return const_reverse_iterator(cend());
22068  }
22069 
22072  const_reverse_iterator crend() const noexcept
22073  {
22074  return const_reverse_iterator(cbegin());
22075  }
22076 
22077  public:
22083  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22084  static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22085  {
22086  return ref.items();
22087  }
22088 
22094  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22095  static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22096  {
22097  return ref.items();
22098  }
22099 
22102  iteration_proxy<iterator> items() noexcept
22103  {
22104  return iteration_proxy<iterator>(*this);
22105  }
22106 
22109  iteration_proxy<const_iterator> items() const noexcept
22110  {
22111  return iteration_proxy<const_iterator>(*this);
22112  }
22113 
22115 
22116 
22118  // capacity //
22120 
22123 
22126  bool empty() const noexcept
22127  {
22128  switch (m_data.m_type)
22129  {
22130  case value_t::null:
22131  {
22132  // null values are empty
22133  return true;
22134  }
22135 
22136  case value_t::array:
22137  {
22138  // delegate call to array_t::empty()
22139  return m_data.m_value.array->empty();
22140  }
22141 
22142  case value_t::object:
22143  {
22144  // delegate call to object_t::empty()
22145  return m_data.m_value.object->empty();
22146  }
22147 
22148  case value_t::string:
22149  case value_t::boolean:
22150  case value_t::number_integer:
22151  case value_t::number_unsigned:
22152  case value_t::number_float:
22153  case value_t::binary:
22154  case value_t::discarded:
22155  default:
22156  {
22157  // all other types are nonempty
22158  return false;
22159  }
22160  }
22161  }
22162 
22165  size_type size() const noexcept
22166  {
22167  switch (m_data.m_type)
22168  {
22169  case value_t::null:
22170  {
22171  // null values are empty
22172  return 0;
22173  }
22174 
22175  case value_t::array:
22176  {
22177  // delegate call to array_t::size()
22178  return m_data.m_value.array->size();
22179  }
22180 
22181  case value_t::object:
22182  {
22183  // delegate call to object_t::size()
22184  return m_data.m_value.object->size();
22185  }
22186 
22187  case value_t::string:
22188  case value_t::boolean:
22189  case value_t::number_integer:
22190  case value_t::number_unsigned:
22191  case value_t::number_float:
22192  case value_t::binary:
22193  case value_t::discarded:
22194  default:
22195  {
22196  // all other types have size 1
22197  return 1;
22198  }
22199  }
22200  }
22201 
22204  size_type max_size() const noexcept
22205  {
22206  switch (m_data.m_type)
22207  {
22208  case value_t::array:
22209  {
22210  // delegate call to array_t::max_size()
22211  return m_data.m_value.array->max_size();
22212  }
22213 
22214  case value_t::object:
22215  {
22216  // delegate call to object_t::max_size()
22217  return m_data.m_value.object->max_size();
22218  }
22219 
22220  case value_t::null:
22221  case value_t::string:
22222  case value_t::boolean:
22223  case value_t::number_integer:
22224  case value_t::number_unsigned:
22225  case value_t::number_float:
22226  case value_t::binary:
22227  case value_t::discarded:
22228  default:
22229  {
22230  // all other types have max_size() == size()
22231  return size();
22232  }
22233  }
22234  }
22235 
22237 
22238 
22240  // modifiers //
22242 
22245 
22248  void clear() noexcept
22249  {
22250  switch (m_data.m_type)
22251  {
22252  case value_t::number_integer:
22253  {
22254  m_data.m_value.number_integer = 0;
22255  break;
22256  }
22257 
22258  case value_t::number_unsigned:
22259  {
22260  m_data.m_value.number_unsigned = 0;
22261  break;
22262  }
22263 
22264  case value_t::number_float:
22265  {
22266  m_data.m_value.number_float = 0.0;
22267  break;
22268  }
22269 
22270  case value_t::boolean:
22271  {
22272  m_data.m_value.boolean = false;
22273  break;
22274  }
22275 
22276  case value_t::string:
22277  {
22278  m_data.m_value.string->clear();
22279  break;
22280  }
22281 
22282  case value_t::binary:
22283  {
22284  m_data.m_value.binary->clear();
22285  break;
22286  }
22287 
22288  case value_t::array:
22289  {
22290  m_data.m_value.array->clear();
22291  break;
22292  }
22293 
22294  case value_t::object:
22295  {
22296  m_data.m_value.object->clear();
22297  break;
22298  }
22299 
22300  case value_t::null:
22301  case value_t::discarded:
22302  default:
22303  break;
22304  }
22305  }
22306 
22309  void push_back(basic_json&& val)
22310  {
22311  // push_back only works for null objects or arrays
22312  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22313  {
22314  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22315  }
22316 
22317  // transform null object into an array
22318  if (is_null())
22319  {
22320  m_data.m_type = value_t::array;
22321  m_data.m_value = value_t::array;
22322  assert_invariant();
22323  }
22324 
22325  // add element to array (move semantics)
22326  const auto old_capacity = m_data.m_value.array->capacity();
22327  m_data.m_value.array->push_back(std::move(val));
22328  set_parent(m_data.m_value.array->back(), old_capacity);
22329  // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
22330  }
22331 
22335  {
22336  push_back(std::move(val));
22337  return *this;
22338  }
22339 
22342  void push_back(const basic_json& val)
22343  {
22344  // push_back only works for null objects or arrays
22345  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22346  {
22347  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22348  }
22349 
22350  // transform null object into an array
22351  if (is_null())
22352  {
22353  m_data.m_type = value_t::array;
22354  m_data.m_value = value_t::array;
22355  assert_invariant();
22356  }
22357 
22358  // add element to array
22359  const auto old_capacity = m_data.m_value.array->capacity();
22360  m_data.m_value.array->push_back(val);
22361  set_parent(m_data.m_value.array->back(), old_capacity);
22362  }
22363 
22367  {
22368  push_back(val);
22369  return *this;
22370  }
22371 
22374  void push_back(const typename object_t::value_type& val)
22375  {
22376  // push_back only works for null objects or objects
22377  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22378  {
22379  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22380  }
22381 
22382  // transform null object into an object
22383  if (is_null())
22384  {
22385  m_data.m_type = value_t::object;
22386  m_data.m_value = value_t::object;
22387  assert_invariant();
22388  }
22389 
22390  // add element to object
22391  auto res = m_data.m_value.object->insert(val);
22392  set_parent(res.first->second);
22393  }
22394 
22397  reference operator+=(const typename object_t::value_type& val)
22398  {
22399  push_back(val);
22400  return *this;
22401  }
22402 
22406  {
22407  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22408  {
22409  basic_json&& key = init.begin()->moved_or_copied();
22410  push_back(typename object_t::value_type(
22411  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22412  }
22413  else
22414  {
22415  push_back(basic_json(init));
22416  }
22417  }
22418 
22422  {
22423  push_back(init);
22424  return *this;
22425  }
22426 
22429  template<class... Args>
22431  {
22432  // emplace_back only works for null objects or arrays
22433  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22434  {
22435  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
22436  }
22437 
22438  // transform null object into an array
22439  if (is_null())
22440  {
22441  m_data.m_type = value_t::array;
22442  m_data.m_value = value_t::array;
22443  assert_invariant();
22444  }
22445 
22446  // add element to array (perfect forwarding)
22447  const auto old_capacity = m_data.m_value.array->capacity();
22448  m_data.m_value.array->emplace_back(std::forward<Args>(args)...);
22449  return set_parent(m_data.m_value.array->back(), old_capacity);
22450  }
22451 
22454  template<class... Args>
22455  std::pair<iterator, bool> emplace(Args&& ... args)
22456  {
22457  // emplace only works for null objects or arrays
22458  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22459  {
22460  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
22461  }
22462 
22463  // transform null object into an object
22464  if (is_null())
22465  {
22466  m_data.m_type = value_t::object;
22467  m_data.m_value = value_t::object;
22468  assert_invariant();
22469  }
22470 
22471  // add element to array (perfect forwarding)
22472  auto res = m_data.m_value.object->emplace(std::forward<Args>(args)...);
22473  set_parent(res.first->second);
22474 
22475  // create result iterator and set iterator to the result of emplace
22476  auto it = begin();
22477  it.m_it.object_iterator = res.first;
22478 
22479  // return pair of iterator and boolean
22480  return {it, res.second};
22481  }
22482 
22486  template<typename... Args>
22488  {
22489  iterator result(this);
22490  JSON_ASSERT(m_data.m_value.array != nullptr);
22491 
22492  auto insert_pos = std::distance(m_data.m_value.array->begin(), pos.m_it.array_iterator);
22493  m_data.m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22494  result.m_it.array_iterator = m_data.m_value.array->begin() + insert_pos;
22495 
22496  // This could have been written as:
22497  // result.m_it.array_iterator = m_data.m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22498  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22499 
22500  set_parents();
22501  return result;
22502  }
22503 
22507  {
22508  // insert only works for arrays
22509  if (JSON_HEDLEY_LIKELY(is_array()))
22510  {
22511  // check if iterator pos fits to this JSON value
22512  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22513  {
22514  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22515  }
22516 
22517  // insert to array and return iterator
22518  return insert_iterator(pos, val);
22519  }
22520 
22521  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22522  }
22523 
22527  {
22528  return insert(pos, val);
22529  }
22530 
22534  {
22535  // insert only works for arrays
22536  if (JSON_HEDLEY_LIKELY(is_array()))
22537  {
22538  // check if iterator pos fits to this JSON value
22539  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22540  {
22541  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22542  }
22543 
22544  // insert to array and return iterator
22545  return insert_iterator(pos, cnt, val);
22546  }
22547 
22548  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22549  }
22550 
22554  {
22555  // insert only works for arrays
22556  if (JSON_HEDLEY_UNLIKELY(!is_array()))
22557  {
22558  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22559  }
22560 
22561  // check if iterator pos fits to this JSON value
22562  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22563  {
22564  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22565  }
22566 
22567  // check if range iterators belong to the same JSON object
22568  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22569  {
22570  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22571  }
22572 
22573  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22574  {
22575  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
22576  }
22577 
22578  // insert to array and return iterator
22579  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22580  }
22581 
22585  {
22586  // insert only works for arrays
22587  if (JSON_HEDLEY_UNLIKELY(!is_array()))
22588  {
22589  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22590  }
22591 
22592  // check if iterator pos fits to this JSON value
22593  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22594  {
22595  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22596  }
22597 
22598  // insert to array and return iterator
22599  return insert_iterator(pos, ilist.begin(), ilist.end());
22600  }
22601 
22605  {
22606  // insert only works for objects
22607  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22608  {
22609  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22610  }
22611 
22612  // check if range iterators belong to the same JSON object
22613  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22614  {
22615  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22616  }
22617 
22618  // passed iterators must belong to objects
22619  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22620  {
22621  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
22622  }
22623 
22624  m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22625  }
22626 
22629  void update(const_reference j, bool merge_objects = false)
22630  {
22631  update(j.begin(), j.end(), merge_objects);
22632  }
22633 
22636  void update(const_iterator first, const_iterator last, bool merge_objects = false)
22637  {
22638  // implicitly convert null value to an empty object
22639  if (is_null())
22640  {
22641  m_data.m_type = value_t::object;
22642  m_data.m_value.object = create<object_t>();
22643  assert_invariant();
22644  }
22645 
22646  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22647  {
22648  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
22649  }
22650 
22651  // check if range iterators belong to the same JSON object
22652  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22653  {
22654  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22655  }
22656 
22657  // passed iterators must belong to objects
22658  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22659  {
22660  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
22661  }
22662 
22663  for (auto it = first; it != last; ++it)
22664  {
22665  if (merge_objects && it.value().is_object())
22666  {
22667  auto it2 = m_data.m_value.object->find(it.key());
22668  if (it2 != m_data.m_value.object->end())
22669  {
22670  it2->second.update(it.value(), true);
22671  continue;
22672  }
22673  }
22674  m_data.m_value.object->operator[](it.key()) = it.value();
22675 #if JSON_DIAGNOSTICS
22676  m_data.m_value.object->operator[](it.key()).m_parent = this;
22677 #endif
22678  }
22679  }
22680 
22683  void swap(reference other) noexcept (
22684  std::is_nothrow_move_constructible<value_t>::value&&
22685  std::is_nothrow_move_assignable<value_t>::value&&
22686  std::is_nothrow_move_constructible<json_value>::value&&
22687  std::is_nothrow_move_assignable<json_value>::value
22688  )
22689  {
22690  std::swap(m_data.m_type, other.m_data.m_type);
22691  std::swap(m_data.m_value, other.m_data.m_value);
22692 
22693  set_parents();
22694  other.set_parents();
22695  assert_invariant();
22696  }
22697 
22700  friend void swap(reference left, reference right) noexcept (
22701  std::is_nothrow_move_constructible<value_t>::value&&
22702  std::is_nothrow_move_assignable<value_t>::value&&
22703  std::is_nothrow_move_constructible<json_value>::value&&
22704  std::is_nothrow_move_assignable<json_value>::value
22705  )
22706  {
22707  left.swap(right);
22708  }
22709 
22712  void swap(array_t& other) // NOLINT(bugprone-exception-escape)
22713  {
22714  // swap only works for arrays
22715  if (JSON_HEDLEY_LIKELY(is_array()))
22716  {
22717  using std::swap;
22718  swap(*(m_data.m_value.array), other);
22719  }
22720  else
22721  {
22722  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
22723  }
22724  }
22725 
22728  void swap(object_t& other) // NOLINT(bugprone-exception-escape)
22729  {
22730  // swap only works for objects
22731  if (JSON_HEDLEY_LIKELY(is_object()))
22732  {
22733  using std::swap;
22734  swap(*(m_data.m_value.object), other);
22735  }
22736  else
22737  {
22738  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
22739  }
22740  }
22741 
22744  void swap(string_t& other) // NOLINT(bugprone-exception-escape)
22745  {
22746  // swap only works for strings
22747  if (JSON_HEDLEY_LIKELY(is_string()))
22748  {
22749  using std::swap;
22750  swap(*(m_data.m_value.string), other);
22751  }
22752  else
22753  {
22754  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
22755  }
22756  }
22757 
22760  void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
22761  {
22762  // swap only works for strings
22763  if (JSON_HEDLEY_LIKELY(is_binary()))
22764  {
22765  using std::swap;
22766  swap(*(m_data.m_value.binary), other);
22767  }
22768  else
22769  {
22770  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
22771  }
22772  }
22773 
22776  void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
22777  {
22778  // swap only works for strings
22779  if (JSON_HEDLEY_LIKELY(is_binary()))
22780  {
22781  using std::swap;
22782  swap(*(m_data.m_value.binary), other);
22783  }
22784  else
22785  {
22786  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
22787  }
22788  }
22789 
22791 
22793  // lexicographical comparison operators //
22795 
22798 
22799  // note parentheses around operands are necessary; see
22800  // https://github.com/nlohmann/json/issues/1530
22801 #define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
22802  const auto lhs_type = lhs.type(); \
22803  const auto rhs_type = rhs.type(); \
22804  \
22805  if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
22806  { \
22807  switch (lhs_type) \
22808  { \
22809  case value_t::array: \
22810  return (*lhs.m_data.m_value.array) op (*rhs.m_data.m_value.array); \
22811  \
22812  case value_t::object: \
22813  return (*lhs.m_data.m_value.object) op (*rhs.m_data.m_value.object); \
22814  \
22815  case value_t::null: \
22816  return (null_result); \
22817  \
22818  case value_t::string: \
22819  return (*lhs.m_data.m_value.string) op (*rhs.m_data.m_value.string); \
22820  \
22821  case value_t::boolean: \
22822  return (lhs.m_data.m_value.boolean) op (rhs.m_data.m_value.boolean); \
22823  \
22824  case value_t::number_integer: \
22825  return (lhs.m_data.m_value.number_integer) op (rhs.m_data.m_value.number_integer); \
22826  \
22827  case value_t::number_unsigned: \
22828  return (lhs.m_data.m_value.number_unsigned) op (rhs.m_data.m_value.number_unsigned); \
22829  \
22830  case value_t::number_float: \
22831  return (lhs.m_data.m_value.number_float) op (rhs.m_data.m_value.number_float); \
22832  \
22833  case value_t::binary: \
22834  return (*lhs.m_data.m_value.binary) op (*rhs.m_data.m_value.binary); \
22835  \
22836  case value_t::discarded: \
22837  default: \
22838  return (unordered_result); \
22839  } \
22840  } \
22841  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
22842  { \
22843  return static_cast<number_float_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_float; \
22844  } \
22845  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
22846  { \
22847  return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_integer); \
22848  } \
22849  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
22850  { \
22851  return static_cast<number_float_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_float; \
22852  } \
22853  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
22854  { \
22855  return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_unsigned); \
22856  } \
22857  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
22858  { \
22859  return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \
22860  } \
22861  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
22862  { \
22863  return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \
22864  } \
22865  else if(compares_unordered(lhs, rhs))\
22866  {\
22867  return (unordered_result);\
22868  }\
22869  \
22870  return (default_result);
22871 
22873  // returns true if:
22874  // - any operand is NaN and the other operand is of number type
22875  // - any operand is discarded
22876  // in legacy mode, discarded values are considered ordered if
22877  // an operation is computed as an odd number of inverses of others
22878  static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
22879  {
22880  if ((lhs.is_number_float() && std::isnan(lhs.m_data.m_value.number_float) && rhs.is_number())
22881  || (rhs.is_number_float() && std::isnan(rhs.m_data.m_value.number_float) && lhs.is_number()))
22882  {
22883  return true;
22884  }
22885 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22886  return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
22887 #else
22888  static_cast<void>(inverse);
22889  return lhs.is_discarded() || rhs.is_discarded();
22890 #endif
22891  }
22892 
22893  private:
22894  bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
22895  {
22896  return compares_unordered(*this, rhs, inverse);
22897  }
22898 
22899  public:
22900 #if JSON_HAS_THREE_WAY_COMPARISON
22901  bool operator==(const_reference rhs) const noexcept
22904  {
22905 #ifdef __GNUC__
22906 #pragma GCC diagnostic push
22907 #pragma GCC diagnostic ignored "-Wfloat-equal"
22908 #endif
22909  const_reference lhs = *this;
22910  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
22911 #ifdef __GNUC__
22912 #pragma GCC diagnostic pop
22913 #endif
22914  }
22915 
22918  template<typename ScalarType>
22919  requires std::is_scalar_v<ScalarType>
22920  bool operator==(ScalarType rhs) const noexcept
22921  {
22922  return *this == basic_json(rhs);
22923  }
22924 
22927  bool operator!=(const_reference rhs) const noexcept
22928  {
22929  if (compares_unordered(rhs, true))
22930  {
22931  return false;
22932  }
22933  return !operator==(rhs);
22934  }
22935 
22938  std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
22939  {
22940  const_reference lhs = *this;
22941  // default_result is used if we cannot compare values. In that case,
22942  // we compare types.
22943  JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD*
22944  std::partial_ordering::equivalent,
22945  std::partial_ordering::unordered,
22946  lhs_type <=> rhs_type) // *NOPAD*
22947  }
22948 
22951  template<typename ScalarType>
22952  requires std::is_scalar_v<ScalarType>
22953  std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
22954  {
22955  return *this <=> basic_json(rhs); // *NOPAD*
22956  }
22957 
22958 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22959  // all operators that are computed as an odd number of inverses of others
22960  // need to be overloaded to emulate the legacy comparison behavior
22961 
22965  bool operator<=(const_reference rhs) const noexcept
22966  {
22967  if (compares_unordered(rhs, true))
22968  {
22969  return false;
22970  }
22971  return !(rhs < *this);
22972  }
22973 
22976  template<typename ScalarType>
22977  requires std::is_scalar_v<ScalarType>
22978  bool operator<=(ScalarType rhs) const noexcept
22979  {
22980  return *this <= basic_json(rhs);
22981  }
22982 
22986  bool operator>=(const_reference rhs) const noexcept
22987  {
22988  if (compares_unordered(rhs, true))
22989  {
22990  return false;
22991  }
22992  return !(*this < rhs);
22993  }
22994 
22997  template<typename ScalarType>
22998  requires std::is_scalar_v<ScalarType>
22999  bool operator>=(ScalarType rhs) const noexcept
23000  {
23001  return *this >= basic_json(rhs);
23002  }
23003 #endif
23004 #else
23005  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23008  {
23009 #ifdef __GNUC__
23010 #pragma GCC diagnostic push
23011 #pragma GCC diagnostic ignored "-Wfloat-equal"
23012 #endif
23013  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
23014 #ifdef __GNUC__
23015 #pragma GCC diagnostic pop
23016 #endif
23017  }
23018 
23021  template<typename ScalarType, typename std::enable_if<
23022  std::is_scalar<ScalarType>::value, int>::type = 0>
23023  friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23024  {
23025  return lhs == basic_json(rhs);
23026  }
23027 
23030  template<typename ScalarType, typename std::enable_if<
23031  std::is_scalar<ScalarType>::value, int>::type = 0>
23032  friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23033  {
23034  return basic_json(lhs) == rhs;
23035  }
23036 
23039  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23040  {
23041  if (compares_unordered(lhs, rhs, true))
23042  {
23043  return false;
23044  }
23045  return !(lhs == rhs);
23046  }
23047 
23050  template<typename ScalarType, typename std::enable_if<
23051  std::is_scalar<ScalarType>::value, int>::type = 0>
23052  friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23053  {
23054  return lhs != basic_json(rhs);
23055  }
23056 
23059  template<typename ScalarType, typename std::enable_if<
23060  std::is_scalar<ScalarType>::value, int>::type = 0>
23061  friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23062  {
23063  return basic_json(lhs) != rhs;
23064  }
23065 
23068  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23069  {
23070  // default_result is used if we cannot compare values. In that case,
23071  // we compare types. Note we have to call the operator explicitly,
23072  // because MSVC has problems otherwise.
23073  JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))
23074  }
23075 
23078  template<typename ScalarType, typename std::enable_if<
23079  std::is_scalar<ScalarType>::value, int>::type = 0>
23080  friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23081  {
23082  return lhs < basic_json(rhs);
23083  }
23084 
23087  template<typename ScalarType, typename std::enable_if<
23088  std::is_scalar<ScalarType>::value, int>::type = 0>
23089  friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
23090  {
23091  return basic_json(lhs) < rhs;
23092  }
23093 
23096  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
23097  {
23098  if (compares_unordered(lhs, rhs, true))
23099  {
23100  return false;
23101  }
23102  return !(rhs < lhs);
23103  }
23104 
23107  template<typename ScalarType, typename std::enable_if<
23108  std::is_scalar<ScalarType>::value, int>::type = 0>
23109  friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
23110  {
23111  return lhs <= basic_json(rhs);
23112  }
23113 
23116  template<typename ScalarType, typename std::enable_if<
23117  std::is_scalar<ScalarType>::value, int>::type = 0>
23118  friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
23119  {
23120  return basic_json(lhs) <= rhs;
23121  }
23122 
23125  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23126  {
23127  // double inverse
23128  if (compares_unordered(lhs, rhs))
23129  {
23130  return false;
23131  }
23132  return !(lhs <= rhs);
23133  }
23134 
23137  template<typename ScalarType, typename std::enable_if<
23138  std::is_scalar<ScalarType>::value, int>::type = 0>
23139  friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
23140  {
23141  return lhs > basic_json(rhs);
23142  }
23143 
23146  template<typename ScalarType, typename std::enable_if<
23147  std::is_scalar<ScalarType>::value, int>::type = 0>
23148  friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
23149  {
23150  return basic_json(lhs) > rhs;
23151  }
23152 
23155  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23156  {
23157  if (compares_unordered(lhs, rhs, true))
23158  {
23159  return false;
23160  }
23161  return !(lhs < rhs);
23162  }
23163 
23166  template<typename ScalarType, typename std::enable_if<
23167  std::is_scalar<ScalarType>::value, int>::type = 0>
23168  friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
23169  {
23170  return lhs >= basic_json(rhs);
23171  }
23172 
23175  template<typename ScalarType, typename std::enable_if<
23176  std::is_scalar<ScalarType>::value, int>::type = 0>
23177  friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
23178  {
23179  return basic_json(lhs) >= rhs;
23180  }
23181 #endif
23182 
23183 #undef JSON_IMPLEMENT_OPERATOR
23184 
23186 
23188  // serialization //
23190 
23193 #ifndef JSON_NO_IO
23194  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23197  {
23198  // read width member and use it as indentation parameter if nonzero
23199  const bool pretty_print = o.width() > 0;
23200  const auto indentation = pretty_print ? o.width() : 0;
23201 
23202  // reset width to 0 for subsequent calls to this stream
23203  o.width(0);
23204 
23205  // do the actual serialization
23206  serializer s(detail::output_adapter<char>(o), o.fill());
23207  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23208  return o;
23209  }
23210 
23217  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23218  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23219  {
23220  return o << j;
23221  }
23222 #endif // JSON_NO_IO
23223 
23225 
23227  // deserialization //
23229 
23232 
23235  template<typename InputType>
23237  static basic_json parse(InputType&& i,
23238  const parser_callback_t cb = nullptr,
23239  const bool allow_exceptions = true,
23240  const bool ignore_comments = false)
23241  {
23242  basic_json result;
23243  parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23244  return result;
23245  }
23246 
23249  template<typename IteratorType>
23251  static basic_json parse(IteratorType first,
23252  IteratorType last,
23253  const parser_callback_t cb = nullptr,
23254  const bool allow_exceptions = true,
23255  const bool ignore_comments = false)
23256  {
23257  basic_json result;
23258  parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23259  return result;
23260  }
23261 
23263  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23264  static basic_json parse(detail::span_input_adapter&& i,
23265  const parser_callback_t cb = nullptr,
23266  const bool allow_exceptions = true,
23267  const bool ignore_comments = false)
23268  {
23269  basic_json result;
23270  parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23271  return result;
23272  }
23273 
23276  template<typename InputType>
23277  static bool accept(InputType&& i,
23278  const bool ignore_comments = false)
23279  {
23280  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23281  }
23282 
23285  template<typename IteratorType>
23286  static bool accept(IteratorType first, IteratorType last,
23287  const bool ignore_comments = false)
23288  {
23289  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23290  }
23291 
23293  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23294  static bool accept(detail::span_input_adapter&& i,
23295  const bool ignore_comments = false)
23296  {
23297  return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23298  }
23299 
23302  template <typename InputType, typename SAX>
23304  static bool sax_parse(InputType&& i, SAX* sax,
23306  const bool strict = true,
23307  const bool ignore_comments = false)
23308  {
23309  auto ia = detail::input_adapter(std::forward<InputType>(i));
23310  return format == input_format_t::json
23311  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23312  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23313  }
23314 
23317  template<class IteratorType, class SAX>
23319  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23321  const bool strict = true,
23322  const bool ignore_comments = false)
23323  {
23324  auto ia = detail::input_adapter(std::move(first), std::move(last));
23325  return format == input_format_t::json
23326  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23327  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23328  }
23329 
23335  template <typename SAX>
23336  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23338  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23340  const bool strict = true,
23341  const bool ignore_comments = false)
23342  {
23343  auto ia = i.get();
23344  return format == input_format_t::json
23345  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23346  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23347  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23348  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23349  }
23350 #ifndef JSON_NO_IO
23351  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23358  friend std::istream& operator<<(basic_json& j, std::istream& i)
23359  {
23360  return operator>>(i, j);
23361  }
23362 
23365  friend std::istream& operator>>(std::istream& i, basic_json& j)
23366  {
23367  parser(detail::input_adapter(i)).parse(false, j);
23368  return i;
23369  }
23370 #endif // JSON_NO_IO
23371 
23374  // convenience functions //
23376 
23380  const char* type_name() const noexcept
23381  {
23382  switch (m_data.m_type)
23383  {
23384  case value_t::null:
23385  return "null";
23386  case value_t::object:
23387  return "object";
23388  case value_t::array:
23389  return "array";
23390  case value_t::string:
23391  return "string";
23392  case value_t::boolean:
23393  return "boolean";
23394  case value_t::binary:
23395  return "binary";
23396  case value_t::discarded:
23397  return "discarded";
23398  case value_t::number_integer:
23399  case value_t::number_unsigned:
23400  case value_t::number_float:
23401  default:
23402  return "number";
23403  }
23404  }
23405 
23406 
23409  // member variables //
23411 
23412  struct data
23413  {
23415  value_t m_type = value_t::null;
23416 
23418  json_value m_value = {};
23419 
23420  data(const value_t v)
23421  : m_type(v), m_value(v)
23422  {
23423  }
23424 
23425  data(size_type cnt, const basic_json& val)
23426  : m_type(value_t::array)
23427  {
23428  m_value.array = create<array_t>(cnt, val);
23429  }
23430 
23431  data() noexcept = default;
23432  data(data&&) noexcept = default;
23433  data(const data&) noexcept = delete;
23434  data& operator=(data&&) noexcept = delete;
23435  data& operator=(const data&) noexcept = delete;
23436 
23437  ~data() noexcept
23438  {
23439  m_value.destroy(m_type);
23440  }
23441  };
23442 
23443  data m_data = {};
23444 
23445 #if JSON_DIAGNOSTICS
23446  basic_json* m_parent = nullptr;
23448 #endif
23449 
23451  // binary serialization/deserialization //
23453 
23456 
23457  public:
23460  static std::vector<std::uint8_t> to_cbor(const basic_json& j)
23461  {
23462  std::vector<std::uint8_t> result;
23463  to_cbor(j, result);
23464  return result;
23465  }
23466 
23470  {
23471  binary_writer<std::uint8_t>(o).write_cbor(j);
23472  }
23473 
23477  {
23478  binary_writer<char>(o).write_cbor(j);
23479  }
23480 
23483  static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
23484  {
23485  std::vector<std::uint8_t> result;
23486  to_msgpack(j, result);
23487  return result;
23488  }
23489 
23493  {
23494  binary_writer<std::uint8_t>(o).write_msgpack(j);
23495  }
23496 
23500  {
23501  binary_writer<char>(o).write_msgpack(j);
23502  }
23503 
23506  static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
23507  const bool use_size = false,
23508  const bool use_type = false)
23509  {
23510  std::vector<std::uint8_t> result;
23511  to_ubjson(j, result, use_size, use_type);
23512  return result;
23513  }
23514 
23518  const bool use_size = false, const bool use_type = false)
23519  {
23520  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
23521  }
23522 
23526  const bool use_size = false, const bool use_type = false)
23527  {
23528  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23529  }
23530 
23533  static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
23534  const bool use_size = false,
23535  const bool use_type = false)
23536  {
23537  std::vector<std::uint8_t> result;
23538  to_bjdata(j, result, use_size, use_type);
23539  return result;
23540  }
23541 
23545  const bool use_size = false, const bool use_type = false)
23546  {
23547  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
23548  }
23549 
23553  const bool use_size = false, const bool use_type = false)
23554  {
23555  binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
23556  }
23557 
23560  static std::vector<std::uint8_t> to_bson(const basic_json& j)
23561  {
23562  std::vector<std::uint8_t> result;
23563  to_bson(j, result);
23564  return result;
23565  }
23566 
23570  {
23571  binary_writer<std::uint8_t>(o).write_bson(j);
23572  }
23573 
23577  {
23578  binary_writer<char>(o).write_bson(j);
23579  }
23580 
23583  template<typename InputType>
23585  static basic_json from_cbor(InputType&& i,
23586  const bool strict = true,
23587  const bool allow_exceptions = true,
23588  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23589  {
23590  basic_json result;
23591  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23592  auto ia = detail::input_adapter(std::forward<InputType>(i));
23593  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23594  return res ? result : basic_json(value_t::discarded);
23595  }
23596 
23599  template<typename IteratorType>
23601  static basic_json from_cbor(IteratorType first, IteratorType last,
23602  const bool strict = true,
23603  const bool allow_exceptions = true,
23604  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23605  {
23606  basic_json result;
23607  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23608  auto ia = detail::input_adapter(std::move(first), std::move(last));
23609  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23610  return res ? result : basic_json(value_t::discarded);
23611  }
23612 
23613  template<typename T>
23615  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23616  static basic_json from_cbor(const T* ptr, std::size_t len,
23617  const bool strict = true,
23618  const bool allow_exceptions = true,
23619  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23620  {
23621  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23622  }
23623 
23624 
23626  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23627  static basic_json from_cbor(detail::span_input_adapter&& i,
23628  const bool strict = true,
23629  const bool allow_exceptions = true,
23630  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23631  {
23632  basic_json result;
23633  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23634  auto ia = i.get();
23635  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23636  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23637  return res ? result : basic_json(value_t::discarded);
23638  }
23639 
23642  template<typename InputType>
23644  static basic_json from_msgpack(InputType&& i,
23645  const bool strict = true,
23646  const bool allow_exceptions = true)
23647  {
23648  basic_json result;
23649  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23650  auto ia = detail::input_adapter(std::forward<InputType>(i));
23651  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23652  return res ? result : basic_json(value_t::discarded);
23653  }
23654 
23657  template<typename IteratorType>
23659  static basic_json from_msgpack(IteratorType first, IteratorType last,
23660  const bool strict = true,
23661  const bool allow_exceptions = true)
23662  {
23663  basic_json result;
23664  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23665  auto ia = detail::input_adapter(std::move(first), std::move(last));
23666  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23667  return res ? result : basic_json(value_t::discarded);
23668  }
23669 
23670  template<typename T>
23672  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23673  static basic_json from_msgpack(const T* ptr, std::size_t len,
23674  const bool strict = true,
23675  const bool allow_exceptions = true)
23676  {
23677  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
23678  }
23679 
23681  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23682  static basic_json from_msgpack(detail::span_input_adapter&& i,
23683  const bool strict = true,
23684  const bool allow_exceptions = true)
23685  {
23686  basic_json result;
23687  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23688  auto ia = i.get();
23689  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23690  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23691  return res ? result : basic_json(value_t::discarded);
23692  }
23693 
23696  template<typename InputType>
23698  static basic_json from_ubjson(InputType&& i,
23699  const bool strict = true,
23700  const bool allow_exceptions = true)
23701  {
23702  basic_json result;
23703  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23704  auto ia = detail::input_adapter(std::forward<InputType>(i));
23705  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23706  return res ? result : basic_json(value_t::discarded);
23707  }
23708 
23711  template<typename IteratorType>
23713  static basic_json from_ubjson(IteratorType first, IteratorType last,
23714  const bool strict = true,
23715  const bool allow_exceptions = true)
23716  {
23717  basic_json result;
23718  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23719  auto ia = detail::input_adapter(std::move(first), std::move(last));
23720  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23721  return res ? result : basic_json(value_t::discarded);
23722  }
23723 
23724  template<typename T>
23726  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23727  static basic_json from_ubjson(const T* ptr, std::size_t len,
23728  const bool strict = true,
23729  const bool allow_exceptions = true)
23730  {
23731  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
23732  }
23733 
23735  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23736  static basic_json from_ubjson(detail::span_input_adapter&& i,
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 = i.get();
23743  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23744  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23745  return res ? result : basic_json(value_t::discarded);
23746  }
23747 
23748 
23751  template<typename InputType>
23753  static basic_json from_bjdata(InputType&& i,
23754  const bool strict = true,
23755  const bool allow_exceptions = true)
23756  {
23757  basic_json result;
23758  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23759  auto ia = detail::input_adapter(std::forward<InputType>(i));
23760  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23761  return res ? result : basic_json(value_t::discarded);
23762  }
23763 
23766  template<typename IteratorType>
23768  static basic_json from_bjdata(IteratorType first, IteratorType last,
23769  const bool strict = true,
23770  const bool allow_exceptions = true)
23771  {
23772  basic_json result;
23773  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23774  auto ia = detail::input_adapter(std::move(first), std::move(last));
23775  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23776  return res ? result : basic_json(value_t::discarded);
23777  }
23778 
23781  template<typename InputType>
23783  static basic_json from_bson(InputType&& i,
23784  const bool strict = true,
23785  const bool allow_exceptions = true)
23786  {
23787  basic_json result;
23788  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23789  auto ia = detail::input_adapter(std::forward<InputType>(i));
23790  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23791  return res ? result : basic_json(value_t::discarded);
23792  }
23793 
23796  template<typename IteratorType>
23798  static basic_json from_bson(IteratorType first, IteratorType last,
23799  const bool strict = true,
23800  const bool allow_exceptions = true)
23801  {
23802  basic_json result;
23803  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23804  auto ia = detail::input_adapter(std::move(first), std::move(last));
23805  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23806  return res ? result : basic_json(value_t::discarded);
23807  }
23808 
23809  template<typename T>
23811  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23812  static basic_json from_bson(const T* ptr, std::size_t len,
23813  const bool strict = true,
23814  const bool allow_exceptions = true)
23815  {
23816  return from_bson(ptr, ptr + len, strict, allow_exceptions);
23817  }
23818 
23820  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23821  static basic_json from_bson(detail::span_input_adapter&& i,
23822  const bool strict = true,
23823  const bool allow_exceptions = true)
23824  {
23825  basic_json result;
23826  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23827  auto ia = i.get();
23828  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23829  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23830  return res ? result : basic_json(value_t::discarded);
23831  }
23833 
23835  // JSON Pointer support //
23837 
23840 
23844  {
23845  return ptr.get_unchecked(this);
23846  }
23847 
23848  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23849  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23850  reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23851  {
23852  return ptr.get_unchecked(this);
23853  }
23854 
23858  {
23859  return ptr.get_unchecked(this);
23860  }
23861 
23862  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23863  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23864  const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23865  {
23866  return ptr.get_unchecked(this);
23867  }
23868 
23871  reference at(const json_pointer& ptr)
23872  {
23873  return ptr.get_checked(this);
23874  }
23875 
23876  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23877  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23878  reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23879  {
23880  return ptr.get_checked(this);
23881  }
23882 
23885  const_reference at(const json_pointer& ptr) const
23886  {
23887  return ptr.get_checked(this);
23888  }
23889 
23890  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23891  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23892  const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23893  {
23894  return ptr.get_checked(this);
23895  }
23896 
23899  basic_json flatten() const
23900  {
23901  basic_json result(value_t::object);
23902  json_pointer::flatten("", *this, result);
23903  return result;
23904  }
23905 
23908  basic_json unflatten() const
23909  {
23910  return json_pointer::unflatten(*this);
23911  }
23912 
23914 
23916  // JSON Patch functions //
23918 
23921 
23924  void patch_inplace(const basic_json& json_patch)
23925  {
23926  basic_json& result = *this;
23927  // the valid JSON Patch operations
23928  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
23929 
23930  const auto get_op = [](const std::string & op)
23931  {
23932  if (op == "add")
23933  {
23934  return patch_operations::add;
23935  }
23936  if (op == "remove")
23937  {
23938  return patch_operations::remove;
23939  }
23940  if (op == "replace")
23941  {
23942  return patch_operations::replace;
23943  }
23944  if (op == "move")
23945  {
23946  return patch_operations::move;
23947  }
23948  if (op == "copy")
23949  {
23950  return patch_operations::copy;
23951  }
23952  if (op == "test")
23953  {
23954  return patch_operations::test;
23955  }
23956 
23957  return patch_operations::invalid;
23958  };
23959 
23960  // wrapper for "add" operation; add value at ptr
23961  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
23962  {
23963  // adding to the root of the target document means replacing it
23964  if (ptr.empty())
23965  {
23966  result = val;
23967  return;
23968  }
23969 
23970  // make sure the top element of the pointer exists
23971  json_pointer const top_pointer = ptr.top();
23972  if (top_pointer != ptr)
23973  {
23974  result.at(top_pointer);
23975  }
23976 
23977  // get reference to parent of JSON pointer ptr
23978  const auto last_path = ptr.back();
23979  ptr.pop_back();
23980  // parent must exist when performing patch add per RFC6902 specs
23981  basic_json& parent = result.at(ptr);
23982 
23983  switch (parent.m_data.m_type)
23984  {
23985  case value_t::null:
23986  case value_t::object:
23987  {
23988  // use operator[] to add value
23989  parent[last_path] = val;
23990  break;
23991  }
23992 
23993  case value_t::array:
23994  {
23995  if (last_path == "-")
23996  {
23997  // special case: append to back
23998  parent.push_back(val);
23999  }
24000  else
24001  {
24002  const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
24003  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24004  {
24005  // avoid undefined behavior
24006  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
24007  }
24008 
24009  // default case: insert add offset
24010  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24011  }
24012  break;
24013  }
24014 
24015  // if there exists a parent it cannot be primitive
24016  case value_t::string: // LCOV_EXCL_LINE
24017  case value_t::boolean: // LCOV_EXCL_LINE
24018  case value_t::number_integer: // LCOV_EXCL_LINE
24019  case value_t::number_unsigned: // LCOV_EXCL_LINE
24020  case value_t::number_float: // LCOV_EXCL_LINE
24021  case value_t::binary: // LCOV_EXCL_LINE
24022  case value_t::discarded: // LCOV_EXCL_LINE
24023  default: // LCOV_EXCL_LINE
24024  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
24025  }
24026  };
24027 
24028  // wrapper for "remove" operation; remove value at ptr
24029  const auto operation_remove = [this, &result](json_pointer & ptr)
24030  {
24031  // get reference to parent of JSON pointer ptr
24032  const auto last_path = ptr.back();
24033  ptr.pop_back();
24034  basic_json& parent = result.at(ptr);
24035 
24036  // remove child
24037  if (parent.is_object())
24038  {
24039  // perform range check
24040  auto it = parent.find(last_path);
24041  if (JSON_HEDLEY_LIKELY(it != parent.end()))
24042  {
24043  parent.erase(it);
24044  }
24045  else
24046  {
24047  JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
24048  }
24049  }
24050  else if (parent.is_array())
24051  {
24052  // note erase performs range check
24053  parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
24054  }
24055  };
24056 
24057  // type check: top level value must be an array
24058  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24059  {
24060  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
24061  }
24062 
24063  // iterate and apply the operations
24064  for (const auto& val : json_patch)
24065  {
24066  // wrapper to get a value for an operation
24067  const auto get_value = [&val](const std::string & op,
24068  const std::string & member,
24069  bool string_type) -> basic_json &
24070  {
24071  // find value
24072  auto it = val.m_data.m_value.object->find(member);
24073 
24074  // context-sensitive error message
24075  const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
24076 
24077  // check if desired value is present
24078  if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))
24079  {
24080  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24081  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
24082  }
24083 
24084  // check if result is of type string
24085  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24086  {
24087  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24088  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
24089  }
24090 
24091  // no error: return value
24092  return it->second;
24093  };
24094 
24095  // type check: every element of the array must be an object
24096  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24097  {
24098  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
24099  }
24100 
24101  // collect mandatory members
24102  const auto op = get_value("op", "op", true).template get<std::string>();
24103  const auto path = get_value(op, "path", true).template get<std::string>();
24104  json_pointer ptr(path);
24105 
24106  switch (get_op(op))
24107  {
24108  case patch_operations::add:
24109  {
24110  operation_add(ptr, get_value("add", "value", false));
24111  break;
24112  }
24113 
24114  case patch_operations::remove:
24115  {
24116  operation_remove(ptr);
24117  break;
24118  }
24119 
24120  case patch_operations::replace:
24121  {
24122  // the "path" location must exist - use at()
24123  result.at(ptr) = get_value("replace", "value", false);
24124  break;
24125  }
24126 
24127  case patch_operations::move:
24128  {
24129  const auto from_path = get_value("move", "from", true).template get<std::string>();
24130  json_pointer from_ptr(from_path);
24131 
24132  // the "from" location must exist - use at()
24133  basic_json const v = result.at(from_ptr);
24134 
24135  // The move operation is functionally identical to a
24136  // "remove" operation on the "from" location, followed
24137  // immediately by an "add" operation at the target
24138  // location with the value that was just removed.
24139  operation_remove(from_ptr);
24140  operation_add(ptr, v);
24141  break;
24142  }
24143 
24144  case patch_operations::copy:
24145  {
24146  const auto from_path = get_value("copy", "from", true).template get<std::string>();
24147  const json_pointer from_ptr(from_path);
24148 
24149  // the "from" location must exist - use at()
24150  basic_json const v = result.at(from_ptr);
24151 
24152  // The copy is functionally identical to an "add"
24153  // operation at the target location using the value
24154  // specified in the "from" member.
24155  operation_add(ptr, v);
24156  break;
24157  }
24158 
24159  case patch_operations::test:
24160  {
24161  bool success = false;
24162  JSON_TRY
24163  {
24164  // check if "value" matches the one at "path"
24165  // the "path" location must exist - use at()
24166  success = (result.at(ptr) == get_value("test", "value", false));
24167  }
24168  JSON_INTERNAL_CATCH (out_of_range&)
24169  {
24170  // ignore out of range errors: success remains false
24171  }
24172 
24173  // throw an exception if test fails
24174  if (JSON_HEDLEY_UNLIKELY(!success))
24175  {
24176  JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
24177  }
24178 
24179  break;
24180  }
24181 
24182  case patch_operations::invalid:
24183  default:
24184  {
24185  // op must be "add", "remove", "replace", "move", "copy", or
24186  // "test"
24187  JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
24188  }
24189  }
24190  }
24191  }
24192 
24195  basic_json patch(const basic_json& json_patch) const
24196  {
24197  basic_json result = *this;
24198  result.patch_inplace(json_patch);
24199  return result;
24200  }
24201 
24205  static basic_json diff(const basic_json& source, const basic_json& target,
24206  const std::string& path = "")
24207  {
24208  // the patch
24209  basic_json result(value_t::array);
24210 
24211  // if the values are the same, return empty patch
24212  if (source == target)
24213  {
24214  return result;
24215  }
24216 
24217  if (source.type() != target.type())
24218  {
24219  // different types: replace value
24220  result.push_back(
24221  {
24222  {"op", "replace"}, {"path", path}, {"value", target}
24223  });
24224  return result;
24225  }
24226 
24227  switch (source.type())
24228  {
24229  case value_t::array:
24230  {
24231  // first pass: traverse common elements
24232  std::size_t i = 0;
24233  while (i < source.size() && i < target.size())
24234  {
24235  // recursive call to compare array values at index i
24236  auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
24237  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24238  ++i;
24239  }
24240 
24241  // We now reached the end of at least one array
24242  // in a second pass, traverse the remaining elements
24243 
24244  // remove my remaining elements
24245  const auto end_index = static_cast<difference_type>(result.size());
24246  while (i < source.size())
24247  {
24248  // add operations in reverse order to avoid invalid
24249  // indices
24250  result.insert(result.begin() + end_index, object(
24251  {
24252  {"op", "remove"},
24253  {"path", detail::concat(path, '/', std::to_string(i))}
24254  }));
24255  ++i;
24256  }
24257 
24258  // add other remaining elements
24259  while (i < target.size())
24260  {
24261  result.push_back(
24262  {
24263  {"op", "add"},
24264  {"path", detail::concat(path, "/-")},
24265  {"value", target[i]}
24266  });
24267  ++i;
24268  }
24269 
24270  break;
24271  }
24272 
24273  case value_t::object:
24274  {
24275  // first pass: traverse this object's elements
24276  for (auto it = source.cbegin(); it != source.cend(); ++it)
24277  {
24278  // escape the key name to be used in a JSON patch
24279  const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24280 
24281  if (target.find(it.key()) != target.end())
24282  {
24283  // recursive call to compare object values at key it
24284  auto temp_diff = diff(it.value(), target[it.key()], path_key);
24285  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24286  }
24287  else
24288  {
24289  // found a key that is not in o -> remove it
24290  result.push_back(object(
24291  {
24292  {"op", "remove"}, {"path", path_key}
24293  }));
24294  }
24295  }
24296 
24297  // second pass: traverse other object's elements
24298  for (auto it = target.cbegin(); it != target.cend(); ++it)
24299  {
24300  if (source.find(it.key()) == source.end())
24301  {
24302  // found a key that is not in this -> add it
24303  const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24304  result.push_back(
24305  {
24306  {"op", "add"}, {"path", path_key},
24307  {"value", it.value()}
24308  });
24309  }
24310  }
24311 
24312  break;
24313  }
24314 
24315  case value_t::null:
24316  case value_t::string:
24317  case value_t::boolean:
24318  case value_t::number_integer:
24319  case value_t::number_unsigned:
24320  case value_t::number_float:
24321  case value_t::binary:
24322  case value_t::discarded:
24323  default:
24324  {
24325  // both primitive type: replace value
24326  result.push_back(
24327  {
24328  {"op", "replace"}, {"path", path}, {"value", target}
24329  });
24330  break;
24331  }
24332  }
24333 
24334  return result;
24335  }
24337 
24339  // JSON Merge Patch functions //
24341 
24344 
24347  void merge_patch(const basic_json& apply_patch)
24348  {
24349  if (apply_patch.is_object())
24350  {
24351  if (!is_object())
24352  {
24353  *this = object();
24354  }
24355  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24356  {
24357  if (it.value().is_null())
24358  {
24359  erase(it.key());
24360  }
24361  else
24362  {
24363  operator[](it.key()).merge_patch(it.value());
24364  }
24365  }
24366  }
24367  else
24368  {
24369  *this = apply_patch;
24370  }
24371  }
24372 
24374 };
24375 
24380 {
24381  return j.dump();
24382 }
24383 
24384 inline namespace literals
24385 {
24386 inline namespace json_literals
24387 {
24388 
24392 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24393 {
24394  return nlohmann::json::parse(s, s + n);
24395 }
24396 
24400 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
24401 {
24402  return nlohmann::json::json_pointer(std::string(s, n));
24403 }
24404 
24405 } // namespace json_literals
24406 } // namespace literals
24408 
24410 // nonmember support //
24412 
24413 namespace std // NOLINT(cert-dcl58-cpp)
24414 {
24415 
24419 struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp)
24420 {
24422  {
24423  return nlohmann::detail::hash(j);
24424  }
24425 };
24426 
24427 // specialization for std::less<value_t>
24428 template<>
24429 struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
24430 {
24436  ::nlohmann::detail::value_t rhs) const noexcept
24437  {
24438 #if JSON_HAS_THREE_WAY_COMPARISON
24439  return std::is_lt(lhs <=> rhs); // *NOPAD*
24440 #else
24442 #endif
24443  }
24444 };
24445 
24446 // C++20 prohibit function specialization in the std namespace.
24447 #ifndef JSON_HAS_CPP_20
24448 
24452 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)
24453  is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
24454  is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
24455 {
24456  j1.swap(j2);
24457 }
24458 
24459 #endif
24460 
24461 } // namespace std
24462 
24463 #if JSON_USE_GLOBAL_UDLS
24464  using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24465  using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24466 #endif
24467 
24468 // #include <nlohmann/detail/macro_unscope.hpp>
24469 // __ _____ _____ _____
24470 // __| | __| | | | JSON for Modern C++
24471 // | | |__ | | | | | | version 3.11.2
24472 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
24473 //
24474 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
24475 // SPDX-License-Identifier: MIT
24476 
24477 
24478 
24479 // restore clang diagnostic settings
24480 #if defined(__clang__)
24481  #pragma clang diagnostic pop
24482 #endif
24483 
24484 // clean up
24485 #undef JSON_ASSERT
24486 #undef JSON_INTERNAL_CATCH
24487 #undef JSON_THROW
24488 #undef JSON_PRIVATE_UNLESS_TESTED
24489 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24490 #undef NLOHMANN_BASIC_JSON_TPL
24491 #undef JSON_EXPLICIT
24492 #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
24493 #undef JSON_INLINE_VARIABLE
24494 #undef JSON_NO_UNIQUE_ADDRESS
24495 #undef JSON_DISABLE_ENUM_SERIALIZATION
24496 #undef JSON_USE_GLOBAL_UDLS
24497 
24498 #ifndef JSON_TEST_KEEP_MACROS
24499  #undef JSON_CATCH
24500  #undef JSON_TRY
24501  #undef JSON_HAS_CPP_11
24502  #undef JSON_HAS_CPP_14
24503  #undef JSON_HAS_CPP_17
24504  #undef JSON_HAS_CPP_20
24505  #undef JSON_HAS_FILESYSTEM
24506  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
24507  #undef JSON_HAS_THREE_WAY_COMPARISON
24508  #undef JSON_HAS_RANGES
24509  #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
24510 #endif
24511 
24512 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
24513 // __ _____ _____ _____
24514 // __| | __| | | | JSON for Modern C++
24515 // | | |__ | | | | | | version 3.11.2
24516 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
24517 //
24518 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
24519 // SPDX-License-Identifier: MIT
24520 
24521 
24522 
24523 #undef JSON_HEDLEY_ALWAYS_INLINE
24524 #undef JSON_HEDLEY_ARM_VERSION
24525 #undef JSON_HEDLEY_ARM_VERSION_CHECK
24526 #undef JSON_HEDLEY_ARRAY_PARAM
24527 #undef JSON_HEDLEY_ASSUME
24528 #undef JSON_HEDLEY_BEGIN_C_DECLS
24529 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24530 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24531 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24532 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24533 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24534 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
24535 #undef JSON_HEDLEY_CLANG_HAS_WARNING
24536 #undef JSON_HEDLEY_COMPCERT_VERSION
24537 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24538 #undef JSON_HEDLEY_CONCAT
24539 #undef JSON_HEDLEY_CONCAT3
24540 #undef JSON_HEDLEY_CONCAT3_EX
24541 #undef JSON_HEDLEY_CONCAT_EX
24542 #undef JSON_HEDLEY_CONST
24543 #undef JSON_HEDLEY_CONSTEXPR
24544 #undef JSON_HEDLEY_CONST_CAST
24545 #undef JSON_HEDLEY_CPP_CAST
24546 #undef JSON_HEDLEY_CRAY_VERSION
24547 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
24548 #undef JSON_HEDLEY_C_DECL
24549 #undef JSON_HEDLEY_DEPRECATED
24550 #undef JSON_HEDLEY_DEPRECATED_FOR
24551 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24552 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24553 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24554 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24555 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24556 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
24557 #undef JSON_HEDLEY_DIAGNOSTIC_POP
24558 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24559 #undef JSON_HEDLEY_DMC_VERSION
24560 #undef JSON_HEDLEY_DMC_VERSION_CHECK
24561 #undef JSON_HEDLEY_EMPTY_BASES
24562 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24563 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24564 #undef JSON_HEDLEY_END_C_DECLS
24565 #undef JSON_HEDLEY_FLAGS
24566 #undef JSON_HEDLEY_FLAGS_CAST
24567 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24568 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
24569 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24570 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24571 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
24572 #undef JSON_HEDLEY_GCC_HAS_FEATURE
24573 #undef JSON_HEDLEY_GCC_HAS_WARNING
24574 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24575 #undef JSON_HEDLEY_GCC_VERSION
24576 #undef JSON_HEDLEY_GCC_VERSION_CHECK
24577 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24578 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24579 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24580 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24581 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24582 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
24583 #undef JSON_HEDLEY_GNUC_HAS_WARNING
24584 #undef JSON_HEDLEY_GNUC_VERSION
24585 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
24586 #undef JSON_HEDLEY_HAS_ATTRIBUTE
24587 #undef JSON_HEDLEY_HAS_BUILTIN
24588 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24589 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24590 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24591 #undef JSON_HEDLEY_HAS_EXTENSION
24592 #undef JSON_HEDLEY_HAS_FEATURE
24593 #undef JSON_HEDLEY_HAS_WARNING
24594 #undef JSON_HEDLEY_IAR_VERSION
24595 #undef JSON_HEDLEY_IAR_VERSION_CHECK
24596 #undef JSON_HEDLEY_IBM_VERSION
24597 #undef JSON_HEDLEY_IBM_VERSION_CHECK
24598 #undef JSON_HEDLEY_IMPORT
24599 #undef JSON_HEDLEY_INLINE
24600 #undef JSON_HEDLEY_INTEL_CL_VERSION
24601 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
24602 #undef JSON_HEDLEY_INTEL_VERSION
24603 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
24604 #undef JSON_HEDLEY_IS_CONSTANT
24605 #undef JSON_HEDLEY_IS_CONSTEXPR_
24606 #undef JSON_HEDLEY_LIKELY
24607 #undef JSON_HEDLEY_MALLOC
24608 #undef JSON_HEDLEY_MCST_LCC_VERSION
24609 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
24610 #undef JSON_HEDLEY_MESSAGE
24611 #undef JSON_HEDLEY_MSVC_VERSION
24612 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
24613 #undef JSON_HEDLEY_NEVER_INLINE
24614 #undef JSON_HEDLEY_NON_NULL
24615 #undef JSON_HEDLEY_NO_ESCAPE
24616 #undef JSON_HEDLEY_NO_RETURN
24617 #undef JSON_HEDLEY_NO_THROW
24618 #undef JSON_HEDLEY_NULL
24619 #undef JSON_HEDLEY_PELLES_VERSION
24620 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
24621 #undef JSON_HEDLEY_PGI_VERSION
24622 #undef JSON_HEDLEY_PGI_VERSION_CHECK
24623 #undef JSON_HEDLEY_PREDICT
24624 #undef JSON_HEDLEY_PRINTF_FORMAT
24625 #undef JSON_HEDLEY_PRIVATE
24626 #undef JSON_HEDLEY_PUBLIC
24627 #undef JSON_HEDLEY_PURE
24628 #undef JSON_HEDLEY_REINTERPRET_CAST
24629 #undef JSON_HEDLEY_REQUIRE
24630 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24631 #undef JSON_HEDLEY_REQUIRE_MSG
24632 #undef JSON_HEDLEY_RESTRICT
24633 #undef JSON_HEDLEY_RETURNS_NON_NULL
24634 #undef JSON_HEDLEY_SENTINEL
24635 #undef JSON_HEDLEY_STATIC_ASSERT
24636 #undef JSON_HEDLEY_STATIC_CAST
24637 #undef JSON_HEDLEY_STRINGIFY
24638 #undef JSON_HEDLEY_STRINGIFY_EX
24639 #undef JSON_HEDLEY_SUNPRO_VERSION
24640 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24641 #undef JSON_HEDLEY_TINYC_VERSION
24642 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
24643 #undef JSON_HEDLEY_TI_ARMCL_VERSION
24644 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24645 #undef JSON_HEDLEY_TI_CL2000_VERSION
24646 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24647 #undef JSON_HEDLEY_TI_CL430_VERSION
24648 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24649 #undef JSON_HEDLEY_TI_CL6X_VERSION
24650 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24651 #undef JSON_HEDLEY_TI_CL7X_VERSION
24652 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24653 #undef JSON_HEDLEY_TI_CLPRU_VERSION
24654 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24655 #undef JSON_HEDLEY_TI_VERSION
24656 #undef JSON_HEDLEY_TI_VERSION_CHECK
24657 #undef JSON_HEDLEY_UNAVAILABLE
24658 #undef JSON_HEDLEY_UNLIKELY
24659 #undef JSON_HEDLEY_UNPREDICTABLE
24660 #undef JSON_HEDLEY_UNREACHABLE
24661 #undef JSON_HEDLEY_UNREACHABLE_RETURN
24662 #undef JSON_HEDLEY_VERSION
24663 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24664 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
24665 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
24666 #undef JSON_HEDLEY_VERSION_ENCODE
24667 #undef JSON_HEDLEY_WARNING
24668 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
24669 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
24670 #undef JSON_HEDLEY_FALL_THROUGH
24671 
24672 
24673 
24674 #endif // INCLUDE_NLOHMANN_JSON_HPP_
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition: json.hpp:15990
std::size_t concat_length()
Definition: json.hpp:4166
binary_t * binary
binary (stored with pointer to save storage)
Definition: json.hpp:19650
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:14995
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9055
#define NLOHMANN_JSON_NAMESPACE_BEGIN
Definition: json.hpp:134
static constexpr auto value
Definition: json.hpp:3750
typename BasicJsonType::object_t object_t
Definition: json.hpp:3575
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:24205
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:13649
static std::size_t calc_bson_string_size(const string_t &value)
Definition: json.hpp:15960
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:5475
general exception of the basic_json class
Definition: json.hpp:4304
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:17408
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:20067
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8778
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:7229
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:20531
Target reinterpret_bits(const Source source)
Definition: json.hpp:16869
ReturnType value(const typename object_t::key_type &key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:21468
string_t indent_string
the indentation string
Definition: json.hpp:18903
virtual bool binary(binary_t &val)=0
a binary value was read
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21443
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition: json.hpp:16050
void insert(InputIt first, InputIt last)
Definition: json.hpp:19265
bool get_ubjson_object()
Definition: json.hpp:11668
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:21323
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:17801
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:22776
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.hpp:20656
array (ordered collection of values)
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.hpp:3950
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:23533
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.hpp:24421
typename BasicJsonType::string_t string_t
Definition: json.hpp:12167
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:20488
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.hpp:22553
static constexpr auto value
Definition: json.hpp:3764
integer_sequence< size_t, Ints... > index_sequence
Definition: json.hpp:3124
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13655
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:5034
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:15042
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5893
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition: json.hpp:19764
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition: json.hpp:16212
typename T::key_type key_type_t
Definition: json.hpp:3485
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.hpp:4210
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:15004
#define JSON_HEDLEY_PURE
Definition: json.hpp:1787
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:20594
StringType string_t
a type for a string
Definition: json.hpp:19563
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:19567
const binary_t & get_binary() const
get a binary value
Definition: json.hpp:21132
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:13637
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition: json.hpp:9246
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:19440
ValueType get_impl(detail::priority_tag< 1 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t &>())))
get a value (explicit); special case
Definition: json.hpp:20864
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.hpp:4222
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition: json.hpp:16018
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:7204
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t &>().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20761
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:19449
reference set_parent(reference j, std::size_t old_capacity=static_cast< std::size_t >(-1))
Definition: json.hpp:19971
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:17010
input_format_t
the supported input formats
Definition: json.hpp:6107
input_stream_adapter & operator=(input_stream_adapter &)=delete
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.hpp:22506
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6137
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6777
#define JSON_CATCH(exception)
Definition: json.hpp:2517
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:12166
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:3959
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition: json.hpp:16028
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition: json.hpp:3578
json_value(string_t &&value)
constructor for rvalue strings
Definition: json.hpp:19746
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:4308
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6961
parse_event_t
Definition: json.hpp:12136
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3506
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition: json.hpp:16083
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:23492
bool get_number(const input_format_t format, NumberType &result)
Definition: json.hpp:11866
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:1103
basic_json patch(const basic_json &json_patch) const
applies a JSON patch to a copy of the current object
Definition: json.hpp:24195
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22629
BaseInputAdapter base_adapter
Definition: json.hpp:6398
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition: json.hpp:10927
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:21956
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:20020
file_input_adapter(std::FILE *f) noexcept
Definition: json.hpp:6124
virtual bool string(string_t &val)=0
a string value was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6737
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8735
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:20587
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:14958
void swap(array_t &other)
exchanges the values
Definition: json.hpp:22712
typename T::key_compare detect_key_compare
Definition: json.hpp:3566
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:2889
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:7228
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:22405
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:12950
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12712
ValueType value(KeyType &&key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21494
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:23525
::nlohmann::detail::internal_iterator< BasicJsonType > internal_iterator
Definition: json.hpp:19360
~basic_json() noexcept
destructor
Definition: json.hpp:20470
bool get_ubjson_size_type(std::pair< std::size_t, char_int_type > &result, bool inside_ndarray=false)
determine the type and size for a container
Definition: json.hpp:11310
std::char_traits< char >::int_type get_character()
Definition: json.hpp:6191
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.hpp:6928
number value (unsigned integer)
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6609
json_ref(Args &&... args)
Definition: json.hpp:14753
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.hpp:19669
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition: json.hpp:15968
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:17976
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4494
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:23476
#define JSON_EXPLICIT
Definition: json.hpp:2810
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:21277
iteration_proxy_value operator++(int) &
Definition: json.hpp:5175
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.hpp:19665
json_ref(value_type &&value)
Definition: json.hpp:14738
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: json.hpp:8625
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:5190
bool get_msgpack_object(const std::size_t len)
Definition: json.hpp:10871
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:23380
bool binary(binary_t &)
Definition: json.hpp:7263
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5830
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:16891
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4459
ValueType & get_to(ValueType &v) const
Definition: json.hpp:21027
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:5142
a minimal map-like container that preserves insertion order
Definition: json.hpp:3413
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.hpp:4216
typename BasicJsonType::exception exception_t
Definition: json.hpp:9029
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:7253
static one test(decltype(&C::capacity))
const string_type & key() const
return key of the iterator
Definition: json.hpp:5196
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.hpp:21336
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.hpp:2497
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:21821
typename BasicJsonType::string_t string_t
Definition: json.hpp:6740
const int id
the id of the exception
Definition: json.hpp:4314
iteration_proxy_value< IteratorType > begin() const noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:5259
void destroy(value_t t)
Definition: json.hpp:19772
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.hpp:18965
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:5535
std::string get_token_string() const
Definition: json.hpp:11979
ReturnType value(const json_pointer &ptr, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21569
static void flatten(const string_t &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition: json.hpp:14454
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:4320
store tags as binary type
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23460
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.hpp:3576
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:13604
bool get_ubjson_value(const char_int_type prefix)
Definition: json.hpp:11377
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:23569
bool string(string_t &val)
Definition: json.hpp:6789
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:17978
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16755
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6741
const_reference front() const
access the first element
Definition: json.hpp:21618
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition: json.hpp:16102
Default type
Definition: json.hpp:283
constexpr bool is_c_string()
Definition: json.hpp:4098
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:1102
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition: json.hpp:9301
token_type scan_string()
scan a string literal
Definition: json.hpp:7559
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:13445
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.hpp:13781
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition: json.hpp:13993
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:18972
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition: json.hpp:4443
namespace for Niels Lohmann
Definition: json.hpp:3381
reference value() const
return the value of an iterator
Definition: json.hpp:13528
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:13423
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:6312
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:12173
std::conditional< detail::is_c_string_uncvref< ValueType >::value, string_t, typename std::decay< ValueType >::type > value_return_type
Definition: json.hpp:21434
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:22366
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:7426
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition: json.hpp:21832
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.hpp:3582
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:13916
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23885
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:19447
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9148
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition: json.hpp:22801
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition: json.hpp:19900
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:19380
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:20573
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.hpp:21899
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:5465
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:13625
void pop_back()
remove last reference token
Definition: json.hpp:13878
void operator=(nonesuch const &)=delete
std::ptrdiff_t difference_type
Definition: json.hpp:12657
bool boolean(bool val)
Definition: json.hpp:6765
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23483
virtual bool number_integer(number_integer_t val)=0
an integer number was read
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:17886
proxy class for the items() function
Definition: json.hpp:5239
typename BasicJsonType::binary_t::value_type binary_char_t
Definition: json.hpp:17979
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:20120
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22374
typename BasicJsonType::object_t object_t
Definition: json.hpp:12847
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix, const bool use_bjdata)
Definition: json.hpp:16274
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:13613
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:8984
std::vector< string_t > reference_tokens
the reference tokens
Definition: json.hpp:14644
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:13412
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:23659
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1448
static constexpr std::size_t size() noexcept
Definition: json.hpp:3112
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:8992
bool start_object(std::size_t len)
Definition: json.hpp:6801
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3558
const char * p
Definition: loadincs.C:9
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition: json.hpp:11909
constexpr int kAlpha
Definition: json.hpp:17132
std::false_type value_t
Definition: json.hpp:282
std::size_t utf8_bytes_index
index to the utf8_codes array for the next valid byte
Definition: json.hpp:6410
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12700
static BasicJsonType unflatten(const BasicJsonType &value)
Definition: json.hpp:14526
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2518
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:5404
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8791
constexpr bool is_errored() const
Definition: json.hpp:7118
a template for a reverse iterator class
Definition: json.hpp:13590
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.hpp:19663
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition: json.hpp:16117
ValueType get_impl(detail::priority_tag< 0 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t &>(), std::declval< ValueType &>())))
get a value (explicit)
Definition: json.hpp:20822
Definition: json.hpp:5295
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:4837
number_integer_t number_integer
number (integer)
Definition: json.hpp:19654
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7283
std::array< std::char_traits< char >::int_type, 4 > utf8_bytes
a buffer for UTF-8 bytes
Definition: json.hpp:6407
void write_character(CharType c) override
Definition: json.hpp:14934
void swap(object_t &other)
exchanges the values
Definition: json.hpp:22728
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:13403
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.hpp:5002
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:12868
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.hpp:20739
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9147
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9056
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12695
size_type erase(KeyType &&key)
Definition: json.hpp:19101
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:20621
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:5380
typename BasicJsonType::string_t string_t
Definition: json.hpp:14994
typename BasicJsonType::exception exception_t
Definition: json.hpp:9060
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:14954
token_type scan()
Definition: json.hpp:8814
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:19443
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:20580
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3528
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.hpp:20638
::nlohmann::detail::iteration_proxy< Iterator > iteration_proxy
Definition: json.hpp:19364
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16748
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:21592
the parser read { and started to process a JSON object
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:5713
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:23469
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:23713
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6606
binary array (ordered collection of bytes)
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:6254
typename make_void< Ts... >::type void_t
Definition: json.hpp:255
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:23601
std::integral_constant< bool, all_signed< Types... >::value||all_unsigned< Types... >::value > same_sign
Definition: json.hpp:4004
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:9010
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.hpp:21221
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:19583
object (unordered set of name/value pairs)
bool get_ubjson_size_value(std::size_t &result, bool &is_ndarray, char_int_type prefix=0)
Definition: json.hpp:11087
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22700
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:13348
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:8976
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:309
std::size_t array_index_last
last stringified array index
Definition: json.hpp:5134
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.hpp:20674
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:9117
iterator erase(iterator pos)
Definition: json.hpp:19120
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4477
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition: json.hpp:2773
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:12672
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:6512
detected_t< result_of_begin, t_ref > iterator
Definition: json.hpp:3661
iteration_proxy & operator=(iteration_proxy const &)=default
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:21939
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:13597
the parser finished reading a JSON value
std::input_iterator_tag iterator_category
Definition: json.hpp:5125
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6783
token_type scan_number()
scan a number literal
Definition: json.hpp:8274
iteration_proxy_value & operator=(iteration_proxy_value const &)=default
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:3151
json_pointer< string_t > convert() &&
Definition: json.hpp:14561
basic_json(const JsonRef &ref)
Definition: json.hpp:20357
typename BasicJsonType::string_t string_t
Definition: json.hpp:17975
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8729
throw a parse_error exception in case of a tag
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:6926
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:4754
friend other_iter_impl
allow basic_json to access private members
Definition: json.hpp:12842
const T & operator[](KeyType &&key) const
Definition: json.hpp:19019
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:20559
void write_character(CharType c) override
Definition: json.hpp:14884
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6967
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:20220
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:23585
bool contains(const BasicJsonType *ptr) const
Definition: json.hpp:14297
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition: json.hpp:16227
exception indicating other library errors
Definition: json.hpp:4507
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:20566
std::basic_ostream< CharType > & stream
Definition: json.hpp:14921
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6607
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition: json.hpp:9162
size_type count(KeyType &&key) const
Definition: json.hpp:19192
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:5167
static std::string position_string(const position_t &pos)
Definition: json.hpp:4446
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:17367
const T & at(const key_type &key) const
Definition: json.hpp:19052
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition: json.hpp:2958
friend BasicJsonType
Definition: json.hpp:12843
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition: json.hpp:20716
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:7231
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13643
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:22421
data m_data
Definition: json.hpp:23443
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition: json.hpp:9271
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9151
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition: json.hpp:16060
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition: json.hpp:77
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:8972
json_sax & operator=(const json_sax &)=default
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6738
constexpr bool value_in_range_of(T val)
Definition: json.hpp:4082
output adapter for basic_string
Definition: json.hpp:14927
static constexpr CharType get_msgpack_float_prefix(float)
Definition: json.hpp:16257
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:21178
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:12940
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition: json.hpp:19767
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition: json.hpp:14199
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition: json.hpp:9468
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:23753
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition: json.hpp:15928
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:22430
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition: json.hpp:10655
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.hpp:20644
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition: json.hpp:11942
output_adapter(StringType &s)
Definition: json.hpp:14962
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3675
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:12165
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:23843
iterator erase(iterator first, iterator last)
Definition: json.hpp:19125
static constexpr CharType get_msgpack_float_prefix(double)
Definition: json.hpp:16262
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:23849
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.hpp:20668
static void unescape(StringType &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2992
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:4937
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5871
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition: json.hpp:19761
json_value(const string_t &value)
constructor for strings
Definition: json.hpp:19743
size_type erase(const key_type &key)
Definition: json.hpp:19080
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.hpp:21413
std::ptrdiff_t difference_type
Definition: json.hpp:13593
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:13827
static std::string diagnostics(std::nullptr_t)
Definition: json.hpp:4325
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:5413
IteratorType::pointer container
the container to iterate
Definition: json.hpp:5243
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:13864
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:20698
static constexpr CharType get_ubjson_float_prefix(float)
Definition: json.hpp:16558
constexpr int kGamma
Definition: json.hpp:17133
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition: json.hpp:20686
value_type const & operator*() const
Definition: json.hpp:14773
typename T::pointer pointer_t
Definition: json.hpp:3494
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:5126
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:23644
void to_json(BasicJsonType &j, const T &b)
Definition: json.hpp:5707
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:19432
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:19579
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:12863
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:24347
bool get_ubjson_high_precision_number()
Definition: json.hpp:11751
string_type empty_str
an empty string (to return a reference for primitive values)
Definition: json.hpp:5138
bool operator()(::nlohmann::detail::value_t lhs, ::nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:24435
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:7419
json_value(const array_t &value)
constructor for arrays
Definition: json.hpp:19755
#define JSON_THROW(exception)
Definition: json.hpp:2515
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:294
constexpr auto get_impl(detail::priority_tag< 4 >) const noexcept -> decltype(std::declval< const basic_json_t &>().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20925
an internal type for a backed binary type
Definition: json.hpp:5823
input_stream_adapter(std::istream &i)
Definition: json.hpp:6172
virtual bool number_float(number_float_t val, const string_t &s)=0
a floating-point number was read
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:5556
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:12164
T & operator[](const key_type &key)
Definition: json.hpp:19000
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8745
#define NLOHMANN_JSON_NAMESPACE_END
Definition: json.hpp:144
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:2047
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:24379
virtual bool end_object()=0
the end of an object was read
const std::size_t byte
byte index of the parse error
Definition: json.hpp:4440
bool scan_comment()
scan a comment
Definition: json.hpp:8149
std::pair< iterator, bool > emplace(KeyType &&key, T &&t)
Definition: json.hpp:18987
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6554
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:17749
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:23506
the parser read ] and finished processing a JSON array
IteratorType anchor
the iterator
Definition: json.hpp:5130
bool parse_ubjson_internal(const bool get_char=true)
Definition: json.hpp:10908
::nlohmann::detail::json_base_class< CustomBaseClass > json_base_class_t
Definition: json.hpp:19339
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:5391
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:9498
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.hpp:21883
typename std::char_traits< char_type >::int_type char_int_type
Definition: json.hpp:9154
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3503
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:12965
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:20209
static std::vector< string_t > split(const string_t &reference_string)
split the string input to reference tokens
Definition: json.hpp:14385
typename InputAdapterType::char_type char_type
Definition: json.hpp:7422
iter_impl operator++(int) &
post-increment (it++)
Definition: json.hpp:13156
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3509
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:13167
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition: json.hpp:16000
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:13357
pointer operator->() const
dereference the iterator
Definition: json.hpp:13114
bool write_bjdata_ndarray(const typename BasicJsonType::object_t &value, const bool use_count, const bool use_type)
Definition: json.hpp:16571
static constexpr bool value
Definition: json.hpp:3671
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:23552
detail namespace with internal helper functions
Definition: json.hpp:248
contiguous_bytes_input_adapter ia
Definition: json.hpp:6563
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.hpp:21358
json_value m_value
the value of the current element
Definition: json.hpp:23418
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:13600
subtype_type m_subtype
Definition: json.hpp:5900
data(const value_t v)
Definition: json.hpp:23420
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:21201
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:5770
bool string(string_t &val)
Definition: json.hpp:6973
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13434
typename std::conditional< std::is_same< T, void >::value, json_default_base, T >::type json_base_class
Definition: json.hpp:13709
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:4009
std::istream * is
the associated input stream
Definition: json.hpp:6204
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:7367
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9059
const T & at(KeyType &&key) const
Definition: json.hpp:19067
serialization to CBOR and MessagePack values
Definition: json.hpp:14992
exception indicating errors with iterators
Definition: json.hpp:4455
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:20545
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:13304
value_type_t< iterator_traits< iterator_t< T > >> range_value_t
Definition: json.hpp:3678
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:12705
SAX interface.
Definition: json.hpp:6603
std::FILE * m_file
the file pointer to read from
Definition: json.hpp:6144
bool parse_msgpack_internal()
Definition: json.hpp:10274
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6420
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:21239
void write_character(CharType c) override
Definition: json.hpp:14909
::nlohmann::detail::binary_writer< basic_json, CharType > binary_writer
Definition: json.hpp:19372
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:19430
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6380
detected_t< result_of_end, t_ref > sentinel
Definition: json.hpp:3662
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:3025
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:19648
value_t
the JSON type enumeration
Definition: json.hpp:2859
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition: json.hpp:19338
typename InputAdapterType::char_type char_type
Definition: json.hpp:9153
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13909
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14650
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:3947
json_sax()=default
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:20041
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition: json.hpp:15913
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:17149
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: json.hpp:14073
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:12743
primitive_iterator_t operator++(int) &noexcept
Definition: json.hpp:12723
an iterator value
Definition: json.hpp:12770
reference operator[](KeyType &&key)
access specified object element
Definition: json.hpp:21389
#define JSON_HEDLEY_CONST
Definition: json.hpp:1818
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:12866
json_value(value_t t)
constructor for empty values of a given type
Definition: json.hpp:19671
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4423
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:306
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition: json.hpp:4219
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:19555
const_reference back() const
access the last element
Definition: json.hpp:21634
bool key(string_t &val)
Definition: json.hpp:6813
const char indent_char
the indentation character
Definition: json.hpp:18901
static JSON_INLINE_VARIABLE constexpr T value
Definition: json.hpp:3200
reference value() const
return the value of an iterator
Definition: json.hpp:13668
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t &>(), v)))
Definition: json.hpp:21038
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 >>, priority_tag< 0 >)
Definition: json.hpp:4943
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:17977
binary_t & get_binary()
get a binary value
Definition: json.hpp:21120
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:6905
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.hpp:18969
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:10180
void write_bson(const BasicJsonType &j)
Definition: json.hpp:15013
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:5735
BasicJsonType value_type
Definition: json.hpp:14736
typename Container::size_type size_type
Definition: json.hpp:18954
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:21963
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:7106
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.hpp:22604
typename T::value_type value_type_t
Definition: json.hpp:3488
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8723
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2598
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition: json.hpp:16075
bool binary(binary_t &val)
Definition: json.hpp:6795
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:21929
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:7418
replace invalid UTF-8 sequences with U+FFFD
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition: json.hpp:15940
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:13787
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:22636
void int_to_string(string_type &target, std::size_t value)
Definition: json.hpp:5112
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.hpp:20662
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:70
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:13218
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:5516
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:9015
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:15366
return result
Definition: json.hpp:13980
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.hpp:4204
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3186
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.hpp:22533
::nlohmann::detail::iter_impl< BasicJsonType > iter_impl
Definition: json.hpp:19362
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:12255
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.hpp:20632
typename T::is_transparent detect_is_transparent
Definition: json.hpp:3917
value_type const * operator->() const
Definition: json.hpp:14778
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6455
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:7227
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition: json.hpp:6882
virtual bool end_array()=0
the end of an array was read
the parser read } and finished processing a JSON object
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:14905
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:13817
number_float_t number_float
number (floating-point)
Definition: json.hpp:19658
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:22760
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:23768
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition: json.hpp:14248
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:19445
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22397
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:13661
basic_json<> json
default specialization
Definition: json.hpp:3408
ConstructibleStringType laundered_type
Definition: json.hpp:3761
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1606
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5879
primitive_iterator_t operator--(int) &noexcept
Definition: json.hpp:12736
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:14873
basic_json get_impl(detail::priority_tag< 3 >) const
get special-case overload
Definition: json.hpp:20912
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:21061
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:9000
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6920
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5955
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6921
typename BasicJsonType::string_t string_t
Definition: json.hpp:9150
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:19438
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:8988
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:5249
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:5313
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) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:24452
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:12717
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:5500
const string_t & back() const
return last reference token
Definition: json.hpp:13890
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13366
typename T::mapped_type mapped_type_t
Definition: json.hpp:3482
bool start_array(std::size_t len)
Definition: json.hpp:6833
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:19546
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:4597
lexical analysis
Definition: json.hpp:7416
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:23877
constexpr std::array< T, sizeof...(Args)> make_array(Args &&... args)
Definition: json.hpp:3209
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:18029
virtual bool boolean(bool val)=0
a boolean value was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6605
std::streambuf * sb
Definition: json.hpp:6205
typename T::reference reference_t
Definition: json.hpp:3497
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:19559
T conditional_static_cast(U value)
Definition: json.hpp:3981
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9024
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.hpp:19656
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition: json.hpp:4213
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:5545
number value (floating-point)
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.hpp:21915
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition: json.hpp:16165
discarded by the parser callback function
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:5426
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:20710
static constexpr bool value
Definition: json.hpp:3522
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21646
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:13595
#define JSON_TRY
Definition: json.hpp:2516
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:20176
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:12777
char_int_type get_ignore_noop()
Definition: json.hpp:11839
static constexpr CharType get_cbor_float_prefix(double)
Definition: json.hpp:16248
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5575
ReturnType value(KeyType &&key, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21521
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:6734
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:12154
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.hpp:7448
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:23517
static bool little_endianness(int num=1) noexcept
determine system byte order
Definition: json.hpp:9131
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:6421
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:12775
ordered_map() noexcept(noexcept(Container()))
Definition: json.hpp:18964
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:12684
constexpr difference_type get_value() const noexcept
Definition: json.hpp:12666
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:13857
iterator find(const key_type &key)
Definition: json.hpp:19204
typename BasicJsonType::string_t string_t
Definition: json.hpp:9027
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:5452
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1713
error_handler_t
how to treat decoding errors
Definition: json.hpp:17965
void set_parents()
Definition: json.hpp:19921
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:20235
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition: json.hpp:9989
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2551
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14700
void add(char_int_type c)
add a character to token_buffer
Definition: json.hpp:8706
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6856
std::equal_to< Key > key_compare
Definition: json.hpp:18959
json_value(object_t &&value)
constructor for rvalue objects
Definition: json.hpp:19752
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:23499
OutStringType concat(Args &&... args)
Definition: json.hpp:4281
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:69
bool start_array(std::size_t len)
Definition: json.hpp:7056
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6922
std::size_t array_index
an index for arrays (used to create key names)
Definition: json.hpp:5132
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9026
typename Container::const_iterator const_iterator
Definition: json.hpp:18953
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:23576
json_value(array_t &&value)
constructor for rvalue arrays
Definition: json.hpp:19758
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:12678
bool number_integer(number_integer_t val)
Definition: json.hpp:6955
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition: json.hpp:15982
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:20524
lexer_t m_lexer
the lexer
Definition: json.hpp:12603
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:8980
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.hpp:19587
bool number_integer(number_integer_t)
Definition: json.hpp:7243
static constexpr CharType get_cbor_float_prefix(float)
Definition: json.hpp:16243
bool number_integer(number_integer_t val)
Definition: json.hpp:6771
j template void())
Definition: json.hpp:4826
struct to capture the start position of the current token
Definition: json.hpp:3022
BasicJsonType get_impl(detail::priority_tag< 2 >) const
get special-case overload
Definition: json.hpp:20889
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:20552
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:9007
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:22487
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:20053
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3543
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:13031
virtual bool null()=0
a null value was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:7420
virtual bool key(string_t &val)=0
an object key was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9149
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3170
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: json.hpp:7474
void concat_into(OutStringType &)
Definition: json.hpp:4197
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3178
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition: json.hpp:20198
const_reference operator[](T *key) const
Definition: json.hpp:21380
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:21839
const T & operator[](const key_type &key) const
Definition: json.hpp:19012
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:19242
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:16968
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:12877
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:6748
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
reference back()
access the last element
Definition: json.hpp:21625
typename BasicJsonType::string_t string_t
Definition: json.hpp:6608
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14675
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:18967
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:20430
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22334
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9025
exception indicating access out of the defined range
Definition: json.hpp:4490
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:13339
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5852
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.hpp:20680
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:22342
Key key_type
Definition: json.hpp:18949
typename BasicJsonType::array_t array_t
Definition: json.hpp:12848
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9057
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.hpp:13207
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.hpp:21259
std::pair< char_int_type, string_t > bjd_type
Definition: json.hpp:12073
number value (signed integer)
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:15692
~nonesuch()=delete
output adapter for output streams
Definition: json.hpp:14902
lexer< BasicJsonType, InputAdapterType > lexer_t
Definition: json.hpp:12168
InputAdapterType ia
input adapter
Definition: json.hpp:8904
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13474
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:14930
throw a type_error exception in case of invalid UTF-8
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6924
iterator find(KeyType &&key)
Definition: json.hpp:19218
decltype(std::declval< StringType & >()+=std::declval< Arg &&>()) string_can_append_op
Definition: json.hpp:4207
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:14746
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:5439
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6217
typename Container::iterator iterator
Definition: json.hpp:18952
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.hpp:22584
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:20033
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:12872
typename BasicJsonType::string_t string_t
Definition: json.hpp:7230
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:23863
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:313
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:21155
the parser read [ and started to process a JSON array
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:22455
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:5184
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.hpp:22526
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition: json.hpp:19368
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5858
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition: json.hpp:19596
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition: json.hpp:19770
T & at(KeyType &&key)
Definition: json.hpp:19039
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23857
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:19382
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:19388
#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
Definition: json.hpp:12053
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:20447
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:13835
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5886
typename BasicJsonType::string_t string_t
Definition: json.hpp:7421
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition: json.hpp:21947
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.hpp:20650
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5864
data(size_type cnt, const basic_json &val)
Definition: json.hpp:23425
bool get_bson_binary(const NumberType len, binary_t &result)
Parses a byte array input of length len from the BSON input.
Definition: json.hpp:9323
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:12690
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:20772
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5840
decltype(std::declval< StringType & >().append(std::declval< Arg &&>())) string_can_append
Definition: json.hpp:4201
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:5232
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:12975
boolean_t boolean
boolean
Definition: json.hpp:19652
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:10218
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:6215
::nlohmann::detail::binary_reader< basic_json, InputType > binary_reader
Definition: json.hpp:19371
typename T::difference_type difference_type_t
Definition: json.hpp:3491
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4511
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:3068
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:17989
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:12749
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition: json.hpp:11992
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:300
typename BasicJsonType::string_t string_t
Definition: json.hpp:9058
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:4415
typename BasicJsonType::string_t string_t
Definition: json.hpp:6923
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:7293
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:21050
void write_number(const NumberType n, const bool OutputIsLittleEndian=false)
Definition: json.hpp:16698
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21544
bool string(string_t &)
Definition: json.hpp:7258
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:5371
bool get_msgpack_array(const std::size_t len)
Definition: json.hpp:10849
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:9003
TFile * Target
typename std::char_traits< char_type >::int_type char_int_type
Definition: json.hpp:7423
token_type
token types for the parser
Definition: json.hpp:7343
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition: json.hpp:20722
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition: json.hpp:10738
std::string get_token_string() const
Definition: json.hpp:8753
const_iterator find(const key_type &key) const
Definition: json.hpp:19230
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:14996
CharType ubjson_prefix(const BasicJsonType &j, const bool use_bjdata) const noexcept
determine the type prefix of container values
Definition: json.hpp:16457
std::size_t utf8_bytes_filled
number of valid bytes in the utf8_codes array
Definition: json.hpp:6412
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:13070
Default base class of the basic_json class.
Definition: json.hpp:13702
std::uint64_t subtype_type
Definition: json.hpp:5827
size_type erase_internal(KeyType &&key)
Definition: json.hpp:21787
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6423
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:20361
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:7428
static ::nlohmann::detail::parser< basic_json, InputAdapterType > parser(InputAdapterType adapter, detail::parser_callback_t< basic_json >cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
Definition: json.hpp:19346
constexpr bool is_errored() const
Definition: json.hpp:6868
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:6925
::nlohmann::detail::primitive_iterator_t primitive_iterator_t
Definition: json.hpp:19358
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:19646
iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
Definition: json.hpp:19958
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3082
string_type array_index_str
a string representation of the array index
Definition: json.hpp:5136
std::ptrdiff_t difference_type
Definition: json.hpp:5121
static constexpr CharType get_ubjson_float_prefix(double)
Definition: json.hpp:16563
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:20247
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:18951
bool next_byte_in_range(std::initializer_list< char_int_type > ranges)
check if the next byte(s) are inside a given range
Definition: json.hpp:7522
JSON Pointer defines a string syntax for identifying a specific value within a JSON document...
Definition: json.hpp:3402
bool key(string_t &)
Definition: json.hpp:7273
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:12730
void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
Definition: json.hpp:17709
bool start_object(std::size_t len)
Definition: json.hpp:6985
size_type count(const key_type &key) const
Definition: json.hpp:19178
void swap(string_t &other)
exchanges the values
Definition: json.hpp:22744
InputAdapterType ia
input adapter
Definition: json.hpp:12032
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:20517
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:16777
json_ref(const value_type &value)
Definition: json.hpp:14742
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition: json.hpp:9430
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:23783
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:6377
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9028
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:6432
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:4611
typename Container::value_type value_type
Definition: json.hpp:18955
T & at(const key_type &key)
Definition: json.hpp:19024
static BasicJsonType::size_type array_index(const string_t &s)
Definition: json.hpp:13933
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:9145
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:20510
result reference_tokens
Definition: json.hpp:13979
std::string exception_message(const token_type expected, const std::string &context)
Definition: json.hpp:12568
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:13842
T & operator[](KeyType &&key)
Definition: json.hpp:19007
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:19464
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5835
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:13850
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:6547
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:16903
void unget()
unget current character (read it again on next get)
Definition: json.hpp:8679
typename std::add_lvalue_reference< T >::type t_ref
Definition: json.hpp:3659
output adapter for byte vectors
Definition: json.hpp:14877
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:8968
constexpr bool is_transparent()
Definition: json.hpp:4126
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:5487
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:20228
abstract output adapter interface
Definition: json.hpp:14858
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6739
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:13537
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:17313
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:18906
exception indicating a parse error
Definition: json.hpp:4402
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13631
reference operator[](T *key)
Definition: json.hpp:21374
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:19456
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:16885
syntax analysis
Definition: json.hpp:12162
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.hpp:4331
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:23798
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:16985
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:23544
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:20692
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:5780
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:20601
#define JSON_INLINE_VARIABLE
Definition: json.hpp:2491
std::runtime_error m
an exception object as storage for error messages
Definition: json.hpp:4397
typename T::iterator_category iterator_category_t
Definition: json.hpp:3500
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2977
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13902
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:5937
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:19575
::nlohmann::detail::json_reverse_iterator< Base > json_reverse_iterator
Definition: json.hpp:19365
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1714
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:6181
static constexpr auto is_iterator_begin
Definition: json.hpp:3667
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.hpp:13619
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:3027
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:20187
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: json.hpp:14141
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:20538
bool binary(binary_t &val)
Definition: json.hpp:6979
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.hpp:1396
typename lexer_t::token_type token_type
Definition: json.hpp:12169
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2588
namespace for Niels Lohmann
Definition: json.hpp:3397
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:13512
json_pointer< string_t > convert() const &
Definition: json.hpp:14554
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.hpp:21869
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:5265
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:3931
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:21716
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7268
void write_compact_float(const number_float_t n, detail::input_format_t format)
Definition: json.hpp:16714
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:7248
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:19247
#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
Definition: json.hpp:12050
typename string_t_helper< RefStringType >::type string_t
Definition: json.hpp:13777
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8717
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:21014
void skip_whitespace()
Definition: json.hpp:8805
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:23365
bool parse_bson_element_internal(const char_int_type element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
Definition: json.hpp:9350
json_value(const object_t &value)
constructor for objects
Definition: json.hpp:19749
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:20704
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition: json.hpp:10085
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:5790
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:23698
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition: json.hpp:15950
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition: json.hpp:7140
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:8996
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:5358
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5845
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:12837
std::size_t lines_read
the number of lines read
Definition: json.hpp:3029
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:19571
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.hpp:13607
#define JSON_ASSERT(x)
Definition: json.hpp:2544
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:14880
bool get_ubjson_ndarray_size(std::vector< size_t > &dim)
Definition: json.hpp:11022
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition: json.hpp:23560
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22683
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:68
exception indicating executing a member function with a wrong type
Definition: json.hpp:4473
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:19435
token_type get_token()
get next token from lexer
Definition: json.hpp:12563
std::char_traits< char_type >::int_type get_character()
Definition: json.hpp:6221
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:12195
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.hpp:19667
std::vector< CharType, AllocatorType > & v
Definition: json.hpp:14896