json.hpp
Go to the documentation of this file.
1 // __ _____ _____ _____
2 // __| | __| | | | JSON for Modern C++
3 // | | |__ | | | | | | version 3.11.3
4 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5 //
6 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
7 // SPDX-License-Identifier: MIT
8 
9 /****************************************************************************\
10  * Note on documentation: The source files contain links to the online *
11  * documentation of the public API at https://json.nlohmann.me. This URL *
12  * contains the most recent documentation and should also be applicable to *
13  * previous versions; documentation for deprecated functions is not *
14  * removed, but marked deprecated. See "Generate documentation" section in *
15  * file docs/README.md. *
16 \****************************************************************************/
17 
18 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
19 #define INCLUDE_NLOHMANN_JSON_HPP_
20 
21 #include <algorithm> // all_of, find, for_each
22 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
23 #include <functional> // hash, less
24 #include <initializer_list> // initializer_list
25 #ifndef JSON_NO_IO
26  #include <iosfwd> // istream, ostream
27 #endif // JSON_NO_IO
28 #include <iterator> // random_access_iterator_tag
29 #include <memory> // unique_ptr
30 #include <string> // string, stoi, to_string
31 #include <utility> // declval, forward, move, pair, swap
32 #include <vector> // vector
33 
34 // #include <nlohmann/adl_serializer.hpp>
35 // __ _____ _____ _____
36 // __| | __| | | | JSON for Modern C++
37 // | | |__ | | | | | | version 3.11.3
38 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
39 //
40 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
41 // SPDX-License-Identifier: MIT
42 
43 
44 
45 #include <utility>
46 
47 // #include <nlohmann/detail/abi_macros.hpp>
48 // __ _____ _____ _____
49 // __| | __| | | | JSON for Modern C++
50 // | | |__ | | | | | | version 3.11.3
51 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
52 //
53 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
54 // SPDX-License-Identifier: MIT
55 
56 
57 
58 // This file contains all macro definitions affecting or depending on the ABI
59 
60 #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
61  #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
62  #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 3
63  #warning "Already included a different version of the library!"
64  #endif
65  #endif
66 #endif
67 
68 #define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
69 #define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum)
70 #define NLOHMANN_JSON_VERSION_PATCH 3 // NOLINT(modernize-macro-to-enum)
71 
72 #ifndef JSON_DIAGNOSTICS
73  #define JSON_DIAGNOSTICS 0
74 #endif
75 
76 #ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
77  #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
78 #endif
79 
80 #if JSON_DIAGNOSTICS
81  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
82 #else
83  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
84 #endif
85 
86 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
87  #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
88 #else
89  #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
90 #endif
91 
92 #ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
93  #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
94 #endif
95 
96 // Construct the namespace ABI tags component
97 #define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
98 #define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
99  NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
100 
101 #define NLOHMANN_JSON_ABI_TAGS \
102  NLOHMANN_JSON_ABI_TAGS_CONCAT( \
103  NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
104  NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
105 
106 // Construct the namespace version component
107 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
108  _v ## major ## _ ## minor ## _ ## patch
109 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
110  NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
111 
112 #if NLOHMANN_JSON_NAMESPACE_NO_VERSION
113 #define NLOHMANN_JSON_NAMESPACE_VERSION
114 #else
115 #define NLOHMANN_JSON_NAMESPACE_VERSION \
116  NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
117  NLOHMANN_JSON_VERSION_MINOR, \
118  NLOHMANN_JSON_VERSION_PATCH)
119 #endif
120 
121 // Combine namespace components
122 #define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
123 #define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
124  NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
125 
126 #ifndef NLOHMANN_JSON_NAMESPACE
127 #define NLOHMANN_JSON_NAMESPACE \
128  nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
129  NLOHMANN_JSON_ABI_TAGS, \
130  NLOHMANN_JSON_NAMESPACE_VERSION)
131 #endif
132 
133 #ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
134 #define NLOHMANN_JSON_NAMESPACE_BEGIN \
135  namespace nlohmann \
136  { \
137  inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
138  NLOHMANN_JSON_ABI_TAGS, \
139  NLOHMANN_JSON_NAMESPACE_VERSION) \
140  {
141 #endif
142 
143 #ifndef NLOHMANN_JSON_NAMESPACE_END
144 #define NLOHMANN_JSON_NAMESPACE_END \
145  } /* namespace (inline namespace) NOLINT(readability/namespace) */ \
146  } // namespace nlohmann
147 #endif
148 
149 // #include <nlohmann/detail/conversions/from_json.hpp>
150 // __ _____ _____ _____
151 // __| | __| | | | JSON for Modern C++
152 // | | |__ | | | | | | version 3.11.3
153 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
154 //
155 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
156 // SPDX-License-Identifier: MIT
157 
158 
159 
160 #include <algorithm> // transform
161 #include <array> // array
162 #include <forward_list> // forward_list
163 #include <iterator> // inserter, front_inserter, end
164 #include <map> // map
165 #include <string> // string
166 #include <tuple> // tuple, make_tuple
167 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
168 #include <unordered_map> // unordered_map
169 #include <utility> // pair, declval
170 #include <valarray> // valarray
171 
172 // #include <nlohmann/detail/exceptions.hpp>
173 // __ _____ _____ _____
174 // __| | __| | | | JSON for Modern C++
175 // | | |__ | | | | | | version 3.11.3
176 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
177 //
178 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
179 // SPDX-License-Identifier: MIT
180 
181 
182 
183 #include <cstddef> // nullptr_t
184 #include <exception> // exception
185 #if JSON_DIAGNOSTICS
186  #include <numeric> // accumulate
187 #endif
188 #include <stdexcept> // runtime_error
189 #include <string> // to_string
190 #include <vector> // vector
191 
192 // #include <nlohmann/detail/value_t.hpp>
193 // __ _____ _____ _____
194 // __| | __| | | | JSON for Modern C++
195 // | | |__ | | | | | | version 3.11.3
196 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
197 //
198 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
199 // SPDX-License-Identifier: MIT
200 
201 
202 
203 #include <array> // array
204 #include <cstddef> // size_t
205 #include <cstdint> // uint8_t
206 #include <string> // string
207 
208 // #include <nlohmann/detail/macro_scope.hpp>
209 // __ _____ _____ _____
210 // __| | __| | | | JSON for Modern C++
211 // | | |__ | | | | | | version 3.11.3
212 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
213 //
214 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
215 // SPDX-License-Identifier: MIT
216 
217 
218 
219 #include <utility> // declval, pair
220 // #include <nlohmann/detail/meta/detected.hpp>
221 // __ _____ _____ _____
222 // __| | __| | | | JSON for Modern C++
223 // | | |__ | | | | | | version 3.11.3
224 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
225 //
226 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
227 // SPDX-License-Identifier: MIT
228 
229 
230 
231 #include <type_traits>
232 
233 // #include <nlohmann/detail/meta/void_t.hpp>
234 // __ _____ _____ _____
235 // __| | __| | | | JSON for Modern C++
236 // | | |__ | | | | | | version 3.11.3
237 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
238 //
239 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
240 // SPDX-License-Identifier: MIT
241 
242 
243 
244 // #include <nlohmann/detail/abi_macros.hpp>
245 
246 
248 namespace detail
249 {
250 
251 template<typename ...Ts> struct make_void
252 {
253  using type = void;
254 };
255 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
256 
257 } // namespace detail
259 
260 
262 namespace detail
263 {
264 
265 // https://en.cppreference.com/w/cpp/experimental/is_detected
266 struct nonesuch
267 {
268  nonesuch() = delete;
269  ~nonesuch() = delete;
270  nonesuch(nonesuch const&) = delete;
271  nonesuch(nonesuch const&&) = delete;
272  void operator=(nonesuch const&) = delete;
273  void operator=(nonesuch&&) = delete;
274 };
275 
276 template<class Default,
277  class AlwaysVoid,
278  template<class...> class Op,
279  class... Args>
280 struct detector
281 {
282  using value_t = std::false_type;
283  using type = Default;
284 };
285 
286 template<class Default, template<class...> class Op, class... Args>
287 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
288 {
289  using value_t = std::true_type;
290  using type = Op<Args...>;
291 };
292 
293 template<template<class...> class Op, class... Args>
294 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
295 
296 template<template<class...> class Op, class... Args>
297 struct is_detected_lazy : is_detected<Op, Args...> { };
298 
299 template<template<class...> class Op, class... Args>
300 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
301 
302 template<class Default, template<class...> class Op, class... Args>
303 using detected_or = detector<Default, void, Op, Args...>;
304 
305 template<class Default, template<class...> class Op, class... Args>
306 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
307 
308 template<class Expected, template<class...> class Op, class... Args>
310 
311 template<class To, template<class...> class Op, class... Args>
313  std::is_convertible<detected_t<Op, Args...>, To>;
314 
315 } // namespace detail
317 
318 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
319 
320 
321 // __ _____ _____ _____
322 // __| | __| | | | JSON for Modern C++
323 // | | |__ | | | | | | version 3.11.3
324 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
325 //
326 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
327 // SPDX-FileCopyrightText: 2016-2021 Evan Nemerson <evan@nemerson.com>
328 // SPDX-License-Identifier: MIT
329 
330 /* Hedley - https://nemequ.github.io/hedley
331  * Created by Evan Nemerson <evan@nemerson.com>
332  */
333 
334 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
335 #if defined(JSON_HEDLEY_VERSION)
336  #undef JSON_HEDLEY_VERSION
337 #endif
338 #define JSON_HEDLEY_VERSION 15
339 
340 #if defined(JSON_HEDLEY_STRINGIFY_EX)
341  #undef JSON_HEDLEY_STRINGIFY_EX
342 #endif
343 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
344 
345 #if defined(JSON_HEDLEY_STRINGIFY)
346  #undef JSON_HEDLEY_STRINGIFY
347 #endif
348 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
349 
350 #if defined(JSON_HEDLEY_CONCAT_EX)
351  #undef JSON_HEDLEY_CONCAT_EX
352 #endif
353 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
354 
355 #if defined(JSON_HEDLEY_CONCAT)
356  #undef JSON_HEDLEY_CONCAT
357 #endif
358 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
359 
360 #if defined(JSON_HEDLEY_CONCAT3_EX)
361  #undef JSON_HEDLEY_CONCAT3_EX
362 #endif
363 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
364 
365 #if defined(JSON_HEDLEY_CONCAT3)
366  #undef JSON_HEDLEY_CONCAT3
367 #endif
368 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
369 
370 #if defined(JSON_HEDLEY_VERSION_ENCODE)
371  #undef JSON_HEDLEY_VERSION_ENCODE
372 #endif
373 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
374 
375 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
376  #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
377 #endif
378 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
379 
380 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
381  #undef JSON_HEDLEY_VERSION_DECODE_MINOR
382 #endif
383 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
384 
385 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
386  #undef JSON_HEDLEY_VERSION_DECODE_REVISION
387 #endif
388 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
389 
390 #if defined(JSON_HEDLEY_GNUC_VERSION)
391  #undef JSON_HEDLEY_GNUC_VERSION
392 #endif
393 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
394  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
395 #elif defined(__GNUC__)
396  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
397 #endif
398 
399 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
400  #undef JSON_HEDLEY_GNUC_VERSION_CHECK
401 #endif
402 #if defined(JSON_HEDLEY_GNUC_VERSION)
403  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
404 #else
405  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
406 #endif
407 
408 #if defined(JSON_HEDLEY_MSVC_VERSION)
409  #undef JSON_HEDLEY_MSVC_VERSION
410 #endif
411 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
412  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
413 #elif defined(_MSC_FULL_VER) && !defined(__ICL)
414  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
415 #elif defined(_MSC_VER) && !defined(__ICL)
416  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
417 #endif
418 
419 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
420  #undef JSON_HEDLEY_MSVC_VERSION_CHECK
421 #endif
422 #if !defined(JSON_HEDLEY_MSVC_VERSION)
423  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
424 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
425  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
426 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
427  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
428 #else
429  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
430 #endif
431 
432 #if defined(JSON_HEDLEY_INTEL_VERSION)
433  #undef JSON_HEDLEY_INTEL_VERSION
434 #endif
435 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
436  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
437 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
438  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
439 #endif
440 
441 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
442  #undef JSON_HEDLEY_INTEL_VERSION_CHECK
443 #endif
444 #if defined(JSON_HEDLEY_INTEL_VERSION)
445  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446 #else
447  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
448 #endif
449 
450 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
451  #undef JSON_HEDLEY_INTEL_CL_VERSION
452 #endif
453 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
454  #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
455 #endif
456 
457 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
458  #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
459 #endif
460 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
461  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462 #else
463  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
464 #endif
465 
466 #if defined(JSON_HEDLEY_PGI_VERSION)
467  #undef JSON_HEDLEY_PGI_VERSION
468 #endif
469 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
470  #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
471 #endif
472 
473 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
474  #undef JSON_HEDLEY_PGI_VERSION_CHECK
475 #endif
476 #if defined(JSON_HEDLEY_PGI_VERSION)
477  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
478 #else
479  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
480 #endif
481 
482 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
483  #undef JSON_HEDLEY_SUNPRO_VERSION
484 #endif
485 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
486  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
487 #elif defined(__SUNPRO_C)
488  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
489 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
490  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
491 #elif defined(__SUNPRO_CC)
492  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
493 #endif
494 
495 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
496  #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
497 #endif
498 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
499  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
500 #else
501  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
502 #endif
503 
504 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
505  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
506 #endif
507 #if defined(__EMSCRIPTEN__)
508  #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
509 #endif
510 
511 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
512  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
513 #endif
514 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
515  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
516 #else
517  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
518 #endif
519 
520 #if defined(JSON_HEDLEY_ARM_VERSION)
521  #undef JSON_HEDLEY_ARM_VERSION
522 #endif
523 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
524  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
525 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
526  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
527 #endif
528 
529 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
530  #undef JSON_HEDLEY_ARM_VERSION_CHECK
531 #endif
532 #if defined(JSON_HEDLEY_ARM_VERSION)
533  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
534 #else
535  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
536 #endif
537 
538 #if defined(JSON_HEDLEY_IBM_VERSION)
539  #undef JSON_HEDLEY_IBM_VERSION
540 #endif
541 #if defined(__ibmxl__)
542  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
543 #elif defined(__xlC__) && defined(__xlC_ver__)
544  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
545 #elif defined(__xlC__)
546  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
547 #endif
548 
549 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
550  #undef JSON_HEDLEY_IBM_VERSION_CHECK
551 #endif
552 #if defined(JSON_HEDLEY_IBM_VERSION)
553  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
554 #else
555  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
556 #endif
557 
558 #if defined(JSON_HEDLEY_TI_VERSION)
559  #undef JSON_HEDLEY_TI_VERSION
560 #endif
561 #if \
562  defined(__TI_COMPILER_VERSION__) && \
563  ( \
564  defined(__TMS470__) || defined(__TI_ARM__) || \
565  defined(__MSP430__) || \
566  defined(__TMS320C2000__) \
567  )
568 #if (__TI_COMPILER_VERSION__ >= 16000000)
569  #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
570 #endif
571 #endif
572 
573 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
574  #undef JSON_HEDLEY_TI_VERSION_CHECK
575 #endif
576 #if defined(JSON_HEDLEY_TI_VERSION)
577  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
578 #else
579  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
580 #endif
581 
582 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
583  #undef JSON_HEDLEY_TI_CL2000_VERSION
584 #endif
585 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
586  #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
587 #endif
588 
589 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
590  #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
591 #endif
592 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
593  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
594 #else
595  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
596 #endif
597 
598 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
599  #undef JSON_HEDLEY_TI_CL430_VERSION
600 #endif
601 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
602  #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
603 #endif
604 
605 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
606  #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
607 #endif
608 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
609  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
610 #else
611  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
612 #endif
613 
614 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
615  #undef JSON_HEDLEY_TI_ARMCL_VERSION
616 #endif
617 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
618  #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
619 #endif
620 
621 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
622  #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
623 #endif
624 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
625  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
626 #else
627  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
628 #endif
629 
630 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
631  #undef JSON_HEDLEY_TI_CL6X_VERSION
632 #endif
633 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
634  #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
635 #endif
636 
637 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
638  #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
639 #endif
640 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
641  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
642 #else
643  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
644 #endif
645 
646 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
647  #undef JSON_HEDLEY_TI_CL7X_VERSION
648 #endif
649 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
650  #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
651 #endif
652 
653 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
654  #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
655 #endif
656 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
657  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
658 #else
659  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
660 #endif
661 
662 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
663  #undef JSON_HEDLEY_TI_CLPRU_VERSION
664 #endif
665 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
666  #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
667 #endif
668 
669 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
670  #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
671 #endif
672 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
673  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
674 #else
675  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
676 #endif
677 
678 #if defined(JSON_HEDLEY_CRAY_VERSION)
679  #undef JSON_HEDLEY_CRAY_VERSION
680 #endif
681 #if defined(_CRAYC)
682  #if defined(_RELEASE_PATCHLEVEL)
683  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
684  #else
685  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
686  #endif
687 #endif
688 
689 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
690  #undef JSON_HEDLEY_CRAY_VERSION_CHECK
691 #endif
692 #if defined(JSON_HEDLEY_CRAY_VERSION)
693  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
694 #else
695  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
696 #endif
697 
698 #if defined(JSON_HEDLEY_IAR_VERSION)
699  #undef JSON_HEDLEY_IAR_VERSION
700 #endif
701 #if defined(__IAR_SYSTEMS_ICC__)
702  #if __VER__ > 1000
703  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
704  #else
705  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
706  #endif
707 #endif
708 
709 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
710  #undef JSON_HEDLEY_IAR_VERSION_CHECK
711 #endif
712 #if defined(JSON_HEDLEY_IAR_VERSION)
713  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
714 #else
715  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
716 #endif
717 
718 #if defined(JSON_HEDLEY_TINYC_VERSION)
719  #undef JSON_HEDLEY_TINYC_VERSION
720 #endif
721 #if defined(__TINYC__)
722  #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
723 #endif
724 
725 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
726  #undef JSON_HEDLEY_TINYC_VERSION_CHECK
727 #endif
728 #if defined(JSON_HEDLEY_TINYC_VERSION)
729  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
730 #else
731  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
732 #endif
733 
734 #if defined(JSON_HEDLEY_DMC_VERSION)
735  #undef JSON_HEDLEY_DMC_VERSION
736 #endif
737 #if defined(__DMC__)
738  #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
739 #endif
740 
741 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
742  #undef JSON_HEDLEY_DMC_VERSION_CHECK
743 #endif
744 #if defined(JSON_HEDLEY_DMC_VERSION)
745  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
746 #else
747  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
748 #endif
749 
750 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
751  #undef JSON_HEDLEY_COMPCERT_VERSION
752 #endif
753 #if defined(__COMPCERT_VERSION__)
754  #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
755 #endif
756 
757 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
758  #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
759 #endif
760 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
761  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
762 #else
763  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
764 #endif
765 
766 #if defined(JSON_HEDLEY_PELLES_VERSION)
767  #undef JSON_HEDLEY_PELLES_VERSION
768 #endif
769 #if defined(__POCC__)
770  #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
771 #endif
772 
773 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
774  #undef JSON_HEDLEY_PELLES_VERSION_CHECK
775 #endif
776 #if defined(JSON_HEDLEY_PELLES_VERSION)
777  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
778 #else
779  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
780 #endif
781 
782 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
783  #undef JSON_HEDLEY_MCST_LCC_VERSION
784 #endif
785 #if defined(__LCC__) && defined(__LCC_MINOR__)
786  #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
787 #endif
788 
789 #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
790  #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
791 #endif
792 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
793  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
794 #else
795  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
796 #endif
797 
798 #if defined(JSON_HEDLEY_GCC_VERSION)
799  #undef JSON_HEDLEY_GCC_VERSION
800 #endif
801 #if \
802  defined(JSON_HEDLEY_GNUC_VERSION) && \
803  !defined(__clang__) && \
804  !defined(JSON_HEDLEY_INTEL_VERSION) && \
805  !defined(JSON_HEDLEY_PGI_VERSION) && \
806  !defined(JSON_HEDLEY_ARM_VERSION) && \
807  !defined(JSON_HEDLEY_CRAY_VERSION) && \
808  !defined(JSON_HEDLEY_TI_VERSION) && \
809  !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
810  !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
811  !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
812  !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
813  !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
814  !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
815  !defined(__COMPCERT__) && \
816  !defined(JSON_HEDLEY_MCST_LCC_VERSION)
817  #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
818 #endif
819 
820 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
821  #undef JSON_HEDLEY_GCC_VERSION_CHECK
822 #endif
823 #if defined(JSON_HEDLEY_GCC_VERSION)
824  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
825 #else
826  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
827 #endif
828 
829 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
830  #undef JSON_HEDLEY_HAS_ATTRIBUTE
831 #endif
832 #if \
833  defined(__has_attribute) && \
834  ( \
835  (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
836  )
837 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
838 #else
839 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
840 #endif
841 
842 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
843  #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
844 #endif
845 #if defined(__has_attribute)
846  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
847 #else
848  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
849 #endif
850 
851 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
852  #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
853 #endif
854 #if defined(__has_attribute)
855  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
856 #else
857  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
858 #endif
859 
860 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
861  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
862 #endif
863 #if \
864  defined(__has_cpp_attribute) && \
865  defined(__cplusplus) && \
866  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
867  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
868 #else
869  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
870 #endif
871 
872 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
873  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
874 #endif
875 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
876  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
877 #elif \
878  !defined(JSON_HEDLEY_PGI_VERSION) && \
879  !defined(JSON_HEDLEY_IAR_VERSION) && \
880  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
881  (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
882  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
883 #else
884  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
885 #endif
886 
887 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
888  #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
889 #endif
890 #if defined(__has_cpp_attribute) && defined(__cplusplus)
891  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
892 #else
893  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
894 #endif
895 
896 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
897  #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
898 #endif
899 #if defined(__has_cpp_attribute) && defined(__cplusplus)
900  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
901 #else
902  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
903 #endif
904 
905 #if defined(JSON_HEDLEY_HAS_BUILTIN)
906  #undef JSON_HEDLEY_HAS_BUILTIN
907 #endif
908 #if defined(__has_builtin)
909  #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
910 #else
911  #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
912 #endif
913 
914 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
915  #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
916 #endif
917 #if defined(__has_builtin)
918  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
919 #else
920  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
921 #endif
922 
923 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
924  #undef JSON_HEDLEY_GCC_HAS_BUILTIN
925 #endif
926 #if defined(__has_builtin)
927  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
928 #else
929  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
930 #endif
931 
932 #if defined(JSON_HEDLEY_HAS_FEATURE)
933  #undef JSON_HEDLEY_HAS_FEATURE
934 #endif
935 #if defined(__has_feature)
936  #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
937 #else
938  #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
939 #endif
940 
941 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
942  #undef JSON_HEDLEY_GNUC_HAS_FEATURE
943 #endif
944 #if defined(__has_feature)
945  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
946 #else
947  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
948 #endif
949 
950 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
951  #undef JSON_HEDLEY_GCC_HAS_FEATURE
952 #endif
953 #if defined(__has_feature)
954  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
955 #else
956  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
957 #endif
958 
959 #if defined(JSON_HEDLEY_HAS_EXTENSION)
960  #undef JSON_HEDLEY_HAS_EXTENSION
961 #endif
962 #if defined(__has_extension)
963  #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
964 #else
965  #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
966 #endif
967 
968 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
969  #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
970 #endif
971 #if defined(__has_extension)
972  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
973 #else
974  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
975 #endif
976 
977 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
978  #undef JSON_HEDLEY_GCC_HAS_EXTENSION
979 #endif
980 #if defined(__has_extension)
981  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
982 #else
983  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
984 #endif
985 
986 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
987  #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
988 #endif
989 #if defined(__has_declspec_attribute)
990  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
991 #else
992  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
993 #endif
994 
995 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
996  #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
997 #endif
998 #if defined(__has_declspec_attribute)
999  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1000 #else
1001  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1002 #endif
1003 
1004 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
1005  #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
1006 #endif
1007 #if defined(__has_declspec_attribute)
1008  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1009 #else
1010  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1011 #endif
1012 
1013 #if defined(JSON_HEDLEY_HAS_WARNING)
1014  #undef JSON_HEDLEY_HAS_WARNING
1015 #endif
1016 #if defined(__has_warning)
1017  #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
1018 #else
1019  #define JSON_HEDLEY_HAS_WARNING(warning) (0)
1020 #endif
1021 
1022 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
1023  #undef JSON_HEDLEY_GNUC_HAS_WARNING
1024 #endif
1025 #if defined(__has_warning)
1026  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1027 #else
1028  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1029 #endif
1030 
1031 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
1032  #undef JSON_HEDLEY_GCC_HAS_WARNING
1033 #endif
1034 #if defined(__has_warning)
1035  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1036 #else
1037  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1038 #endif
1039 
1040 #if \
1041  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1042  defined(__clang__) || \
1043  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1044  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1045  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1046  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1047  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1048  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1049  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1050  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1051  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1052  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
1053  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1054  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1055  JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
1056  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
1057  JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
1058  (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
1059  #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
1060 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1061  #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
1062 #else
1063  #define JSON_HEDLEY_PRAGMA(value)
1064 #endif
1065 
1066 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
1067  #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
1068 #endif
1069 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
1070  #undef JSON_HEDLEY_DIAGNOSTIC_POP
1071 #endif
1072 #if defined(__clang__)
1073  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
1074  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
1075 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1076  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1077  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1078 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1079  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
1080  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
1081 #elif \
1082  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1083  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1084  #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
1085  #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
1086 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
1087  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
1088  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
1089 #elif \
1090  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1091  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1092  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
1093  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1094  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1095  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1096  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
1097  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
1098 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1099  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1100  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1101 #else
1102  #define JSON_HEDLEY_DIAGNOSTIC_PUSH
1103  #define JSON_HEDLEY_DIAGNOSTIC_POP
1104 #endif
1105 
1106 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
1107  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1108 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1109  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
1110 #endif
1111 #if defined(__cplusplus)
1112 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
1113 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
1114 # if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
1115 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1116  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1117  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1118  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1119  _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
1120  xpr \
1121  JSON_HEDLEY_DIAGNOSTIC_POP
1122 # else
1123 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1124  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1125  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1126  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1127  xpr \
1128  JSON_HEDLEY_DIAGNOSTIC_POP
1129 # endif
1130 # else
1131 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1132  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1133  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1134  xpr \
1135  JSON_HEDLEY_DIAGNOSTIC_POP
1136 # endif
1137 # endif
1138 #endif
1139 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1140  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1141 #endif
1142 
1143 #if defined(JSON_HEDLEY_CONST_CAST)
1144  #undef JSON_HEDLEY_CONST_CAST
1145 #endif
1146 #if defined(__cplusplus)
1147 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1148 #elif \
1149  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1150  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1151  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1152 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1153  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1154  JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1155  ((T) (expr)); \
1156  JSON_HEDLEY_DIAGNOSTIC_POP \
1157  }))
1158 #else
1159 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1160 #endif
1161 
1162 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
1163  #undef JSON_HEDLEY_REINTERPRET_CAST
1164 #endif
1165 #if defined(__cplusplus)
1166  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1167 #else
1168  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1169 #endif
1170 
1171 #if defined(JSON_HEDLEY_STATIC_CAST)
1172  #undef JSON_HEDLEY_STATIC_CAST
1173 #endif
1174 #if defined(__cplusplus)
1175  #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1176 #else
1177  #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1178 #endif
1179 
1180 #if defined(JSON_HEDLEY_CPP_CAST)
1181  #undef JSON_HEDLEY_CPP_CAST
1182 #endif
1183 #if defined(__cplusplus)
1184 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1185 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1186  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1187  _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1188  ((T) (expr)) \
1189  JSON_HEDLEY_DIAGNOSTIC_POP
1190 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1191 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1192  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1193  _Pragma("diag_suppress=Pe137") \
1194  JSON_HEDLEY_DIAGNOSTIC_POP
1195 # else
1196 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1197 # endif
1198 #else
1199 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1200 #endif
1201 
1202 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1203  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1204 #endif
1205 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1206  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1207 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1208  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1209 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1210  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1211 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1212  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1213 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1214  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1215 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1216  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1217 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1218  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1219 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1220  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1221 #elif \
1222  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1233  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1234 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1235  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1236 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1237  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1238 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1239  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1240 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1241  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1242 #else
1243  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1244 #endif
1245 
1246 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1247  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1248 #endif
1249 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1250  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1251 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1252  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1253 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1254  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1255 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1256  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1257 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1258  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1259 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1260  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1261 #elif \
1262  JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1263  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1264  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1265  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1266  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1267 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1268  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1269 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1270  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1271 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1272  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1273 #else
1274  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1275 #endif
1276 
1277 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1278  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1279 #endif
1280 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1281  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1282 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1283  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1284 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1285  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1286 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1287  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1288 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1289  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1290 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1291  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1292 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1293  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1294 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1295  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1296 #elif \
1297  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1298  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1299  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1300  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1301 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1302  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1303 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1304  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1305 #else
1306  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1307 #endif
1308 
1309 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1310  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1311 #endif
1312 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1313  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1314 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1315  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1316 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1317  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1318 #else
1319  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1320 #endif
1321 
1322 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1323  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1324 #endif
1325 #if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1326  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1327 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1328  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1329 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1330  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1331 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1332  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1333 #else
1334  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1335 #endif
1336 
1337 #if defined(JSON_HEDLEY_DEPRECATED)
1338  #undef JSON_HEDLEY_DEPRECATED
1339 #endif
1340 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1341  #undef JSON_HEDLEY_DEPRECATED_FOR
1342 #endif
1343 #if \
1344  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1345  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1346  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1347  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1348 #elif \
1349  (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1350  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1351  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1352  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1353  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1354  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1355  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1356  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1357  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1358  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1359  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1360  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1361  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1362  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1363 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1364  #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1365  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1366 #elif \
1367  JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1368  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1369  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1370  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1371  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1372  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1373  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1374  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1375  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1376  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1377  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1378  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1379  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1380  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1381  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1382  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1383  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1384  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1385 #elif \
1386  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1387  JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1388  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1389  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1390  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1391 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1392  #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1393  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1394 #else
1395  #define JSON_HEDLEY_DEPRECATED(since)
1396  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1397 #endif
1398 
1399 #if defined(JSON_HEDLEY_UNAVAILABLE)
1400  #undef JSON_HEDLEY_UNAVAILABLE
1401 #endif
1402 #if \
1403  JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1404  JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1405  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1406  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1407  #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1408 #else
1409  #define JSON_HEDLEY_UNAVAILABLE(available_since)
1410 #endif
1411 
1412 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1413  #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1414 #endif
1415 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1416  #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1417 #endif
1418 #if \
1419  JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1420  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1421  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1422  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1423  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1424  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1425  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1426  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1427  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1428  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1429  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1430  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1431  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1432  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1433  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1434  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1435  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1436  #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1437  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1438 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1439  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1440  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1441 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1442  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1443  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1444 #elif defined(_Check_return_) /* SAL */
1445  #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1446  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1447 #else
1448  #define JSON_HEDLEY_WARN_UNUSED_RESULT
1449  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1450 #endif
1451 
1452 #if defined(JSON_HEDLEY_SENTINEL)
1453  #undef JSON_HEDLEY_SENTINEL
1454 #endif
1455 #if \
1456  JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1457  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1458  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1459  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1460  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1461  #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1462 #else
1463  #define JSON_HEDLEY_SENTINEL(position)
1464 #endif
1465 
1466 #if defined(JSON_HEDLEY_NO_RETURN)
1467  #undef JSON_HEDLEY_NO_RETURN
1468 #endif
1469 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1470  #define JSON_HEDLEY_NO_RETURN __noreturn
1471 #elif \
1472  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1474  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1475 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1476  #define JSON_HEDLEY_NO_RETURN _Noreturn
1477 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1478  #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1479 #elif \
1480  JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1481  JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1482  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1483  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1484  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1485  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1486  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1487  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1488  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1489  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1490  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1491  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1492  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1493  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1494  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1495  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1496  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1497  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1498 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1499  #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1500 #elif \
1501  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1502  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1503  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1504 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1505  #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1506 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1507  #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1508 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1509  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1510 #else
1511  #define JSON_HEDLEY_NO_RETURN
1512 #endif
1513 
1514 #if defined(JSON_HEDLEY_NO_ESCAPE)
1515  #undef JSON_HEDLEY_NO_ESCAPE
1516 #endif
1517 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1518  #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1519 #else
1520  #define JSON_HEDLEY_NO_ESCAPE
1521 #endif
1522 
1523 #if defined(JSON_HEDLEY_UNREACHABLE)
1524  #undef JSON_HEDLEY_UNREACHABLE
1525 #endif
1526 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1527  #undef JSON_HEDLEY_UNREACHABLE_RETURN
1528 #endif
1529 #if defined(JSON_HEDLEY_ASSUME)
1530  #undef JSON_HEDLEY_ASSUME
1531 #endif
1532 #if \
1533  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1534  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1535  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1536  #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1537 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1538  #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1539 #elif \
1540  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1541  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1542  #if defined(__cplusplus)
1543  #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1544  #else
1545  #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1546  #endif
1547 #endif
1548 #if \
1549  (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1550  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1551  JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1552  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1553  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1554  JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1555  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1556  #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1557 #elif defined(JSON_HEDLEY_ASSUME)
1558  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1559 #endif
1560 #if !defined(JSON_HEDLEY_ASSUME)
1561  #if defined(JSON_HEDLEY_UNREACHABLE)
1562  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1563  #else
1564  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1565  #endif
1566 #endif
1567 #if defined(JSON_HEDLEY_UNREACHABLE)
1568  #if \
1569  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1570  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1571  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1572  #else
1573  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1574  #endif
1575 #else
1576  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1577 #endif
1578 #if !defined(JSON_HEDLEY_UNREACHABLE)
1579  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1580 #endif
1581 
1583 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1584  #pragma clang diagnostic ignored "-Wpedantic"
1585 #endif
1586 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1587  #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1588 #endif
1589 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1590  #if defined(__clang__)
1591  #pragma clang diagnostic ignored "-Wvariadic-macros"
1592  #elif defined(JSON_HEDLEY_GCC_VERSION)
1593  #pragma GCC diagnostic ignored "-Wvariadic-macros"
1594  #endif
1595 #endif
1596 #if defined(JSON_HEDLEY_NON_NULL)
1597  #undef JSON_HEDLEY_NON_NULL
1598 #endif
1599 #if \
1600  JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1601  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1602  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1603  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1604  #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1605 #else
1606  #define JSON_HEDLEY_NON_NULL(...)
1607 #endif
1609 
1610 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1611  #undef JSON_HEDLEY_PRINTF_FORMAT
1612 #endif
1613 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1614  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1615 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1616  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1617 #elif \
1618  JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1619  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1620  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1621  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1622  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1623  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1624  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1625  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1626  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1627  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1628  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1629  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1630  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1631  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1632  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1633  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1634  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1635  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1636 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1637  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1638 #else
1639  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1640 #endif
1641 
1642 #if defined(JSON_HEDLEY_CONSTEXPR)
1643  #undef JSON_HEDLEY_CONSTEXPR
1644 #endif
1645 #if defined(__cplusplus)
1646  #if __cplusplus >= 201103L
1647  #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1648  #endif
1649 #endif
1650 #if !defined(JSON_HEDLEY_CONSTEXPR)
1651  #define JSON_HEDLEY_CONSTEXPR
1652 #endif
1653 
1654 #if defined(JSON_HEDLEY_PREDICT)
1655  #undef JSON_HEDLEY_PREDICT
1656 #endif
1657 #if defined(JSON_HEDLEY_LIKELY)
1658  #undef JSON_HEDLEY_LIKELY
1659 #endif
1660 #if defined(JSON_HEDLEY_UNLIKELY)
1661  #undef JSON_HEDLEY_UNLIKELY
1662 #endif
1663 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1664  #undef JSON_HEDLEY_UNPREDICTABLE
1665 #endif
1666 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1667  #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1668 #endif
1669 #if \
1670  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1671  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1672  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1673 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1674 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1675 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1676 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1677 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1678 #elif \
1679  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1680  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1681  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1682  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1683  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1684  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1685  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1686  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1687  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1688  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1689  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1690  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1691  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1692  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1693  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1694  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1695 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1696  (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1697 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1698  (__extension__ ({ \
1699  double hedley_probability_ = (probability); \
1700  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1701  }))
1702 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1703  (__extension__ ({ \
1704  double hedley_probability_ = (probability); \
1705  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1706  }))
1707 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1708 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1709 #else
1710 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1711 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1712 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1713 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1714 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1715 #endif
1716 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1717  #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1718 #endif
1719 
1720 #if defined(JSON_HEDLEY_MALLOC)
1721  #undef JSON_HEDLEY_MALLOC
1722 #endif
1723 #if \
1724  JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1725  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1726  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1727  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1728  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1729  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1730  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1731  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1732  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1733  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1734  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1735  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1736  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1737  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1738  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1739  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1740  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1741  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1742  #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1743 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1744  #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1745 #elif \
1746  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1747  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1748  #define JSON_HEDLEY_MALLOC __declspec(restrict)
1749 #else
1750  #define JSON_HEDLEY_MALLOC
1751 #endif
1752 
1753 #if defined(JSON_HEDLEY_PURE)
1754  #undef JSON_HEDLEY_PURE
1755 #endif
1756 #if \
1757  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1758  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1759  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1760  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1761  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1762  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1763  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1764  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1765  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1766  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1767  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1768  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1769  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1770  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1771  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1772  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1773  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1774  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1775  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1776 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1777 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1778 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1779 #elif defined(__cplusplus) && \
1780  ( \
1781  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1782  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1783  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1784  )
1785 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1786 #else
1787 # define JSON_HEDLEY_PURE
1788 #endif
1789 
1790 #if defined(JSON_HEDLEY_CONST)
1791  #undef JSON_HEDLEY_CONST
1792 #endif
1793 #if \
1794  JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1795  JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1796  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1797  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1798  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1799  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1800  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1801  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1802  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1803  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1804  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1805  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1806  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1807  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1808  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1809  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1810  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1811  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1812  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1813  #define JSON_HEDLEY_CONST __attribute__((__const__))
1814 #elif \
1815  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1816  #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1817 #else
1818  #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1819 #endif
1820 
1821 #if defined(JSON_HEDLEY_RESTRICT)
1822  #undef JSON_HEDLEY_RESTRICT
1823 #endif
1824 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1825  #define JSON_HEDLEY_RESTRICT restrict
1826 #elif \
1827  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1828  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1829  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1830  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1831  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1832  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1833  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1834  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1835  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1836  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1837  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1838  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1839  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1840  defined(__clang__) || \
1841  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1842  #define JSON_HEDLEY_RESTRICT __restrict
1843 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1844  #define JSON_HEDLEY_RESTRICT _Restrict
1845 #else
1846  #define JSON_HEDLEY_RESTRICT
1847 #endif
1848 
1849 #if defined(JSON_HEDLEY_INLINE)
1850  #undef JSON_HEDLEY_INLINE
1851 #endif
1852 #if \
1853  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1854  (defined(__cplusplus) && (__cplusplus >= 199711L))
1855  #define JSON_HEDLEY_INLINE inline
1856 #elif \
1857  defined(JSON_HEDLEY_GCC_VERSION) || \
1858  JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1859  #define JSON_HEDLEY_INLINE __inline__
1860 #elif \
1861  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1862  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1863  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1864  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1865  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1866  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1867  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1868  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1869  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1870  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1871  #define JSON_HEDLEY_INLINE __inline
1872 #else
1873  #define JSON_HEDLEY_INLINE
1874 #endif
1875 
1876 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1877  #undef JSON_HEDLEY_ALWAYS_INLINE
1878 #endif
1879 #if \
1880  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1881  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1882  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1883  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1884  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1885  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1886  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1887  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1888  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1889  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1890  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1891  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1892  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1893  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1894  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1895  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1896  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1897  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1898  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1899 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1900 #elif \
1901  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1902  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1903 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1904 #elif defined(__cplusplus) && \
1905  ( \
1906  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1907  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1908  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1909  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1910  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1911  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1912  )
1913 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1914 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1915 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1916 #else
1917 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1918 #endif
1919 
1920 #if defined(JSON_HEDLEY_NEVER_INLINE)
1921  #undef JSON_HEDLEY_NEVER_INLINE
1922 #endif
1923 #if \
1924  JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1925  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1926  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1927  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1928  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1929  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1930  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1931  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1932  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1933  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1934  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1935  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1936  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1937  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1938  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1939  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1940  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1941  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1942  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1943  #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1944 #elif \
1945  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1946  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1947  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1948 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1949  #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1950 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1951  #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1952 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1953  #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1954 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1955  #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1956 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1957  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1958 #else
1959  #define JSON_HEDLEY_NEVER_INLINE
1960 #endif
1961 
1962 #if defined(JSON_HEDLEY_PRIVATE)
1963  #undef JSON_HEDLEY_PRIVATE
1964 #endif
1965 #if defined(JSON_HEDLEY_PUBLIC)
1966  #undef JSON_HEDLEY_PUBLIC
1967 #endif
1968 #if defined(JSON_HEDLEY_IMPORT)
1969  #undef JSON_HEDLEY_IMPORT
1970 #endif
1971 #if defined(_WIN32) || defined(__CYGWIN__)
1972 # define JSON_HEDLEY_PRIVATE
1973 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1974 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1975 #else
1976 # if \
1977  JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1978  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1979  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1980  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1981  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1982  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1983  ( \
1984  defined(__TI_EABI__) && \
1985  ( \
1986  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1987  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1988  ) \
1989  ) || \
1990  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1991 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1992 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1993 # else
1994 # define JSON_HEDLEY_PRIVATE
1995 # define JSON_HEDLEY_PUBLIC
1996 # endif
1997 # define JSON_HEDLEY_IMPORT extern
1998 #endif
1999 
2000 #if defined(JSON_HEDLEY_NO_THROW)
2001  #undef JSON_HEDLEY_NO_THROW
2002 #endif
2003 #if \
2004  JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
2005  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
2006  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2007  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2008  #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
2009 #elif \
2010  JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
2011  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
2012  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
2013  #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
2014 #else
2015  #define JSON_HEDLEY_NO_THROW
2016 #endif
2017 
2018 #if defined(JSON_HEDLEY_FALL_THROUGH)
2019  #undef JSON_HEDLEY_FALL_THROUGH
2020 #endif
2021 #if \
2022  JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
2023  JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
2024  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2025  #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
2026 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
2027  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
2028 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
2029  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
2030 #elif defined(__fallthrough) /* SAL */
2031  #define JSON_HEDLEY_FALL_THROUGH __fallthrough
2032 #else
2033  #define JSON_HEDLEY_FALL_THROUGH
2034 #endif
2035 
2036 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
2037  #undef JSON_HEDLEY_RETURNS_NON_NULL
2038 #endif
2039 #if \
2040  JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
2041  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2042  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2043  #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
2044 #elif defined(_Ret_notnull_) /* SAL */
2045  #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
2046 #else
2047  #define JSON_HEDLEY_RETURNS_NON_NULL
2048 #endif
2049 
2050 #if defined(JSON_HEDLEY_ARRAY_PARAM)
2051  #undef JSON_HEDLEY_ARRAY_PARAM
2052 #endif
2053 #if \
2054  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
2055  !defined(__STDC_NO_VLA__) && \
2056  !defined(__cplusplus) && \
2057  !defined(JSON_HEDLEY_PGI_VERSION) && \
2058  !defined(JSON_HEDLEY_TINYC_VERSION)
2059  #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
2060 #else
2061  #define JSON_HEDLEY_ARRAY_PARAM(name)
2062 #endif
2063 
2064 #if defined(JSON_HEDLEY_IS_CONSTANT)
2065  #undef JSON_HEDLEY_IS_CONSTANT
2066 #endif
2067 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
2068  #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
2069 #endif
2070 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
2071  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
2072 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2073  #undef JSON_HEDLEY_IS_CONSTEXPR_
2074 #endif
2075 #if \
2076  JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
2077  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2078  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2079  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
2080  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2081  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2082  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
2083  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
2084  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2085  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2086  #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
2087 #endif
2088 #if !defined(__cplusplus)
2089 # if \
2090  JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
2091  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2092  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2093  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2094  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2095  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
2096  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
2097 #if defined(__INTPTR_TYPE__)
2098  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
2099 #else
2100  #include <stdint.h>
2101  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
2102 #endif
2103 # elif \
2104  ( \
2105  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
2106  !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
2107  !defined(JSON_HEDLEY_PGI_VERSION) && \
2108  !defined(JSON_HEDLEY_IAR_VERSION)) || \
2109  (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
2110  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2111  JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
2112  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
2113  JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
2114 #if defined(__INTPTR_TYPE__)
2115  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
2116 #else
2117  #include <stdint.h>
2118  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
2119 #endif
2120 # elif \
2121  defined(JSON_HEDLEY_GCC_VERSION) || \
2122  defined(JSON_HEDLEY_INTEL_VERSION) || \
2123  defined(JSON_HEDLEY_TINYC_VERSION) || \
2124  defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
2125  JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
2126  defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
2127  defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
2128  defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
2129  defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
2130  defined(__clang__)
2131 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2132  sizeof(void) != \
2133  sizeof(*( \
2134  1 ? \
2135  ((void*) ((expr) * 0L) ) : \
2136 ((struct { char v[sizeof(void) * 2]; } *) 1) \
2137  ) \
2138  ) \
2139  )
2140 # endif
2141 #endif
2142 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2143  #if !defined(JSON_HEDLEY_IS_CONSTANT)
2144  #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2145  #endif
2146  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2147 #else
2148  #if !defined(JSON_HEDLEY_IS_CONSTANT)
2149  #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2150  #endif
2151  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2152 #endif
2153 
2154 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2155  #undef JSON_HEDLEY_BEGIN_C_DECLS
2156 #endif
2157 #if defined(JSON_HEDLEY_END_C_DECLS)
2158  #undef JSON_HEDLEY_END_C_DECLS
2159 #endif
2160 #if defined(JSON_HEDLEY_C_DECL)
2161  #undef JSON_HEDLEY_C_DECL
2162 #endif
2163 #if defined(__cplusplus)
2164  #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2165  #define JSON_HEDLEY_END_C_DECLS }
2166  #define JSON_HEDLEY_C_DECL extern "C"
2167 #else
2168  #define JSON_HEDLEY_BEGIN_C_DECLS
2169  #define JSON_HEDLEY_END_C_DECLS
2170  #define JSON_HEDLEY_C_DECL
2171 #endif
2172 
2173 #if defined(JSON_HEDLEY_STATIC_ASSERT)
2174  #undef JSON_HEDLEY_STATIC_ASSERT
2175 #endif
2176 #if \
2177  !defined(__cplusplus) && ( \
2178  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2179  (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2180  JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2181  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2182  defined(_Static_assert) \
2183  )
2184 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2185 #elif \
2186  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2187  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2188  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2189 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2190 #else
2191 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2192 #endif
2193 
2194 #if defined(JSON_HEDLEY_NULL)
2195  #undef JSON_HEDLEY_NULL
2196 #endif
2197 #if defined(__cplusplus)
2198  #if __cplusplus >= 201103L
2199  #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2200  #elif defined(NULL)
2201  #define JSON_HEDLEY_NULL NULL
2202  #else
2203  #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2204  #endif
2205 #elif defined(NULL)
2206  #define JSON_HEDLEY_NULL NULL
2207 #else
2208  #define JSON_HEDLEY_NULL ((void*) 0)
2209 #endif
2210 
2211 #if defined(JSON_HEDLEY_MESSAGE)
2212  #undef JSON_HEDLEY_MESSAGE
2213 #endif
2214 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2215 # define JSON_HEDLEY_MESSAGE(msg) \
2216  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2217  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2218  JSON_HEDLEY_PRAGMA(message msg) \
2219  JSON_HEDLEY_DIAGNOSTIC_POP
2220 #elif \
2221  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2222  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2223 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2224 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2225 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2226 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2227 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2228 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2229 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2230 #else
2231 # define JSON_HEDLEY_MESSAGE(msg)
2232 #endif
2233 
2234 #if defined(JSON_HEDLEY_WARNING)
2235  #undef JSON_HEDLEY_WARNING
2236 #endif
2237 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2238 # define JSON_HEDLEY_WARNING(msg) \
2239  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2240  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2241  JSON_HEDLEY_PRAGMA(clang warning msg) \
2242  JSON_HEDLEY_DIAGNOSTIC_POP
2243 #elif \
2244  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2245  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2246  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2247 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2248 #elif \
2249  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2250  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2251 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2252 #else
2253 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2254 #endif
2255 
2256 #if defined(JSON_HEDLEY_REQUIRE)
2257  #undef JSON_HEDLEY_REQUIRE
2258 #endif
2259 #if defined(JSON_HEDLEY_REQUIRE_MSG)
2260  #undef JSON_HEDLEY_REQUIRE_MSG
2261 #endif
2262 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2263 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2264 # define JSON_HEDLEY_REQUIRE(expr) \
2265  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2266  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2267  __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2268  JSON_HEDLEY_DIAGNOSTIC_POP
2269 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2270  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2271  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2272  __attribute__((diagnose_if(!(expr), msg, "error"))) \
2273  JSON_HEDLEY_DIAGNOSTIC_POP
2274 # else
2275 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2276 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2277 # endif
2278 #else
2279 # define JSON_HEDLEY_REQUIRE(expr)
2280 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2281 #endif
2282 
2283 #if defined(JSON_HEDLEY_FLAGS)
2284  #undef JSON_HEDLEY_FLAGS
2285 #endif
2286 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2287  #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2288 #else
2289  #define JSON_HEDLEY_FLAGS
2290 #endif
2291 
2292 #if defined(JSON_HEDLEY_FLAGS_CAST)
2293  #undef JSON_HEDLEY_FLAGS_CAST
2294 #endif
2295 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2296 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2297  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2298  _Pragma("warning(disable:188)") \
2299  ((T) (expr)); \
2300  JSON_HEDLEY_DIAGNOSTIC_POP \
2301  }))
2302 #else
2303 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2304 #endif
2305 
2306 #if defined(JSON_HEDLEY_EMPTY_BASES)
2307  #undef JSON_HEDLEY_EMPTY_BASES
2308 #endif
2309 #if \
2310  (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2311  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2312  #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2313 #else
2314  #define JSON_HEDLEY_EMPTY_BASES
2315 #endif
2316 
2317 /* Remaining macros are deprecated. */
2318 
2319 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2320  #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2321 #endif
2322 #if defined(__clang__)
2323  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2324 #else
2325  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2326 #endif
2327 
2328 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2329  #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2330 #endif
2331 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2332 
2333 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2334  #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2335 #endif
2336 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2337 
2338 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2339  #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2340 #endif
2341 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2342 
2343 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2344  #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2345 #endif
2346 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2347 
2348 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2349  #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2350 #endif
2351 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2352 
2353 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2354  #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2355 #endif
2356 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2357 
2358 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2359  #undef JSON_HEDLEY_CLANG_HAS_WARNING
2360 #endif
2361 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2362 
2363 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2364 
2365 
2366 // This file contains all internal macro definitions (except those affecting ABI)
2367 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2368 
2369 // #include <nlohmann/detail/abi_macros.hpp>
2370 
2371 
2372 // exclude unsupported compilers
2373 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2374  #if defined(__clang__)
2375  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2376  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2377  #endif
2378  #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2379  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2380  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2381  #endif
2382  #endif
2383 #endif
2384 
2385 // C++ language standard detection
2386 // if the user manually specified the used c++ version this is skipped
2387 #if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2388  #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2389  #define JSON_HAS_CPP_20
2390  #define JSON_HAS_CPP_17
2391  #define JSON_HAS_CPP_14
2392  #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2393  #define JSON_HAS_CPP_17
2394  #define JSON_HAS_CPP_14
2395  #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2396  #define JSON_HAS_CPP_14
2397  #endif
2398  // the cpp 11 flag is always specified because it is the minimal required version
2399  #define JSON_HAS_CPP_11
2400 #endif
2401 
2402 #ifdef __has_include
2403  #if __has_include(<version>)
2404  #include <version>
2405  #endif
2406 #endif
2407 
2408 #if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2409  #ifdef JSON_HAS_CPP_17
2410  #if defined(__cpp_lib_filesystem)
2411  #define JSON_HAS_FILESYSTEM 1
2412  #elif defined(__cpp_lib_experimental_filesystem)
2413  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2414  #elif !defined(__has_include)
2415  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2416  #elif __has_include(<filesystem>)
2417  #define JSON_HAS_FILESYSTEM 1
2418  #elif __has_include(<experimental/filesystem>)
2419  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2420  #endif
2421 
2422  // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2423  #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2424  #undef JSON_HAS_FILESYSTEM
2425  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2426  #endif
2427 
2428  // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2429  #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2430  #undef JSON_HAS_FILESYSTEM
2431  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2432  #endif
2433 
2434  // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2435  #if defined(__clang_major__) && __clang_major__ < 7
2436  #undef JSON_HAS_FILESYSTEM
2437  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2438  #endif
2439 
2440  // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2441  #if defined(_MSC_VER) && _MSC_VER < 1914
2442  #undef JSON_HAS_FILESYSTEM
2443  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2444  #endif
2445 
2446  // no filesystem support before iOS 13
2447  #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2448  #undef JSON_HAS_FILESYSTEM
2449  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2450  #endif
2451 
2452  // no filesystem support before macOS Catalina
2453  #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2454  #undef JSON_HAS_FILESYSTEM
2455  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2456  #endif
2457  #endif
2458 #endif
2459 
2460 #ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2461  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2462 #endif
2463 
2464 #ifndef JSON_HAS_FILESYSTEM
2465  #define JSON_HAS_FILESYSTEM 0
2466 #endif
2467 
2468 #ifndef JSON_HAS_THREE_WAY_COMPARISON
2469  #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
2470  && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
2471  #define JSON_HAS_THREE_WAY_COMPARISON 1
2472  #else
2473  #define JSON_HAS_THREE_WAY_COMPARISON 0
2474  #endif
2475 #endif
2476 
2477 #ifndef JSON_HAS_RANGES
2478  // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error
2479  #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427
2480  #define JSON_HAS_RANGES 0
2481  #elif defined(__cpp_lib_ranges)
2482  #define JSON_HAS_RANGES 1
2483  #else
2484  #define JSON_HAS_RANGES 0
2485  #endif
2486 #endif
2487 
2488 #ifndef JSON_HAS_STATIC_RTTI
2489  #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0
2490  #define JSON_HAS_STATIC_RTTI 1
2491  #else
2492  #define JSON_HAS_STATIC_RTTI 0
2493  #endif
2494 #endif
2495 
2496 #ifdef JSON_HAS_CPP_17
2497  #define JSON_INLINE_VARIABLE inline
2498 #else
2499  #define JSON_INLINE_VARIABLE
2500 #endif
2501 
2502 #if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2503  #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2504 #else
2505  #define JSON_NO_UNIQUE_ADDRESS
2506 #endif
2507 
2508 // disable documentation warnings on clang
2509 #if defined(__clang__)
2510  #pragma clang diagnostic push
2511  #pragma clang diagnostic ignored "-Wdocumentation"
2512  #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2513 #endif
2514 
2515 // allow disabling exceptions
2516 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2517  #define JSON_THROW(exception) throw exception
2518  #define JSON_TRY try
2519  #define JSON_CATCH(exception) catch(exception)
2520  #define JSON_INTERNAL_CATCH(exception) catch(exception)
2521 #else
2522  #include <cstdlib>
2523  #define JSON_THROW(exception) std::abort()
2524  #define JSON_TRY if(true)
2525  #define JSON_CATCH(exception) if(false)
2526  #define JSON_INTERNAL_CATCH(exception) if(false)
2527 #endif
2528 
2529 // override exception macros
2530 #if defined(JSON_THROW_USER)
2531  #undef JSON_THROW
2532  #define JSON_THROW JSON_THROW_USER
2533 #endif
2534 #if defined(JSON_TRY_USER)
2535  #undef JSON_TRY
2536  #define JSON_TRY JSON_TRY_USER
2537 #endif
2538 #if defined(JSON_CATCH_USER)
2539  #undef JSON_CATCH
2540  #define JSON_CATCH JSON_CATCH_USER
2541  #undef JSON_INTERNAL_CATCH
2542  #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2543 #endif
2544 #if defined(JSON_INTERNAL_CATCH_USER)
2545  #undef JSON_INTERNAL_CATCH
2546  #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2547 #endif
2548 
2549 // allow overriding assert
2550 #if !defined(JSON_ASSERT)
2551  #include <cassert> // assert
2552  #define JSON_ASSERT(x) assert(x)
2553 #endif
2554 
2555 // allow to access some private functions (needed by the test suite)
2556 #if defined(JSON_TESTS_PRIVATE)
2557  #define JSON_PRIVATE_UNLESS_TESTED public
2558 #else
2559  #define JSON_PRIVATE_UNLESS_TESTED private
2560 #endif
2561 
2567 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2568  template<typename BasicJsonType> \
2569  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2570  { \
2571  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2572  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2573  auto it = std::find_if(std::begin(m), std::end(m), \
2574  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2575  { \
2576  return ej_pair.first == e; \
2577  }); \
2578  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2579  } \
2580  template<typename BasicJsonType> \
2581  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2582  { \
2583  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2584  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2585  auto it = std::find_if(std::begin(m), std::end(m), \
2586  [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2587  { \
2588  return ej_pair.second == j; \
2589  }); \
2590  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2591  }
2592 
2593 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2594 // may be removed in the future once the class is split.
2595 
2596 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2597  template<template<typename, typename, typename...> class ObjectType, \
2598  template<typename, typename...> class ArrayType, \
2599  class StringType, class BooleanType, class NumberIntegerType, \
2600  class NumberUnsignedType, class NumberFloatType, \
2601  template<typename> class AllocatorType, \
2602  template<typename, typename = void> class JSONSerializer, \
2603  class BinaryType, \
2604  class CustomBaseClass>
2605 
2606 #define NLOHMANN_BASIC_JSON_TPL \
2607  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2608  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2609  AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>
2610 
2611 // Macros to simplify conversion from/to types
2612 
2613 #define NLOHMANN_JSON_EXPAND( x ) x
2614 #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2615 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2616  NLOHMANN_JSON_PASTE64, \
2617  NLOHMANN_JSON_PASTE63, \
2618  NLOHMANN_JSON_PASTE62, \
2619  NLOHMANN_JSON_PASTE61, \
2620  NLOHMANN_JSON_PASTE60, \
2621  NLOHMANN_JSON_PASTE59, \
2622  NLOHMANN_JSON_PASTE58, \
2623  NLOHMANN_JSON_PASTE57, \
2624  NLOHMANN_JSON_PASTE56, \
2625  NLOHMANN_JSON_PASTE55, \
2626  NLOHMANN_JSON_PASTE54, \
2627  NLOHMANN_JSON_PASTE53, \
2628  NLOHMANN_JSON_PASTE52, \
2629  NLOHMANN_JSON_PASTE51, \
2630  NLOHMANN_JSON_PASTE50, \
2631  NLOHMANN_JSON_PASTE49, \
2632  NLOHMANN_JSON_PASTE48, \
2633  NLOHMANN_JSON_PASTE47, \
2634  NLOHMANN_JSON_PASTE46, \
2635  NLOHMANN_JSON_PASTE45, \
2636  NLOHMANN_JSON_PASTE44, \
2637  NLOHMANN_JSON_PASTE43, \
2638  NLOHMANN_JSON_PASTE42, \
2639  NLOHMANN_JSON_PASTE41, \
2640  NLOHMANN_JSON_PASTE40, \
2641  NLOHMANN_JSON_PASTE39, \
2642  NLOHMANN_JSON_PASTE38, \
2643  NLOHMANN_JSON_PASTE37, \
2644  NLOHMANN_JSON_PASTE36, \
2645  NLOHMANN_JSON_PASTE35, \
2646  NLOHMANN_JSON_PASTE34, \
2647  NLOHMANN_JSON_PASTE33, \
2648  NLOHMANN_JSON_PASTE32, \
2649  NLOHMANN_JSON_PASTE31, \
2650  NLOHMANN_JSON_PASTE30, \
2651  NLOHMANN_JSON_PASTE29, \
2652  NLOHMANN_JSON_PASTE28, \
2653  NLOHMANN_JSON_PASTE27, \
2654  NLOHMANN_JSON_PASTE26, \
2655  NLOHMANN_JSON_PASTE25, \
2656  NLOHMANN_JSON_PASTE24, \
2657  NLOHMANN_JSON_PASTE23, \
2658  NLOHMANN_JSON_PASTE22, \
2659  NLOHMANN_JSON_PASTE21, \
2660  NLOHMANN_JSON_PASTE20, \
2661  NLOHMANN_JSON_PASTE19, \
2662  NLOHMANN_JSON_PASTE18, \
2663  NLOHMANN_JSON_PASTE17, \
2664  NLOHMANN_JSON_PASTE16, \
2665  NLOHMANN_JSON_PASTE15, \
2666  NLOHMANN_JSON_PASTE14, \
2667  NLOHMANN_JSON_PASTE13, \
2668  NLOHMANN_JSON_PASTE12, \
2669  NLOHMANN_JSON_PASTE11, \
2670  NLOHMANN_JSON_PASTE10, \
2671  NLOHMANN_JSON_PASTE9, \
2672  NLOHMANN_JSON_PASTE8, \
2673  NLOHMANN_JSON_PASTE7, \
2674  NLOHMANN_JSON_PASTE6, \
2675  NLOHMANN_JSON_PASTE5, \
2676  NLOHMANN_JSON_PASTE4, \
2677  NLOHMANN_JSON_PASTE3, \
2678  NLOHMANN_JSON_PASTE2, \
2679  NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2680 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2681 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2682 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2683 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2684 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2685 #define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2686 #define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2687 #define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2688 #define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2689 #define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2690 #define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2691 #define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2692 #define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2693 #define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2694 #define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2695 #define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2696 #define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2697 #define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2698 #define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2699 #define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2700 #define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2701 #define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2702 #define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2703 #define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2704 #define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2705 #define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2706 #define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2707 #define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2708 #define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2709 #define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2710 #define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2711 #define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2712 #define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2713 #define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2714 #define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2715 #define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2716 #define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2717 #define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2718 #define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2719 #define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2720 #define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2721 #define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2722 #define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2723 #define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2724 #define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2725 #define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2726 #define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2727 #define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2728 #define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2729 #define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2730 #define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2731 #define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2732 #define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2733 #define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2734 #define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2735 #define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2736 #define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2737 #define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2738 #define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2739 #define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2740 #define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2741 #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2742 #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2743 
2744 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2745 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2746 #define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2747 
2753 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2754  friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2755  friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2756 
2757 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2758  friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2759  friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2760 
2761 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
2762  friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2763 
2769 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2770  inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2771  inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2772 
2773 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
2774  inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2775 
2776 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2777  inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2778  inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2779 
2780 // inspired from https://stackoverflow.com/a/26745591
2781 // allows to call any std function as if (e.g. with begin):
2782 // using std::begin; begin(x);
2783 //
2784 // it allows using the detected idiom to retrieve the return type
2785 // of such an expression
2786 #define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2787  namespace detail { \
2788  using std::std_name; \
2789  \
2790  template<typename... T> \
2791  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2792  } \
2793  \
2794  namespace detail2 { \
2795  struct std_name##_tag \
2796  { \
2797  }; \
2798  \
2799  template<typename... T> \
2800  std_name##_tag std_name(T&&...); \
2801  \
2802  template<typename... T> \
2803  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2804  \
2805  template<typename... T> \
2806  struct would_call_std_##std_name \
2807  { \
2808  static constexpr auto const value = ::nlohmann::detail:: \
2809  is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2810  }; \
2811  } /* namespace detail2 */ \
2812  \
2813  template<typename... T> \
2814  struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2815  { \
2816  }
2817 
2818 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2819  #define JSON_USE_IMPLICIT_CONVERSIONS 1
2820 #endif
2821 
2822 #if JSON_USE_IMPLICIT_CONVERSIONS
2823  #define JSON_EXPLICIT
2824 #else
2825  #define JSON_EXPLICIT explicit
2826 #endif
2827 
2828 #ifndef JSON_DISABLE_ENUM_SERIALIZATION
2829  #define JSON_DISABLE_ENUM_SERIALIZATION 0
2830 #endif
2831 
2832 #ifndef JSON_USE_GLOBAL_UDLS
2833  #define JSON_USE_GLOBAL_UDLS 1
2834 #endif
2835 
2836 #if JSON_HAS_THREE_WAY_COMPARISON
2837  #include <compare> // partial_ordering
2838 #endif
2839 
2841 namespace detail
2842 {
2843 
2845 // JSON type enumeration //
2847 
2872 enum class value_t : std::uint8_t
2873 {
2874  null,
2875  object,
2876  array,
2877  string,
2878  boolean,
2879  number_integer,
2880  number_unsigned,
2881  number_float,
2882  binary,
2883  discarded
2884 };
2885 
2899 #if JSON_HAS_THREE_WAY_COMPARISON
2900  inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
2901 #else
2902  inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2903 #endif
2904 {
2905  static constexpr std::array<std::uint8_t, 9> order = {{
2906  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2907  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
2908  6 /* binary */
2909  }
2910  };
2911 
2912  const auto l_index = static_cast<std::size_t>(lhs);
2913  const auto r_index = static_cast<std::size_t>(rhs);
2914 #if JSON_HAS_THREE_WAY_COMPARISON
2915  if (l_index < order.size() && r_index < order.size())
2916  {
2917  return order[l_index] <=> order[r_index]; // *NOPAD*
2918  }
2919  return std::partial_ordering::unordered;
2920 #else
2921  return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
2922 #endif
2923 }
2924 
2925 // GCC selects the built-in operator< over an operator rewritten from
2926 // a user-defined spaceship operator
2927 // Clang, MSVC, and ICC select the rewritten candidate
2928 // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
2929 #if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
2930 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2931 {
2932  return std::is_lt(lhs <=> rhs); // *NOPAD*
2933 }
2934 #endif
2935 
2936 } // namespace detail
2938 
2939 // #include <nlohmann/detail/string_escape.hpp>
2940 // __ _____ _____ _____
2941 // __| | __| | | | JSON for Modern C++
2942 // | | |__ | | | | | | version 3.11.3
2943 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
2944 //
2945 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
2946 // SPDX-License-Identifier: MIT
2947 
2948 
2949 
2950 // #include <nlohmann/detail/abi_macros.hpp>
2951 
2952 
2954 namespace detail
2955 {
2956 
2970 template<typename StringType>
2971 inline void replace_substring(StringType& s, const StringType& f,
2972  const StringType& t)
2973 {
2974  JSON_ASSERT(!f.empty());
2975  for (auto pos = s.find(f); // find first occurrence of f
2976  pos != StringType::npos; // make sure f was found
2977  s.replace(pos, f.size(), t), // replace with t, and
2978  pos = s.find(f, pos + t.size())) // find next occurrence of f
2979  {}
2980 }
2981 
2989 template<typename StringType>
2990 inline StringType escape(StringType s)
2991 {
2992  replace_substring(s, StringType{"~"}, StringType{"~0"});
2993  replace_substring(s, StringType{"/"}, StringType{"~1"});
2994  return s;
2995 }
2996 
3004 template<typename StringType>
3005 static void unescape(StringType& s)
3006 {
3007  replace_substring(s, StringType{"~1"}, StringType{"/"});
3008  replace_substring(s, StringType{"~0"}, StringType{"~"});
3009 }
3010 
3011 } // namespace detail
3013 
3014 // #include <nlohmann/detail/input/position_t.hpp>
3015 // __ _____ _____ _____
3016 // __| | __| | | | JSON for Modern C++
3017 // | | |__ | | | | | | version 3.11.3
3018 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3019 //
3020 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3021 // SPDX-License-Identifier: MIT
3022 
3023 
3024 
3025 #include <cstddef> // size_t
3026 
3027 // #include <nlohmann/detail/abi_macros.hpp>
3028 
3029 
3031 namespace detail
3032 {
3033 
3036 {
3038  std::size_t chars_read_total = 0;
3040  std::size_t chars_read_current_line = 0;
3042  std::size_t lines_read = 0;
3043 
3045  constexpr operator size_t() const
3046  {
3047  return chars_read_total;
3048  }
3049 };
3050 
3051 } // namespace detail
3053 
3054 // #include <nlohmann/detail/macro_scope.hpp>
3055 
3056 // #include <nlohmann/detail/meta/cpp_future.hpp>
3057 // __ _____ _____ _____
3058 // __| | __| | | | JSON for Modern C++
3059 // | | |__ | | | | | | version 3.11.3
3060 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3061 //
3062 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3063 // SPDX-FileCopyrightText: 2018 The Abseil Authors
3064 // SPDX-License-Identifier: MIT
3065 
3066 
3067 
3068 #include <array> // array
3069 #include <cstddef> // size_t
3070 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3071 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3072 
3073 // #include <nlohmann/detail/macro_scope.hpp>
3074 
3075 
3077 namespace detail
3078 {
3079 
3080 template<typename T>
3081 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3082 
3083 #ifdef JSON_HAS_CPP_14
3084 
3085 // the following utilities are natively available in C++14
3086 using std::enable_if_t;
3087 using std::index_sequence;
3090 
3091 #else
3092 
3093 // alias templates to reduce boilerplate
3094 template<bool B, typename T = void>
3095 using enable_if_t = typename std::enable_if<B, T>::type;
3096 
3097 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3098 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3099 
3101 
3102 // integer_sequence
3103 //
3104 // Class template representing a compile-time integer sequence. An instantiation
3105 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3106 // type through its template arguments (which is a common need when
3107 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3108 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3109 //
3110 // Example:
3111 //
3112 // template< class T, T... Ints >
3113 // void user_function(integer_sequence<T, Ints...>);
3114 //
3115 // int main()
3116 // {
3117 // // user_function's `T` will be deduced to `int` and `Ints...`
3118 // // will be deduced to `0, 1, 2, 3, 4`.
3119 // user_function(make_integer_sequence<int, 5>());
3120 // }
3121 template <typename T, T... Ints>
3123 {
3124  using value_type = T;
3125  static constexpr std::size_t size() noexcept
3126  {
3127  return sizeof...(Ints);
3128  }
3129 };
3130 
3131 // index_sequence
3132 //
3133 // A helper template for an `integer_sequence` of `size_t`,
3134 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3135 // `std::index_sequence`.
3136 template <size_t... Ints>
3137 using index_sequence = integer_sequence<size_t, Ints...>;
3138 
3139 namespace utility_internal
3140 {
3141 
3142 template <typename Seq, size_t SeqSize, size_t Rem>
3143 struct Extend;
3144 
3145 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3146 template <typename T, T... Ints, size_t SeqSize>
3147 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3148 {
3149  using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3150 };
3151 
3152 template <typename T, T... Ints, size_t SeqSize>
3153 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3154 {
3155  using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3156 };
3157 
3158 // Recursion helper for 'make_integer_sequence<T, N>'.
3159 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3160 template <typename T, size_t N>
3161 struct Gen
3162 {
3163  using type =
3164  typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3165 };
3166 
3167 template <typename T>
3168 struct Gen<T, 0>
3169 {
3171 };
3172 
3173 } // namespace utility_internal
3174 
3175 // Compile-time sequences of integers
3176 
3177 // make_integer_sequence
3178 //
3179 // This template alias is equivalent to
3180 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3181 // replacement for C++14's `std::make_integer_sequence`.
3182 template <typename T, T N>
3184 
3185 // make_index_sequence
3186 //
3187 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3188 // and is designed to be a drop-in replacement for C++14's
3189 // `std::make_index_sequence`.
3190 template <size_t N>
3192 
3193 // index_sequence_for
3194 //
3195 // Converts a typename pack into an index sequence of the same length, and
3196 // is designed to be a drop-in replacement for C++14's
3197 // `std::index_sequence_for()`
3198 template <typename... Ts>
3200 
3202 
3203 #endif
3204 
3205 // dispatch utility (taken from ranges-v3)
3206 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3207 template<> struct priority_tag<0> {};
3208 
3209 // taken from ranges-v3
3210 template<typename T>
3212 {
3213  static JSON_INLINE_VARIABLE constexpr T value{};
3214 };
3215 
3216 #ifndef JSON_HAS_CPP_17
3217  template<typename T>
3218  constexpr T static_const<T>::value;
3219 #endif
3220 
3221 template<typename T, typename... Args>
3222 inline constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args)
3223 {
3224  return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}};
3225 }
3226 
3227 } // namespace detail
3229 
3230 // #include <nlohmann/detail/meta/type_traits.hpp>
3231 // __ _____ _____ _____
3232 // __| | __| | | | JSON for Modern C++
3233 // | | |__ | | | | | | version 3.11.3
3234 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3235 //
3236 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3237 // SPDX-License-Identifier: MIT
3238 
3239 
3240 
3241 #include <limits> // numeric_limits
3242 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3243 #include <utility> // declval
3244 #include <tuple> // tuple
3245 #include <string> // char_traits
3246 
3247 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3248 // __ _____ _____ _____
3249 // __| | __| | | | JSON for Modern C++
3250 // | | |__ | | | | | | version 3.11.3
3251 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3252 //
3253 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3254 // SPDX-License-Identifier: MIT
3255 
3256 
3257 
3258 #include <iterator> // random_access_iterator_tag
3259 
3260 // #include <nlohmann/detail/abi_macros.hpp>
3261 
3262 // #include <nlohmann/detail/meta/void_t.hpp>
3263 
3264 // #include <nlohmann/detail/meta/cpp_future.hpp>
3265 
3266 
3268 namespace detail
3269 {
3270 
3271 template<typename It, typename = void>
3272 struct iterator_types {};
3273 
3274 template<typename It>
3276  It,
3277  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3278  typename It::reference, typename It::iterator_category >>
3279 {
3280  using difference_type = typename It::difference_type;
3281  using value_type = typename It::value_type;
3282  using pointer = typename It::pointer;
3283  using reference = typename It::reference;
3284  using iterator_category = typename It::iterator_category;
3285 };
3286 
3287 // This is required as some compilers implement std::iterator_traits in a way that
3288 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3289 template<typename T, typename = void>
3291 {
3292 };
3293 
3294 template<typename T>
3295 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3296  : iterator_types<T>
3297 {
3298 };
3299 
3300 template<typename T>
3302 {
3303  using iterator_category = std::random_access_iterator_tag;
3304  using value_type = T;
3305  using difference_type = ptrdiff_t;
3306  using pointer = T*;
3307  using reference = T&;
3308 };
3309 
3310 } // namespace detail
3312 
3313 // #include <nlohmann/detail/macro_scope.hpp>
3314 
3315 // #include <nlohmann/detail/meta/call_std/begin.hpp>
3316 // __ _____ _____ _____
3317 // __| | __| | | | JSON for Modern C++
3318 // | | |__ | | | | | | version 3.11.3
3319 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3320 //
3321 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3322 // SPDX-License-Identifier: MIT
3323 
3324 
3325 
3326 // #include <nlohmann/detail/macro_scope.hpp>
3327 
3328 
3330 
3332 
3334 
3335 // #include <nlohmann/detail/meta/call_std/end.hpp>
3336 // __ _____ _____ _____
3337 // __| | __| | | | JSON for Modern C++
3338 // | | |__ | | | | | | version 3.11.3
3339 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3340 //
3341 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3342 // SPDX-License-Identifier: MIT
3343 
3344 
3345 
3346 // #include <nlohmann/detail/macro_scope.hpp>
3347 
3348 
3350 
3352 
3354 
3355 // #include <nlohmann/detail/meta/cpp_future.hpp>
3356 
3357 // #include <nlohmann/detail/meta/detected.hpp>
3358 
3359 // #include <nlohmann/json_fwd.hpp>
3360 // __ _____ _____ _____
3361 // __| | __| | | | JSON for Modern C++
3362 // | | |__ | | | | | | version 3.11.3
3363 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3364 //
3365 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3366 // SPDX-License-Identifier: MIT
3367 
3368 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3369  #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3370 
3371  #include <cstdint> // int64_t, uint64_t
3372  #include <map> // map
3373  #include <memory> // allocator
3374  #include <string> // string
3375  #include <vector> // vector
3376 
3377  // #include <nlohmann/detail/abi_macros.hpp>
3378 
3379 
3386 
3394  template<typename T = void, typename SFINAE = void>
3396 
3399  template<template<typename U, typename V, typename... Args> class ObjectType =
3400  std::map,
3401  template<typename U, typename... Args> class ArrayType = std::vector,
3402  class StringType = std::string, class BooleanType = bool,
3403  class NumberIntegerType = std::int64_t,
3404  class NumberUnsignedType = std::uint64_t,
3405  class NumberFloatType = double,
3406  template<typename U> class AllocatorType = std::allocator,
3407  template<typename T, typename SFINAE = void> class JSONSerializer =
3409  class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
3410  class CustomBaseClass = void>
3411  class basic_json;
3412 
3415  template<typename RefStringType>
3417 
3423 
3426  template<class Key, class T, class IgnoredLess, class Allocator>
3427  struct ordered_map;
3428 
3432 
3434 
3435 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3436 
3437 
3447 namespace detail
3448 {
3449 
3451 // helpers //
3453 
3454 // Note to maintainers:
3455 //
3456 // Every trait in this file expects a non CV-qualified type.
3457 // The only exceptions are in the 'aliases for detected' section
3458 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3459 //
3460 // In this case, T has to be properly CV-qualified to constraint the function arguments
3461 // (e.g. to_json(BasicJsonType&, const T&))
3462 
3463 template<typename> struct is_basic_json : std::false_type {};
3464 
3466 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3467 
3468 // used by exceptions create() member functions
3469 // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3470 // false_type otherwise
3471 template<typename BasicJsonContext>
3473  std::integral_constant < bool,
3474  is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3475  || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3476 {};
3477 
3479 // json_ref helpers //
3481 
3482 template<typename>
3483 class json_ref;
3484 
3485 template<typename>
3486 struct is_json_ref : std::false_type {};
3487 
3488 template<typename T>
3489 struct is_json_ref<json_ref<T>> : std::true_type {};
3490 
3492 // aliases for detected //
3494 
3495 template<typename T>
3496 using mapped_type_t = typename T::mapped_type;
3497 
3498 template<typename T>
3499 using key_type_t = typename T::key_type;
3500 
3501 template<typename T>
3502 using value_type_t = typename T::value_type;
3503 
3504 template<typename T>
3505 using difference_type_t = typename T::difference_type;
3506 
3507 template<typename T>
3508 using pointer_t = typename T::pointer;
3509 
3510 template<typename T>
3511 using reference_t = typename T::reference;
3512 
3513 template<typename T>
3514 using iterator_category_t = typename T::iterator_category;
3515 
3516 template<typename T, typename... Args>
3517 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3518 
3519 template<typename T, typename... Args>
3520 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3521 
3522 template<typename T, typename U>
3523 using get_template_function = decltype(std::declval<T>().template get<U>());
3524 
3525 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3526 template<typename BasicJsonType, typename T, typename = void>
3527 struct has_from_json : std::false_type {};
3528 
3529 // trait checking if j.get<T> is valid
3530 // use this trait instead of std::is_constructible or std::is_convertible,
3531 // both rely on, or make use of implicit conversions, and thus fail when T
3532 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3533 template <typename BasicJsonType, typename T>
3535 {
3537 };
3538 
3539 template<typename BasicJsonType, typename T>
3540 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3541 {
3542  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3543 
3544  static constexpr bool value =
3546  const BasicJsonType&, T&>::value;
3547 };
3548 
3549 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3550 // this overload is used for non-default-constructible user-defined-types
3551 template<typename BasicJsonType, typename T, typename = void>
3552 struct has_non_default_from_json : std::false_type {};
3553 
3554 template<typename BasicJsonType, typename T>
3555 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3556 {
3557  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3558 
3559  static constexpr bool value =
3561  const BasicJsonType&>::value;
3562 };
3563 
3564 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3565 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3566 template<typename BasicJsonType, typename T, typename = void>
3567 struct has_to_json : std::false_type {};
3568 
3569 template<typename BasicJsonType, typename T>
3570 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3571 {
3572  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3573 
3574  static constexpr bool value =
3576  T>::value;
3577 };
3578 
3579 template<typename T>
3580 using detect_key_compare = typename T::key_compare;
3581 
3582 template<typename T>
3583 struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3584 
3585 // obtains the actual object key comparator
3586 template<typename BasicJsonType>
3588 {
3589  using object_t = typename BasicJsonType::object_t;
3590  using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3592  typename object_t::key_compare, object_comparator_t>::type;
3593 };
3594 
3595 template<typename BasicJsonType>
3597 
3599 // char_traits //
3601 
3602 // Primary template of char_traits calls std char_traits
3603 template<typename T>
3604 struct char_traits : std::char_traits<T>
3605 {};
3606 
3607 // Explicitly define char traits for unsigned char since it is not standard
3608 template<>
3609 struct char_traits<unsigned char> : std::char_traits<char>
3610 {
3611  using char_type = unsigned char;
3612  using int_type = uint64_t;
3613 
3614  // Redefine to_int_type function
3615  static int_type to_int_type(char_type c) noexcept
3616  {
3617  return static_cast<int_type>(c);
3618  }
3619 
3620  static char_type to_char_type(int_type i) noexcept
3621  {
3622  return static_cast<char_type>(i);
3623  }
3624 
3625  static constexpr int_type eof() noexcept
3626  {
3627  return static_cast<int_type>(EOF);
3628  }
3629 };
3630 
3631 // Explicitly define char traits for signed char since it is not standard
3632 template<>
3633 struct char_traits<signed char> : std::char_traits<char>
3634 {
3635  using char_type = signed char;
3636  using int_type = uint64_t;
3637 
3638  // Redefine to_int_type function
3639  static int_type to_int_type(char_type c) noexcept
3640  {
3641  return static_cast<int_type>(c);
3642  }
3643 
3644  static char_type to_char_type(int_type i) noexcept
3645  {
3646  return static_cast<char_type>(i);
3647  }
3648 
3649  static constexpr int_type eof() noexcept
3650  {
3651  return static_cast<int_type>(EOF);
3652  }
3653 };
3654 
3656 // is_ functions //
3658 
3659 // https://en.cppreference.com/w/cpp/types/conjunction
3660 template<class...> struct conjunction : std::true_type { };
3661 template<class B> struct conjunction<B> : B { };
3662 template<class B, class... Bn>
3663 struct conjunction<B, Bn...>
3664 : std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
3665 
3666 // https://en.cppreference.com/w/cpp/types/negation
3667 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3668 
3669 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3670 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3671 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3672 template <typename T>
3673 struct is_default_constructible : std::is_default_constructible<T> {};
3674 
3675 template <typename T1, typename T2>
3676 struct is_default_constructible<std::pair<T1, T2>>
3677  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3678 
3679 template <typename T1, typename T2>
3680 struct is_default_constructible<const std::pair<T1, T2>>
3681  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3682 
3683 template <typename... Ts>
3684 struct is_default_constructible<std::tuple<Ts...>>
3685  : conjunction<is_default_constructible<Ts>...> {};
3686 
3687 template <typename... Ts>
3688 struct is_default_constructible<const std::tuple<Ts...>>
3689  : conjunction<is_default_constructible<Ts>...> {};
3690 
3691 template <typename T, typename... Args>
3692 struct is_constructible : std::is_constructible<T, Args...> {};
3693 
3694 template <typename T1, typename T2>
3695 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3696 
3697 template <typename T1, typename T2>
3698 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3699 
3700 template <typename... Ts>
3701 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3702 
3703 template <typename... Ts>
3704 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3705 
3706 template<typename T, typename = void>
3707 struct is_iterator_traits : std::false_type {};
3708 
3709 template<typename T>
3711 {
3712  private:
3714 
3715  public:
3716  static constexpr auto value =
3722 };
3723 
3724 template<typename T>
3725 struct is_range
3726 {
3727  private:
3728  using t_ref = typename std::add_lvalue_reference<T>::type;
3729 
3732 
3733  // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3734  // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3735  // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3736  static constexpr auto is_iterator_begin =
3738 
3739  public:
3741 };
3742 
3743 template<typename R>
3744 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3745 
3746 template<typename T>
3748 
3749 // The following implementation of is_complete_type is taken from
3750 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3751 // and is written by Xiang Fan who agreed to using it in this library.
3752 
3753 template<typename T, typename = void>
3754 struct is_complete_type : std::false_type {};
3755 
3756 template<typename T>
3757 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3758 
3759 template<typename BasicJsonType, typename CompatibleObjectType,
3760  typename = void>
3761 struct is_compatible_object_type_impl : std::false_type {};
3762 
3763 template<typename BasicJsonType, typename CompatibleObjectType>
3765  BasicJsonType, CompatibleObjectType,
3766  enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3767  is_detected<key_type_t, CompatibleObjectType>::value >>
3768 {
3769  using object_t = typename BasicJsonType::object_t;
3770 
3771  // macOS's is_constructible does not play well with nonesuch...
3772  static constexpr bool value =
3773  is_constructible<typename object_t::key_type,
3774  typename CompatibleObjectType::key_type>::value &&
3775  is_constructible<typename object_t::mapped_type,
3776  typename CompatibleObjectType::mapped_type>::value;
3777 };
3778 
3779 template<typename BasicJsonType, typename CompatibleObjectType>
3781  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3782 
3783 template<typename BasicJsonType, typename ConstructibleObjectType,
3784  typename = void>
3785 struct is_constructible_object_type_impl : std::false_type {};
3786 
3787 template<typename BasicJsonType, typename ConstructibleObjectType>
3789  BasicJsonType, ConstructibleObjectType,
3790  enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3791  is_detected<key_type_t, ConstructibleObjectType>::value >>
3792 {
3793  using object_t = typename BasicJsonType::object_t;
3794 
3795  static constexpr bool value =
3799  (is_constructible<typename ConstructibleObjectType::key_type,
3800  typename object_t::key_type>::value &&
3801  std::is_same <
3802  typename object_t::mapped_type,
3803  typename ConstructibleObjectType::mapped_type >::value)) ||
3804  (has_from_json<BasicJsonType,
3805  typename ConstructibleObjectType::mapped_type>::value ||
3807  BasicJsonType,
3808  typename ConstructibleObjectType::mapped_type >::value);
3809 };
3810 
3811 template<typename BasicJsonType, typename ConstructibleObjectType>
3813  : is_constructible_object_type_impl<BasicJsonType,
3814  ConstructibleObjectType> {};
3815 
3816 template<typename BasicJsonType, typename CompatibleStringType>
3818 {
3819  static constexpr auto value =
3821 };
3822 
3823 template<typename BasicJsonType, typename ConstructibleStringType>
3825 {
3826  // launder type through decltype() to fix compilation failure on ICPC
3827 #ifdef __INTEL_COMPILER
3828  using laundered_type = decltype(std::declval<ConstructibleStringType>());
3829 #else
3830  using laundered_type = ConstructibleStringType;
3831 #endif
3832 
3833  static constexpr auto value =
3834  conjunction <
3836  is_detected_exact<typename BasicJsonType::string_t::value_type,
3838 };
3839 
3840 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3841 struct is_compatible_array_type_impl : std::false_type {};
3842 
3843 template<typename BasicJsonType, typename CompatibleArrayType>
3845  BasicJsonType, CompatibleArrayType,
3846  enable_if_t <
3847  is_detected<iterator_t, CompatibleArrayType>::value&&
3848  is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3849 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3850 // c.f. https://github.com/nlohmann/json/pull/3073
3851  !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3852 {
3853  static constexpr bool value =
3854  is_constructible<BasicJsonType,
3856 };
3857 
3858 template<typename BasicJsonType, typename CompatibleArrayType>
3860  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3861 
3862 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3863 struct is_constructible_array_type_impl : std::false_type {};
3864 
3865 template<typename BasicJsonType, typename ConstructibleArrayType>
3867  BasicJsonType, ConstructibleArrayType,
3868  enable_if_t<std::is_same<ConstructibleArrayType,
3869  typename BasicJsonType::value_type>::value >>
3870  : std::true_type {};
3871 
3872 template<typename BasicJsonType, typename ConstructibleArrayType>
3874  BasicJsonType, ConstructibleArrayType,
3875  enable_if_t < !std::is_same<ConstructibleArrayType,
3876  typename BasicJsonType::value_type>::value&&
3877  !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3878  is_default_constructible<ConstructibleArrayType>::value&&
3879 (std::is_move_assignable<ConstructibleArrayType>::value ||
3880  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3881 is_detected<iterator_t, ConstructibleArrayType>::value&&
3882 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3883 is_detected<range_value_t, ConstructibleArrayType>::value&&
3884 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3885 // c.f. https://github.com/nlohmann/json/pull/3073
3886 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3888  detected_t<range_value_t, ConstructibleArrayType >>::value >>
3889 {
3891 
3892  static constexpr bool value =
3894  typename BasicJsonType::array_t::value_type>::value ||
3895  has_from_json<BasicJsonType,
3896  value_type>::value ||
3898  BasicJsonType,
3899  value_type >::value;
3900 };
3901 
3902 template<typename BasicJsonType, typename ConstructibleArrayType>
3904  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3905 
3906 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3907  typename = void>
3908 struct is_compatible_integer_type_impl : std::false_type {};
3909 
3910 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3912  RealIntegerType, CompatibleNumberIntegerType,
3913  enable_if_t < std::is_integral<RealIntegerType>::value&&
3914  std::is_integral<CompatibleNumberIntegerType>::value&&
3915  !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3916 {
3917  // is there an assert somewhere on overflows?
3918  using RealLimits = std::numeric_limits<RealIntegerType>;
3919  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3920 
3921  static constexpr auto value =
3922  is_constructible<RealIntegerType,
3923  CompatibleNumberIntegerType>::value &&
3926 };
3927 
3928 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3930  : is_compatible_integer_type_impl<RealIntegerType,
3931  CompatibleNumberIntegerType> {};
3932 
3933 template<typename BasicJsonType, typename CompatibleType, typename = void>
3934 struct is_compatible_type_impl: std::false_type {};
3935 
3936 template<typename BasicJsonType, typename CompatibleType>
3938  BasicJsonType, CompatibleType,
3939  enable_if_t<is_complete_type<CompatibleType>::value >>
3940 {
3941  static constexpr bool value =
3943 };
3944 
3945 template<typename BasicJsonType, typename CompatibleType>
3947  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3948 
3949 template<typename T1, typename T2>
3950 struct is_constructible_tuple : std::false_type {};
3951 
3952 template<typename T1, typename... Args>
3953 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3954 
3955 template<typename BasicJsonType, typename T>
3956 struct is_json_iterator_of : std::false_type {};
3957 
3958 template<typename BasicJsonType>
3959 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3960 
3961 template<typename BasicJsonType>
3962 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3963 {};
3964 
3965 // checks if a given type T is a template specialization of Primary
3966 template<template <typename...> class Primary, typename T>
3967 struct is_specialization_of : std::false_type {};
3968 
3969 template<template <typename...> class Primary, typename... Args>
3970 struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3971 
3972 template<typename T>
3974 
3975 // checks if A and B are comparable using Compare functor
3976 template<typename Compare, typename A, typename B, typename = void>
3977 struct is_comparable : std::false_type {};
3978 
3979 template<typename Compare, typename A, typename B>
3980 struct is_comparable<Compare, A, B, void_t<
3981 decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3982 decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3983 >> : std::true_type {};
3984 
3985 template<typename T>
3987 
3988 // type trait to check if KeyType can be used as object key (without a BasicJsonType)
3989 // see is_usable_as_basic_json_key_type below
3990 template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3991  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3992 using is_usable_as_key_type = typename std::conditional <
3994  && !(ExcludeObjectKeyType && std::is_same<KeyType,
3995  ObjectKeyType>::value)
3996  && (!RequireTransparentComparator
3999  std::true_type,
4000  std::false_type >::type;
4001 
4002 // type trait to check if KeyType can be used as object key
4003 // true if:
4004 // - KeyType is comparable with BasicJsonType::object_t::key_type
4005 // - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
4006 // - the comparator is transparent or RequireTransparentComparator is false
4007 // - KeyType is not a JSON iterator or json_pointer
4008 template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
4009  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
4010 using is_usable_as_basic_json_key_type = typename std::conditional <
4011  is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
4012  typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
4013  RequireTransparentComparator, ExcludeObjectKeyType>::value
4015  std::true_type,
4016  std::false_type >::type;
4017 
4018 template<typename ObjectType, typename KeyType>
4019 using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
4020 
4021 // type trait to check if object_t has an erase() member functions accepting KeyType
4022 template<typename BasicJsonType, typename KeyType>
4023 using has_erase_with_key_type = typename std::conditional <
4024  is_detected <
4026  typename BasicJsonType::object_t, KeyType >::value,
4027  std::true_type,
4028  std::false_type >::type;
4029 
4030 // a naive helper to check if a type is an ordered_map (exploits the fact that
4031 // ordered_map inherits capacity() from std::vector)
4032 template <typename T>
4034 {
4035  using one = char;
4036 
4037  struct two
4038  {
4039  char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4040  };
4041 
4042  template <typename C> static one test( decltype(&C::capacity) ) ;
4043  template <typename C> static two test(...);
4044 
4045  enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
4046 };
4047 
4048 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
4051 {
4052  return static_cast<T>(value);
4053 }
4054 
4056 T conditional_static_cast(U value)
4057 {
4058  return value;
4059 }
4060 
4061 template<typename... Types>
4063 
4064 template<typename... Types>
4066 
4067 template<typename... Types>
4069 
4070 // there's a disjunction trait in another PR; replace when merged
4071 template<typename... Types>
4072 using same_sign = std::integral_constant < bool,
4073  all_signed<Types...>::value || all_unsigned<Types...>::value >;
4074 
4075 template<typename OfType, typename T>
4076 using never_out_of_range = std::integral_constant < bool,
4077  (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
4078  || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
4079 
4080 template<typename OfType, typename T,
4081  bool OfTypeSigned = std::is_signed<OfType>::value,
4082  bool TSigned = std::is_signed<T>::value>
4084 
4085 template<typename OfType, typename T>
4086 struct value_in_range_of_impl2<OfType, T, false, false>
4087 {
4088  static constexpr bool test(T val)
4089  {
4090  using CommonType = typename std::common_type<OfType, T>::type;
4091  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4092  }
4093 };
4094 
4095 template<typename OfType, typename T>
4096 struct value_in_range_of_impl2<OfType, T, true, false>
4097 {
4098  static constexpr bool test(T val)
4099  {
4100  using CommonType = typename std::common_type<OfType, T>::type;
4101  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4102  }
4103 };
4104 
4105 template<typename OfType, typename T>
4106 struct value_in_range_of_impl2<OfType, T, false, true>
4107 {
4108  static constexpr bool test(T val)
4109  {
4110  using CommonType = typename std::common_type<OfType, T>::type;
4111  return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4112  }
4113 };
4114 
4115 template<typename OfType, typename T>
4116 struct value_in_range_of_impl2<OfType, T, true, true>
4117 {
4118  static constexpr bool test(T val)
4119  {
4120  using CommonType = typename std::common_type<OfType, T>::type;
4121  return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
4122  && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4123  }
4124 };
4125 
4126 template<typename OfType, typename T,
4127  bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
4130 
4131 template<typename OfType, typename T>
4132 struct value_in_range_of_impl1<OfType, T, false>
4133 {
4134  static constexpr bool test(T val)
4135  {
4137  }
4138 };
4139 
4140 template<typename OfType, typename T>
4141 struct value_in_range_of_impl1<OfType, T, true>
4142 {
4143  static constexpr bool test(T /*val*/)
4144  {
4145  return true;
4146  }
4147 };
4148 
4149 template<typename OfType, typename T>
4150 inline constexpr bool value_in_range_of(T val)
4151 {
4153 }
4154 
4155 template<bool Value>
4156 using bool_constant = std::integral_constant<bool, Value>;
4157 
4159 // is_c_string
4161 
4162 namespace impl
4163 {
4164 
4165 template<typename T>
4166 inline constexpr bool is_c_string()
4167 {
4168  using TUnExt = typename std::remove_extent<T>::type;
4169  using TUnCVExt = typename std::remove_cv<TUnExt>::type;
4170  using TUnPtr = typename std::remove_pointer<T>::type;
4171  using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
4172  return
4175 }
4176 
4177 } // namespace impl
4178 
4179 // checks whether T is a [cv] char */[cv] char[] C string
4180 template<typename T>
4181 struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
4182 
4183 template<typename T>
4185 
4187 // is_transparent
4189 
4190 namespace impl
4191 {
4192 
4193 template<typename T>
4194 inline constexpr bool is_transparent()
4195 {
4197 }
4198 
4199 } // namespace impl
4200 
4201 // checks whether T has a member named is_transparent
4202 template<typename T>
4203 struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
4204 
4206 
4207 } // namespace detail
4209 
4210 // #include <nlohmann/detail/string_concat.hpp>
4211 // __ _____ _____ _____
4212 // __| | __| | | | JSON for Modern C++
4213 // | | |__ | | | | | | version 3.11.3
4214 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4215 //
4216 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
4217 // SPDX-License-Identifier: MIT
4218 
4219 
4220 
4221 #include <cstring> // strlen
4222 #include <string> // string
4223 #include <utility> // forward
4224 
4225 // #include <nlohmann/detail/meta/cpp_future.hpp>
4226 
4227 // #include <nlohmann/detail/meta/detected.hpp>
4228 
4229 
4231 namespace detail
4232 {
4233 
4234 inline std::size_t concat_length()
4235 {
4236  return 0;
4237 }
4238 
4239 template<typename... Args>
4240 inline std::size_t concat_length(const char* cstr, const Args& ... rest);
4241 
4242 template<typename StringType, typename... Args>
4243 inline std::size_t concat_length(const StringType& str, const Args& ... rest);
4244 
4245 template<typename... Args>
4246 inline std::size_t concat_length(const char /*c*/, const Args& ... rest)
4247 {
4248  return 1 + concat_length(rest...);
4249 }
4250 
4251 template<typename... Args>
4252 inline std::size_t concat_length(const char* cstr, const Args& ... rest)
4253 {
4254  // cppcheck-suppress ignoredReturnValue
4255  return ::strlen(cstr) + concat_length(rest...);
4256 }
4257 
4258 template<typename StringType, typename... Args>
4259 inline std::size_t concat_length(const StringType& str, const Args& ... rest)
4260 {
4261  return str.size() + concat_length(rest...);
4262 }
4263 
4264 template<typename OutStringType>
4265 inline void concat_into(OutStringType& /*out*/)
4266 {}
4267 
4268 template<typename StringType, typename Arg>
4269 using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
4270 
4271 template<typename StringType, typename Arg>
4273 
4274 template<typename StringType, typename Arg>
4275 using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
4276 
4277 template<typename StringType, typename Arg>
4279 
4280 template<typename StringType, typename Arg>
4281 using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
4282 
4283 template<typename StringType, typename Arg>
4285 
4286 template<typename StringType, typename Arg>
4287 using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
4288 
4289 template<typename StringType, typename Arg>
4291 
4292 template < typename OutStringType, typename Arg, typename... Args,
4295 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
4296 
4297 template < typename OutStringType, typename Arg, typename... Args,
4301 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4302 
4303 template < typename OutStringType, typename Arg, typename... Args,
4308 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4309 
4310 template<typename OutStringType, typename Arg, typename... Args,
4312 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
4313 {
4314  out.append(std::forward<Arg>(arg));
4315  concat_into(out, std::forward<Args>(rest)...);
4316 }
4317 
4318 template < typename OutStringType, typename Arg, typename... Args,
4321 inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
4322 {
4323  out += std::forward<Arg>(arg);
4324  concat_into(out, std::forward<Args>(rest)...);
4325 }
4326 
4327 template < typename OutStringType, typename Arg, typename... Args,
4331 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4332 {
4333  out.append(arg.begin(), arg.end());
4334  concat_into(out, std::forward<Args>(rest)...);
4335 }
4336 
4337 template < typename OutStringType, typename Arg, typename... Args,
4342 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4343 {
4344  out.append(arg.data(), arg.size());
4345  concat_into(out, std::forward<Args>(rest)...);
4346 }
4347 
4348 template<typename OutStringType = std::string, typename... Args>
4349 inline OutStringType concat(Args && ... args)
4350 {
4351  OutStringType str;
4352  str.reserve(concat_length(args...));
4353  concat_into(str, std::forward<Args>(args)...);
4354  return str;
4355 }
4356 
4357 } // namespace detail
4359 
4360 
4362 namespace detail
4363 {
4364 
4366 // exceptions //
4368 
4371 class exception : public std::exception
4372 {
4373  public:
4375  const char* what() const noexcept override
4376  {
4377  return m.what();
4378  }
4379 
4381  const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4382 
4383  protected:
4385  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
4386 
4387  static std::string name(const std::string& ename, int id_)
4388  {
4389  return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
4390  }
4391 
4392  static std::string diagnostics(std::nullptr_t /*leaf_element*/)
4393  {
4394  return "";
4395  }
4396 
4397  template<typename BasicJsonType>
4398  static std::string diagnostics(const BasicJsonType* leaf_element)
4399  {
4400 #if JSON_DIAGNOSTICS
4401  std::vector<std::string> tokens;
4402  for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
4403  {
4404  switch (current->m_parent->type())
4405  {
4406  case value_t::array:
4407  {
4408  for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i)
4409  {
4410  if (&current->m_parent->m_data.m_value.array->operator[](i) == current)
4411  {
4412  tokens.emplace_back(std::to_string(i));
4413  break;
4414  }
4415  }
4416  break;
4417  }
4418 
4419  case value_t::object:
4420  {
4421  for (const auto& element : *current->m_parent->m_data.m_value.object)
4422  {
4423  if (&element.second == current)
4424  {
4425  tokens.emplace_back(element.first.c_str());
4426  break;
4427  }
4428  }
4429  break;
4430  }
4431 
4432  case value_t::null: // LCOV_EXCL_LINE
4433  case value_t::string: // LCOV_EXCL_LINE
4434  case value_t::boolean: // LCOV_EXCL_LINE
4435  case value_t::number_integer: // LCOV_EXCL_LINE
4436  case value_t::number_unsigned: // LCOV_EXCL_LINE
4437  case value_t::number_float: // LCOV_EXCL_LINE
4438  case value_t::binary: // LCOV_EXCL_LINE
4439  case value_t::discarded: // LCOV_EXCL_LINE
4440  default: // LCOV_EXCL_LINE
4441  break; // LCOV_EXCL_LINE
4442  }
4443  }
4444 
4445  if (tokens.empty())
4446  {
4447  return "";
4448  }
4449 
4450  auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4451  [](const std::string & a, const std::string & b)
4452  {
4453  return concat(a, '/', detail::escape(b));
4454  });
4455  return concat('(', str, ") ");
4456 #else
4457  static_cast<void>(leaf_element);
4458  return "";
4459 #endif
4460  }
4461 
4462  private:
4464  std::runtime_error m;
4465 };
4466 
4469 class parse_error : public exception
4470 {
4471  public:
4482  static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4483  {
4484  const std::string w = concat(exception::name("parse_error", id_), "parse error",
4485  position_string(pos), ": ", exception::diagnostics(context), what_arg);
4486  return {id_, pos.chars_read_total, w.c_str()};
4487  }
4488 
4490  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4491  {
4492  const std::string w = concat(exception::name("parse_error", id_), "parse error",
4493  (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4494  ": ", exception::diagnostics(context), what_arg);
4495  return {id_, byte_, w.c_str()};
4496  }
4497 
4507  const std::size_t byte;
4508 
4509  private:
4510  parse_error(int id_, std::size_t byte_, const char* what_arg)
4511  : exception(id_, what_arg), byte(byte_) {}
4512 
4513  static std::string position_string(const position_t& pos)
4514  {
4515  return concat(" at line ", std::to_string(pos.lines_read + 1),
4516  ", column ", std::to_string(pos.chars_read_current_line));
4517  }
4518 };
4519 
4523 {
4524  public:
4526  static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4527  {
4528  const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4529  return {id_, w.c_str()};
4530  }
4531 
4532  private:
4534  invalid_iterator(int id_, const char* what_arg)
4535  : exception(id_, what_arg) {}
4536 };
4537 
4540 class type_error : public exception
4541 {
4542  public:
4544  static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4545  {
4546  const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4547  return {id_, w.c_str()};
4548  }
4549 
4550  private:
4552  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4553 };
4554 
4557 class out_of_range : public exception
4558 {
4559  public:
4561  static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4562  {
4563  const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4564  return {id_, w.c_str()};
4565  }
4566 
4567  private:
4569  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4570 };
4571 
4574 class other_error : public exception
4575 {
4576  public:
4578  static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4579  {
4580  const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4581  return {id_, w.c_str()};
4582  }
4583 
4584  private:
4586  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4587 };
4588 
4589 } // namespace detail
4591 
4592 // #include <nlohmann/detail/macro_scope.hpp>
4593 
4594 // #include <nlohmann/detail/meta/cpp_future.hpp>
4595 
4596 // #include <nlohmann/detail/meta/identity_tag.hpp>
4597 // __ _____ _____ _____
4598 // __| | __| | | | JSON for Modern C++
4599 // | | |__ | | | | | | version 3.11.3
4600 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4601 //
4602 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
4603 // SPDX-License-Identifier: MIT
4604 
4605 
4606 
4607 // #include <nlohmann/detail/abi_macros.hpp>
4608 
4609 
4611 namespace detail
4612 {
4613 
4614 // dispatching helper struct
4615 template <class T> struct identity_tag {};
4616 
4617 } // namespace detail
4619 
4620 // #include <nlohmann/detail/meta/std_fs.hpp>
4621 // __ _____ _____ _____
4622 // __| | __| | | | JSON for Modern C++
4623 // | | |__ | | | | | | version 3.11.3
4624 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4625 //
4626 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
4627 // SPDX-License-Identifier: MIT
4628 
4629 
4630 
4631 // #include <nlohmann/detail/macro_scope.hpp>
4632 
4633 
4634 #if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4635 #include <experimental/filesystem>
4637 namespace detail
4638 {
4639 namespace std_fs = std::experimental::filesystem;
4640 } // namespace detail
4642 #elif JSON_HAS_FILESYSTEM
4643 #include <filesystem>
4645 namespace detail
4646 {
4647 namespace std_fs = std::filesystem;
4648 } // namespace detail
4650 #endif
4651 
4652 // #include <nlohmann/detail/meta/type_traits.hpp>
4653 
4654 // #include <nlohmann/detail/string_concat.hpp>
4655 
4656 // #include <nlohmann/detail/value_t.hpp>
4657 
4658 
4660 namespace detail
4661 {
4662 
4663 template<typename BasicJsonType>
4664 inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4665 {
4666  if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4667  {
4668  JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4669  }
4670  n = nullptr;
4671 }
4672 
4673 // overloads for basic_json template parameters
4674 template < typename BasicJsonType, typename ArithmeticType,
4677  int > = 0 >
4678 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4679 {
4680  switch (static_cast<value_t>(j))
4681  {
4683  {
4684  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4685  break;
4686  }
4688  {
4689  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4690  break;
4691  }
4692  case value_t::number_float:
4693  {
4694  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4695  break;
4696  }
4697 
4698  case value_t::null:
4699  case value_t::object:
4700  case value_t::array:
4701  case value_t::string:
4702  case value_t::boolean:
4703  case value_t::binary:
4704  case value_t::discarded:
4705  default:
4706  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4707  }
4708 }
4709 
4710 template<typename BasicJsonType>
4711 inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4712 {
4713  if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4714  {
4715  JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4716  }
4717  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4718 }
4719 
4720 template<typename BasicJsonType>
4721 inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4722 {
4723  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4724  {
4725  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4726  }
4727  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4728 }
4729 
4730 template <
4731  typename BasicJsonType, typename StringType,
4732  enable_if_t <
4736  && !is_json_ref<StringType>::value, int > = 0 >
4737 inline void from_json(const BasicJsonType& j, StringType& s)
4738 {
4739  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4740  {
4741  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4742  }
4743 
4744  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4745 }
4746 
4747 template<typename BasicJsonType>
4748 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4749 {
4750  get_arithmetic_value(j, val);
4751 }
4752 
4753 template<typename BasicJsonType>
4754 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4755 {
4756  get_arithmetic_value(j, val);
4757 }
4758 
4759 template<typename BasicJsonType>
4760 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4761 {
4762  get_arithmetic_value(j, val);
4763 }
4764 
4765 #if !JSON_DISABLE_ENUM_SERIALIZATION
4766 template<typename BasicJsonType, typename EnumType,
4768 inline void from_json(const BasicJsonType& j, EnumType& e)
4769 {
4770  typename std::underlying_type<EnumType>::type val;
4771  get_arithmetic_value(j, val);
4772  e = static_cast<EnumType>(val);
4773 }
4774 #endif // JSON_DISABLE_ENUM_SERIALIZATION
4775 
4776 // forward_list doesn't have an insert method
4777 template<typename BasicJsonType, typename T, typename Allocator,
4779 inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4780 {
4781  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4782  {
4783  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4784  }
4785  l.clear();
4786  std::transform(j.rbegin(), j.rend(),
4787  std::front_inserter(l), [](const BasicJsonType & i)
4788  {
4789  return i.template get<T>();
4790  });
4791 }
4792 
4793 // valarray doesn't have an insert method
4794 template<typename BasicJsonType, typename T,
4796 inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
4797 {
4798  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4799  {
4800  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4801  }
4802  l.resize(j.size());
4803  std::transform(j.begin(), j.end(), std::begin(l),
4804  [](const BasicJsonType & elem)
4805  {
4806  return elem.template get<T>();
4807  });
4808 }
4809 
4810 template<typename BasicJsonType, typename T, std::size_t N>
4811 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4812 -> decltype(j.template get<T>(), void())
4813 {
4814  for (std::size_t i = 0; i < N; ++i)
4815  {
4816  arr[i] = j.at(i).template get<T>();
4817  }
4818 }
4819 
4820 template<typename BasicJsonType>
4821 inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4822 {
4823  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4824 }
4825 
4826 template<typename BasicJsonType, typename T, std::size_t N>
4827 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4828  priority_tag<2> /*unused*/)
4829 -> decltype(j.template get<T>(), void())
4830 {
4831  for (std::size_t i = 0; i < N; ++i)
4832  {
4833  arr[i] = j.at(i).template get<T>();
4834  }
4835 }
4836 
4837 template<typename BasicJsonType, typename ConstructibleArrayType,
4838  enable_if_t<
4840  int> = 0>
4841 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4842 -> decltype(
4843  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4844  j.template get<typename ConstructibleArrayType::value_type>(),
4845  void())
4846 {
4847  using std::end;
4848 
4849  ConstructibleArrayType ret;
4850  ret.reserve(j.size());
4851  std::transform(j.begin(), j.end(),
4852  std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4853  {
4854  // get<BasicJsonType>() returns *this, this won't call a from_json
4855  // method when value_type is BasicJsonType
4856  return i.template get<typename ConstructibleArrayType::value_type>();
4857  });
4858  arr = std::move(ret);
4859 }
4860 
4861 template<typename BasicJsonType, typename ConstructibleArrayType,
4862  enable_if_t<
4864  int> = 0>
4865 inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4866  priority_tag<0> /*unused*/)
4867 {
4868  using std::end;
4869 
4870  ConstructibleArrayType ret;
4871  std::transform(
4872  j.begin(), j.end(), std::inserter(ret, end(ret)),
4873  [](const BasicJsonType & i)
4874  {
4875  // get<BasicJsonType>() returns *this, this won't call a from_json
4876  // method when value_type is BasicJsonType
4877  return i.template get<typename ConstructibleArrayType::value_type>();
4878  });
4879  arr = std::move(ret);
4880 }
4881 
4882 template < typename BasicJsonType, typename ConstructibleArrayType,
4883  enable_if_t <
4889  int > = 0 >
4890 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4891 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4892 j.template get<typename ConstructibleArrayType::value_type>(),
4893 void())
4894 {
4895  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4896  {
4897  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4898  }
4899 
4901 }
4902 
4903 template < typename BasicJsonType, typename T, std::size_t... Idx >
4904 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4905  identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4906 {
4907  return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4908 }
4909 
4910 template < typename BasicJsonType, typename T, std::size_t N >
4911 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4912 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4913 {
4914  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4915  {
4916  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4917  }
4918 
4919  return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4920 }
4921 
4922 template<typename BasicJsonType>
4923 inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4924 {
4925  if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4926  {
4927  JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4928  }
4929 
4930  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4931 }
4932 
4933 template<typename BasicJsonType, typename ConstructibleObjectType,
4935 inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4936 {
4937  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4938  {
4939  JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4940  }
4941 
4942  ConstructibleObjectType ret;
4943  const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4944  using value_type = typename ConstructibleObjectType::value_type;
4945  std::transform(
4946  inner_object->begin(), inner_object->end(),
4947  std::inserter(ret, ret.begin()),
4948  [](typename BasicJsonType::object_t::value_type const & p)
4949  {
4950  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4951  });
4952  obj = std::move(ret);
4953 }
4954 
4955 // overload for arithmetic types, not chosen for basic_json template arguments
4956 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4957 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4958 // an arithmetic type?
4959 template < typename BasicJsonType, typename ArithmeticType,
4960  enable_if_t <
4966  int > = 0 >
4967 inline void from_json(const BasicJsonType& j, ArithmeticType& val)
4968 {
4969  switch (static_cast<value_t>(j))
4970  {
4972  {
4973  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4974  break;
4975  }
4977  {
4978  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4979  break;
4980  }
4981  case value_t::number_float:
4982  {
4983  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4984  break;
4985  }
4986  case value_t::boolean:
4987  {
4988  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4989  break;
4990  }
4991 
4992  case value_t::null:
4993  case value_t::object:
4994  case value_t::array:
4995  case value_t::string:
4996  case value_t::binary:
4997  case value_t::discarded:
4998  default:
4999  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
5000  }
5001 }
5002 
5003 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
5004 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
5005 {
5006  return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
5007 }
5008 
5009 template < typename BasicJsonType, class A1, class A2 >
5010 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
5011 {
5012  return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
5013  std::forward<BasicJsonType>(j).at(1).template get<A2>()};
5014 }
5015 
5016 template<typename BasicJsonType, typename A1, typename A2>
5017 inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
5018 {
5019  p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
5020 }
5021 
5022 template<typename BasicJsonType, typename... Args>
5023 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
5024 {
5025  return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
5026 }
5027 
5028 template<typename BasicJsonType, typename... Args>
5029 inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
5030 {
5031  t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
5032 }
5033 
5034 template<typename BasicJsonType, typename TupleRelated>
5035 auto from_json(BasicJsonType&& j, TupleRelated&& t)
5036 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
5037 {
5038  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5039  {
5040  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5041  }
5042 
5043  return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
5044 }
5045 
5046 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
5047  typename = enable_if_t < !std::is_constructible <
5048  typename BasicJsonType::string_t, Key >::value >>
5049 inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
5050 {
5051  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5052  {
5053  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5054  }
5055  m.clear();
5056  for (const auto& p : j)
5057  {
5058  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5059  {
5060  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5061  }
5062  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5063  }
5064 }
5065 
5066 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
5067  typename = enable_if_t < !std::is_constructible <
5068  typename BasicJsonType::string_t, Key >::value >>
5069 inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
5070 {
5071  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5072  {
5073  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5074  }
5075  m.clear();
5076  for (const auto& p : j)
5077  {
5078  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5079  {
5080  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5081  }
5082  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5083  }
5084 }
5085 
5086 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5087 template<typename BasicJsonType>
5088 inline void from_json(const BasicJsonType& j, std_fs::path& p)
5089 {
5090  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
5091  {
5092  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
5093  }
5094  p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
5095 }
5096 #endif
5097 
5099 {
5100  template<typename BasicJsonType, typename T>
5101  auto operator()(const BasicJsonType& j, T&& val) const
5102  noexcept(noexcept(from_json(j, std::forward<T>(val))))
5103  -> decltype(from_json(j, std::forward<T>(val)))
5104  {
5105  return from_json(j, std::forward<T>(val));
5106  }
5107 };
5108 
5109 } // namespace detail
5110 
5111 #ifndef JSON_HAS_CPP_17
5112 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5116 {
5117 #endif
5118 JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
5120 #ifndef JSON_HAS_CPP_17
5121 } // namespace
5122 #endif
5123 
5125 
5126 // #include <nlohmann/detail/conversions/to_json.hpp>
5127 // __ _____ _____ _____
5128 // __| | __| | | | JSON for Modern C++
5129 // | | |__ | | | | | | version 3.11.3
5130 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5131 //
5132 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5133 // SPDX-License-Identifier: MIT
5134 
5135 
5136 
5137 #include <algorithm> // copy
5138 #include <iterator> // begin, end
5139 #include <string> // string
5140 #include <tuple> // tuple, get
5141 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
5142 #include <utility> // move, forward, declval, pair
5143 #include <valarray> // valarray
5144 #include <vector> // vector
5145 
5146 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5147 // __ _____ _____ _____
5148 // __| | __| | | | JSON for Modern C++
5149 // | | |__ | | | | | | version 3.11.3
5150 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5151 //
5152 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5153 // SPDX-License-Identifier: MIT
5154 
5155 
5156 
5157 #include <cstddef> // size_t
5158 #include <iterator> // input_iterator_tag
5159 #include <string> // string, to_string
5160 #include <tuple> // tuple_size, get, tuple_element
5161 #include <utility> // move
5162 
5163 #if JSON_HAS_RANGES
5164  #include <ranges> // enable_borrowed_range
5165 #endif
5166 
5167 // #include <nlohmann/detail/abi_macros.hpp>
5168 
5169 // #include <nlohmann/detail/meta/type_traits.hpp>
5170 
5171 // #include <nlohmann/detail/value_t.hpp>
5172 
5173 
5175 namespace detail
5176 {
5177 
5178 template<typename string_type>
5179 void int_to_string( string_type& target, std::size_t value )
5180 {
5181  // For ADL
5182  using std::to_string;
5183  target = to_string(value);
5184 }
5185 template<typename IteratorType> class iteration_proxy_value
5186 {
5187  public:
5188  using difference_type = std::ptrdiff_t;
5190  using pointer = value_type *;
5192  using iterator_category = std::input_iterator_tag;
5193  using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
5194 
5195  private:
5197  IteratorType anchor{};
5199  std::size_t array_index = 0;
5201  mutable std::size_t array_index_last = 0;
5206 
5207  public:
5208  explicit iteration_proxy_value() = default;
5209  explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
5210  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5211  && std::is_nothrow_default_constructible<string_type>::value)
5212  : anchor(std::move(it))
5213  , array_index(array_index_)
5214  {}
5215 
5216  iteration_proxy_value(iteration_proxy_value const&) = default;
5218  // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
5220  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5221  && std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
5223  noexcept(std::is_nothrow_move_assignable<IteratorType>::value
5224  && std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
5225  ~iteration_proxy_value() = default;
5226 
5228  const iteration_proxy_value& operator*() const
5229  {
5230  return *this;
5231  }
5232 
5235  {
5236  ++anchor;
5237  ++array_index;
5238 
5239  return *this;
5240  }
5241 
5242  iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
5243  {
5245  ++anchor;
5246  ++array_index;
5247  return tmp;
5248  }
5249 
5251  bool operator==(const iteration_proxy_value& o) const
5252  {
5253  return anchor == o.anchor;
5254  }
5255 
5257  bool operator!=(const iteration_proxy_value& o) const
5258  {
5259  return anchor != o.anchor;
5260  }
5261 
5263  const string_type& key() const
5264  {
5265  JSON_ASSERT(anchor.m_object != nullptr);
5266 
5267  switch (anchor.m_object->type())
5268  {
5269  // use integer array index as key
5270  case value_t::array:
5271  {
5273  {
5276  }
5277  return array_index_str;
5278  }
5279 
5280  // use key from the object
5281  case value_t::object:
5282  return anchor.key();
5283 
5284  // use an empty key for all primitive types
5285  case value_t::null:
5286  case value_t::string:
5287  case value_t::boolean:
5290  case value_t::number_float:
5291  case value_t::binary:
5292  case value_t::discarded:
5293  default:
5294  return empty_str;
5295  }
5296  }
5297 
5299  typename IteratorType::reference value() const
5300  {
5301  return anchor.value();
5302  }
5303 };
5304 
5306 template<typename IteratorType> class iteration_proxy
5307 {
5308  private:
5310  typename IteratorType::pointer container = nullptr;
5311 
5312  public:
5313  explicit iteration_proxy() = default;
5314 
5316  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
5317  : container(&cont) {}
5318 
5319  iteration_proxy(iteration_proxy const&) = default;
5320  iteration_proxy& operator=(iteration_proxy const&) = default;
5321  iteration_proxy(iteration_proxy&&) noexcept = default;
5322  iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
5323  ~iteration_proxy() = default;
5324 
5326  iteration_proxy_value<IteratorType> begin() const noexcept
5327  {
5329  }
5330 
5333  {
5335  }
5336 };
5337 
5338 // Structured Bindings Support
5339 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5340 // And see https://github.com/nlohmann/json/pull/1391
5341 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
5342 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
5343 {
5344  return i.key();
5345 }
5346 // Structured Bindings Support
5347 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5348 // And see https://github.com/nlohmann/json/pull/1391
5349 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
5350 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
5351 {
5352  return i.value();
5353 }
5354 
5355 } // namespace detail
5357 
5358 // The Addition to the STD Namespace is required to add
5359 // Structured Bindings Support to the iteration_proxy_value class
5360 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5361 // And see https://github.com/nlohmann/json/pull/1391
5362 namespace std
5363 {
5364 
5365 #if defined(__clang__)
5366  // Fix: https://github.com/nlohmann/json/issues/1401
5367  #pragma clang diagnostic push
5368  #pragma clang diagnostic ignored "-Wmismatched-tags"
5369 #endif
5370 template<typename IteratorType>
5371 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
5372  : public std::integral_constant<std::size_t, 2> {};
5373 
5374 template<std::size_t N, typename IteratorType>
5375 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)
5376 {
5377  public:
5378  using type = decltype(
5379  get<N>(std::declval <
5380  ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
5381 };
5382 #if defined(__clang__)
5383  #pragma clang diagnostic pop
5384 #endif
5385 
5386 } // namespace std
5387 
5388 #if JSON_HAS_RANGES
5389  template <typename IteratorType>
5390  inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
5391 #endif
5392 
5393 // #include <nlohmann/detail/macro_scope.hpp>
5394 
5395 // #include <nlohmann/detail/meta/cpp_future.hpp>
5396 
5397 // #include <nlohmann/detail/meta/std_fs.hpp>
5398 
5399 // #include <nlohmann/detail/meta/type_traits.hpp>
5400 
5401 // #include <nlohmann/detail/value_t.hpp>
5402 
5403 
5405 namespace detail
5406 {
5407 
5409 // constructors //
5411 
5412 /*
5413  * Note all external_constructor<>::construct functions need to call
5414  * j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an
5415  * allocated value (e.g., a string). See bug issue
5416  * https://github.com/nlohmann/json/issues/2865 for more information.
5417  */
5418 
5419 template<value_t> struct external_constructor;
5420 
5421 template<>
5423 {
5424  template<typename BasicJsonType>
5425  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
5426  {
5427  j.m_data.m_value.destroy(j.m_data.m_type);
5428  j.m_data.m_type = value_t::boolean;
5429  j.m_data.m_value = b;
5430  j.assert_invariant();
5431  }
5432 };
5433 
5434 template<>
5436 {
5437  template<typename BasicJsonType>
5438  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
5439  {
5440  j.m_data.m_value.destroy(j.m_data.m_type);
5441  j.m_data.m_type = value_t::string;
5442  j.m_data.m_value = s;
5443  j.assert_invariant();
5444  }
5445 
5446  template<typename BasicJsonType>
5447  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5448  {
5449  j.m_data.m_value.destroy(j.m_data.m_type);
5450  j.m_data.m_type = value_t::string;
5451  j.m_data.m_value = std::move(s);
5452  j.assert_invariant();
5453  }
5454 
5455  template < typename BasicJsonType, typename CompatibleStringType,
5457  int > = 0 >
5458  static void construct(BasicJsonType& j, const CompatibleStringType& str)
5459  {
5460  j.m_data.m_value.destroy(j.m_data.m_type);
5461  j.m_data.m_type = value_t::string;
5462  j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
5463  j.assert_invariant();
5464  }
5465 };
5466 
5467 template<>
5469 {
5470  template<typename BasicJsonType>
5471  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
5472  {
5473  j.m_data.m_value.destroy(j.m_data.m_type);
5474  j.m_data.m_type = value_t::binary;
5475  j.m_data.m_value = typename BasicJsonType::binary_t(b);
5476  j.assert_invariant();
5477  }
5478 
5479  template<typename BasicJsonType>
5480  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
5481  {
5482  j.m_data.m_value.destroy(j.m_data.m_type);
5483  j.m_data.m_type = value_t::binary;
5484  j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
5485  j.assert_invariant();
5486  }
5487 };
5488 
5489 template<>
5491 {
5492  template<typename BasicJsonType>
5493  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5494  {
5495  j.m_data.m_value.destroy(j.m_data.m_type);
5496  j.m_data.m_type = value_t::number_float;
5497  j.m_data.m_value = val;
5498  j.assert_invariant();
5499  }
5500 };
5501 
5502 template<>
5504 {
5505  template<typename BasicJsonType>
5506  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5507  {
5508  j.m_data.m_value.destroy(j.m_data.m_type);
5509  j.m_data.m_type = value_t::number_unsigned;
5510  j.m_data.m_value = val;
5511  j.assert_invariant();
5512  }
5513 };
5514 
5515 template<>
5517 {
5518  template<typename BasicJsonType>
5519  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5520  {
5521  j.m_data.m_value.destroy(j.m_data.m_type);
5522  j.m_data.m_type = value_t::number_integer;
5523  j.m_data.m_value = val;
5524  j.assert_invariant();
5525  }
5526 };
5527 
5528 template<>
5530 {
5531  template<typename BasicJsonType>
5532  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5533  {
5534  j.m_data.m_value.destroy(j.m_data.m_type);
5535  j.m_data.m_type = value_t::array;
5536  j.m_data.m_value = arr;
5537  j.set_parents();
5538  j.assert_invariant();
5539  }
5540 
5541  template<typename BasicJsonType>
5542  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5543  {
5544  j.m_data.m_value.destroy(j.m_data.m_type);
5545  j.m_data.m_type = value_t::array;
5546  j.m_data.m_value = std::move(arr);
5547  j.set_parents();
5548  j.assert_invariant();
5549  }
5550 
5551  template < typename BasicJsonType, typename CompatibleArrayType,
5553  int > = 0 >
5554  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5555  {
5556  using std::begin;
5557  using std::end;
5558 
5559  j.m_data.m_value.destroy(j.m_data.m_type);
5560  j.m_data.m_type = value_t::array;
5561  j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5562  j.set_parents();
5563  j.assert_invariant();
5564  }
5565 
5566  template<typename BasicJsonType>
5567  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5568  {
5569  j.m_data.m_value.destroy(j.m_data.m_type);
5570  j.m_data.m_type = value_t::array;
5571  j.m_data.m_value = value_t::array;
5572  j.m_data.m_value.array->reserve(arr.size());
5573  for (const bool x : arr)
5574  {
5575  j.m_data.m_value.array->push_back(x);
5576  j.set_parent(j.m_data.m_value.array->back());
5577  }
5578  j.assert_invariant();
5579  }
5580 
5581  template<typename BasicJsonType, typename T,
5583  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5584  {
5585  j.m_data.m_value.destroy(j.m_data.m_type);
5586  j.m_data.m_type = value_t::array;
5587  j.m_data.m_value = value_t::array;
5588  j.m_data.m_value.array->resize(arr.size());
5589  if (arr.size() > 0)
5590  {
5591  std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());
5592  }
5593  j.set_parents();
5594  j.assert_invariant();
5595  }
5596 };
5597 
5598 template<>
5600 {
5601  template<typename BasicJsonType>
5602  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5603  {
5604  j.m_data.m_value.destroy(j.m_data.m_type);
5605  j.m_data.m_type = value_t::object;
5606  j.m_data.m_value = obj;
5607  j.set_parents();
5608  j.assert_invariant();
5609  }
5610 
5611  template<typename BasicJsonType>
5612  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5613  {
5614  j.m_data.m_value.destroy(j.m_data.m_type);
5615  j.m_data.m_type = value_t::object;
5616  j.m_data.m_value = std::move(obj);
5617  j.set_parents();
5618  j.assert_invariant();
5619  }
5620 
5621  template < typename BasicJsonType, typename CompatibleObjectType,
5623  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5624  {
5625  using std::begin;
5626  using std::end;
5627 
5628  j.m_data.m_value.destroy(j.m_data.m_type);
5629  j.m_data.m_type = value_t::object;
5630  j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5631  j.set_parents();
5632  j.assert_invariant();
5633  }
5634 };
5635 
5637 // to_json //
5639 
5640 template<typename BasicJsonType, typename T,
5642 inline void to_json(BasicJsonType& j, T b) noexcept
5643 {
5645 }
5646 
5647 template < typename BasicJsonType, typename BoolRef,
5648  enable_if_t <
5649  ((std::is_same<std::vector<bool>::reference, BoolRef>::value
5650  && !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
5651  || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
5652  && !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
5653  typename BasicJsonType::boolean_t >::value))
5655 inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
5656 {
5657  external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
5658 }
5659 
5660 template<typename BasicJsonType, typename CompatibleString,
5662 inline void to_json(BasicJsonType& j, const CompatibleString& s)
5663 {
5665 }
5666 
5667 template<typename BasicJsonType>
5668 inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5669 {
5671 }
5672 
5673 template<typename BasicJsonType, typename FloatType,
5675 inline void to_json(BasicJsonType& j, FloatType val) noexcept
5676 {
5677  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5678 }
5679 
5680 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5682 inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5683 {
5684  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5685 }
5686 
5687 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5689 inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5690 {
5691  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5692 }
5693 
5694 #if !JSON_DISABLE_ENUM_SERIALIZATION
5695 template<typename BasicJsonType, typename EnumType,
5697 inline void to_json(BasicJsonType& j, EnumType e) noexcept
5698 {
5699  using underlying_type = typename std::underlying_type<EnumType>::type;
5700  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5701 }
5702 #endif // JSON_DISABLE_ENUM_SERIALIZATION
5703 
5704 template<typename BasicJsonType>
5705 inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
5706 {
5708 }
5709 
5710 template < typename BasicJsonType, typename CompatibleArrayType,
5711  enable_if_t < is_compatible_array_type<BasicJsonType,
5712  CompatibleArrayType>::value&&
5717  int > = 0 >
5718 inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5719 {
5721 }
5722 
5723 template<typename BasicJsonType>
5724 inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5725 {
5727 }
5728 
5729 template<typename BasicJsonType, typename T,
5731 inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5732 {
5734 }
5735 
5736 template<typename BasicJsonType>
5737 inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5738 {
5740 }
5741 
5742 template < typename BasicJsonType, typename CompatibleObjectType,
5744 inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5745 {
5747 }
5748 
5749 template<typename BasicJsonType>
5750 inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5751 {
5753 }
5754 
5755 template <
5756  typename BasicJsonType, typename T, std::size_t N,
5757  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5758  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5759  int > = 0 >
5760 inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5761 {
5763 }
5764 
5766 inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5767 {
5768  j = { p.first, p.second };
5769 }
5770 
5771 // for https://github.com/nlohmann/json/pull/1134
5772 template<typename BasicJsonType, typename T,
5773  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
5774 inline void to_json(BasicJsonType& j, const T& b)
5775 {
5776  j = { {b.key(), b.value()} };
5777 }
5778 
5779 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5780 inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5781 {
5782  j = { std::get<Idx>(t)... };
5783 }
5784 
5786 inline void to_json(BasicJsonType& j, const T& t)
5787 {
5789 }
5790 
5791 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5792 template<typename BasicJsonType>
5793 inline void to_json(BasicJsonType& j, const std_fs::path& p)
5794 {
5795  j = p.string();
5796 }
5797 #endif
5798 
5800 {
5801  template<typename BasicJsonType, typename T>
5802  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5803  -> decltype(to_json(j, std::forward<T>(val)), void())
5804  {
5805  return to_json(j, std::forward<T>(val));
5806  }
5807 };
5808 } // namespace detail
5809 
5810 #ifndef JSON_HAS_CPP_17
5811 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5815 {
5816 #endif
5817 JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
5819 #ifndef JSON_HAS_CPP_17
5820 } // namespace
5821 #endif
5822 
5824 
5825 // #include <nlohmann/detail/meta/identity_tag.hpp>
5826 
5827 
5829 
5831 template<typename ValueType, typename>
5832 struct adl_serializer
5833 {
5836  template<typename BasicJsonType, typename TargetType = ValueType>
5837  static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5838  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5839  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5840  {
5841  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5842  }
5843 
5846  template<typename BasicJsonType, typename TargetType = ValueType>
5847  static auto from_json(BasicJsonType && j) noexcept(
5848  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5849  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5850  {
5851  return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5852  }
5853 
5856  template<typename BasicJsonType, typename TargetType = ValueType>
5857  static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5858  noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5859  -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5860  {
5861  ::nlohmann::to_json(j, std::forward<TargetType>(val));
5862  }
5863 };
5864 
5866 
5867 // #include <nlohmann/byte_container_with_subtype.hpp>
5868 // __ _____ _____ _____
5869 // __| | __| | | | JSON for Modern C++
5870 // | | |__ | | | | | | version 3.11.3
5871 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5872 //
5873 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5874 // SPDX-License-Identifier: MIT
5875 
5876 
5877 
5878 #include <cstdint> // uint8_t, uint64_t
5879 #include <tuple> // tie
5880 #include <utility> // move
5881 
5882 // #include <nlohmann/detail/abi_macros.hpp>
5883 
5884 
5886 
5889 template<typename BinaryType>
5890 class byte_container_with_subtype : public BinaryType
5891 {
5892  public:
5893  using container_type = BinaryType;
5894  using subtype_type = std::uint64_t;
5895 
5898  : container_type()
5899  {}
5900 
5903  : container_type(b)
5904  {}
5905 
5907  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5908  : container_type(std::move(b))
5909  {}
5910 
5912  byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5913  : container_type(b)
5914  , m_subtype(subtype_)
5915  , m_has_subtype(true)
5916  {}
5917 
5919  byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5920  : container_type(std::move(b))
5921  , m_subtype(subtype_)
5922  , m_has_subtype(true)
5923  {}
5924 
5926  {
5927  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5928  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5929  }
5930 
5932  {
5933  return !(rhs == *this);
5934  }
5935 
5938  void set_subtype(subtype_type subtype_) noexcept
5939  {
5940  m_subtype = subtype_;
5941  m_has_subtype = true;
5942  }
5943 
5946  constexpr subtype_type subtype() const noexcept
5947  {
5948  return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5949  }
5950 
5953  constexpr bool has_subtype() const noexcept
5954  {
5955  return m_has_subtype;
5956  }
5957 
5960  void clear_subtype() noexcept
5961  {
5962  m_subtype = 0;
5963  m_has_subtype = false;
5964  }
5965 
5966  private:
5968  bool m_has_subtype = false;
5969 };
5970 
5972 
5973 // #include <nlohmann/detail/conversions/from_json.hpp>
5974 
5975 // #include <nlohmann/detail/conversions/to_json.hpp>
5976 
5977 // #include <nlohmann/detail/exceptions.hpp>
5978 
5979 // #include <nlohmann/detail/hash.hpp>
5980 // __ _____ _____ _____
5981 // __| | __| | | | JSON for Modern C++
5982 // | | |__ | | | | | | version 3.11.3
5983 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5984 //
5985 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5986 // SPDX-License-Identifier: MIT
5987 
5988 
5989 
5990 #include <cstdint> // uint8_t
5991 #include <cstddef> // size_t
5992 #include <functional> // hash
5993 
5994 // #include <nlohmann/detail/abi_macros.hpp>
5995 
5996 // #include <nlohmann/detail/value_t.hpp>
5997 
5998 
6000 namespace detail
6001 {
6002 
6003 // boost::hash_combine
6004 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
6005 {
6006  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
6007  return seed;
6008 }
6009 
6021 template<typename BasicJsonType>
6022 std::size_t hash(const BasicJsonType& j)
6023 {
6024  using string_t = typename BasicJsonType::string_t;
6025  using number_integer_t = typename BasicJsonType::number_integer_t;
6026  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6027  using number_float_t = typename BasicJsonType::number_float_t;
6028 
6029  const auto type = static_cast<std::size_t>(j.type());
6030  switch (j.type())
6031  {
6032  case BasicJsonType::value_t::null:
6033  case BasicJsonType::value_t::discarded:
6034  {
6035  return combine(type, 0);
6036  }
6037 
6038  case BasicJsonType::value_t::object:
6039  {
6040  auto seed = combine(type, j.size());
6041  for (const auto& element : j.items())
6042  {
6043  const auto h = std::hash<string_t> {}(element.key());
6044  seed = combine(seed, h);
6045  seed = combine(seed, hash(element.value()));
6046  }
6047  return seed;
6048  }
6049 
6050  case BasicJsonType::value_t::array:
6051  {
6052  auto seed = combine(type, j.size());
6053  for (const auto& element : j)
6054  {
6055  seed = combine(seed, hash(element));
6056  }
6057  return seed;
6058  }
6059 
6060  case BasicJsonType::value_t::string:
6061  {
6062  const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
6063  return combine(type, h);
6064  }
6065 
6066  case BasicJsonType::value_t::boolean:
6067  {
6068  const auto h = std::hash<bool> {}(j.template get<bool>());
6069  return combine(type, h);
6070  }
6071 
6072  case BasicJsonType::value_t::number_integer:
6073  {
6074  const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
6075  return combine(type, h);
6076  }
6077 
6078  case BasicJsonType::value_t::number_unsigned:
6079  {
6080  const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
6081  return combine(type, h);
6082  }
6083 
6084  case BasicJsonType::value_t::number_float:
6085  {
6086  const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
6087  return combine(type, h);
6088  }
6089 
6091  {
6092  auto seed = combine(type, j.get_binary().size());
6093  const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
6094  seed = combine(seed, h);
6095  seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
6096  for (const auto byte : j.get_binary())
6097  {
6098  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
6099  }
6100  return seed;
6101  }
6102 
6103  default: // LCOV_EXCL_LINE
6104  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
6105  return 0; // LCOV_EXCL_LINE
6106  }
6107 }
6108 
6109 } // namespace detail
6111 
6112 // #include <nlohmann/detail/input/binary_reader.hpp>
6113 // __ _____ _____ _____
6114 // __| | __| | | | JSON for Modern C++
6115 // | | |__ | | | | | | version 3.11.3
6116 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6117 //
6118 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
6119 // SPDX-License-Identifier: MIT
6120 
6121 
6122 
6123 #include <algorithm> // generate_n
6124 #include <array> // array
6125 #include <cmath> // ldexp
6126 #include <cstddef> // size_t
6127 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6128 #include <cstdio> // snprintf
6129 #include <cstring> // memcpy
6130 #include <iterator> // back_inserter
6131 #include <limits> // numeric_limits
6132 #include <string> // char_traits, string
6133 #include <utility> // make_pair, move
6134 #include <vector> // vector
6135 
6136 // #include <nlohmann/detail/exceptions.hpp>
6137 
6138 // #include <nlohmann/detail/input/input_adapters.hpp>
6139 // __ _____ _____ _____
6140 // __| | __| | | | JSON for Modern C++
6141 // | | |__ | | | | | | version 3.11.3
6142 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6143 //
6144 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
6145 // SPDX-License-Identifier: MIT
6146 
6147 
6148 
6149 #include <array> // array
6150 #include <cstddef> // size_t
6151 #include <cstring> // strlen
6152 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
6153 #include <memory> // shared_ptr, make_shared, addressof
6154 #include <numeric> // accumulate
6155 #include <string> // string, char_traits
6156 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
6157 #include <utility> // pair, declval
6158 
6159 #ifndef JSON_NO_IO
6160  #include <cstdio> // FILE *
6161  #include <istream> // istream
6162 #endif // JSON_NO_IO
6163 
6164 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
6165 
6166 // #include <nlohmann/detail/macro_scope.hpp>
6167 
6168 // #include <nlohmann/detail/meta/type_traits.hpp>
6169 
6170 
6172 namespace detail
6173 {
6174 
6177 
6179 // input adapters //
6181 
6182 #ifndef JSON_NO_IO
6183 
6188 {
6189  public:
6190  using char_type = char;
6191 
6193  explicit file_input_adapter(std::FILE* f) noexcept
6194  : m_file(f)
6195  {
6196  JSON_ASSERT(m_file != nullptr);
6197  }
6198 
6199  // make class move-only
6200  file_input_adapter(const file_input_adapter&) = delete;
6201  file_input_adapter(file_input_adapter&&) noexcept = default;
6202  file_input_adapter& operator=(const file_input_adapter&) = delete;
6203  file_input_adapter& operator=(file_input_adapter&&) = delete;
6204  ~file_input_adapter() = default;
6205 
6206  std::char_traits<char>::int_type get_character() noexcept
6207  {
6208  return std::fgetc(m_file);
6209  }
6210 
6211  private:
6213  std::FILE* m_file;
6214 };
6215 
6226 {
6227  public:
6228  using char_type = char;
6229 
6231  {
6232  // clear stream flags; we use underlying streambuf I/O, do not
6233  // maintain ifstream flags, except eof
6234  if (is != nullptr)
6235  {
6236  is->clear(is->rdstate() & std::ios::eofbit);
6237  }
6238  }
6239 
6240  explicit input_stream_adapter(std::istream& i)
6241  : is(&i), sb(i.rdbuf())
6242  {}
6243 
6244  // delete because of pointer members
6245  input_stream_adapter(const input_stream_adapter&) = delete;
6248 
6250  : is(rhs.is), sb(rhs.sb)
6251  {
6252  rhs.is = nullptr;
6253  rhs.sb = nullptr;
6254  }
6255 
6256  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
6257  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
6258  // end up as the same value, e.g. 0xFFFFFFFF.
6259  std::char_traits<char>::int_type get_character()
6260  {
6261  auto res = sb->sbumpc();
6262  // set eof manually, as we don't use the istream interface.
6264  {
6265  is->clear(is->rdstate() | std::ios::eofbit);
6266  }
6267  return res;
6268  }
6269 
6270  private:
6272  std::istream* is = nullptr;
6273  std::streambuf* sb = nullptr;
6274 };
6275 #endif // JSON_NO_IO
6276 
6277 // General-purpose iterator-based adapter. It might not be as fast as
6278 // theoretically possible for some containers, but it is extremely versatile.
6279 template<typename IteratorType>
6281 {
6282  public:
6283  using char_type = typename std::iterator_traits<IteratorType>::value_type;
6284 
6285  iterator_input_adapter(IteratorType first, IteratorType last)
6286  : current(std::move(first)), end(std::move(last))
6287  {}
6288 
6290  {
6291  if (JSON_HEDLEY_LIKELY(current != end))
6292  {
6294  std::advance(current, 1);
6295  return result;
6296  }
6297 
6298  return char_traits<char_type>::eof();
6299  }
6300 
6301  private:
6302  IteratorType current;
6303  IteratorType end;
6304 
6305  template<typename BaseInputAdapter, size_t T>
6307 
6308  bool empty() const
6309  {
6310  return current == end;
6311  }
6312 };
6313 
6314 template<typename BaseInputAdapter, size_t T>
6316 
6317 template<typename BaseInputAdapter>
6318 struct wide_string_input_helper<BaseInputAdapter, 4>
6319 {
6320  // UTF-32
6321  static void fill_buffer(BaseInputAdapter& input,
6322  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6323  size_t& utf8_bytes_index,
6324  size_t& utf8_bytes_filled)
6325  {
6326  utf8_bytes_index = 0;
6327 
6328  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6329  {
6330  utf8_bytes[0] = std::char_traits<char>::eof();
6331  utf8_bytes_filled = 1;
6332  }
6333  else
6334  {
6335  // get the current character
6336  const auto wc = input.get_character();
6337 
6338  // UTF-32 to UTF-8 encoding
6339  if (wc < 0x80)
6340  {
6341  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6342  utf8_bytes_filled = 1;
6343  }
6344  else if (wc <= 0x7FF)
6345  {
6346  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
6347  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6348  utf8_bytes_filled = 2;
6349  }
6350  else if (wc <= 0xFFFF)
6351  {
6352  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
6353  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6354  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6355  utf8_bytes_filled = 3;
6356  }
6357  else if (wc <= 0x10FFFF)
6358  {
6359  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
6360  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
6361  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6362  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6363  utf8_bytes_filled = 4;
6364  }
6365  else
6366  {
6367  // unknown character
6368  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6369  utf8_bytes_filled = 1;
6370  }
6371  }
6372  }
6373 };
6374 
6375 template<typename BaseInputAdapter>
6376 struct wide_string_input_helper<BaseInputAdapter, 2>
6377 {
6378  // UTF-16
6379  static void fill_buffer(BaseInputAdapter& input,
6380  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6381  size_t& utf8_bytes_index,
6382  size_t& utf8_bytes_filled)
6383  {
6384  utf8_bytes_index = 0;
6385 
6386  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6387  {
6388  utf8_bytes[0] = std::char_traits<char>::eof();
6389  utf8_bytes_filled = 1;
6390  }
6391  else
6392  {
6393  // get the current character
6394  const auto wc = input.get_character();
6395 
6396  // UTF-16 to UTF-8 encoding
6397  if (wc < 0x80)
6398  {
6399  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6400  utf8_bytes_filled = 1;
6401  }
6402  else if (wc <= 0x7FF)
6403  {
6404  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
6405  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6406  utf8_bytes_filled = 2;
6407  }
6408  else if (0xD800 > wc || wc >= 0xE000)
6409  {
6410  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
6411  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6412  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6413  utf8_bytes_filled = 3;
6414  }
6415  else
6416  {
6417  if (JSON_HEDLEY_UNLIKELY(!input.empty()))
6418  {
6419  const auto wc2 = static_cast<unsigned int>(input.get_character());
6420  const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
6421  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
6422  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
6423  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
6424  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
6425  utf8_bytes_filled = 4;
6426  }
6427  else
6428  {
6429  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6430  utf8_bytes_filled = 1;
6431  }
6432  }
6433  }
6434  }
6435 };
6436 
6437 // Wraps another input adapter to convert wide character types into individual bytes.
6438 template<typename BaseInputAdapter, typename WideCharType>
6440 {
6441  public:
6442  using char_type = char;
6443 
6444  wide_string_input_adapter(BaseInputAdapter base)
6445  : base_adapter(base) {}
6446 
6447  typename std::char_traits<char>::int_type get_character() noexcept
6448  {
6449  // check if buffer needs to be filled
6451  {
6452  fill_buffer<sizeof(WideCharType)>();
6453 
6456  }
6457 
6458  // use buffer
6461  return utf8_bytes[utf8_bytes_index++];
6462  }
6463 
6464  private:
6465  BaseInputAdapter base_adapter;
6466 
6467  template<size_t T>
6469  {
6471  }
6472 
6474  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
6475 
6477  std::size_t utf8_bytes_index = 0;
6479  std::size_t utf8_bytes_filled = 0;
6480 };
6481 
6482 template<typename IteratorType, typename Enable = void>
6484 {
6485  using iterator_type = IteratorType;
6486  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6488 
6489  static adapter_type create(IteratorType first, IteratorType last)
6490  {
6491  return adapter_type(std::move(first), std::move(last));
6492  }
6493 };
6494 
6495 template<typename T>
6497 {
6498  using value_type = typename std::iterator_traits<T>::value_type;
6499  enum
6500  {
6501  value = sizeof(value_type) > 1
6502  };
6503 };
6504 
6505 template<typename IteratorType>
6507 {
6508  using iterator_type = IteratorType;
6509  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6512 
6513  static adapter_type create(IteratorType first, IteratorType last)
6514  {
6515  return adapter_type(base_adapter_type(std::move(first), std::move(last)));
6516  }
6517 };
6518 
6519 // General purpose iterator-based input
6520 template<typename IteratorType>
6521 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
6522 {
6523  using factory_type = iterator_input_adapter_factory<IteratorType>;
6524  return factory_type::create(first, last);
6525 }
6526 
6527 // Convenience shorthand from container to iterator
6528 // Enables ADL on begin(container) and end(container)
6529 // Encloses the using declarations in namespace for not to leak them to outside scope
6530 
6531 namespace container_input_adapter_factory_impl
6532 {
6533 
6534 using std::begin;
6535 using std::end;
6536 
6537 template<typename ContainerType, typename Enable = void>
6539 
6540 template<typename ContainerType>
6541 struct container_input_adapter_factory< ContainerType,
6542  void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6543  {
6544  using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6545 
6546  static adapter_type create(const ContainerType& container)
6547 {
6548  return input_adapter(begin(container), end(container));
6549 }
6550  };
6551 
6552 } // namespace container_input_adapter_factory_impl
6553 
6554 template<typename ContainerType>
6556 {
6558 }
6559 
6560 #ifndef JSON_NO_IO
6561 // Special cases with fast paths
6562 inline file_input_adapter input_adapter(std::FILE* file)
6563 {
6564  return file_input_adapter(file);
6565 }
6566 
6567 inline input_stream_adapter input_adapter(std::istream& stream)
6568 {
6569  return input_stream_adapter(stream);
6570 }
6571 
6572 inline input_stream_adapter input_adapter(std::istream&& stream)
6573 {
6574  return input_stream_adapter(stream);
6575 }
6576 #endif // JSON_NO_IO
6577 
6578 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6579 
6580 // Null-delimited strings, and the like.
6581 template < typename CharT,
6582  typename std::enable_if <
6585  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
6586  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6587  int >::type = 0 >
6589 {
6590  auto length = std::strlen(reinterpret_cast<const char*>(b));
6591  const auto* ptr = reinterpret_cast<const char*>(b);
6592  return input_adapter(ptr, ptr + length);
6593 }
6594 
6595 template<typename T, std::size_t N>
6596 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)
6597 {
6598  return input_adapter(array, array + N);
6599 }
6600 
6601 // This class only handles inputs of input_buffer_adapter type.
6602 // It's required so that expressions like {ptr, len} can be implicitly cast
6603 // to the correct adapter.
6605 {
6606  public:
6607  template < typename CharT,
6608  typename std::enable_if <
6610  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
6611  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6612  int >::type = 0 >
6613  span_input_adapter(CharT b, std::size_t l)
6614  : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
6615 
6616  template<class IteratorType,
6617  typename std::enable_if<
6618  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
6619  int>::type = 0>
6620  span_input_adapter(IteratorType first, IteratorType last)
6621  : ia(input_adapter(first, last)) {}
6622 
6624  {
6625  return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6626  }
6627 
6628  private:
6630 };
6631 
6632 } // namespace detail
6634 
6635 // #include <nlohmann/detail/input/json_sax.hpp>
6636 // __ _____ _____ _____
6637 // __| | __| | | | JSON for Modern C++
6638 // | | |__ | | | | | | version 3.11.3
6639 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6640 //
6641 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
6642 // SPDX-License-Identifier: MIT
6643 
6644 
6645 
6646 #include <cstddef>
6647 #include <string> // string
6648 #include <utility> // move
6649 #include <vector> // vector
6650 
6651 // #include <nlohmann/detail/exceptions.hpp>
6652 
6653 // #include <nlohmann/detail/macro_scope.hpp>
6654 
6655 // #include <nlohmann/detail/string_concat.hpp>
6656 
6657 
6659 
6668 template<typename BasicJsonType>
6669 struct json_sax
6670 {
6671  using number_integer_t = typename BasicJsonType::number_integer_t;
6672  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6673  using number_float_t = typename BasicJsonType::number_float_t;
6674  using string_t = typename BasicJsonType::string_t;
6675  using binary_t = typename BasicJsonType::binary_t;
6676 
6681  virtual bool null() = 0;
6682 
6688  virtual bool boolean(bool val) = 0;
6689 
6695  virtual bool number_integer(number_integer_t val) = 0;
6696 
6702  virtual bool number_unsigned(number_unsigned_t val) = 0;
6703 
6710  virtual bool number_float(number_float_t val, const string_t& s) = 0;
6711 
6718  virtual bool string(string_t& val) = 0;
6719 
6726  virtual bool binary(binary_t& val) = 0;
6727 
6734  virtual bool start_object(std::size_t elements) = 0;
6735 
6742  virtual bool key(string_t& val) = 0;
6743 
6748  virtual bool end_object() = 0;
6749 
6756  virtual bool start_array(std::size_t elements) = 0;
6757 
6762  virtual bool end_array() = 0;
6763 
6771  virtual bool parse_error(std::size_t position,
6772  const std::string& last_token,
6773  const detail::exception& ex) = 0;
6774 
6775  json_sax() = default;
6776  json_sax(const json_sax&) = default;
6777  json_sax(json_sax&&) noexcept = default;
6778  json_sax& operator=(const json_sax&) = default;
6779  json_sax& operator=(json_sax&&) noexcept = default;
6780  virtual ~json_sax() = default;
6781 };
6782 
6783 namespace detail
6784 {
6798 template<typename BasicJsonType>
6800 {
6801  public:
6802  using number_integer_t = typename BasicJsonType::number_integer_t;
6803  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6804  using number_float_t = typename BasicJsonType::number_float_t;
6805  using string_t = typename BasicJsonType::string_t;
6806  using binary_t = typename BasicJsonType::binary_t;
6807 
6813  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6814  : root(r), allow_exceptions(allow_exceptions_)
6815  {}
6816 
6817  // make class move-only
6818  json_sax_dom_parser(const json_sax_dom_parser&) = delete;
6819  json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6821  json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6822  ~json_sax_dom_parser() = default;
6823 
6824  bool null()
6825  {
6826  handle_value(nullptr);
6827  return true;
6828  }
6829 
6830  bool boolean(bool val)
6831  {
6832  handle_value(val);
6833  return true;
6834  }
6835 
6837  {
6838  handle_value(val);
6839  return true;
6840  }
6841 
6843  {
6844  handle_value(val);
6845  return true;
6846  }
6847 
6848  bool number_float(number_float_t val, const string_t& /*unused*/)
6849  {
6850  handle_value(val);
6851  return true;
6852  }
6853 
6854  bool string(string_t& val)
6855  {
6856  handle_value(val);
6857  return true;
6858  }
6859 
6860  bool binary(binary_t& val)
6861  {
6862  handle_value(std::move(val));
6863  return true;
6864  }
6865 
6866  bool start_object(std::size_t len)
6867  {
6868  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6869 
6870  if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6871  {
6872  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6873  }
6874 
6875  return true;
6876  }
6877 
6878  bool key(string_t& val)
6879  {
6880  JSON_ASSERT(!ref_stack.empty());
6881  JSON_ASSERT(ref_stack.back()->is_object());
6882 
6883  // add null at given key and store the reference for later
6884  object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val));
6885  return true;
6886  }
6887 
6888  bool end_object()
6889  {
6890  JSON_ASSERT(!ref_stack.empty());
6891  JSON_ASSERT(ref_stack.back()->is_object());
6892 
6893  ref_stack.back()->set_parents();
6894  ref_stack.pop_back();
6895  return true;
6896  }
6897 
6898  bool start_array(std::size_t len)
6899  {
6900  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6901 
6902  if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6903  {
6904  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6905  }
6906 
6907  return true;
6908  }
6909 
6910  bool end_array()
6911  {
6912  JSON_ASSERT(!ref_stack.empty());
6913  JSON_ASSERT(ref_stack.back()->is_array());
6914 
6915  ref_stack.back()->set_parents();
6916  ref_stack.pop_back();
6917  return true;
6918  }
6919 
6920  template<class Exception>
6921  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6922  const Exception& ex)
6923  {
6924  errored = true;
6925  static_cast<void>(ex);
6926  if (allow_exceptions)
6927  {
6928  JSON_THROW(ex);
6929  }
6930  return false;
6931  }
6932 
6933  constexpr bool is_errored() const
6934  {
6935  return errored;
6936  }
6937 
6938  private:
6945  template<typename Value>
6947  BasicJsonType* handle_value(Value&& v)
6948  {
6949  if (ref_stack.empty())
6950  {
6951  root = BasicJsonType(std::forward<Value>(v));
6952  return &root;
6953  }
6954 
6955  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6956 
6957  if (ref_stack.back()->is_array())
6958  {
6959  ref_stack.back()->m_data.m_value.array->emplace_back(std::forward<Value>(v));
6960  return &(ref_stack.back()->m_data.m_value.array->back());
6961  }
6962 
6963  JSON_ASSERT(ref_stack.back()->is_object());
6964  JSON_ASSERT(object_element);
6965  *object_element = BasicJsonType(std::forward<Value>(v));
6966  return object_element;
6967  }
6968 
6970  BasicJsonType& root;
6972  std::vector<BasicJsonType*> ref_stack {};
6974  BasicJsonType* object_element = nullptr;
6976  bool errored = false;
6978  const bool allow_exceptions = true;
6979 };
6980 
6981 template<typename BasicJsonType>
6983 {
6984  public:
6985  using number_integer_t = typename BasicJsonType::number_integer_t;
6986  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6987  using number_float_t = typename BasicJsonType::number_float_t;
6988  using string_t = typename BasicJsonType::string_t;
6989  using binary_t = typename BasicJsonType::binary_t;
6992 
6994  const parser_callback_t cb,
6995  const bool allow_exceptions_ = true)
6996  : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6997  {
6998  keep_stack.push_back(true);
6999  }
7000 
7001  // make class move-only
7003  json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7005  json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7006  ~json_sax_dom_callback_parser() = default;
7007 
7008  bool null()
7009  {
7010  handle_value(nullptr);
7011  return true;
7012  }
7013 
7014  bool boolean(bool val)
7015  {
7016  handle_value(val);
7017  return true;
7018  }
7019 
7021  {
7022  handle_value(val);
7023  return true;
7024  }
7025 
7027  {
7028  handle_value(val);
7029  return true;
7030  }
7031 
7032  bool number_float(number_float_t val, const string_t& /*unused*/)
7033  {
7034  handle_value(val);
7035  return true;
7036  }
7037 
7038  bool string(string_t& val)
7039  {
7040  handle_value(val);
7041  return true;
7042  }
7043 
7044  bool binary(binary_t& val)
7045  {
7046  handle_value(std::move(val));
7047  return true;
7048  }
7049 
7050  bool start_object(std::size_t len)
7051  {
7052  // check callback for object start
7053  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
7054  keep_stack.push_back(keep);
7055 
7056  auto val = handle_value(BasicJsonType::value_t::object, true);
7057  ref_stack.push_back(val.second);
7058 
7059  // check object limit
7060  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
7061  {
7062  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
7063  }
7064 
7065  return true;
7066  }
7067 
7068  bool key(string_t& val)
7069  {
7070  BasicJsonType k = BasicJsonType(val);
7071 
7072  // check callback for key
7073  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
7074  key_keep_stack.push_back(keep);
7075 
7076  // add discarded value at given key and store the reference for later
7077  if (keep && ref_stack.back())
7078  {
7079  object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded);
7080  }
7081 
7082  return true;
7083  }
7084 
7085  bool end_object()
7086  {
7087  if (ref_stack.back())
7088  {
7089  if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
7090  {
7091  // discard object
7092  *ref_stack.back() = discarded;
7093  }
7094  else
7095  {
7096  ref_stack.back()->set_parents();
7097  }
7098  }
7099 
7100  JSON_ASSERT(!ref_stack.empty());
7101  JSON_ASSERT(!keep_stack.empty());
7102  ref_stack.pop_back();
7103  keep_stack.pop_back();
7104 
7105  if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
7106  {
7107  // remove discarded value
7108  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
7109  {
7110  if (it->is_discarded())
7111  {
7112  ref_stack.back()->erase(it);
7113  break;
7114  }
7115  }
7116  }
7117 
7118  return true;
7119  }
7120 
7121  bool start_array(std::size_t len)
7122  {
7123  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
7124  keep_stack.push_back(keep);
7125 
7126  auto val = handle_value(BasicJsonType::value_t::array, true);
7127  ref_stack.push_back(val.second);
7128 
7129  // check array limit
7130  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
7131  {
7132  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
7133  }
7134 
7135  return true;
7136  }
7137 
7138  bool end_array()
7139  {
7140  bool keep = true;
7141 
7142  if (ref_stack.back())
7143  {
7144  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
7145  if (keep)
7146  {
7147  ref_stack.back()->set_parents();
7148  }
7149  else
7150  {
7151  // discard array
7152  *ref_stack.back() = discarded;
7153  }
7154  }
7155 
7156  JSON_ASSERT(!ref_stack.empty());
7157  JSON_ASSERT(!keep_stack.empty());
7158  ref_stack.pop_back();
7159  keep_stack.pop_back();
7160 
7161  // remove discarded value
7162  if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
7163  {
7164  ref_stack.back()->m_data.m_value.array->pop_back();
7165  }
7166 
7167  return true;
7168  }
7169 
7170  template<class Exception>
7171  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
7172  const Exception& ex)
7173  {
7174  errored = true;
7175  static_cast<void>(ex);
7176  if (allow_exceptions)
7177  {
7178  JSON_THROW(ex);
7179  }
7180  return false;
7181  }
7182 
7183  constexpr bool is_errored() const
7184  {
7185  return errored;
7186  }
7187 
7188  private:
7204  template<typename Value>
7205  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
7206  {
7207  JSON_ASSERT(!keep_stack.empty());
7208 
7209  // do not handle this value if we know it would be added to a discarded
7210  // container
7211  if (!keep_stack.back())
7212  {
7213  return {false, nullptr};
7214  }
7215 
7216  // create value
7217  auto value = BasicJsonType(std::forward<Value>(v));
7218 
7219  // check callback
7220  const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
7221 
7222  // do not handle this value if we just learnt it shall be discarded
7223  if (!keep)
7224  {
7225  return {false, nullptr};
7226  }
7227 
7228  if (ref_stack.empty())
7229  {
7230  root = std::move(value);
7231  return {true, & root};
7232  }
7233 
7234  // skip this value if we already decided to skip the parent
7235  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
7236  if (!ref_stack.back())
7237  {
7238  return {false, nullptr};
7239  }
7240 
7241  // we now only expect arrays and objects
7242  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
7243 
7244  // array
7245  if (ref_stack.back()->is_array())
7246  {
7247  ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));
7248  return {true, & (ref_stack.back()->m_data.m_value.array->back())};
7249  }
7250 
7251  // object
7252  JSON_ASSERT(ref_stack.back()->is_object());
7253  // check if we should store an element for the current key
7254  JSON_ASSERT(!key_keep_stack.empty());
7255  const bool store_element = key_keep_stack.back();
7256  key_keep_stack.pop_back();
7257 
7258  if (!store_element)
7259  {
7260  return {false, nullptr};
7261  }
7262 
7263  JSON_ASSERT(object_element);
7264  *object_element = std::move(value);
7265  return {true, object_element};
7266  }
7267 
7269  BasicJsonType& root;
7271  std::vector<BasicJsonType*> ref_stack {};
7273  std::vector<bool> keep_stack {};
7275  std::vector<bool> key_keep_stack {};
7277  BasicJsonType* object_element = nullptr;
7279  bool errored = false;
7281  const parser_callback_t callback = nullptr;
7283  const bool allow_exceptions = true;
7285  BasicJsonType discarded = BasicJsonType::value_t::discarded;
7286 };
7287 
7288 template<typename BasicJsonType>
7290 {
7291  public:
7292  using number_integer_t = typename BasicJsonType::number_integer_t;
7293  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7294  using number_float_t = typename BasicJsonType::number_float_t;
7295  using string_t = typename BasicJsonType::string_t;
7296  using binary_t = typename BasicJsonType::binary_t;
7297 
7298  bool null()
7299  {
7300  return true;
7301  }
7302 
7303  bool boolean(bool /*unused*/)
7304  {
7305  return true;
7306  }
7307 
7309  {
7310  return true;
7311  }
7312 
7314  {
7315  return true;
7316  }
7317 
7318  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
7319  {
7320  return true;
7321  }
7322 
7323  bool string(string_t& /*unused*/)
7324  {
7325  return true;
7326  }
7327 
7328  bool binary(binary_t& /*unused*/)
7329  {
7330  return true;
7331  }
7332 
7333  bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7334  {
7335  return true;
7336  }
7337 
7338  bool key(string_t& /*unused*/)
7339  {
7340  return true;
7341  }
7342 
7343  bool end_object()
7344  {
7345  return true;
7346  }
7347 
7348  bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7349  {
7350  return true;
7351  }
7352 
7353  bool end_array()
7354  {
7355  return true;
7356  }
7357 
7358  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
7359  {
7360  return false;
7361  }
7362 };
7363 
7364 } // namespace detail
7366 
7367 // #include <nlohmann/detail/input/lexer.hpp>
7368 // __ _____ _____ _____
7369 // __| | __| | | | JSON for Modern C++
7370 // | | |__ | | | | | | version 3.11.3
7371 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
7372 //
7373 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
7374 // SPDX-License-Identifier: MIT
7375 
7376 
7377 
7378 #include <array> // array
7379 #include <clocale> // localeconv
7380 #include <cstddef> // size_t
7381 #include <cstdio> // snprintf
7382 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7383 #include <initializer_list> // initializer_list
7384 #include <string> // char_traits, string
7385 #include <utility> // move
7386 #include <vector> // vector
7387 
7388 // #include <nlohmann/detail/input/input_adapters.hpp>
7389 
7390 // #include <nlohmann/detail/input/position_t.hpp>
7391 
7392 // #include <nlohmann/detail/macro_scope.hpp>
7393 
7394 // #include <nlohmann/detail/meta/type_traits.hpp>
7395 
7396 
7398 namespace detail
7399 {
7400 
7402 // lexer //
7404 
7405 template<typename BasicJsonType>
7407 {
7408  public:
7410  enum class token_type
7411  {
7412  uninitialized,
7413  literal_true,
7414  literal_false,
7415  literal_null,
7416  value_string,
7417  value_unsigned,
7418  value_integer,
7419  value_float,
7420  begin_array,
7421  begin_object,
7422  end_array,
7423  end_object,
7424  name_separator,
7425  value_separator,
7426  parse_error,
7427  end_of_input,
7428  literal_or_value
7429  };
7430 
7434  static const char* token_type_name(const token_type t) noexcept
7435  {
7436  switch (t)
7437  {
7438  case token_type::uninitialized:
7439  return "<uninitialized>";
7440  case token_type::literal_true:
7441  return "true literal";
7442  case token_type::literal_false:
7443  return "false literal";
7444  case token_type::literal_null:
7445  return "null literal";
7446  case token_type::value_string:
7447  return "string literal";
7448  case token_type::value_unsigned:
7449  case token_type::value_integer:
7450  case token_type::value_float:
7451  return "number literal";
7452  case token_type::begin_array:
7453  return "'['";
7454  case token_type::begin_object:
7455  return "'{'";
7456  case token_type::end_array:
7457  return "']'";
7458  case token_type::end_object:
7459  return "'}'";
7460  case token_type::name_separator:
7461  return "':'";
7462  case token_type::value_separator:
7463  return "','";
7464  case token_type::parse_error:
7465  return "<parse error>";
7466  case token_type::end_of_input:
7467  return "end of input";
7468  case token_type::literal_or_value:
7469  return "'[', '{', or a literal";
7470  // LCOV_EXCL_START
7471  default: // catch non-enum values
7472  return "unknown token";
7473  // LCOV_EXCL_STOP
7474  }
7475  }
7476 };
7482 template<typename BasicJsonType, typename InputAdapterType>
7483 class lexer : public lexer_base<BasicJsonType>
7484 {
7485  using number_integer_t = typename BasicJsonType::number_integer_t;
7486  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7487  using number_float_t = typename BasicJsonType::number_float_t;
7488  using string_t = typename BasicJsonType::string_t;
7491 
7492  public:
7494 
7495  explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
7496  : ia(std::move(adapter))
7497  , ignore_comments(ignore_comments_)
7498  , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
7499  {}
7500 
7501  // delete because of pointer members
7502  lexer(const lexer&) = delete;
7503  lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7504  lexer& operator=(lexer&) = delete;
7505  lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7506  ~lexer() = default;
7507 
7508  private:
7510  // locales
7512 
7515  static char get_decimal_point() noexcept
7516  {
7517  const auto* loc = localeconv();
7518  JSON_ASSERT(loc != nullptr);
7519  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7520  }
7521 
7523  // scan functions
7525 
7542  {
7543  // this function only makes sense after reading `\u`
7544  JSON_ASSERT(current == 'u');
7545  int codepoint = 0;
7546 
7547  const auto factors = { 12u, 8u, 4u, 0u };
7548  for (const auto factor : factors)
7549  {
7550  get();
7551 
7552  if (current >= '0' && current <= '9')
7553  {
7554  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7555  }
7556  else if (current >= 'A' && current <= 'F')
7557  {
7558  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7559  }
7560  else if (current >= 'a' && current <= 'f')
7561  {
7562  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7563  }
7564  else
7565  {
7566  return -1;
7567  }
7568  }
7569 
7570  JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7571  return codepoint;
7572  }
7573 
7589  bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7590  {
7591  JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7592  add(current);
7593 
7594  for (auto range = ranges.begin(); range != ranges.end(); ++range)
7595  {
7596  get();
7597  if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) // NOLINT(bugprone-inc-dec-in-conditions)
7598  {
7599  add(current);
7600  }
7601  else
7602  {
7603  error_message = "invalid string: ill-formed UTF-8 byte";
7604  return false;
7605  }
7606  }
7607 
7608  return true;
7609  }
7610 
7627  {
7628  // reset token_buffer (ignore opening quote)
7629  reset();
7630 
7631  // we entered the function by reading an open quote
7632  JSON_ASSERT(current == '\"');
7633 
7634  while (true)
7635  {
7636  // get next character
7637  switch (get())
7638  {
7639  // end of file while parsing string
7641  {
7642  error_message = "invalid string: missing closing quote";
7643  return token_type::parse_error;
7644  }
7645 
7646  // closing quote
7647  case '\"':
7648  {
7649  return token_type::value_string;
7650  }
7651 
7652  // escapes
7653  case '\\':
7654  {
7655  switch (get())
7656  {
7657  // quotation mark
7658  case '\"':
7659  add('\"');
7660  break;
7661  // reverse solidus
7662  case '\\':
7663  add('\\');
7664  break;
7665  // solidus
7666  case '/':
7667  add('/');
7668  break;
7669  // backspace
7670  case 'b':
7671  add('\b');
7672  break;
7673  // form feed
7674  case 'f':
7675  add('\f');
7676  break;
7677  // line feed
7678  case 'n':
7679  add('\n');
7680  break;
7681  // carriage return
7682  case 'r':
7683  add('\r');
7684  break;
7685  // tab
7686  case 't':
7687  add('\t');
7688  break;
7689 
7690  // unicode escapes
7691  case 'u':
7692  {
7693  const int codepoint1 = get_codepoint();
7694  int codepoint = codepoint1; // start with codepoint1
7695 
7696  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7697  {
7698  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7699  return token_type::parse_error;
7700  }
7701 
7702  // check if code point is a high surrogate
7703  if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7704  {
7705  // expect next \uxxxx entry
7706  if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7707  {
7708  const int codepoint2 = get_codepoint();
7709 
7710  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7711  {
7712  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7713  return token_type::parse_error;
7714  }
7715 
7716  // check if codepoint2 is a low surrogate
7717  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7718  {
7719  // overwrite codepoint
7720  codepoint = static_cast<int>(
7721  // high surrogate occupies the most significant 22 bits
7722  (static_cast<unsigned int>(codepoint1) << 10u)
7723  // low surrogate occupies the least significant 15 bits
7724  + static_cast<unsigned int>(codepoint2)
7725  // there is still the 0xD800, 0xDC00 and 0x10000 noise
7726  // in the result, so we have to subtract with:
7727  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7728  - 0x35FDC00u);
7729  }
7730  else
7731  {
7732  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7733  return token_type::parse_error;
7734  }
7735  }
7736  else
7737  {
7738  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7739  return token_type::parse_error;
7740  }
7741  }
7742  else
7743  {
7744  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7745  {
7746  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7747  return token_type::parse_error;
7748  }
7749  }
7750 
7751  // result of the above calculation yields a proper codepoint
7752  JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7753 
7754  // translate codepoint into bytes
7755  if (codepoint < 0x80)
7756  {
7757  // 1-byte characters: 0xxxxxxx (ASCII)
7758  add(static_cast<char_int_type>(codepoint));
7759  }
7760  else if (codepoint <= 0x7FF)
7761  {
7762  // 2-byte characters: 110xxxxx 10xxxxxx
7763  add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7764  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7765  }
7766  else if (codepoint <= 0xFFFF)
7767  {
7768  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7769  add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7770  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7771  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7772  }
7773  else
7774  {
7775  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7776  add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7777  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7778  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7779  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7780  }
7781 
7782  break;
7783  }
7784 
7785  // other characters after escape
7786  default:
7787  error_message = "invalid string: forbidden character after backslash";
7788  return token_type::parse_error;
7789  }
7790 
7791  break;
7792  }
7793 
7794  // invalid control characters
7795  case 0x00:
7796  {
7797  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7798  return token_type::parse_error;
7799  }
7800 
7801  case 0x01:
7802  {
7803  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7804  return token_type::parse_error;
7805  }
7806 
7807  case 0x02:
7808  {
7809  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7810  return token_type::parse_error;
7811  }
7812 
7813  case 0x03:
7814  {
7815  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7816  return token_type::parse_error;
7817  }
7818 
7819  case 0x04:
7820  {
7821  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7822  return token_type::parse_error;
7823  }
7824 
7825  case 0x05:
7826  {
7827  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7828  return token_type::parse_error;
7829  }
7830 
7831  case 0x06:
7832  {
7833  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7834  return token_type::parse_error;
7835  }
7836 
7837  case 0x07:
7838  {
7839  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7840  return token_type::parse_error;
7841  }
7842 
7843  case 0x08:
7844  {
7845  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7846  return token_type::parse_error;
7847  }
7848 
7849  case 0x09:
7850  {
7851  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7852  return token_type::parse_error;
7853  }
7854 
7855  case 0x0A:
7856  {
7857  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7858  return token_type::parse_error;
7859  }
7860 
7861  case 0x0B:
7862  {
7863  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7864  return token_type::parse_error;
7865  }
7866 
7867  case 0x0C:
7868  {
7869  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7870  return token_type::parse_error;
7871  }
7872 
7873  case 0x0D:
7874  {
7875  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7876  return token_type::parse_error;
7877  }
7878 
7879  case 0x0E:
7880  {
7881  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7882  return token_type::parse_error;
7883  }
7884 
7885  case 0x0F:
7886  {
7887  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7888  return token_type::parse_error;
7889  }
7890 
7891  case 0x10:
7892  {
7893  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7894  return token_type::parse_error;
7895  }
7896 
7897  case 0x11:
7898  {
7899  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7900  return token_type::parse_error;
7901  }
7902 
7903  case 0x12:
7904  {
7905  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7906  return token_type::parse_error;
7907  }
7908 
7909  case 0x13:
7910  {
7911  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7912  return token_type::parse_error;
7913  }
7914 
7915  case 0x14:
7916  {
7917  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7918  return token_type::parse_error;
7919  }
7920 
7921  case 0x15:
7922  {
7923  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7924  return token_type::parse_error;
7925  }
7926 
7927  case 0x16:
7928  {
7929  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7930  return token_type::parse_error;
7931  }
7932 
7933  case 0x17:
7934  {
7935  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7936  return token_type::parse_error;
7937  }
7938 
7939  case 0x18:
7940  {
7941  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7942  return token_type::parse_error;
7943  }
7944 
7945  case 0x19:
7946  {
7947  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7948  return token_type::parse_error;
7949  }
7950 
7951  case 0x1A:
7952  {
7953  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7954  return token_type::parse_error;
7955  }
7956 
7957  case 0x1B:
7958  {
7959  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7960  return token_type::parse_error;
7961  }
7962 
7963  case 0x1C:
7964  {
7965  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7966  return token_type::parse_error;
7967  }
7968 
7969  case 0x1D:
7970  {
7971  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7972  return token_type::parse_error;
7973  }
7974 
7975  case 0x1E:
7976  {
7977  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7978  return token_type::parse_error;
7979  }
7980 
7981  case 0x1F:
7982  {
7983  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7984  return token_type::parse_error;
7985  }
7986 
7987  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7988  case 0x20:
7989  case 0x21:
7990  case 0x23:
7991  case 0x24:
7992  case 0x25:
7993  case 0x26:
7994  case 0x27:
7995  case 0x28:
7996  case 0x29:
7997  case 0x2A:
7998  case 0x2B:
7999  case 0x2C:
8000  case 0x2D:
8001  case 0x2E:
8002  case 0x2F:
8003  case 0x30:
8004  case 0x31:
8005  case 0x32:
8006  case 0x33:
8007  case 0x34:
8008  case 0x35:
8009  case 0x36:
8010  case 0x37:
8011  case 0x38:
8012  case 0x39:
8013  case 0x3A:
8014  case 0x3B:
8015  case 0x3C:
8016  case 0x3D:
8017  case 0x3E:
8018  case 0x3F:
8019  case 0x40:
8020  case 0x41:
8021  case 0x42:
8022  case 0x43:
8023  case 0x44:
8024  case 0x45:
8025  case 0x46:
8026  case 0x47:
8027  case 0x48:
8028  case 0x49:
8029  case 0x4A:
8030  case 0x4B:
8031  case 0x4C:
8032  case 0x4D:
8033  case 0x4E:
8034  case 0x4F:
8035  case 0x50:
8036  case 0x51:
8037  case 0x52:
8038  case 0x53:
8039  case 0x54:
8040  case 0x55:
8041  case 0x56:
8042  case 0x57:
8043  case 0x58:
8044  case 0x59:
8045  case 0x5A:
8046  case 0x5B:
8047  case 0x5D:
8048  case 0x5E:
8049  case 0x5F:
8050  case 0x60:
8051  case 0x61:
8052  case 0x62:
8053  case 0x63:
8054  case 0x64:
8055  case 0x65:
8056  case 0x66:
8057  case 0x67:
8058  case 0x68:
8059  case 0x69:
8060  case 0x6A:
8061  case 0x6B:
8062  case 0x6C:
8063  case 0x6D:
8064  case 0x6E:
8065  case 0x6F:
8066  case 0x70:
8067  case 0x71:
8068  case 0x72:
8069  case 0x73:
8070  case 0x74:
8071  case 0x75:
8072  case 0x76:
8073  case 0x77:
8074  case 0x78:
8075  case 0x79:
8076  case 0x7A:
8077  case 0x7B:
8078  case 0x7C:
8079  case 0x7D:
8080  case 0x7E:
8081  case 0x7F:
8082  {
8083  add(current);
8084  break;
8085  }
8086 
8087  // U+0080..U+07FF: bytes C2..DF 80..BF
8088  case 0xC2:
8089  case 0xC3:
8090  case 0xC4:
8091  case 0xC5:
8092  case 0xC6:
8093  case 0xC7:
8094  case 0xC8:
8095  case 0xC9:
8096  case 0xCA:
8097  case 0xCB:
8098  case 0xCC:
8099  case 0xCD:
8100  case 0xCE:
8101  case 0xCF:
8102  case 0xD0:
8103  case 0xD1:
8104  case 0xD2:
8105  case 0xD3:
8106  case 0xD4:
8107  case 0xD5:
8108  case 0xD6:
8109  case 0xD7:
8110  case 0xD8:
8111  case 0xD9:
8112  case 0xDA:
8113  case 0xDB:
8114  case 0xDC:
8115  case 0xDD:
8116  case 0xDE:
8117  case 0xDF:
8118  {
8119  if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
8120  {
8121  return token_type::parse_error;
8122  }
8123  break;
8124  }
8125 
8126  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
8127  case 0xE0:
8128  {
8129  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
8130  {
8131  return token_type::parse_error;
8132  }
8133  break;
8134  }
8135 
8136  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
8137  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
8138  case 0xE1:
8139  case 0xE2:
8140  case 0xE3:
8141  case 0xE4:
8142  case 0xE5:
8143  case 0xE6:
8144  case 0xE7:
8145  case 0xE8:
8146  case 0xE9:
8147  case 0xEA:
8148  case 0xEB:
8149  case 0xEC:
8150  case 0xEE:
8151  case 0xEF:
8152  {
8153  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
8154  {
8155  return token_type::parse_error;
8156  }
8157  break;
8158  }
8159 
8160  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
8161  case 0xED:
8162  {
8163  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
8164  {
8165  return token_type::parse_error;
8166  }
8167  break;
8168  }
8169 
8170  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
8171  case 0xF0:
8172  {
8173  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8174  {
8175  return token_type::parse_error;
8176  }
8177  break;
8178  }
8179 
8180  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
8181  case 0xF1:
8182  case 0xF2:
8183  case 0xF3:
8184  {
8185  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8186  {
8187  return token_type::parse_error;
8188  }
8189  break;
8190  }
8191 
8192  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
8193  case 0xF4:
8194  {
8195  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
8196  {
8197  return token_type::parse_error;
8198  }
8199  break;
8200  }
8201 
8202  // remaining bytes (80..C1 and F5..FF) are ill-formed
8203  default:
8204  {
8205  error_message = "invalid string: ill-formed UTF-8 byte";
8206  return token_type::parse_error;
8207  }
8208  }
8209  }
8210  }
8211 
8217  {
8218  switch (get())
8219  {
8220  // single-line comments skip input until a newline or EOF is read
8221  case '/':
8222  {
8223  while (true)
8224  {
8225  switch (get())
8226  {
8227  case '\n':
8228  case '\r':
8230  case '\0':
8231  return true;
8232 
8233  default:
8234  break;
8235  }
8236  }
8237  }
8238 
8239  // multi-line comments skip input until */ is read
8240  case '*':
8241  {
8242  while (true)
8243  {
8244  switch (get())
8245  {
8247  case '\0':
8248  {
8249  error_message = "invalid comment; missing closing '*/'";
8250  return false;
8251  }
8252 
8253  case '*':
8254  {
8255  switch (get())
8256  {
8257  case '/':
8258  return true;
8259 
8260  default:
8261  {
8262  unget();
8263  continue;
8264  }
8265  }
8266  }
8267 
8268  default:
8269  continue;
8270  }
8271  }
8272  }
8273 
8274  // unexpected character after reading '/'
8275  default:
8276  {
8277  error_message = "invalid comment; expecting '/' or '*' after '/'";
8278  return false;
8279  }
8280  }
8281  }
8282 
8284  static void strtof(float& f, const char* str, char** endptr) noexcept
8285  {
8286  f = std::strtof(str, endptr);
8287  }
8288 
8290  static void strtof(double& f, const char* str, char** endptr) noexcept
8291  {
8292  f = std::strtod(str, endptr);
8293  }
8294 
8296  static void strtof(long double& f, const char* str, char** endptr) noexcept
8297  {
8298  f = std::strtold(str, endptr);
8299  }
8300 
8341  token_type scan_number() // lgtm [cpp/use-of-goto]
8342  {
8343  // reset token_buffer to store the number's bytes
8344  reset();
8345 
8346  // the type of the parsed number; initially set to unsigned; will be
8347  // changed if minus sign, decimal point or exponent is read
8348  token_type number_type = token_type::value_unsigned;
8349 
8350  // state (init): we just found out we need to scan a number
8351  switch (current)
8352  {
8353  case '-':
8354  {
8355  add(current);
8356  goto scan_number_minus;
8357  }
8358 
8359  case '0':
8360  {
8361  add(current);
8362  goto scan_number_zero;
8363  }
8364 
8365  case '1':
8366  case '2':
8367  case '3':
8368  case '4':
8369  case '5':
8370  case '6':
8371  case '7':
8372  case '8':
8373  case '9':
8374  {
8375  add(current);
8376  goto scan_number_any1;
8377  }
8378 
8379  // all other characters are rejected outside scan_number()
8380  default: // LCOV_EXCL_LINE
8381  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8382  }
8383 
8384 scan_number_minus:
8385  // state: we just parsed a leading minus sign
8386  number_type = token_type::value_integer;
8387  switch (get())
8388  {
8389  case '0':
8390  {
8391  add(current);
8392  goto scan_number_zero;
8393  }
8394 
8395  case '1':
8396  case '2':
8397  case '3':
8398  case '4':
8399  case '5':
8400  case '6':
8401  case '7':
8402  case '8':
8403  case '9':
8404  {
8405  add(current);
8406  goto scan_number_any1;
8407  }
8408 
8409  default:
8410  {
8411  error_message = "invalid number; expected digit after '-'";
8412  return token_type::parse_error;
8413  }
8414  }
8415 
8416 scan_number_zero:
8417  // state: we just parse a zero (maybe with a leading minus sign)
8418  switch (get())
8419  {
8420  case '.':
8421  {
8422  add(decimal_point_char);
8423  goto scan_number_decimal1;
8424  }
8425 
8426  case 'e':
8427  case 'E':
8428  {
8429  add(current);
8430  goto scan_number_exponent;
8431  }
8432 
8433  default:
8434  goto scan_number_done;
8435  }
8436 
8437 scan_number_any1:
8438  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8439  switch (get())
8440  {
8441  case '0':
8442  case '1':
8443  case '2':
8444  case '3':
8445  case '4':
8446  case '5':
8447  case '6':
8448  case '7':
8449  case '8':
8450  case '9':
8451  {
8452  add(current);
8453  goto scan_number_any1;
8454  }
8455 
8456  case '.':
8457  {
8458  add(decimal_point_char);
8459  goto scan_number_decimal1;
8460  }
8461 
8462  case 'e':
8463  case 'E':
8464  {
8465  add(current);
8466  goto scan_number_exponent;
8467  }
8468 
8469  default:
8470  goto scan_number_done;
8471  }
8472 
8473 scan_number_decimal1:
8474  // state: we just parsed a decimal point
8475  number_type = token_type::value_float;
8476  switch (get())
8477  {
8478  case '0':
8479  case '1':
8480  case '2':
8481  case '3':
8482  case '4':
8483  case '5':
8484  case '6':
8485  case '7':
8486  case '8':
8487  case '9':
8488  {
8489  add(current);
8490  goto scan_number_decimal2;
8491  }
8492 
8493  default:
8494  {
8495  error_message = "invalid number; expected digit after '.'";
8496  return token_type::parse_error;
8497  }
8498  }
8499 
8500 scan_number_decimal2:
8501  // we just parsed at least one number after a decimal point
8502  switch (get())
8503  {
8504  case '0':
8505  case '1':
8506  case '2':
8507  case '3':
8508  case '4':
8509  case '5':
8510  case '6':
8511  case '7':
8512  case '8':
8513  case '9':
8514  {
8515  add(current);
8516  goto scan_number_decimal2;
8517  }
8518 
8519  case 'e':
8520  case 'E':
8521  {
8522  add(current);
8523  goto scan_number_exponent;
8524  }
8525 
8526  default:
8527  goto scan_number_done;
8528  }
8529 
8530 scan_number_exponent:
8531  // we just parsed an exponent
8532  number_type = token_type::value_float;
8533  switch (get())
8534  {
8535  case '+':
8536  case '-':
8537  {
8538  add(current);
8539  goto scan_number_sign;
8540  }
8541 
8542  case '0':
8543  case '1':
8544  case '2':
8545  case '3':
8546  case '4':
8547  case '5':
8548  case '6':
8549  case '7':
8550  case '8':
8551  case '9':
8552  {
8553  add(current);
8554  goto scan_number_any2;
8555  }
8556 
8557  default:
8558  {
8559  error_message =
8560  "invalid number; expected '+', '-', or digit after exponent";
8561  return token_type::parse_error;
8562  }
8563  }
8564 
8565 scan_number_sign:
8566  // we just parsed an exponent sign
8567  switch (get())
8568  {
8569  case '0':
8570  case '1':
8571  case '2':
8572  case '3':
8573  case '4':
8574  case '5':
8575  case '6':
8576  case '7':
8577  case '8':
8578  case '9':
8579  {
8580  add(current);
8581  goto scan_number_any2;
8582  }
8583 
8584  default:
8585  {
8586  error_message = "invalid number; expected digit after exponent sign";
8587  return token_type::parse_error;
8588  }
8589  }
8590 
8591 scan_number_any2:
8592  // we just parsed a number after the exponent or exponent sign
8593  switch (get())
8594  {
8595  case '0':
8596  case '1':
8597  case '2':
8598  case '3':
8599  case '4':
8600  case '5':
8601  case '6':
8602  case '7':
8603  case '8':
8604  case '9':
8605  {
8606  add(current);
8607  goto scan_number_any2;
8608  }
8609 
8610  default:
8611  goto scan_number_done;
8612  }
8613 
8614 scan_number_done:
8615  // unget the character after the number (we only read it to know that
8616  // we are done scanning a number)
8617  unget();
8618 
8619  char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8620  errno = 0;
8621 
8622  // try to parse integers first and fall back to floats
8623  if (number_type == token_type::value_unsigned)
8624  {
8625  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8626 
8627  // we checked the number format before
8628  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8629 
8630  if (errno == 0)
8631  {
8632  value_unsigned = static_cast<number_unsigned_t>(x);
8633  if (value_unsigned == x)
8634  {
8635  return token_type::value_unsigned;
8636  }
8637  }
8638  }
8639  else if (number_type == token_type::value_integer)
8640  {
8641  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8642 
8643  // we checked the number format before
8644  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8645 
8646  if (errno == 0)
8647  {
8648  value_integer = static_cast<number_integer_t>(x);
8649  if (value_integer == x)
8650  {
8651  return token_type::value_integer;
8652  }
8653  }
8654  }
8655 
8656  // this code is reached if we parse a floating-point number or if an
8657  // integer conversion above failed
8658  strtof(value_float, token_buffer.data(), &endptr);
8659 
8660  // we checked the number format before
8661  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8662 
8663  return token_type::value_float;
8664  }
8665 
8672  token_type scan_literal(const char_type* literal_text, const std::size_t length,
8673  token_type return_type)
8674  {
8675  JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);
8676  for (std::size_t i = 1; i < length; ++i)
8677  {
8679  {
8680  error_message = "invalid literal";
8681  return token_type::parse_error;
8682  }
8683  }
8684  return return_type;
8685  }
8686 
8688  // input management
8690 
8692  void reset() noexcept
8693  {
8694  token_buffer.clear();
8695  token_string.clear();
8696  token_string.push_back(char_traits<char_type>::to_char_type(current));
8697  }
8698 
8699  /*
8700  @brief get next character from the input
8701 
8702  This function provides the interface to the used input adapter. It does
8703  not throw in case the input reached EOF, but returns a
8704  `char_traits<char>::eof()` in that case. Stores the scanned characters
8705  for use in error messages.
8706 
8707  @return character read from the input
8708  */
8710  {
8711  ++position.chars_read_total;
8712  ++position.chars_read_current_line;
8713 
8714  if (next_unget)
8715  {
8716  // just reset the next_unget variable and work with current
8717  next_unget = false;
8718  }
8719  else
8720  {
8721  current = ia.get_character();
8722  }
8723 
8725  {
8726  token_string.push_back(char_traits<char_type>::to_char_type(current));
8727  }
8728 
8729  if (current == '\n')
8730  {
8731  ++position.lines_read;
8732  position.chars_read_current_line = 0;
8733  }
8734 
8735  return current;
8736  }
8737 
8746  void unget()
8747  {
8748  next_unget = true;
8749 
8750  --position.chars_read_total;
8751 
8752  // in case we "unget" a newline, we have to also decrement the lines_read
8753  if (position.chars_read_current_line == 0)
8754  {
8755  if (position.lines_read > 0)
8756  {
8757  --position.lines_read;
8758  }
8759  }
8760  else
8761  {
8762  --position.chars_read_current_line;
8763  }
8764 
8766  {
8767  JSON_ASSERT(!token_string.empty());
8768  token_string.pop_back();
8769  }
8770  }
8771 
8774  {
8775  token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8776  }
8777 
8778  public:
8780  // value getters
8782 
8784  constexpr number_integer_t get_number_integer() const noexcept
8785  {
8786  return value_integer;
8787  }
8788 
8790  constexpr number_unsigned_t get_number_unsigned() const noexcept
8791  {
8792  return value_unsigned;
8793  }
8794 
8796  constexpr number_float_t get_number_float() const noexcept
8797  {
8798  return value_float;
8799  }
8800 
8803  {
8804  return token_buffer;
8805  }
8806 
8808  // diagnostics
8810 
8812  constexpr position_t get_position() const noexcept
8813  {
8814  return position;
8815  }
8816 
8820  std::string get_token_string() const
8821  {
8822  // escape control characters
8823  std::string result;
8824  for (const auto c : token_string)
8825  {
8826  if (static_cast<unsigned char>(c) <= '\x1F')
8827  {
8828  // escape control characters
8829  std::array<char, 9> cs{{}};
8830  static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8831  result += cs.data();
8832  }
8833  else
8834  {
8835  // add character as is
8836  result.push_back(static_cast<std::string::value_type>(c));
8837  }
8838  }
8839 
8840  return result;
8841  }
8842 
8845  constexpr const char* get_error_message() const noexcept
8846  {
8847  return error_message;
8848  }
8849 
8851  // actual scanner
8853 
8858  bool skip_bom()
8859  {
8860  if (get() == 0xEF)
8861  {
8862  // check if we completely parse the BOM
8863  return get() == 0xBB && get() == 0xBF;
8864  }
8865 
8866  // the first character is not the beginning of the BOM; unget it to
8867  // process is later
8868  unget();
8869  return true;
8870  }
8871 
8873  {
8874  do
8875  {
8876  get();
8877  }
8878  while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8879  }
8880 
8882  {
8883  // initially, skip the BOM
8884  if (position.chars_read_total == 0 && !skip_bom())
8885  {
8886  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8887  return token_type::parse_error;
8888  }
8889 
8890  // read next character and ignore whitespace
8891  skip_whitespace();
8892 
8893  // ignore comments
8894  while (ignore_comments && current == '/')
8895  {
8896  if (!scan_comment())
8897  {
8898  return token_type::parse_error;
8899  }
8900 
8901  // skip following whitespace
8902  skip_whitespace();
8903  }
8904 
8905  switch (current)
8906  {
8907  // structural characters
8908  case '[':
8909  return token_type::begin_array;
8910  case ']':
8911  return token_type::end_array;
8912  case '{':
8913  return token_type::begin_object;
8914  case '}':
8915  return token_type::end_object;
8916  case ':':
8917  return token_type::name_separator;
8918  case ',':
8919  return token_type::value_separator;
8920 
8921  // literals
8922  case 't':
8923  {
8924  std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
8925  return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8926  }
8927  case 'f':
8928  {
8929  std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
8930  return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8931  }
8932  case 'n':
8933  {
8934  std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
8935  return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8936  }
8937 
8938  // string
8939  case '\"':
8940  return scan_string();
8941 
8942  // number
8943  case '-':
8944  case '0':
8945  case '1':
8946  case '2':
8947  case '3':
8948  case '4':
8949  case '5':
8950  case '6':
8951  case '7':
8952  case '8':
8953  case '9':
8954  return scan_number();
8955 
8956  // end of input (the null byte is needed when parsing from
8957  // string literals)
8958  case '\0':
8960  return token_type::end_of_input;
8961 
8962  // error
8963  default:
8964  error_message = "invalid literal";
8965  return token_type::parse_error;
8966  }
8967  }
8968 
8969  private:
8971  InputAdapterType ia;
8972 
8974  const bool ignore_comments = false;
8975 
8978 
8980  bool next_unget = false;
8981 
8984 
8986  std::vector<char_type> token_string {};
8987 
8989  string_t token_buffer {};
8990 
8992  const char* error_message = "";
8993 
8994  // number values
8995  number_integer_t value_integer = 0;
8996  number_unsigned_t value_unsigned = 0;
8997  number_float_t value_float = 0;
8998 
9000  const char_int_type decimal_point_char = '.';
9001 };
9002 
9003 } // namespace detail
9005 
9006 // #include <nlohmann/detail/macro_scope.hpp>
9007 
9008 // #include <nlohmann/detail/meta/is_sax.hpp>
9009 // __ _____ _____ _____
9010 // __| | __| | | | JSON for Modern C++
9011 // | | |__ | | | | | | version 3.11.3
9012 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
9013 //
9014 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
9015 // SPDX-License-Identifier: MIT
9016 
9017 
9018 
9019 #include <cstdint> // size_t
9020 #include <utility> // declval
9021 #include <string> // string
9022 
9023 // #include <nlohmann/detail/abi_macros.hpp>
9024 
9025 // #include <nlohmann/detail/meta/detected.hpp>
9026 
9027 // #include <nlohmann/detail/meta/type_traits.hpp>
9028 
9029 
9031 namespace detail
9032 {
9033 
9034 template<typename T>
9035 using null_function_t = decltype(std::declval<T&>().null());
9036 
9037 template<typename T>
9038 using boolean_function_t =
9039  decltype(std::declval<T&>().boolean(std::declval<bool>()));
9040 
9041 template<typename T, typename Integer>
9043  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
9044 
9045 template<typename T, typename Unsigned>
9047  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
9048 
9049 template<typename T, typename Float, typename String>
9050 using number_float_function_t = decltype(std::declval<T&>().number_float(
9051  std::declval<Float>(), std::declval<const String&>()));
9052 
9053 template<typename T, typename String>
9054 using string_function_t =
9055  decltype(std::declval<T&>().string(std::declval<String&>()));
9056 
9057 template<typename T, typename Binary>
9058 using binary_function_t =
9059  decltype(std::declval<T&>().binary(std::declval<Binary&>()));
9060 
9061 template<typename T>
9063  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
9064 
9065 template<typename T, typename String>
9066 using key_function_t =
9067  decltype(std::declval<T&>().key(std::declval<String&>()));
9068 
9069 template<typename T>
9070 using end_object_function_t = decltype(std::declval<T&>().end_object());
9071 
9072 template<typename T>
9073 using start_array_function_t =
9074  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
9075 
9076 template<typename T>
9077 using end_array_function_t = decltype(std::declval<T&>().end_array());
9078 
9079 template<typename T, typename Exception>
9080 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
9081  std::declval<std::size_t>(), std::declval<const std::string&>(),
9082  std::declval<const Exception&>()));
9083 
9084 template<typename SAX, typename BasicJsonType>
9085 struct is_sax
9086 {
9087  private:
9089  "BasicJsonType must be of type basic_json<...>");
9090 
9091  using number_integer_t = typename BasicJsonType::number_integer_t;
9092  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9093  using number_float_t = typename BasicJsonType::number_float_t;
9094  using string_t = typename BasicJsonType::string_t;
9095  using binary_t = typename BasicJsonType::binary_t;
9096  using exception_t = typename BasicJsonType::exception;
9097 
9098  public:
9099  static constexpr bool value =
9113 };
9114 
9115 template<typename SAX, typename BasicJsonType>
9117 {
9118  private:
9120  "BasicJsonType must be of type basic_json<...>");
9121 
9122  using number_integer_t = typename BasicJsonType::number_integer_t;
9123  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9124  using number_float_t = typename BasicJsonType::number_float_t;
9125  using string_t = typename BasicJsonType::string_t;
9126  using binary_t = typename BasicJsonType::binary_t;
9127  using exception_t = typename BasicJsonType::exception;
9128 
9129  public:
9131  "Missing/invalid function: bool null()");
9133  "Missing/invalid function: bool boolean(bool)");
9135  "Missing/invalid function: bool boolean(bool)");
9136  static_assert(
9139  "Missing/invalid function: bool number_integer(number_integer_t)");
9140  static_assert(
9143  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
9144  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
9146  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
9147  static_assert(
9149  "Missing/invalid function: bool string(string_t&)");
9150  static_assert(
9152  "Missing/invalid function: bool binary(binary_t&)");
9154  "Missing/invalid function: bool start_object(std::size_t)");
9156  "Missing/invalid function: bool key(string_t&)");
9158  "Missing/invalid function: bool end_object()");
9160  "Missing/invalid function: bool start_array(std::size_t)");
9162  "Missing/invalid function: bool end_array()");
9163  static_assert(
9165  "Missing/invalid function: bool parse_error(std::size_t, const "
9166  "std::string&, const exception&)");
9167 };
9168 
9169 } // namespace detail
9171 
9172 // #include <nlohmann/detail/meta/type_traits.hpp>
9173 
9174 // #include <nlohmann/detail/string_concat.hpp>
9175 
9176 // #include <nlohmann/detail/value_t.hpp>
9177 
9178 
9180 namespace detail
9181 {
9182 
9185 {
9186  error,
9187  ignore,
9188  store
9189 };
9190 
9198 static inline bool little_endianness(int num = 1) noexcept
9199 {
9200  return *reinterpret_cast<char*>(&num) == 1;
9201 }
9202 
9204 // binary reader //
9206 
9210 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
9212 {
9213  using number_integer_t = typename BasicJsonType::number_integer_t;
9214  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9215  using number_float_t = typename BasicJsonType::number_float_t;
9216  using string_t = typename BasicJsonType::string_t;
9217  using binary_t = typename BasicJsonType::binary_t;
9218  using json_sax_t = SAX;
9221 
9222  public:
9228  explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
9229  {
9231  }
9232 
9233  // make class move-only
9234  binary_reader(const binary_reader&) = delete;
9235  binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9236  binary_reader& operator=(const binary_reader&) = delete;
9237  binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9238  ~binary_reader() = default;
9239 
9249  bool sax_parse(const input_format_t format,
9250  json_sax_t* sax_,
9251  const bool strict = true,
9252  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
9253  {
9254  sax = sax_;
9255  bool result = false;
9256 
9257  switch (format)
9258  {
9259  case input_format_t::bson:
9260  result = parse_bson_internal();
9261  break;
9262 
9263  case input_format_t::cbor:
9264  result = parse_cbor_internal(true, tag_handler);
9265  break;
9266 
9267  case input_format_t::msgpack:
9268  result = parse_msgpack_internal();
9269  break;
9270 
9271  case input_format_t::ubjson:
9272  case input_format_t::bjdata:
9273  result = parse_ubjson_internal();
9274  break;
9275 
9276  case input_format_t::json: // LCOV_EXCL_LINE
9277  default: // LCOV_EXCL_LINE
9278  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9279  }
9280 
9281  // strict mode: next byte must be EOF
9282  if (result && strict)
9283  {
9284  if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
9285  {
9286  get_ignore_noop();
9287  }
9288  else
9289  {
9290  get();
9291  }
9292 
9294  {
9295  return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
9296  exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
9297  }
9298  }
9299 
9300  return result;
9301  }
9302 
9303  private:
9305  // BSON //
9307 
9313  {
9314  std::int32_t document_size{};
9315  get_number<std::int32_t, true>(input_format_t::bson, document_size);
9316 
9317  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
9318  {
9319  return false;
9320  }
9321 
9322  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
9323  {
9324  return false;
9325  }
9326 
9327  return sax->end_object();
9328  }
9329 
9337  bool get_bson_cstr(string_t& result)
9338  {
9339  auto out = std::back_inserter(result);
9340  while (true)
9341  {
9342  get();
9343  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
9344  {
9345  return false;
9346  }
9347  if (current == 0x00)
9348  {
9349  return true;
9350  }
9351  *out++ = static_cast<typename string_t::value_type>(current);
9352  }
9353  }
9354 
9366  template<typename NumberType>
9367  bool get_bson_string(const NumberType len, string_t& result)
9368  {
9369  if (JSON_HEDLEY_UNLIKELY(len < 1))
9370  {
9371  auto last_token = get_token_string();
9372  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9373  exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
9374  }
9375 
9376  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != char_traits<char_type>::eof();
9377  }
9378 
9388  template<typename NumberType>
9389  bool get_bson_binary(const NumberType len, binary_t& result)
9390  {
9391  if (JSON_HEDLEY_UNLIKELY(len < 0))
9392  {
9393  auto last_token = get_token_string();
9394  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9395  exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
9396  }
9397 
9398  // All BSON binary values have a subtype
9399  std::uint8_t subtype{};
9400  get_number<std::uint8_t>(input_format_t::bson, subtype);
9401  result.set_subtype(subtype);
9402 
9403  return get_binary(input_format_t::bson, len, result);
9404  }
9405 
9417  const std::size_t element_type_parse_position)
9418  {
9419  switch (element_type)
9420  {
9421  case 0x01: // double
9422  {
9423  double number{};
9424  return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9425  }
9426 
9427  case 0x02: // string
9428  {
9429  std::int32_t len{};
9430  string_t value;
9431  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
9432  }
9433 
9434  case 0x03: // object
9435  {
9436  return parse_bson_internal();
9437  }
9438 
9439  case 0x04: // array
9440  {
9441  return parse_bson_array();
9442  }
9443 
9444  case 0x05: // binary
9445  {
9446  std::int32_t len{};
9447  binary_t value;
9448  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
9449  }
9450 
9451  case 0x08: // boolean
9452  {
9453  return sax->boolean(get() != 0);
9454  }
9455 
9456  case 0x0A: // null
9457  {
9458  return sax->null();
9459  }
9460 
9461  case 0x10: // int32
9462  {
9463  std::int32_t value{};
9464  return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9465  }
9466 
9467  case 0x12: // int64
9468  {
9469  std::int64_t value{};
9470  return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9471  }
9472 
9473  default: // anything else not supported (yet)
9474  {
9475  std::array<char, 3> cr{{}};
9476  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
9477  const std::string cr_str{cr.data()};
9478  return sax->parse_error(element_type_parse_position, cr_str,
9479  parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
9480  }
9481  }
9482  }
9483 
9496  bool parse_bson_element_list(const bool is_array)
9497  {
9498  string_t key;
9499 
9500  while (auto element_type = get())
9501  {
9502  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
9503  {
9504  return false;
9505  }
9506 
9507  const std::size_t element_type_parse_position = chars_read;
9508  if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
9509  {
9510  return false;
9511  }
9512 
9513  if (!is_array && !sax->key(key))
9514  {
9515  return false;
9516  }
9517 
9518  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
9519  {
9520  return false;
9521  }
9522 
9523  // get_bson_cstr only appends
9524  key.clear();
9525  }
9526 
9527  return true;
9528  }
9529 
9535  {
9536  std::int32_t document_size{};
9537  get_number<std::int32_t, true>(input_format_t::bson, document_size);
9538 
9539  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
9540  {
9541  return false;
9542  }
9543 
9544  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
9545  {
9546  return false;
9547  }
9548 
9549  return sax->end_array();
9550  }
9551 
9553  // CBOR //
9555 
9564  bool parse_cbor_internal(const bool get_char,
9565  const cbor_tag_handler_t tag_handler)
9566  {
9567  switch (get_char ? get() : current)
9568  {
9569  // EOF
9571  return unexpect_eof(input_format_t::cbor, "value");
9572 
9573  // Integer 0x00..0x17 (0..23)
9574  case 0x00:
9575  case 0x01:
9576  case 0x02:
9577  case 0x03:
9578  case 0x04:
9579  case 0x05:
9580  case 0x06:
9581  case 0x07:
9582  case 0x08:
9583  case 0x09:
9584  case 0x0A:
9585  case 0x0B:
9586  case 0x0C:
9587  case 0x0D:
9588  case 0x0E:
9589  case 0x0F:
9590  case 0x10:
9591  case 0x11:
9592  case 0x12:
9593  case 0x13:
9594  case 0x14:
9595  case 0x15:
9596  case 0x16:
9597  case 0x17:
9598  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9599 
9600  case 0x18: // Unsigned integer (one-byte uint8_t follows)
9601  {
9602  std::uint8_t number{};
9603  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9604  }
9605 
9606  case 0x19: // Unsigned integer (two-byte uint16_t follows)
9607  {
9608  std::uint16_t number{};
9609  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9610  }
9611 
9612  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
9613  {
9614  std::uint32_t number{};
9615  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9616  }
9617 
9618  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
9619  {
9620  std::uint64_t number{};
9621  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9622  }
9623 
9624  // Negative integer -1-0x00..-1-0x17 (-1..-24)
9625  case 0x20:
9626  case 0x21:
9627  case 0x22:
9628  case 0x23:
9629  case 0x24:
9630  case 0x25:
9631  case 0x26:
9632  case 0x27:
9633  case 0x28:
9634  case 0x29:
9635  case 0x2A:
9636  case 0x2B:
9637  case 0x2C:
9638  case 0x2D:
9639  case 0x2E:
9640  case 0x2F:
9641  case 0x30:
9642  case 0x31:
9643  case 0x32:
9644  case 0x33:
9645  case 0x34:
9646  case 0x35:
9647  case 0x36:
9648  case 0x37:
9649  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
9650 
9651  case 0x38: // Negative integer (one-byte uint8_t follows)
9652  {
9653  std::uint8_t number{};
9654  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9655  }
9656 
9657  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
9658  {
9659  std::uint16_t number{};
9660  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9661  }
9662 
9663  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
9664  {
9665  std::uint32_t number{};
9666  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9667  }
9668 
9669  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
9670  {
9671  std::uint64_t number{};
9672  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
9673  - static_cast<number_integer_t>(number));
9674  }
9675 
9676  // Binary data (0x00..0x17 bytes follow)
9677  case 0x40:
9678  case 0x41:
9679  case 0x42:
9680  case 0x43:
9681  case 0x44:
9682  case 0x45:
9683  case 0x46:
9684  case 0x47:
9685  case 0x48:
9686  case 0x49:
9687  case 0x4A:
9688  case 0x4B:
9689  case 0x4C:
9690  case 0x4D:
9691  case 0x4E:
9692  case 0x4F:
9693  case 0x50:
9694  case 0x51:
9695  case 0x52:
9696  case 0x53:
9697  case 0x54:
9698  case 0x55:
9699  case 0x56:
9700  case 0x57:
9701  case 0x58: // Binary data (one-byte uint8_t for n follows)
9702  case 0x59: // Binary data (two-byte uint16_t for n follow)
9703  case 0x5A: // Binary data (four-byte uint32_t for n follow)
9704  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9705  case 0x5F: // Binary data (indefinite length)
9706  {
9707  binary_t b;
9708  return get_cbor_binary(b) && sax->binary(b);
9709  }
9710 
9711  // UTF-8 string (0x00..0x17 bytes follow)
9712  case 0x60:
9713  case 0x61:
9714  case 0x62:
9715  case 0x63:
9716  case 0x64:
9717  case 0x65:
9718  case 0x66:
9719  case 0x67:
9720  case 0x68:
9721  case 0x69:
9722  case 0x6A:
9723  case 0x6B:
9724  case 0x6C:
9725  case 0x6D:
9726  case 0x6E:
9727  case 0x6F:
9728  case 0x70:
9729  case 0x71:
9730  case 0x72:
9731  case 0x73:
9732  case 0x74:
9733  case 0x75:
9734  case 0x76:
9735  case 0x77:
9736  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9737  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9738  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9739  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9740  case 0x7F: // UTF-8 string (indefinite length)
9741  {
9742  string_t s;
9743  return get_cbor_string(s) && sax->string(s);
9744  }
9745 
9746  // array (0x00..0x17 data items follow)
9747  case 0x80:
9748  case 0x81:
9749  case 0x82:
9750  case 0x83:
9751  case 0x84:
9752  case 0x85:
9753  case 0x86:
9754  case 0x87:
9755  case 0x88:
9756  case 0x89:
9757  case 0x8A:
9758  case 0x8B:
9759  case 0x8C:
9760  case 0x8D:
9761  case 0x8E:
9762  case 0x8F:
9763  case 0x90:
9764  case 0x91:
9765  case 0x92:
9766  case 0x93:
9767  case 0x94:
9768  case 0x95:
9769  case 0x96:
9770  case 0x97:
9771  return get_cbor_array(
9772  conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9773 
9774  case 0x98: // array (one-byte uint8_t for n follows)
9775  {
9776  std::uint8_t len{};
9777  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9778  }
9779 
9780  case 0x99: // array (two-byte uint16_t for n follow)
9781  {
9782  std::uint16_t len{};
9783  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9784  }
9785 
9786  case 0x9A: // array (four-byte uint32_t for n follow)
9787  {
9788  std::uint32_t len{};
9789  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9790  }
9791 
9792  case 0x9B: // array (eight-byte uint64_t for n follow)
9793  {
9794  std::uint64_t len{};
9795  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9796  }
9797 
9798  case 0x9F: // array (indefinite length)
9799  return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9800 
9801  // map (0x00..0x17 pairs of data items follow)
9802  case 0xA0:
9803  case 0xA1:
9804  case 0xA2:
9805  case 0xA3:
9806  case 0xA4:
9807  case 0xA5:
9808  case 0xA6:
9809  case 0xA7:
9810  case 0xA8:
9811  case 0xA9:
9812  case 0xAA:
9813  case 0xAB:
9814  case 0xAC:
9815  case 0xAD:
9816  case 0xAE:
9817  case 0xAF:
9818  case 0xB0:
9819  case 0xB1:
9820  case 0xB2:
9821  case 0xB3:
9822  case 0xB4:
9823  case 0xB5:
9824  case 0xB6:
9825  case 0xB7:
9826  return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9827 
9828  case 0xB8: // map (one-byte uint8_t for n follows)
9829  {
9830  std::uint8_t len{};
9831  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9832  }
9833 
9834  case 0xB9: // map (two-byte uint16_t for n follow)
9835  {
9836  std::uint16_t len{};
9837  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9838  }
9839 
9840  case 0xBA: // map (four-byte uint32_t for n follow)
9841  {
9842  std::uint32_t len{};
9843  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9844  }
9845 
9846  case 0xBB: // map (eight-byte uint64_t for n follow)
9847  {
9848  std::uint64_t len{};
9849  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9850  }
9851 
9852  case 0xBF: // map (indefinite length)
9853  return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9854 
9855  case 0xC6: // tagged item
9856  case 0xC7:
9857  case 0xC8:
9858  case 0xC9:
9859  case 0xCA:
9860  case 0xCB:
9861  case 0xCC:
9862  case 0xCD:
9863  case 0xCE:
9864  case 0xCF:
9865  case 0xD0:
9866  case 0xD1:
9867  case 0xD2:
9868  case 0xD3:
9869  case 0xD4:
9870  case 0xD8: // tagged item (1 bytes follow)
9871  case 0xD9: // tagged item (2 bytes follow)
9872  case 0xDA: // tagged item (4 bytes follow)
9873  case 0xDB: // tagged item (8 bytes follow)
9874  {
9875  switch (tag_handler)
9876  {
9878  {
9879  auto last_token = get_token_string();
9880  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9881  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9882  }
9883 
9884  case cbor_tag_handler_t::ignore:
9885  {
9886  // ignore binary subtype
9887  switch (current)
9888  {
9889  case 0xD8:
9890  {
9891  std::uint8_t subtype_to_ignore{};
9892  get_number(input_format_t::cbor, subtype_to_ignore);
9893  break;
9894  }
9895  case 0xD9:
9896  {
9897  std::uint16_t subtype_to_ignore{};
9898  get_number(input_format_t::cbor, subtype_to_ignore);
9899  break;
9900  }
9901  case 0xDA:
9902  {
9903  std::uint32_t subtype_to_ignore{};
9904  get_number(input_format_t::cbor, subtype_to_ignore);
9905  break;
9906  }
9907  case 0xDB:
9908  {
9909  std::uint64_t subtype_to_ignore{};
9910  get_number(input_format_t::cbor, subtype_to_ignore);
9911  break;
9912  }
9913  default:
9914  break;
9915  }
9916  return parse_cbor_internal(true, tag_handler);
9917  }
9918 
9919  case cbor_tag_handler_t::store:
9920  {
9921  binary_t b;
9922  // use binary subtype and store in binary container
9923  switch (current)
9924  {
9925  case 0xD8:
9926  {
9927  std::uint8_t subtype{};
9928  get_number(input_format_t::cbor, subtype);
9929  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9930  break;
9931  }
9932  case 0xD9:
9933  {
9934  std::uint16_t subtype{};
9935  get_number(input_format_t::cbor, subtype);
9936  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9937  break;
9938  }
9939  case 0xDA:
9940  {
9941  std::uint32_t subtype{};
9942  get_number(input_format_t::cbor, subtype);
9943  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9944  break;
9945  }
9946  case 0xDB:
9947  {
9948  std::uint64_t subtype{};
9949  get_number(input_format_t::cbor, subtype);
9950  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9951  break;
9952  }
9953  default:
9954  return parse_cbor_internal(true, tag_handler);
9955  }
9956  get();
9957  return get_cbor_binary(b) && sax->binary(b);
9958  }
9959 
9960  default: // LCOV_EXCL_LINE
9961  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9962  return false; // LCOV_EXCL_LINE
9963  }
9964  }
9965 
9966  case 0xF4: // false
9967  return sax->boolean(false);
9968 
9969  case 0xF5: // true
9970  return sax->boolean(true);
9971 
9972  case 0xF6: // null
9973  return sax->null();
9974 
9975  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9976  {
9977  const auto byte1_raw = get();
9978  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9979  {
9980  return false;
9981  }
9982  const auto byte2_raw = get();
9983  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9984  {
9985  return false;
9986  }
9987 
9988  const auto byte1 = static_cast<unsigned char>(byte1_raw);
9989  const auto byte2 = static_cast<unsigned char>(byte2_raw);
9990 
9991  // code from RFC 7049, Appendix D, Figure 3:
9992  // As half-precision floating-point numbers were only added
9993  // to IEEE 754 in 2008, today's programming platforms often
9994  // still only have limited support for them. It is very
9995  // easy to include at least decoding support for them even
9996  // without such support. An example of a small decoder for
9997  // half-precision floating-point numbers in the C language
9998  // is shown in Fig. 3.
9999  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
10000  const double val = [&half]
10001  {
10002  const int exp = (half >> 10u) & 0x1Fu;
10003  const unsigned int mant = half & 0x3FFu;
10004  JSON_ASSERT(0 <= exp&& exp <= 32);
10005  JSON_ASSERT(mant <= 1024);
10006  switch (exp)
10007  {
10008  case 0:
10009  return std::ldexp(mant, -24);
10010  case 31:
10011  return (mant == 0)
10012  ? std::numeric_limits<double>::infinity()
10013  : std::numeric_limits<double>::quiet_NaN();
10014  default:
10015  return std::ldexp(mant + 1024, exp - 25);
10016  }
10017  }();
10018  return sax->number_float((half & 0x8000u) != 0
10019  ? static_cast<number_float_t>(-val)
10020  : static_cast<number_float_t>(val), "");
10021  }
10022 
10023  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
10024  {
10025  float number{};
10026  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
10027  }
10028 
10029  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
10030  {
10031  double number{};
10032  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
10033  }
10034 
10035  default: // anything else (0xFF is handled inside the other types)
10036  {
10037  auto last_token = get_token_string();
10038  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10039  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
10040  }
10041  }
10042  }
10043 
10056  {
10057  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
10058  {
10059  return false;
10060  }
10061 
10062  switch (current)
10063  {
10064  // UTF-8 string (0x00..0x17 bytes follow)
10065  case 0x60:
10066  case 0x61:
10067  case 0x62:
10068  case 0x63:
10069  case 0x64:
10070  case 0x65:
10071  case 0x66:
10072  case 0x67:
10073  case 0x68:
10074  case 0x69:
10075  case 0x6A:
10076  case 0x6B:
10077  case 0x6C:
10078  case 0x6D:
10079  case 0x6E:
10080  case 0x6F:
10081  case 0x70:
10082  case 0x71:
10083  case 0x72:
10084  case 0x73:
10085  case 0x74:
10086  case 0x75:
10087  case 0x76:
10088  case 0x77:
10089  {
10090  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10091  }
10092 
10093  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
10094  {
10095  std::uint8_t len{};
10096  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10097  }
10098 
10099  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
10100  {
10101  std::uint16_t len{};
10102  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10103  }
10104 
10105  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
10106  {
10107  std::uint32_t len{};
10108  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10109  }
10110 
10111  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
10112  {
10113  std::uint64_t len{};
10114  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10115  }
10116 
10117  case 0x7F: // UTF-8 string (indefinite length)
10118  {
10119  while (get() != 0xFF)
10120  {
10121  string_t chunk;
10122  if (!get_cbor_string(chunk))
10123  {
10124  return false;
10125  }
10126  result.append(chunk);
10127  }
10128  return true;
10129  }
10130 
10131  default:
10132  {
10133  auto last_token = get_token_string();
10134  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10135  exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
10136  }
10137  }
10138  }
10139 
10152  {
10153  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
10154  {
10155  return false;
10156  }
10157 
10158  switch (current)
10159  {
10160  // Binary data (0x00..0x17 bytes follow)
10161  case 0x40:
10162  case 0x41:
10163  case 0x42:
10164  case 0x43:
10165  case 0x44:
10166  case 0x45:
10167  case 0x46:
10168  case 0x47:
10169  case 0x48:
10170  case 0x49:
10171  case 0x4A:
10172  case 0x4B:
10173  case 0x4C:
10174  case 0x4D:
10175  case 0x4E:
10176  case 0x4F:
10177  case 0x50:
10178  case 0x51:
10179  case 0x52:
10180  case 0x53:
10181  case 0x54:
10182  case 0x55:
10183  case 0x56:
10184  case 0x57:
10185  {
10186  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10187  }
10188 
10189  case 0x58: // Binary data (one-byte uint8_t for n follows)
10190  {
10191  std::uint8_t len{};
10192  return get_number(input_format_t::cbor, len) &&
10193  get_binary(input_format_t::cbor, len, result);
10194  }
10195 
10196  case 0x59: // Binary data (two-byte uint16_t for n follow)
10197  {
10198  std::uint16_t len{};
10199  return get_number(input_format_t::cbor, len) &&
10200  get_binary(input_format_t::cbor, len, result);
10201  }
10202 
10203  case 0x5A: // Binary data (four-byte uint32_t for n follow)
10204  {
10205  std::uint32_t len{};
10206  return get_number(input_format_t::cbor, len) &&
10207  get_binary(input_format_t::cbor, len, result);
10208  }
10209 
10210  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10211  {
10212  std::uint64_t len{};
10213  return get_number(input_format_t::cbor, len) &&
10214  get_binary(input_format_t::cbor, len, result);
10215  }
10216 
10217  case 0x5F: // Binary data (indefinite length)
10218  {
10219  while (get() != 0xFF)
10220  {
10221  binary_t chunk;
10222  if (!get_cbor_binary(chunk))
10223  {
10224  return false;
10225  }
10226  result.insert(result.end(), chunk.begin(), chunk.end());
10227  }
10228  return true;
10229  }
10230 
10231  default:
10232  {
10233  auto last_token = get_token_string();
10234  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10235  exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));
10236  }
10237  }
10238  }
10239 
10246  bool get_cbor_array(const std::size_t len,
10247  const cbor_tag_handler_t tag_handler)
10248  {
10249  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10250  {
10251  return false;
10252  }
10253 
10254  if (len != static_cast<std::size_t>(-1))
10255  {
10256  for (std::size_t i = 0; i < len; ++i)
10257  {
10258  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10259  {
10260  return false;
10261  }
10262  }
10263  }
10264  else
10265  {
10266  while (get() != 0xFF)
10267  {
10268  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
10269  {
10270  return false;
10271  }
10272  }
10273  }
10274 
10275  return sax->end_array();
10276  }
10277 
10284  bool get_cbor_object(const std::size_t len,
10285  const cbor_tag_handler_t tag_handler)
10286  {
10287  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10288  {
10289  return false;
10290  }
10291 
10292  if (len != 0)
10293  {
10294  string_t key;
10295  if (len != static_cast<std::size_t>(-1))
10296  {
10297  for (std::size_t i = 0; i < len; ++i)
10298  {
10299  get();
10300  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10301  {
10302  return false;
10303  }
10304 
10305  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10306  {
10307  return false;
10308  }
10309  key.clear();
10310  }
10311  }
10312  else
10313  {
10314  while (get() != 0xFF)
10315  {
10316  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10317  {
10318  return false;
10319  }
10320 
10321  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10322  {
10323  return false;
10324  }
10325  key.clear();
10326  }
10327  }
10328  }
10329 
10330  return sax->end_object();
10331  }
10332 
10334  // MsgPack //
10336 
10341  {
10342  switch (get())
10343  {
10344  // EOF
10346  return unexpect_eof(input_format_t::msgpack, "value");
10347 
10348  // positive fixint
10349  case 0x00:
10350  case 0x01:
10351  case 0x02:
10352  case 0x03:
10353  case 0x04:
10354  case 0x05:
10355  case 0x06:
10356  case 0x07:
10357  case 0x08:
10358  case 0x09:
10359  case 0x0A:
10360  case 0x0B:
10361  case 0x0C:
10362  case 0x0D:
10363  case 0x0E:
10364  case 0x0F:
10365  case 0x10:
10366  case 0x11:
10367  case 0x12:
10368  case 0x13:
10369  case 0x14:
10370  case 0x15:
10371  case 0x16:
10372  case 0x17:
10373  case 0x18:
10374  case 0x19:
10375  case 0x1A:
10376  case 0x1B:
10377  case 0x1C:
10378  case 0x1D:
10379  case 0x1E:
10380  case 0x1F:
10381  case 0x20:
10382  case 0x21:
10383  case 0x22:
10384  case 0x23:
10385  case 0x24:
10386  case 0x25:
10387  case 0x26:
10388  case 0x27:
10389  case 0x28:
10390  case 0x29:
10391  case 0x2A:
10392  case 0x2B:
10393  case 0x2C:
10394  case 0x2D:
10395  case 0x2E:
10396  case 0x2F:
10397  case 0x30:
10398  case 0x31:
10399  case 0x32:
10400  case 0x33:
10401  case 0x34:
10402  case 0x35:
10403  case 0x36:
10404  case 0x37:
10405  case 0x38:
10406  case 0x39:
10407  case 0x3A:
10408  case 0x3B:
10409  case 0x3C:
10410  case 0x3D:
10411  case 0x3E:
10412  case 0x3F:
10413  case 0x40:
10414  case 0x41:
10415  case 0x42:
10416  case 0x43:
10417  case 0x44:
10418  case 0x45:
10419  case 0x46:
10420  case 0x47:
10421  case 0x48:
10422  case 0x49:
10423  case 0x4A:
10424  case 0x4B:
10425  case 0x4C:
10426  case 0x4D:
10427  case 0x4E:
10428  case 0x4F:
10429  case 0x50:
10430  case 0x51:
10431  case 0x52:
10432  case 0x53:
10433  case 0x54:
10434  case 0x55:
10435  case 0x56:
10436  case 0x57:
10437  case 0x58:
10438  case 0x59:
10439  case 0x5A:
10440  case 0x5B:
10441  case 0x5C:
10442  case 0x5D:
10443  case 0x5E:
10444  case 0x5F:
10445  case 0x60:
10446  case 0x61:
10447  case 0x62:
10448  case 0x63:
10449  case 0x64:
10450  case 0x65:
10451  case 0x66:
10452  case 0x67:
10453  case 0x68:
10454  case 0x69:
10455  case 0x6A:
10456  case 0x6B:
10457  case 0x6C:
10458  case 0x6D:
10459  case 0x6E:
10460  case 0x6F:
10461  case 0x70:
10462  case 0x71:
10463  case 0x72:
10464  case 0x73:
10465  case 0x74:
10466  case 0x75:
10467  case 0x76:
10468  case 0x77:
10469  case 0x78:
10470  case 0x79:
10471  case 0x7A:
10472  case 0x7B:
10473  case 0x7C:
10474  case 0x7D:
10475  case 0x7E:
10476  case 0x7F:
10477  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
10478 
10479  // fixmap
10480  case 0x80:
10481  case 0x81:
10482  case 0x82:
10483  case 0x83:
10484  case 0x84:
10485  case 0x85:
10486  case 0x86:
10487  case 0x87:
10488  case 0x88:
10489  case 0x89:
10490  case 0x8A:
10491  case 0x8B:
10492  case 0x8C:
10493  case 0x8D:
10494  case 0x8E:
10495  case 0x8F:
10496  return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10497 
10498  // fixarray
10499  case 0x90:
10500  case 0x91:
10501  case 0x92:
10502  case 0x93:
10503  case 0x94:
10504  case 0x95:
10505  case 0x96:
10506  case 0x97:
10507  case 0x98:
10508  case 0x99:
10509  case 0x9A:
10510  case 0x9B:
10511  case 0x9C:
10512  case 0x9D:
10513  case 0x9E:
10514  case 0x9F:
10515  return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10516 
10517  // fixstr
10518  case 0xA0:
10519  case 0xA1:
10520  case 0xA2:
10521  case 0xA3:
10522  case 0xA4:
10523  case 0xA5:
10524  case 0xA6:
10525  case 0xA7:
10526  case 0xA8:
10527  case 0xA9:
10528  case 0xAA:
10529  case 0xAB:
10530  case 0xAC:
10531  case 0xAD:
10532  case 0xAE:
10533  case 0xAF:
10534  case 0xB0:
10535  case 0xB1:
10536  case 0xB2:
10537  case 0xB3:
10538  case 0xB4:
10539  case 0xB5:
10540  case 0xB6:
10541  case 0xB7:
10542  case 0xB8:
10543  case 0xB9:
10544  case 0xBA:
10545  case 0xBB:
10546  case 0xBC:
10547  case 0xBD:
10548  case 0xBE:
10549  case 0xBF:
10550  case 0xD9: // str 8
10551  case 0xDA: // str 16
10552  case 0xDB: // str 32
10553  {
10554  string_t s;
10555  return get_msgpack_string(s) && sax->string(s);
10556  }
10557 
10558  case 0xC0: // nil
10559  return sax->null();
10560 
10561  case 0xC2: // false
10562  return sax->boolean(false);
10563 
10564  case 0xC3: // true
10565  return sax->boolean(true);
10566 
10567  case 0xC4: // bin 8
10568  case 0xC5: // bin 16
10569  case 0xC6: // bin 32
10570  case 0xC7: // ext 8
10571  case 0xC8: // ext 16
10572  case 0xC9: // ext 32
10573  case 0xD4: // fixext 1
10574  case 0xD5: // fixext 2
10575  case 0xD6: // fixext 4
10576  case 0xD7: // fixext 8
10577  case 0xD8: // fixext 16
10578  {
10579  binary_t b;
10580  return get_msgpack_binary(b) && sax->binary(b);
10581  }
10582 
10583  case 0xCA: // float 32
10584  {
10585  float number{};
10586  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10587  }
10588 
10589  case 0xCB: // float 64
10590  {
10591  double number{};
10592  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10593  }
10594 
10595  case 0xCC: // uint 8
10596  {
10597  std::uint8_t number{};
10598  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10599  }
10600 
10601  case 0xCD: // uint 16
10602  {
10603  std::uint16_t number{};
10604  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10605  }
10606 
10607  case 0xCE: // uint 32
10608  {
10609  std::uint32_t number{};
10610  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10611  }
10612 
10613  case 0xCF: // uint 64
10614  {
10615  std::uint64_t number{};
10616  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10617  }
10618 
10619  case 0xD0: // int 8
10620  {
10621  std::int8_t number{};
10622  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10623  }
10624 
10625  case 0xD1: // int 16
10626  {
10627  std::int16_t number{};
10628  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10629  }
10630 
10631  case 0xD2: // int 32
10632  {
10633  std::int32_t number{};
10634  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10635  }
10636 
10637  case 0xD3: // int 64
10638  {
10639  std::int64_t number{};
10640  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10641  }
10642 
10643  case 0xDC: // array 16
10644  {
10645  std::uint16_t len{};
10646  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
10647  }
10648 
10649  case 0xDD: // array 32
10650  {
10651  std::uint32_t len{};
10652  return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));
10653  }
10654 
10655  case 0xDE: // map 16
10656  {
10657  std::uint16_t len{};
10658  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
10659  }
10660 
10661  case 0xDF: // map 32
10662  {
10663  std::uint32_t len{};
10664  return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));
10665  }
10666 
10667  // negative fixint
10668  case 0xE0:
10669  case 0xE1:
10670  case 0xE2:
10671  case 0xE3:
10672  case 0xE4:
10673  case 0xE5:
10674  case 0xE6:
10675  case 0xE7:
10676  case 0xE8:
10677  case 0xE9:
10678  case 0xEA:
10679  case 0xEB:
10680  case 0xEC:
10681  case 0xED:
10682  case 0xEE:
10683  case 0xEF:
10684  case 0xF0:
10685  case 0xF1:
10686  case 0xF2:
10687  case 0xF3:
10688  case 0xF4:
10689  case 0xF5:
10690  case 0xF6:
10691  case 0xF7:
10692  case 0xF8:
10693  case 0xF9:
10694  case 0xFA:
10695  case 0xFB:
10696  case 0xFC:
10697  case 0xFD:
10698  case 0xFE:
10699  case 0xFF:
10700  return sax->number_integer(static_cast<std::int8_t>(current));
10701 
10702  default: // anything else
10703  {
10704  auto last_token = get_token_string();
10705  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10706  exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10707  }
10708  }
10709  }
10710 
10722  {
10723  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
10724  {
10725  return false;
10726  }
10727 
10728  switch (current)
10729  {
10730  // fixstr
10731  case 0xA0:
10732  case 0xA1:
10733  case 0xA2:
10734  case 0xA3:
10735  case 0xA4:
10736  case 0xA5:
10737  case 0xA6:
10738  case 0xA7:
10739  case 0xA8:
10740  case 0xA9:
10741  case 0xAA:
10742  case 0xAB:
10743  case 0xAC:
10744  case 0xAD:
10745  case 0xAE:
10746  case 0xAF:
10747  case 0xB0:
10748  case 0xB1:
10749  case 0xB2:
10750  case 0xB3:
10751  case 0xB4:
10752  case 0xB5:
10753  case 0xB6:
10754  case 0xB7:
10755  case 0xB8:
10756  case 0xB9:
10757  case 0xBA:
10758  case 0xBB:
10759  case 0xBC:
10760  case 0xBD:
10761  case 0xBE:
10762  case 0xBF:
10763  {
10764  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10765  }
10766 
10767  case 0xD9: // str 8
10768  {
10769  std::uint8_t len{};
10770  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10771  }
10772 
10773  case 0xDA: // str 16
10774  {
10775  std::uint16_t len{};
10776  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10777  }
10778 
10779  case 0xDB: // str 32
10780  {
10781  std::uint32_t len{};
10782  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10783  }
10784 
10785  default:
10786  {
10787  auto last_token = get_token_string();
10788  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10789  exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10790  }
10791  }
10792  }
10793 
10805  {
10806  // helper function to set the subtype
10807  auto assign_and_return_true = [&result](std::int8_t subtype)
10808  {
10809  result.set_subtype(static_cast<std::uint8_t>(subtype));
10810  return true;
10811  };
10812 
10813  switch (current)
10814  {
10815  case 0xC4: // bin 8
10816  {
10817  std::uint8_t len{};
10818  return get_number(input_format_t::msgpack, len) &&
10819  get_binary(input_format_t::msgpack, len, result);
10820  }
10821 
10822  case 0xC5: // bin 16
10823  {
10824  std::uint16_t len{};
10825  return get_number(input_format_t::msgpack, len) &&
10826  get_binary(input_format_t::msgpack, len, result);
10827  }
10828 
10829  case 0xC6: // bin 32
10830  {
10831  std::uint32_t len{};
10832  return get_number(input_format_t::msgpack, len) &&
10833  get_binary(input_format_t::msgpack, len, result);
10834  }
10835 
10836  case 0xC7: // ext 8
10837  {
10838  std::uint8_t len{};
10839  std::int8_t subtype{};
10840  return get_number(input_format_t::msgpack, len) &&
10841  get_number(input_format_t::msgpack, subtype) &&
10842  get_binary(input_format_t::msgpack, len, result) &&
10843  assign_and_return_true(subtype);
10844  }
10845 
10846  case 0xC8: // ext 16
10847  {
10848  std::uint16_t len{};
10849  std::int8_t subtype{};
10850  return get_number(input_format_t::msgpack, len) &&
10851  get_number(input_format_t::msgpack, subtype) &&
10852  get_binary(input_format_t::msgpack, len, result) &&
10853  assign_and_return_true(subtype);
10854  }
10855 
10856  case 0xC9: // ext 32
10857  {
10858  std::uint32_t len{};
10859  std::int8_t subtype{};
10860  return get_number(input_format_t::msgpack, len) &&
10861  get_number(input_format_t::msgpack, subtype) &&
10862  get_binary(input_format_t::msgpack, len, result) &&
10863  assign_and_return_true(subtype);
10864  }
10865 
10866  case 0xD4: // fixext 1
10867  {
10868  std::int8_t subtype{};
10869  return get_number(input_format_t::msgpack, subtype) &&
10870  get_binary(input_format_t::msgpack, 1, result) &&
10871  assign_and_return_true(subtype);
10872  }
10873 
10874  case 0xD5: // fixext 2
10875  {
10876  std::int8_t subtype{};
10877  return get_number(input_format_t::msgpack, subtype) &&
10878  get_binary(input_format_t::msgpack, 2, result) &&
10879  assign_and_return_true(subtype);
10880  }
10881 
10882  case 0xD6: // fixext 4
10883  {
10884  std::int8_t subtype{};
10885  return get_number(input_format_t::msgpack, subtype) &&
10886  get_binary(input_format_t::msgpack, 4, result) &&
10887  assign_and_return_true(subtype);
10888  }
10889 
10890  case 0xD7: // fixext 8
10891  {
10892  std::int8_t subtype{};
10893  return get_number(input_format_t::msgpack, subtype) &&
10894  get_binary(input_format_t::msgpack, 8, result) &&
10895  assign_and_return_true(subtype);
10896  }
10897 
10898  case 0xD8: // fixext 16
10899  {
10900  std::int8_t subtype{};
10901  return get_number(input_format_t::msgpack, subtype) &&
10902  get_binary(input_format_t::msgpack, 16, result) &&
10903  assign_and_return_true(subtype);
10904  }
10905 
10906  default: // LCOV_EXCL_LINE
10907  return false; // LCOV_EXCL_LINE
10908  }
10909  }
10910 
10915  bool get_msgpack_array(const std::size_t len)
10916  {
10917  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10918  {
10919  return false;
10920  }
10921 
10922  for (std::size_t i = 0; i < len; ++i)
10923  {
10924  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10925  {
10926  return false;
10927  }
10928  }
10929 
10930  return sax->end_array();
10931  }
10932 
10937  bool get_msgpack_object(const std::size_t len)
10938  {
10939  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10940  {
10941  return false;
10942  }
10943 
10944  string_t key;
10945  for (std::size_t i = 0; i < len; ++i)
10946  {
10947  get();
10948  if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10949  {
10950  return false;
10951  }
10952 
10953  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10954  {
10955  return false;
10956  }
10957  key.clear();
10958  }
10959 
10960  return sax->end_object();
10961  }
10962 
10964  // UBJSON //
10966 
10974  bool parse_ubjson_internal(const bool get_char = true)
10975  {
10976  return get_ubjson_value(get_char ? get_ignore_noop() : current);
10977  }
10978 
10993  bool get_ubjson_string(string_t& result, const bool get_char = true)
10994  {
10995  if (get_char)
10996  {
10997  get(); // TODO(niels): may we ignore N here?
10998  }
10999 
11000  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
11001  {
11002  return false;
11003  }
11004 
11005  switch (current)
11006  {
11007  case 'U':
11008  {
11009  std::uint8_t len{};
11010  return get_number(input_format, len) && get_string(input_format, len, result);
11011  }
11012 
11013  case 'i':
11014  {
11015  std::int8_t len{};
11016  return get_number(input_format, len) && get_string(input_format, len, result);
11017  }
11018 
11019  case 'I':
11020  {
11021  std::int16_t len{};
11022  return get_number(input_format, len) && get_string(input_format, len, result);
11023  }
11024 
11025  case 'l':
11026  {
11027  std::int32_t len{};
11028  return get_number(input_format, len) && get_string(input_format, len, result);
11029  }
11030 
11031  case 'L':
11032  {
11033  std::int64_t len{};
11034  return get_number(input_format, len) && get_string(input_format, len, result);
11035  }
11036 
11037  case 'u':
11038  {
11039  if (input_format != input_format_t::bjdata)
11040  {
11041  break;
11042  }
11043  std::uint16_t len{};
11044  return get_number(input_format, len) && get_string(input_format, len, result);
11045  }
11046 
11047  case 'm':
11048  {
11049  if (input_format != input_format_t::bjdata)
11050  {
11051  break;
11052  }
11053  std::uint32_t len{};
11054  return get_number(input_format, len) && get_string(input_format, len, result);
11055  }
11056 
11057  case 'M':
11058  {
11059  if (input_format != input_format_t::bjdata)
11060  {
11061  break;
11062  }
11063  std::uint64_t len{};
11064  return get_number(input_format, len) && get_string(input_format, len, result);
11065  }
11066 
11067  default:
11068  break;
11069  }
11070  auto last_token = get_token_string();
11071  std::string message;
11072 
11073  if (input_format != input_format_t::bjdata)
11074  {
11075  message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
11076  }
11077  else
11078  {
11079  message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
11080  }
11081  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
11082  }
11083 
11088  bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
11089  {
11090  std::pair<std::size_t, char_int_type> size_and_type;
11091  size_t dimlen = 0;
11092  bool no_ndarray = true;
11093 
11094  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
11095  {
11096  return false;
11097  }
11098 
11099  if (size_and_type.first != npos)
11100  {
11101  if (size_and_type.second != 0)
11102  {
11103  if (size_and_type.second != 'N')
11104  {
11105  for (std::size_t i = 0; i < size_and_type.first; ++i)
11106  {
11107  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
11108  {
11109  return false;
11110  }
11111  dim.push_back(dimlen);
11112  }
11113  }
11114  }
11115  else
11116  {
11117  for (std::size_t i = 0; i < size_and_type.first; ++i)
11118  {
11119  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
11120  {
11121  return false;
11122  }
11123  dim.push_back(dimlen);
11124  }
11125  }
11126  }
11127  else
11128  {
11129  while (current != ']')
11130  {
11131  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
11132  {
11133  return false;
11134  }
11135  dim.push_back(dimlen);
11136  get_ignore_noop();
11137  }
11138  }
11139  return true;
11140  }
11141 
11153  bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
11154  {
11155  if (prefix == 0)
11156  {
11157  prefix = get_ignore_noop();
11158  }
11159 
11160  switch (prefix)
11161  {
11162  case 'U':
11163  {
11164  std::uint8_t number{};
11165  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11166  {
11167  return false;
11168  }
11169  result = static_cast<std::size_t>(number);
11170  return true;
11171  }
11172 
11173  case 'i':
11174  {
11175  std::int8_t number{};
11176  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11177  {
11178  return false;
11179  }
11180  if (number < 0)
11181  {
11182  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11183  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11184  }
11185  result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
11186  return true;
11187  }
11188 
11189  case 'I':
11190  {
11191  std::int16_t number{};
11192  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11193  {
11194  return false;
11195  }
11196  if (number < 0)
11197  {
11198  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11199  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11200  }
11201  result = static_cast<std::size_t>(number);
11202  return true;
11203  }
11204 
11205  case 'l':
11206  {
11207  std::int32_t number{};
11208  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11209  {
11210  return false;
11211  }
11212  if (number < 0)
11213  {
11214  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11215  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11216  }
11217  result = static_cast<std::size_t>(number);
11218  return true;
11219  }
11220 
11221  case 'L':
11222  {
11223  std::int64_t number{};
11224  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11225  {
11226  return false;
11227  }
11228  if (number < 0)
11229  {
11230  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11231  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11232  }
11233  if (!value_in_range_of<std::size_t>(number))
11234  {
11235  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11236  exception_message(input_format, "integer value overflow", "size"), nullptr));
11237  }
11238  result = static_cast<std::size_t>(number);
11239  return true;
11240  }
11241 
11242  case 'u':
11243  {
11244  if (input_format != input_format_t::bjdata)
11245  {
11246  break;
11247  }
11248  std::uint16_t number{};
11249  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11250  {
11251  return false;
11252  }
11253  result = static_cast<std::size_t>(number);
11254  return true;
11255  }
11256 
11257  case 'm':
11258  {
11259  if (input_format != input_format_t::bjdata)
11260  {
11261  break;
11262  }
11263  std::uint32_t number{};
11264  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11265  {
11266  return false;
11267  }
11268  result = conditional_static_cast<std::size_t>(number);
11269  return true;
11270  }
11271 
11272  case 'M':
11273  {
11274  if (input_format != input_format_t::bjdata)
11275  {
11276  break;
11277  }
11278  std::uint64_t number{};
11279  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11280  {
11281  return false;
11282  }
11283  if (!value_in_range_of<std::size_t>(number))
11284  {
11285  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11286  exception_message(input_format, "integer value overflow", "size"), nullptr));
11287  }
11288  result = detail::conditional_static_cast<std::size_t>(number);
11289  return true;
11290  }
11291 
11292  case '[':
11293  {
11294  if (input_format != input_format_t::bjdata)
11295  {
11296  break;
11297  }
11298  if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
11299  {
11300  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimensional vector is not allowed", "size"), nullptr));
11301  }
11302  std::vector<size_t> dim;
11303  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
11304  {
11305  return false;
11306  }
11307  if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
11308  {
11309  result = dim.at(dim.size() - 1);
11310  return true;
11311  }
11312  if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
11313  {
11314  for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
11315  {
11316  if ( i == 0 )
11317  {
11318  result = 0;
11319  return true;
11320  }
11321  }
11322 
11323  string_t key = "_ArraySize_";
11324  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
11325  {
11326  return false;
11327  }
11328  result = 1;
11329  for (auto i : dim)
11330  {
11331  result *= i;
11332  if (result == 0 || result == npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be npos as it is used to initialize size in get_ubjson_size_type()
11333  {
11334  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr));
11335  }
11336  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
11337  {
11338  return false;
11339  }
11340  }
11341  is_ndarray = true;
11342  return sax->end_array();
11343  }
11344  result = 0;
11345  return true;
11346  }
11347 
11348  default:
11349  break;
11350  }
11351  auto last_token = get_token_string();
11352  std::string message;
11353 
11354  if (input_format != input_format_t::bjdata)
11355  {
11356  message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
11357  }
11358  else
11359  {
11360  message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
11361  }
11362  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
11363  }
11364 
11376  bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
11377  {
11378  result.first = npos; // size
11379  result.second = 0; // type
11380  bool is_ndarray = false;
11381 
11382  get_ignore_noop();
11383 
11384  if (current == '$')
11385  {
11386  result.second = get(); // must not ignore 'N', because 'N' maybe the type
11387  if (input_format == input_format_t::bjdata
11388  && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
11389  {
11390  auto last_token = get_token_string();
11391  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11392  exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
11393  }
11394 
11395  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
11396  {
11397  return false;
11398  }
11399 
11400  get_ignore_noop();
11401  if (JSON_HEDLEY_UNLIKELY(current != '#'))
11402  {
11403  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
11404  {
11405  return false;
11406  }
11407  auto last_token = get_token_string();
11408  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11409  exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
11410  }
11411 
11412  const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11413  if (input_format == input_format_t::bjdata && is_ndarray)
11414  {
11415  if (inside_ndarray)
11416  {
11417  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11418  exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
11419  }
11420  result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
11421  }
11422  return is_error;
11423  }
11424 
11425  if (current == '#')
11426  {
11427  const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11428  if (input_format == input_format_t::bjdata && is_ndarray)
11429  {
11430  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11431  exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
11432  }
11433  return is_error;
11434  }
11435 
11436  return true;
11437  }
11438 
11443  bool get_ubjson_value(const char_int_type prefix)
11444  {
11445  switch (prefix)
11446  {
11447  case char_traits<char_type>::eof(): // EOF
11448  return unexpect_eof(input_format, "value");
11449 
11450  case 'T': // true
11451  return sax->boolean(true);
11452  case 'F': // false
11453  return sax->boolean(false);
11454 
11455  case 'Z': // null
11456  return sax->null();
11457 
11458  case 'U':
11459  {
11460  std::uint8_t number{};
11461  return get_number(input_format, number) && sax->number_unsigned(number);
11462  }
11463 
11464  case 'i':
11465  {
11466  std::int8_t number{};
11467  return get_number(input_format, number) && sax->number_integer(number);
11468  }
11469 
11470  case 'I':
11471  {
11472  std::int16_t number{};
11473  return get_number(input_format, number) && sax->number_integer(number);
11474  }
11475 
11476  case 'l':
11477  {
11478  std::int32_t number{};
11479  return get_number(input_format, number) && sax->number_integer(number);
11480  }
11481 
11482  case 'L':
11483  {
11484  std::int64_t number{};
11485  return get_number(input_format, number) && sax->number_integer(number);
11486  }
11487 
11488  case 'u':
11489  {
11490  if (input_format != input_format_t::bjdata)
11491  {
11492  break;
11493  }
11494  std::uint16_t number{};
11495  return get_number(input_format, number) && sax->number_unsigned(number);
11496  }
11497 
11498  case 'm':
11499  {
11500  if (input_format != input_format_t::bjdata)
11501  {
11502  break;
11503  }
11504  std::uint32_t number{};
11505  return get_number(input_format, number) && sax->number_unsigned(number);
11506  }
11507 
11508  case 'M':
11509  {
11510  if (input_format != input_format_t::bjdata)
11511  {
11512  break;
11513  }
11514  std::uint64_t number{};
11515  return get_number(input_format, number) && sax->number_unsigned(number);
11516  }
11517 
11518  case 'h':
11519  {
11520  if (input_format != input_format_t::bjdata)
11521  {
11522  break;
11523  }
11524  const auto byte1_raw = get();
11525  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11526  {
11527  return false;
11528  }
11529  const auto byte2_raw = get();
11530  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11531  {
11532  return false;
11533  }
11534 
11535  const auto byte1 = static_cast<unsigned char>(byte1_raw);
11536  const auto byte2 = static_cast<unsigned char>(byte2_raw);
11537 
11538  // code from RFC 7049, Appendix D, Figure 3:
11539  // As half-precision floating-point numbers were only added
11540  // to IEEE 754 in 2008, today's programming platforms often
11541  // still only have limited support for them. It is very
11542  // easy to include at least decoding support for them even
11543  // without such support. An example of a small decoder for
11544  // half-precision floating-point numbers in the C language
11545  // is shown in Fig. 3.
11546  const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
11547  const double val = [&half]
11548  {
11549  const int exp = (half >> 10u) & 0x1Fu;
11550  const unsigned int mant = half & 0x3FFu;
11551  JSON_ASSERT(0 <= exp&& exp <= 32);
11552  JSON_ASSERT(mant <= 1024);
11553  switch (exp)
11554  {
11555  case 0:
11556  return std::ldexp(mant, -24);
11557  case 31:
11558  return (mant == 0)
11559  ? std::numeric_limits<double>::infinity()
11560  : std::numeric_limits<double>::quiet_NaN();
11561  default:
11562  return std::ldexp(mant + 1024, exp - 25);
11563  }
11564  }();
11565  return sax->number_float((half & 0x8000u) != 0
11566  ? static_cast<number_float_t>(-val)
11567  : static_cast<number_float_t>(val), "");
11568  }
11569 
11570  case 'd':
11571  {
11572  float number{};
11573  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11574  }
11575 
11576  case 'D':
11577  {
11578  double number{};
11579  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11580  }
11581 
11582  case 'H':
11583  {
11584  return get_ubjson_high_precision_number();
11585  }
11586 
11587  case 'C': // char
11588  {
11589  get();
11590  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
11591  {
11592  return false;
11593  }
11594  if (JSON_HEDLEY_UNLIKELY(current > 127))
11595  {
11596  auto last_token = get_token_string();
11597  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11598  exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
11599  }
11600  string_t s(1, static_cast<typename string_t::value_type>(current));
11601  return sax->string(s);
11602  }
11603 
11604  case 'S': // string
11605  {
11606  string_t s;
11607  return get_ubjson_string(s) && sax->string(s);
11608  }
11609 
11610  case '[': // array
11611  return get_ubjson_array();
11612 
11613  case '{': // object
11614  return get_ubjson_object();
11615 
11616  default: // anything else
11617  break;
11618  }
11619  auto last_token = get_token_string();
11620  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));
11621  }
11622 
11627  {
11628  std::pair<std::size_t, char_int_type> size_and_type;
11629  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11630  {
11631  return false;
11632  }
11633 
11634  // if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata):
11635  // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
11636 
11637  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11638  {
11639  size_and_type.second &= ~(static_cast<char_int_type>(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker
11640  auto it = std::lower_bound(bjd_types_map.begin(), bjd_types_map.end(), size_and_type.second, [](const bjd_type & p, char_int_type t)
11641  {
11642  return p.first < t;
11643  });
11644  string_t key = "_ArrayType_";
11645  if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
11646  {
11647  auto last_token = get_token_string();
11648  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11649  exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
11650  }
11651 
11652  string_t type = it->second; // sax->string() takes a reference
11653  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type)))
11654  {
11655  return false;
11656  }
11657 
11658  if (size_and_type.second == 'C')
11659  {
11660  size_and_type.second = 'U';
11661  }
11662 
11663  key = "_ArrayData_";
11664  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) ))
11665  {
11666  return false;
11667  }
11668 
11669  for (std::size_t i = 0; i < size_and_type.first; ++i)
11670  {
11671  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11672  {
11673  return false;
11674  }
11675  }
11676 
11677  return (sax->end_array() && sax->end_object());
11678  }
11679 
11680  if (size_and_type.first != npos)
11681  {
11682  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
11683  {
11684  return false;
11685  }
11686 
11687  if (size_and_type.second != 0)
11688  {
11689  if (size_and_type.second != 'N')
11690  {
11691  for (std::size_t i = 0; i < size_and_type.first; ++i)
11692  {
11693  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11694  {
11695  return false;
11696  }
11697  }
11698  }
11699  }
11700  else
11701  {
11702  for (std::size_t i = 0; i < size_and_type.first; ++i)
11703  {
11704  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11705  {
11706  return false;
11707  }
11708  }
11709  }
11710  }
11711  else
11712  {
11713  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11714  {
11715  return false;
11716  }
11717 
11718  while (current != ']')
11719  {
11720  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
11721  {
11722  return false;
11723  }
11724  get_ignore_noop();
11725  }
11726  }
11727 
11728  return sax->end_array();
11729  }
11730 
11735  {
11736  std::pair<std::size_t, char_int_type> size_and_type;
11737  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11738  {
11739  return false;
11740  }
11741 
11742  // do not accept ND-array size in objects in BJData
11743  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11744  {
11745  auto last_token = get_token_string();
11746  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11747  exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
11748  }
11749 
11750  string_t key;
11751  if (size_and_type.first != npos)
11752  {
11753  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
11754  {
11755  return false;
11756  }
11757 
11758  if (size_and_type.second != 0)
11759  {
11760  for (std::size_t i = 0; i < size_and_type.first; ++i)
11761  {
11762  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11763  {
11764  return false;
11765  }
11766  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11767  {
11768  return false;
11769  }
11770  key.clear();
11771  }
11772  }
11773  else
11774  {
11775  for (std::size_t i = 0; i < size_and_type.first; ++i)
11776  {
11777  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11778  {
11779  return false;
11780  }
11781  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11782  {
11783  return false;
11784  }
11785  key.clear();
11786  }
11787  }
11788  }
11789  else
11790  {
11791  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11792  {
11793  return false;
11794  }
11795 
11796  while (current != '}')
11797  {
11798  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11799  {
11800  return false;
11801  }
11802  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11803  {
11804  return false;
11805  }
11806  get_ignore_noop();
11807  key.clear();
11808  }
11809  }
11810 
11811  return sax->end_object();
11812  }
11813 
11814  // Note, no reader for UBJSON binary types is implemented because they do
11815  // not exist
11816 
11818  {
11819  // get size of following number string
11820  std::size_t size{};
11821  bool no_ndarray = true;
11822  auto res = get_ubjson_size_value(size, no_ndarray);
11823  if (JSON_HEDLEY_UNLIKELY(!res))
11824  {
11825  return res;
11826  }
11827 
11828  // get number string
11829  std::vector<char> number_vector;
11830  for (std::size_t i = 0; i < size; ++i)
11831  {
11832  get();
11833  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11834  {
11835  return false;
11836  }
11837  number_vector.push_back(static_cast<char>(current));
11838  }
11839 
11840  // parse number string
11841  using ia_type = decltype(detail::input_adapter(number_vector));
11842  auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11843  const auto result_number = number_lexer.scan();
11844  const auto number_string = number_lexer.get_token_string();
11845  const auto result_remainder = number_lexer.scan();
11846 
11847  using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11848 
11849  if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11850  {
11851  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11852  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11853  }
11854 
11855  switch (result_number)
11856  {
11857  case token_type::value_integer:
11858  return sax->number_integer(number_lexer.get_number_integer());
11859  case token_type::value_unsigned:
11860  return sax->number_unsigned(number_lexer.get_number_unsigned());
11861  case token_type::value_float:
11862  return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11863  case token_type::uninitialized:
11864  case token_type::literal_true:
11865  case token_type::literal_false:
11866  case token_type::literal_null:
11867  case token_type::value_string:
11868  case token_type::begin_array:
11869  case token_type::begin_object:
11870  case token_type::end_array:
11871  case token_type::end_object:
11872  case token_type::name_separator:
11873  case token_type::value_separator:
11874  case token_type::parse_error:
11875  case token_type::end_of_input:
11876  case token_type::literal_or_value:
11877  default:
11878  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11879  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11880  }
11881  }
11882 
11884  // Utility functions //
11886 
11897  {
11898  ++chars_read;
11899  return current = ia.get_character();
11900  }
11901 
11906  {
11907  do
11908  {
11909  get();
11910  }
11911  while (current == 'N');
11912 
11913  return current;
11914  }
11915 
11916  /*
11917  @brief read a number from the input
11918 
11919  @tparam NumberType the type of the number
11920  @param[in] format the current format (for diagnostics)
11921  @param[out] result number of type @a NumberType
11922 
11923  @return whether conversion completed
11924 
11925  @note This function needs to respect the system's endianness, because
11926  bytes in CBOR, MessagePack, and UBJSON are stored in network order
11927  (big endian) and therefore need reordering on little endian systems.
11928  On the other hand, BSON and BJData use little endian and should reorder
11929  on big endian systems.
11930  */
11931  template<typename NumberType, bool InputIsLittleEndian = false>
11932  bool get_number(const input_format_t format, NumberType& result)
11933  {
11934  // step 1: read input into array with system's byte order
11935  std::array<std::uint8_t, sizeof(NumberType)> vec{};
11936  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11937  {
11938  get();
11939  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11940  {
11941  return false;
11942  }
11943 
11944  // reverse byte order prior to conversion if necessary
11945  if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11946  {
11947  vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11948  }
11949  else
11950  {
11951  vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11952  }
11953  }
11954 
11955  // step 2: convert array into number of type T and return
11956  std::memcpy(&result, vec.data(), sizeof(NumberType));
11957  return true;
11958  }
11959 
11974  template<typename NumberType>
11975  bool get_string(const input_format_t format,
11976  const NumberType len,
11977  string_t& result)
11978  {
11979  bool success = true;
11980  for (NumberType i = 0; i < len; i++)
11981  {
11982  get();
11983  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11984  {
11985  success = false;
11986  break;
11987  }
11988  result.push_back(static_cast<typename string_t::value_type>(current));
11989  }
11990  return success;
11991  }
11992 
12007  template<typename NumberType>
12008  bool get_binary(const input_format_t format,
12009  const NumberType len,
12010  binary_t& result)
12011  {
12012  bool success = true;
12013  for (NumberType i = 0; i < len; i++)
12014  {
12015  get();
12016  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
12017  {
12018  success = false;
12019  break;
12020  }
12021  result.push_back(static_cast<std::uint8_t>(current));
12022  }
12023  return success;
12024  }
12025 
12032  bool unexpect_eof(const input_format_t format, const char* context) const
12033  {
12035  {
12036  return sax->parse_error(chars_read, "<end of file>",
12037  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
12038  }
12039  return true;
12040  }
12041 
12045  std::string get_token_string() const
12046  {
12047  std::array<char, 3> cr{{}};
12048  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
12049  return std::string{cr.data()};
12050  }
12051 
12058  std::string exception_message(const input_format_t format,
12059  const std::string& detail,
12060  const std::string& context) const
12061  {
12062  std::string error_msg = "syntax error while parsing ";
12063 
12064  switch (format)
12065  {
12066  case input_format_t::cbor:
12067  error_msg += "CBOR";
12068  break;
12069 
12070  case input_format_t::msgpack:
12071  error_msg += "MessagePack";
12072  break;
12073 
12074  case input_format_t::ubjson:
12075  error_msg += "UBJSON";
12076  break;
12077 
12078  case input_format_t::bson:
12079  error_msg += "BSON";
12080  break;
12081 
12082  case input_format_t::bjdata:
12083  error_msg += "BJData";
12084  break;
12085 
12086  case input_format_t::json: // LCOV_EXCL_LINE
12087  default: // LCOV_EXCL_LINE
12088  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
12089  }
12090 
12091  return concat(error_msg, ' ', context, ": ", detail);
12092  }
12093 
12094  private:
12095  static JSON_INLINE_VARIABLE constexpr std::size_t npos = static_cast<std::size_t>(-1);
12096 
12098  InputAdapterType ia;
12099 
12102 
12104  std::size_t chars_read = 0;
12105 
12107  const bool is_little_endian = little_endianness();
12108 
12110  const input_format_t input_format = input_format_t::json;
12111 
12113  json_sax_t* sax = nullptr;
12114 
12115  // excluded markers in bjdata optimized type
12116 #define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \
12117  make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
12118 
12119 #define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
12120  make_array<bjd_type>( \
12121  bjd_type{'C', "char"}, \
12122  bjd_type{'D', "double"}, \
12123  bjd_type{'I', "int16"}, \
12124  bjd_type{'L', "int64"}, \
12125  bjd_type{'M', "uint64"}, \
12126  bjd_type{'U', "uint8"}, \
12127  bjd_type{'d', "single"}, \
12128  bjd_type{'i', "int8"}, \
12129  bjd_type{'l', "int32"}, \
12130  bjd_type{'m', "uint32"}, \
12131  bjd_type{'u', "uint16"})
12132 
12134  // lookup tables
12135  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12136  const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =
12138 
12139  using bjd_type = std::pair<char_int_type, string_t>;
12140  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12141  const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map =
12143 
12144 #undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
12145 #undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
12146 };
12147 
12148 #ifndef JSON_HAS_CPP_17
12149  template<typename BasicJsonType, typename InputAdapterType, typename SAX>
12151 #endif
12152 
12153 } // namespace detail
12155 
12156 // #include <nlohmann/detail/input/input_adapters.hpp>
12157 
12158 // #include <nlohmann/detail/input/lexer.hpp>
12159 
12160 // #include <nlohmann/detail/input/parser.hpp>
12161 // __ _____ _____ _____
12162 // __| | __| | | | JSON for Modern C++
12163 // | | |__ | | | | | | version 3.11.3
12164 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12165 //
12166 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12167 // SPDX-License-Identifier: MIT
12168 
12169 
12170 
12171 #include <cmath> // isfinite
12172 #include <cstdint> // uint8_t
12173 #include <functional> // function
12174 #include <string> // string
12175 #include <utility> // move
12176 #include <vector> // vector
12177 
12178 // #include <nlohmann/detail/exceptions.hpp>
12179 
12180 // #include <nlohmann/detail/input/input_adapters.hpp>
12181 
12182 // #include <nlohmann/detail/input/json_sax.hpp>
12183 
12184 // #include <nlohmann/detail/input/lexer.hpp>
12185 
12186 // #include <nlohmann/detail/macro_scope.hpp>
12187 
12188 // #include <nlohmann/detail/meta/is_sax.hpp>
12189 
12190 // #include <nlohmann/detail/string_concat.hpp>
12191 
12192 // #include <nlohmann/detail/value_t.hpp>
12193 
12194 
12196 namespace detail
12197 {
12199 // parser //
12201 
12202 enum class parse_event_t : std::uint8_t
12203 {
12205  object_start,
12207  object_end,
12209  array_start,
12211  array_end,
12213  key,
12215  value
12216 };
12217 
12218 template<typename BasicJsonType>
12219 using parser_callback_t =
12220  std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
12221 
12227 template<typename BasicJsonType, typename InputAdapterType>
12228 class parser
12229 {
12230  using number_integer_t = typename BasicJsonType::number_integer_t;
12231  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12232  using number_float_t = typename BasicJsonType::number_float_t;
12233  using string_t = typename BasicJsonType::string_t;
12236 
12237  public:
12239  explicit parser(InputAdapterType&& adapter,
12240  const parser_callback_t<BasicJsonType> cb = nullptr,
12241  const bool allow_exceptions_ = true,
12242  const bool skip_comments = false)
12243  : callback(cb)
12244  , m_lexer(std::move(adapter), skip_comments)
12245  , allow_exceptions(allow_exceptions_)
12246  {
12247  // read first token
12248  get_token();
12249  }
12250 
12261  void parse(const bool strict, BasicJsonType& result)
12262  {
12263  if (callback)
12264  {
12265  json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
12266  sax_parse_internal(&sdp);
12267 
12268  // in strict mode, input must be completely read
12269  if (strict && (get_token() != token_type::end_of_input))
12270  {
12271  sdp.parse_error(m_lexer.get_position(),
12272  m_lexer.get_token_string(),
12273  parse_error::create(101, m_lexer.get_position(),
12274  exception_message(token_type::end_of_input, "value"), nullptr));
12275  }
12276 
12277  // in case of an error, return discarded value
12278  if (sdp.is_errored())
12279  {
12280  result = value_t::discarded;
12281  return;
12282  }
12283 
12284  // set top-level value to null if it was discarded by the callback
12285  // function
12286  if (result.is_discarded())
12287  {
12288  result = nullptr;
12289  }
12290  }
12291  else
12292  {
12293  json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
12294  sax_parse_internal(&sdp);
12295 
12296  // in strict mode, input must be completely read
12297  if (strict && (get_token() != token_type::end_of_input))
12298  {
12299  sdp.parse_error(m_lexer.get_position(),
12300  m_lexer.get_token_string(),
12301  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12302  }
12303 
12304  // in case of an error, return discarded value
12305  if (sdp.is_errored())
12306  {
12307  result = value_t::discarded;
12308  return;
12309  }
12310  }
12311 
12312  result.assert_invariant();
12313  }
12314 
12321  bool accept(const bool strict = true)
12322  {
12323  json_sax_acceptor<BasicJsonType> sax_acceptor;
12324  return sax_parse(&sax_acceptor, strict);
12325  }
12326 
12327  template<typename SAX>
12329  bool sax_parse(SAX* sax, const bool strict = true)
12330  {
12332  const bool result = sax_parse_internal(sax);
12333 
12334  // strict mode: next byte must be EOF
12335  if (result && strict && (get_token() != token_type::end_of_input))
12336  {
12337  return sax->parse_error(m_lexer.get_position(),
12338  m_lexer.get_token_string(),
12339  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12340  }
12341 
12342  return result;
12343  }
12344 
12345  private:
12346  template<typename SAX>
12348  bool sax_parse_internal(SAX* sax)
12349  {
12350  // stack to remember the hierarchy of structured values we are parsing
12351  // true = array; false = object
12352  std::vector<bool> states;
12353  // value to avoid a goto (see comment where set to true)
12354  bool skip_to_state_evaluation = false;
12355 
12356  while (true)
12357  {
12358  if (!skip_to_state_evaluation)
12359  {
12360  // invariant: get_token() was called before each iteration
12361  switch (last_token)
12362  {
12363  case token_type::begin_object:
12364  {
12365  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
12366  {
12367  return false;
12368  }
12369 
12370  // closing } -> we are done
12371  if (get_token() == token_type::end_object)
12372  {
12373  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12374  {
12375  return false;
12376  }
12377  break;
12378  }
12379 
12380  // parse key
12381  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
12382  {
12383  return sax->parse_error(m_lexer.get_position(),
12384  m_lexer.get_token_string(),
12385  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12386  }
12387  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12388  {
12389  return false;
12390  }
12391 
12392  // parse separator (:)
12393  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12394  {
12395  return sax->parse_error(m_lexer.get_position(),
12396  m_lexer.get_token_string(),
12397  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12398  }
12399 
12400  // remember we are now inside an object
12401  states.push_back(false);
12402 
12403  // parse values
12404  get_token();
12405  continue;
12406  }
12407 
12408  case token_type::begin_array:
12409  {
12410  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
12411  {
12412  return false;
12413  }
12414 
12415  // closing ] -> we are done
12416  if (get_token() == token_type::end_array)
12417  {
12418  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12419  {
12420  return false;
12421  }
12422  break;
12423  }
12424 
12425  // remember we are now inside an array
12426  states.push_back(true);
12427 
12428  // parse values (no need to call get_token)
12429  continue;
12430  }
12431 
12432  case token_type::value_float:
12433  {
12434  const auto res = m_lexer.get_number_float();
12435 
12436  if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
12437  {
12438  return sax->parse_error(m_lexer.get_position(),
12439  m_lexer.get_token_string(),
12440  out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
12441  }
12442 
12443  if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
12444  {
12445  return false;
12446  }
12447 
12448  break;
12449  }
12450 
12451  case token_type::literal_false:
12452  {
12453  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
12454  {
12455  return false;
12456  }
12457  break;
12458  }
12459 
12460  case token_type::literal_null:
12461  {
12462  if (JSON_HEDLEY_UNLIKELY(!sax->null()))
12463  {
12464  return false;
12465  }
12466  break;
12467  }
12468 
12469  case token_type::literal_true:
12470  {
12471  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
12472  {
12473  return false;
12474  }
12475  break;
12476  }
12477 
12478  case token_type::value_integer:
12479  {
12480  if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
12481  {
12482  return false;
12483  }
12484  break;
12485  }
12486 
12487  case token_type::value_string:
12488  {
12489  if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
12490  {
12491  return false;
12492  }
12493  break;
12494  }
12495 
12496  case token_type::value_unsigned:
12497  {
12498  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
12499  {
12500  return false;
12501  }
12502  break;
12503  }
12504 
12505  case token_type::parse_error:
12506  {
12507  // using "uninitialized" to avoid "expected" message
12508  return sax->parse_error(m_lexer.get_position(),
12509  m_lexer.get_token_string(),
12510  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
12511  }
12512  case token_type::end_of_input:
12513  {
12514  if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1))
12515  {
12516  return sax->parse_error(m_lexer.get_position(),
12517  m_lexer.get_token_string(),
12518  parse_error::create(101, m_lexer.get_position(),
12519  "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
12520  }
12521 
12522  return sax->parse_error(m_lexer.get_position(),
12523  m_lexer.get_token_string(),
12524  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12525  }
12526  case token_type::uninitialized:
12527  case token_type::end_array:
12528  case token_type::end_object:
12529  case token_type::name_separator:
12530  case token_type::value_separator:
12531  case token_type::literal_or_value:
12532  default: // the last token was unexpected
12533  {
12534  return sax->parse_error(m_lexer.get_position(),
12535  m_lexer.get_token_string(),
12536  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12537  }
12538  }
12539  }
12540  else
12541  {
12542  skip_to_state_evaluation = false;
12543  }
12544 
12545  // we reached this line after we successfully parsed a value
12546  if (states.empty())
12547  {
12548  // empty stack: we reached the end of the hierarchy: done
12549  return true;
12550  }
12551 
12552  if (states.back()) // array
12553  {
12554  // comma -> next value
12555  if (get_token() == token_type::value_separator)
12556  {
12557  // parse a new value
12558  get_token();
12559  continue;
12560  }
12561 
12562  // closing ]
12563  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
12564  {
12565  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12566  {
12567  return false;
12568  }
12569 
12570  // We are done with this array. Before we can parse a
12571  // new value, we need to evaluate the new state first.
12572  // By setting skip_to_state_evaluation to false, we
12573  // are effectively jumping to the beginning of this if.
12574  JSON_ASSERT(!states.empty());
12575  states.pop_back();
12576  skip_to_state_evaluation = true;
12577  continue;
12578  }
12579 
12580  return sax->parse_error(m_lexer.get_position(),
12581  m_lexer.get_token_string(),
12582  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
12583  }
12584 
12585  // states.back() is false -> object
12586 
12587  // comma -> next value
12588  if (get_token() == token_type::value_separator)
12589  {
12590  // parse key
12591  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
12592  {
12593  return sax->parse_error(m_lexer.get_position(),
12594  m_lexer.get_token_string(),
12595  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12596  }
12597 
12598  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12599  {
12600  return false;
12601  }
12602 
12603  // parse separator (:)
12604  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12605  {
12606  return sax->parse_error(m_lexer.get_position(),
12607  m_lexer.get_token_string(),
12608  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12609  }
12610 
12611  // parse values
12612  get_token();
12613  continue;
12614  }
12615 
12616  // closing }
12617  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
12618  {
12619  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12620  {
12621  return false;
12622  }
12623 
12624  // We are done with this object. Before we can parse a
12625  // new value, we need to evaluate the new state first.
12626  // By setting skip_to_state_evaluation to false, we
12627  // are effectively jumping to the beginning of this if.
12628  JSON_ASSERT(!states.empty());
12629  states.pop_back();
12630  skip_to_state_evaluation = true;
12631  continue;
12632  }
12633 
12634  return sax->parse_error(m_lexer.get_position(),
12635  m_lexer.get_token_string(),
12636  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
12637  }
12638  }
12639 
12642  {
12643  return last_token = m_lexer.scan();
12644  }
12645 
12646  std::string exception_message(const token_type expected, const std::string& context)
12647  {
12648  std::string error_msg = "syntax error ";
12649 
12650  if (!context.empty())
12651  {
12652  error_msg += concat("while parsing ", context, ' ');
12653  }
12654 
12655  error_msg += "- ";
12656 
12657  if (last_token == token_type::parse_error)
12658  {
12659  error_msg += concat(m_lexer.get_error_message(), "; last read: '",
12660  m_lexer.get_token_string(), '\'');
12661  }
12662  else
12663  {
12664  error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
12665  }
12666 
12667  if (expected != token_type::uninitialized)
12668  {
12669  error_msg += concat("; expected ", lexer_t::token_type_name(expected));
12670  }
12671 
12672  return error_msg;
12673  }
12674 
12675  private:
12679  token_type last_token = token_type::uninitialized;
12683  const bool allow_exceptions = true;
12684 };
12685 
12686 } // namespace detail
12688 
12689 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
12690 // __ _____ _____ _____
12691 // __| | __| | | | JSON for Modern C++
12692 // | | |__ | | | | | | version 3.11.3
12693 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12694 //
12695 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12696 // SPDX-License-Identifier: MIT
12697 
12698 
12699 
12700 // #include <nlohmann/detail/abi_macros.hpp>
12701 
12702 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12703 // __ _____ _____ _____
12704 // __| | __| | | | JSON for Modern C++
12705 // | | |__ | | | | | | version 3.11.3
12706 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12707 //
12708 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12709 // SPDX-License-Identifier: MIT
12710 
12711 
12712 
12713 #include <cstddef> // ptrdiff_t
12714 #include <limits> // numeric_limits
12715 
12716 // #include <nlohmann/detail/macro_scope.hpp>
12717 
12718 
12720 namespace detail
12721 {
12722 
12723 /*
12724 @brief an iterator for primitive JSON types
12725 
12726 This class models an iterator for primitive JSON types (boolean, number,
12727 string). It's only purpose is to allow the iterator/const_iterator classes
12728 to "iterate" over primitive values. Internally, the iterator is modeled by
12729 a `difference_type` variable. Value begin_value (`0`) models the begin,
12730 end_value (`1`) models past the end.
12731 */
12733 {
12734  private:
12735  using difference_type = std::ptrdiff_t;
12736  static constexpr difference_type begin_value = 0;
12737  static constexpr difference_type end_value = begin_value + 1;
12738 
12741  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
12742 
12743  public:
12744  constexpr difference_type get_value() const noexcept
12745  {
12746  return m_it;
12747  }
12748 
12750  void set_begin() noexcept
12751  {
12752  m_it = begin_value;
12753  }
12754 
12756  void set_end() noexcept
12757  {
12758  m_it = end_value;
12759  }
12760 
12762  constexpr bool is_begin() const noexcept
12763  {
12764  return m_it == begin_value;
12765  }
12766 
12768  constexpr bool is_end() const noexcept
12769  {
12770  return m_it == end_value;
12771  }
12772 
12773  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12774  {
12775  return lhs.m_it == rhs.m_it;
12776  }
12777 
12778  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12779  {
12780  return lhs.m_it < rhs.m_it;
12781  }
12782 
12784  {
12785  auto result = *this;
12786  result += n;
12787  return result;
12788  }
12789 
12791  {
12792  return lhs.m_it - rhs.m_it;
12793  }
12794 
12796  {
12797  ++m_it;
12798  return *this;
12799  }
12800 
12801  primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
12802  {
12803  auto result = *this;
12804  ++m_it;
12805  return result;
12806  }
12807 
12809  {
12810  --m_it;
12811  return *this;
12812  }
12813 
12814  primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
12815  {
12816  auto result = *this;
12817  --m_it;
12818  return result;
12819  }
12820 
12822  {
12823  m_it += n;
12824  return *this;
12825  }
12826 
12828  {
12829  m_it -= n;
12830  return *this;
12831  }
12832 };
12833 
12834 } // namespace detail
12836 
12837 
12839 namespace detail
12840 {
12841 
12848 template<typename BasicJsonType> struct internal_iterator
12849 {
12851  typename BasicJsonType::object_t::iterator object_iterator {};
12853  typename BasicJsonType::array_t::iterator array_iterator {};
12855  primitive_iterator_t primitive_iterator {};
12856 };
12857 
12858 } // namespace detail
12860 
12861 // #include <nlohmann/detail/iterators/iter_impl.hpp>
12862 // __ _____ _____ _____
12863 // __| | __| | | | JSON for Modern C++
12864 // | | |__ | | | | | | version 3.11.3
12865 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12866 //
12867 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12868 // SPDX-License-Identifier: MIT
12869 
12870 
12871 
12872 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12873 #include <type_traits> // conditional, is_const, remove_const
12874 
12875 // #include <nlohmann/detail/exceptions.hpp>
12876 
12877 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
12878 
12879 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12880 
12881 // #include <nlohmann/detail/macro_scope.hpp>
12882 
12883 // #include <nlohmann/detail/meta/cpp_future.hpp>
12884 
12885 // #include <nlohmann/detail/meta/type_traits.hpp>
12886 
12887 // #include <nlohmann/detail/value_t.hpp>
12888 
12889 
12891 namespace detail
12892 {
12893 
12894 // forward declare, to be able to friend it later on
12895 template<typename IteratorType> class iteration_proxy;
12896 template<typename IteratorType> class iteration_proxy_value;
12897 
12914 template<typename BasicJsonType>
12915 class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12916 {
12918  using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
12924 
12925  using object_t = typename BasicJsonType::object_t;
12926  using array_t = typename BasicJsonType::array_t;
12927  // make sure BasicJsonType is basic_json or const basic_json
12928  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
12929  "iter_impl only accepts (const) basic_json");
12930  // superficial check for the LegacyBidirectionalIterator named requirement
12932  && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
12933  "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
12934 
12935  public:
12941  using iterator_category = std::bidirectional_iterator_tag;
12942 
12944  using value_type = typename BasicJsonType::value_type;
12946  using difference_type = typename BasicJsonType::difference_type;
12949  typename BasicJsonType::const_pointer,
12950  typename BasicJsonType::pointer>::type;
12952  using reference =
12954  typename BasicJsonType::const_reference,
12955  typename BasicJsonType::reference>::type;
12956 
12957  iter_impl() = default;
12958  ~iter_impl() = default;
12959  iter_impl(iter_impl&&) noexcept = default;
12960  iter_impl& operator=(iter_impl&&) noexcept = default;
12961 
12968  explicit iter_impl(pointer object) noexcept : m_object(object)
12969  {
12970  JSON_ASSERT(m_object != nullptr);
12971 
12972  switch (m_object->m_data.m_type)
12973  {
12974  case value_t::object:
12975  {
12976  m_it.object_iterator = typename object_t::iterator();
12977  break;
12978  }
12979 
12980  case value_t::array:
12981  {
12982  m_it.array_iterator = typename array_t::iterator();
12983  break;
12984  }
12985 
12986  case value_t::null:
12987  case value_t::string:
12988  case value_t::boolean:
12989  case value_t::number_integer:
12990  case value_t::number_unsigned:
12991  case value_t::number_float:
12992  case value_t::binary:
12993  case value_t::discarded:
12994  default:
12995  {
12996  m_it.primitive_iterator = primitive_iterator_t();
12997  break;
12998  }
12999  }
13000  }
13001 
13019  : m_object(other.m_object), m_it(other.m_it)
13020  {}
13021 
13029  {
13030  if (&other != this)
13031  {
13032  m_object = other.m_object;
13033  m_it = other.m_it;
13034  }
13035  return *this;
13036  }
13037 
13043  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
13044  : m_object(other.m_object), m_it(other.m_it)
13045  {}
13046 
13053  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
13054  {
13055  m_object = other.m_object;
13056  m_it = other.m_it;
13057  return *this;
13058  }
13059 
13065  void set_begin() noexcept
13066  {
13067  JSON_ASSERT(m_object != nullptr);
13068 
13069  switch (m_object->m_data.m_type)
13070  {
13071  case value_t::object:
13072  {
13073  m_it.object_iterator = m_object->m_data.m_value.object->begin();
13074  break;
13075  }
13076 
13077  case value_t::array:
13078  {
13079  m_it.array_iterator = m_object->m_data.m_value.array->begin();
13080  break;
13081  }
13082 
13083  case value_t::null:
13084  {
13085  // set to end so begin()==end() is true: null is empty
13086  m_it.primitive_iterator.set_end();
13087  break;
13088  }
13089 
13090  case value_t::string:
13091  case value_t::boolean:
13092  case value_t::number_integer:
13093  case value_t::number_unsigned:
13094  case value_t::number_float:
13095  case value_t::binary:
13096  case value_t::discarded:
13097  default:
13098  {
13099  m_it.primitive_iterator.set_begin();
13100  break;
13101  }
13102  }
13103  }
13104 
13109  void set_end() noexcept
13110  {
13111  JSON_ASSERT(m_object != nullptr);
13112 
13113  switch (m_object->m_data.m_type)
13114  {
13115  case value_t::object:
13116  {
13117  m_it.object_iterator = m_object->m_data.m_value.object->end();
13118  break;
13119  }
13120 
13121  case value_t::array:
13122  {
13123  m_it.array_iterator = m_object->m_data.m_value.array->end();
13124  break;
13125  }
13126 
13127  case value_t::null:
13128  case value_t::string:
13129  case value_t::boolean:
13130  case value_t::number_integer:
13131  case value_t::number_unsigned:
13132  case value_t::number_float:
13133  case value_t::binary:
13134  case value_t::discarded:
13135  default:
13136  {
13137  m_it.primitive_iterator.set_end();
13138  break;
13139  }
13140  }
13141  }
13142 
13143  public:
13149  {
13150  JSON_ASSERT(m_object != nullptr);
13151 
13152  switch (m_object->m_data.m_type)
13153  {
13154  case value_t::object:
13155  {
13156  JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13157  return m_it.object_iterator->second;
13158  }
13159 
13160  case value_t::array:
13161  {
13162  JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13163  return *m_it.array_iterator;
13164  }
13165 
13166  case value_t::null:
13167  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13168 
13169  case value_t::string:
13170  case value_t::boolean:
13171  case value_t::number_integer:
13172  case value_t::number_unsigned:
13173  case value_t::number_float:
13174  case value_t::binary:
13175  case value_t::discarded:
13176  default:
13177  {
13178  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13179  {
13180  return *m_object;
13181  }
13182 
13183  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13184  }
13185  }
13186  }
13187 
13193  {
13194  JSON_ASSERT(m_object != nullptr);
13195 
13196  switch (m_object->m_data.m_type)
13197  {
13198  case value_t::object:
13199  {
13200  JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13201  return &(m_it.object_iterator->second);
13202  }
13203 
13204  case value_t::array:
13205  {
13206  JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13207  return &*m_it.array_iterator;
13208  }
13209 
13210  case value_t::null:
13211  case value_t::string:
13212  case value_t::boolean:
13213  case value_t::number_integer:
13214  case value_t::number_unsigned:
13215  case value_t::number_float:
13216  case value_t::binary:
13217  case value_t::discarded:
13218  default:
13219  {
13220  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13221  {
13222  return m_object;
13223  }
13224 
13225  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13226  }
13227  }
13228  }
13229 
13234  iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
13235  {
13236  auto result = *this;
13237  ++(*this);
13238  return result;
13239  }
13240 
13246  {
13247  JSON_ASSERT(m_object != nullptr);
13248 
13249  switch (m_object->m_data.m_type)
13250  {
13251  case value_t::object:
13252  {
13253  std::advance(m_it.object_iterator, 1);
13254  break;
13255  }
13256 
13257  case value_t::array:
13258  {
13259  std::advance(m_it.array_iterator, 1);
13260  break;
13261  }
13262 
13263  case value_t::null:
13264  case value_t::string:
13265  case value_t::boolean:
13266  case value_t::number_integer:
13267  case value_t::number_unsigned:
13268  case value_t::number_float:
13269  case value_t::binary:
13270  case value_t::discarded:
13271  default:
13272  {
13273  ++m_it.primitive_iterator;
13274  break;
13275  }
13276  }
13277 
13278  return *this;
13279  }
13280 
13285  iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
13286  {
13287  auto result = *this;
13288  --(*this);
13289  return result;
13290  }
13291 
13297  {
13298  JSON_ASSERT(m_object != nullptr);
13299 
13300  switch (m_object->m_data.m_type)
13301  {
13302  case value_t::object:
13303  {
13304  std::advance(m_it.object_iterator, -1);
13305  break;
13306  }
13307 
13308  case value_t::array:
13309  {
13310  std::advance(m_it.array_iterator, -1);
13311  break;
13312  }
13313 
13314  case value_t::null:
13315  case value_t::string:
13316  case value_t::boolean:
13317  case value_t::number_integer:
13318  case value_t::number_unsigned:
13319  case value_t::number_float:
13320  case value_t::binary:
13321  case value_t::discarded:
13322  default:
13323  {
13324  --m_it.primitive_iterator;
13325  break;
13326  }
13327  }
13328 
13329  return *this;
13330  }
13331 
13336  template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
13337  bool operator==(const IterImpl& other) const
13338  {
13339  // if objects are not the same, the comparison is undefined
13340  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13341  {
13342  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13343  }
13344 
13345  JSON_ASSERT(m_object != nullptr);
13346 
13347  switch (m_object->m_data.m_type)
13348  {
13349  case value_t::object:
13350  return (m_it.object_iterator == other.m_it.object_iterator);
13351 
13352  case value_t::array:
13353  return (m_it.array_iterator == other.m_it.array_iterator);
13354 
13355  case value_t::null:
13356  case value_t::string:
13357  case value_t::boolean:
13358  case value_t::number_integer:
13359  case value_t::number_unsigned:
13360  case value_t::number_float:
13361  case value_t::binary:
13362  case value_t::discarded:
13363  default:
13364  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
13365  }
13366  }
13367 
13372  template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
13373  bool operator!=(const IterImpl& other) const
13374  {
13375  return !operator==(other);
13376  }
13377 
13382  bool operator<(const iter_impl& other) const
13383  {
13384  // if objects are not the same, the comparison is undefined
13385  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13386  {
13387  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13388  }
13389 
13390  JSON_ASSERT(m_object != nullptr);
13391 
13392  switch (m_object->m_data.m_type)
13393  {
13394  case value_t::object:
13395  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
13396 
13397  case value_t::array:
13398  return (m_it.array_iterator < other.m_it.array_iterator);
13399 
13400  case value_t::null:
13401  case value_t::string:
13402  case value_t::boolean:
13403  case value_t::number_integer:
13404  case value_t::number_unsigned:
13405  case value_t::number_float:
13406  case value_t::binary:
13407  case value_t::discarded:
13408  default:
13409  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
13410  }
13411  }
13412 
13417  bool operator<=(const iter_impl& other) const
13418  {
13419  return !other.operator < (*this);
13420  }
13421 
13426  bool operator>(const iter_impl& other) const
13427  {
13428  return !operator<=(other);
13429  }
13430 
13435  bool operator>=(const iter_impl& other) const
13436  {
13437  return !operator<(other);
13438  }
13439 
13445  {
13446  JSON_ASSERT(m_object != nullptr);
13447 
13448  switch (m_object->m_data.m_type)
13449  {
13450  case value_t::object:
13451  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13452 
13453  case value_t::array:
13454  {
13455  std::advance(m_it.array_iterator, i);
13456  break;
13457  }
13458 
13459  case value_t::null:
13460  case value_t::string:
13461  case value_t::boolean:
13462  case value_t::number_integer:
13463  case value_t::number_unsigned:
13464  case value_t::number_float:
13465  case value_t::binary:
13466  case value_t::discarded:
13467  default:
13468  {
13469  m_it.primitive_iterator += i;
13470  break;
13471  }
13472  }
13473 
13474  return *this;
13475  }
13476 
13482  {
13483  return operator+=(-i);
13484  }
13485 
13491  {
13492  auto result = *this;
13493  result += i;
13494  return result;
13495  }
13496 
13502  {
13503  auto result = it;
13504  result += i;
13505  return result;
13506  }
13507 
13513  {
13514  auto result = *this;
13515  result -= i;
13516  return result;
13517  }
13518 
13524  {
13525  JSON_ASSERT(m_object != nullptr);
13526 
13527  switch (m_object->m_data.m_type)
13528  {
13529  case value_t::object:
13530  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13531 
13532  case value_t::array:
13533  return m_it.array_iterator - other.m_it.array_iterator;
13534 
13535  case value_t::null:
13536  case value_t::string:
13537  case value_t::boolean:
13538  case value_t::number_integer:
13539  case value_t::number_unsigned:
13540  case value_t::number_float:
13541  case value_t::binary:
13542  case value_t::discarded:
13543  default:
13544  return m_it.primitive_iterator - other.m_it.primitive_iterator;
13545  }
13546  }
13547 
13553  {
13554  JSON_ASSERT(m_object != nullptr);
13555 
13556  switch (m_object->m_data.m_type)
13557  {
13558  case value_t::object:
13559  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
13560 
13561  case value_t::array:
13562  return *std::next(m_it.array_iterator, n);
13563 
13564  case value_t::null:
13565  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13566 
13567  case value_t::string:
13568  case value_t::boolean:
13569  case value_t::number_integer:
13570  case value_t::number_unsigned:
13571  case value_t::number_float:
13572  case value_t::binary:
13573  case value_t::discarded:
13574  default:
13575  {
13576  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
13577  {
13578  return *m_object;
13579  }
13580 
13581  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13582  }
13583  }
13584  }
13585 
13590  const typename object_t::key_type& key() const
13591  {
13592  JSON_ASSERT(m_object != nullptr);
13593 
13594  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
13595  {
13596  return m_it.object_iterator->first;
13597  }
13598 
13599  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
13600  }
13601 
13607  {
13608  return operator*();
13609  }
13610 
13613  pointer m_object = nullptr;
13616 };
13617 
13618 } // namespace detail
13620 
13621 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
13622 
13623 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
13624 // __ _____ _____ _____
13625 // __| | __| | | | JSON for Modern C++
13626 // | | |__ | | | | | | version 3.11.3
13627 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13628 //
13629 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
13630 // SPDX-License-Identifier: MIT
13631 
13632 
13633 
13634 #include <cstddef> // ptrdiff_t
13635 #include <iterator> // reverse_iterator
13636 #include <utility> // declval
13637 
13638 // #include <nlohmann/detail/abi_macros.hpp>
13639 
13640 
13642 namespace detail
13643 {
13644 
13646 // reverse_iterator //
13648 
13667 template<typename Base>
13668 class json_reverse_iterator : public std::reverse_iterator<Base>
13669 {
13670  public:
13671  using difference_type = std::ptrdiff_t;
13673  using base_iterator = std::reverse_iterator<Base>;
13675  using reference = typename Base::reference;
13676 
13678  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
13679  : base_iterator(it) {}
13680 
13682  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
13683 
13685  json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
13686  {
13687  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
13688  }
13689 
13692  {
13693  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
13694  }
13695 
13697  json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
13698  {
13699  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
13700  }
13701 
13704  {
13705  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
13706  }
13707 
13710  {
13711  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
13712  }
13713 
13716  {
13717  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
13718  }
13719 
13722  {
13723  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
13724  }
13725 
13728  {
13729  return base_iterator(*this) - base_iterator(other);
13730  }
13731 
13734  {
13735  return *(this->operator+(n));
13736  }
13737 
13739  auto key() const -> decltype(std::declval<Base>().key())
13740  {
13741  auto it = --this->base();
13742  return it.key();
13743  }
13744 
13747  {
13748  auto it = --this->base();
13749  return it.operator * ();
13750  }
13751 };
13752 
13753 } // namespace detail
13755 
13756 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13757 
13758 // #include <nlohmann/detail/json_custom_base_class.hpp>
13759 // __ _____ _____ _____
13760 // __| | __| | | | JSON for Modern C++
13761 // | | |__ | | | | | | version 3.11.3
13762 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13763 //
13764 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
13765 // SPDX-License-Identifier: MIT
13766 
13767 
13768 
13769 #include <type_traits> // conditional, is_same
13770 
13771 // #include <nlohmann/detail/abi_macros.hpp>
13772 
13773 
13775 namespace detail
13776 {
13777 
13789 
13790 template<class T>
13791 using json_base_class = typename std::conditional <
13794  T
13795  >::type;
13796 
13797 } // namespace detail
13799 
13800 // #include <nlohmann/detail/json_pointer.hpp>
13801 // __ _____ _____ _____
13802 // __| | __| | | | JSON for Modern C++
13803 // | | |__ | | | | | | version 3.11.3
13804 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13805 //
13806 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
13807 // SPDX-License-Identifier: MIT
13808 
13809 
13810 
13811 #include <algorithm> // all_of
13812 #include <cctype> // isdigit
13813 #include <cerrno> // errno, ERANGE
13814 #include <cstdlib> // strtoull
13815 #ifndef JSON_NO_IO
13816  #include <iosfwd> // ostream
13817 #endif // JSON_NO_IO
13818 #include <limits> // max
13819 #include <numeric> // accumulate
13820 #include <string> // string
13821 #include <utility> // move
13822 #include <vector> // vector
13823 
13824 // #include <nlohmann/detail/exceptions.hpp>
13825 
13826 // #include <nlohmann/detail/macro_scope.hpp>
13827 
13828 // #include <nlohmann/detail/string_concat.hpp>
13829 
13830 // #include <nlohmann/detail/string_escape.hpp>
13831 
13832 // #include <nlohmann/detail/value_t.hpp>
13833 
13834 
13836 
13839 template<typename RefStringType>
13840 class json_pointer
13841 {
13842  // allow basic_json to access private members
13844  friend class basic_json;
13845 
13846  template<typename>
13847  friend class json_pointer;
13848 
13849  template<typename T>
13851  {
13852  using type = T;
13853  };
13854 
13857  {
13858  using type = StringType;
13859  };
13860 
13861  public:
13862  // for backwards compatibility accept BasicJsonType
13864 
13867  explicit json_pointer(const string_t& s = "")
13868  : reference_tokens(split(s))
13869  {}
13870 
13874  {
13875  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
13876  string_t{},
13877  [](const string_t& a, const string_t& b)
13878  {
13879  return detail::concat(a, '/', detail::escape(b));
13880  });
13881  }
13882 
13886  operator string_t() const
13887  {
13888  return to_string();
13889  }
13890 
13891 #ifndef JSON_NO_IO
13892  friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
13895  {
13896  o << ptr.to_string();
13897  return o;
13898  }
13899 #endif
13900 
13904  {
13905  reference_tokens.insert(reference_tokens.end(),
13906  ptr.reference_tokens.begin(),
13907  ptr.reference_tokens.end());
13908  return *this;
13909  }
13910 
13914  {
13915  push_back(std::move(token));
13916  return *this;
13917  }
13918 
13921  json_pointer& operator/=(std::size_t array_idx)
13922  {
13923  return *this /= std::to_string(array_idx);
13924  }
13925 
13929  const json_pointer& rhs)
13930  {
13931  return json_pointer(lhs) /= rhs;
13932  }
13933 
13936  friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
13937  {
13938  return json_pointer(lhs) /= std::move(token);
13939  }
13940 
13943  friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13944  {
13945  return json_pointer(lhs) /= array_idx;
13946  }
13947 
13951  {
13952  if (empty())
13953  {
13954  return *this;
13955  }
13956 
13957  json_pointer res = *this;
13958  res.pop_back();
13959  return res;
13960  }
13961 
13964  void pop_back()
13965  {
13966  if (JSON_HEDLEY_UNLIKELY(empty()))
13967  {
13968  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13969  }
13970 
13971  reference_tokens.pop_back();
13972  }
13973 
13976  const string_t& back() const
13977  {
13978  if (JSON_HEDLEY_UNLIKELY(empty()))
13979  {
13980  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13981  }
13982 
13983  return reference_tokens.back();
13984  }
13985 
13988  void push_back(const string_t& token)
13989  {
13990  reference_tokens.push_back(token);
13991  }
13992 
13996  {
13997  reference_tokens.push_back(std::move(token));
13998  }
13999 
14002  bool empty() const noexcept
14003  {
14004  return reference_tokens.empty();
14005  }
14006 
14007  private:
14018  template<typename BasicJsonType>
14019  static typename BasicJsonType::size_type array_index(const string_t& s)
14020  {
14021  using size_type = typename BasicJsonType::size_type;
14022 
14023  // error condition (cf. RFC 6901, Sect. 4)
14024  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
14025  {
14026  JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
14027  }
14028 
14029  // error condition (cf. RFC 6901, Sect. 4)
14030  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
14031  {
14032  JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
14033  }
14034 
14035  const char* p = s.c_str();
14036  char* p_end = nullptr;
14037  errno = 0; // strtoull doesn't reset errno
14038  const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
14039  if (p == p_end // invalid input or empty string
14040  || errno == ERANGE // out of range
14041  || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
14042  {
14043  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
14044  }
14045 
14046  // only triggered on special platforms (like 32bit), see also
14047  // https://github.com/nlohmann/json/pull/2203
14048  if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
14049  {
14050  JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
14051  }
14052 
14053  return static_cast<size_type>(res);
14054  }
14055 
14057  json_pointer top() const
14058  {
14059  if (JSON_HEDLEY_UNLIKELY(empty()))
14060  {
14061  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
14062  }
14063 
14064  json_pointer result = *this;
14065  result.reference_tokens = {reference_tokens[0]};
14066  return result;
14067  }
14068 
14069  private:
14078  template<typename BasicJsonType>
14079  BasicJsonType& get_and_create(BasicJsonType& j) const
14080  {
14081  auto* result = &j;
14082 
14083  // in case no reference tokens exist, return a reference to the JSON value
14084  // j which will be overwritten by a primitive value
14085  for (const auto& reference_token : reference_tokens)
14086  {
14087  switch (result->type())
14088  {
14089  case detail::value_t::null:
14090  {
14091  if (reference_token == "0")
14092  {
14093  // start a new array if reference token is 0
14094  result = &result->operator[](0);
14095  }
14096  else
14097  {
14098  // start a new object otherwise
14099  result = &result->operator[](reference_token);
14100  }
14101  break;
14102  }
14103 
14105  {
14106  // create an entry in the object
14107  result = &result->operator[](reference_token);
14108  break;
14109  }
14110 
14112  {
14113  // create an entry in the array
14114  result = &result->operator[](array_index<BasicJsonType>(reference_token));
14115  break;
14116  }
14117 
14118  /*
14119  The following code is only reached if there exists a reference
14120  token _and_ the current value is primitive. In this case, we have
14121  an error situation, because primitive values may only occur as
14122  single value; that is, with an empty list of reference tokens.
14123  */
14131  default:
14132  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
14133  }
14134  }
14135 
14136  return *result;
14137  }
14138 
14158  template<typename BasicJsonType>
14159  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
14160  {
14161  for (const auto& reference_token : reference_tokens)
14162  {
14163  // convert null values to arrays or objects before continuing
14164  if (ptr->is_null())
14165  {
14166  // check if reference token is a number
14167  const bool nums =
14168  std::all_of(reference_token.begin(), reference_token.end(),
14169  [](const unsigned char x)
14170  {
14171  return std::isdigit(x);
14172  });
14173 
14174  // change value to array for numbers or "-" or to object otherwise
14175  *ptr = (nums || reference_token == "-")
14178  }
14179 
14180  switch (ptr->type())
14181  {
14183  {
14184  // use unchecked object access
14185  ptr = &ptr->operator[](reference_token);
14186  break;
14187  }
14188 
14190  {
14191  if (reference_token == "-")
14192  {
14193  // explicitly treat "-" as index beyond the end
14194  ptr = &ptr->operator[](ptr->m_data.m_value.array->size());
14195  }
14196  else
14197  {
14198  // convert array index to number; unchecked access
14199  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14200  }
14201  break;
14202  }
14203 
14204  case detail::value_t::null:
14212  default:
14213  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14214  }
14215  }
14216 
14217  return *ptr;
14218  }
14219 
14226  template<typename BasicJsonType>
14227  BasicJsonType& get_checked(BasicJsonType* ptr) const
14228  {
14229  for (const auto& reference_token : reference_tokens)
14230  {
14231  switch (ptr->type())
14232  {
14234  {
14235  // note: at performs range check
14236  ptr = &ptr->at(reference_token);
14237  break;
14238  }
14239 
14241  {
14242  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14243  {
14244  // "-" always fails the range check
14246  "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
14247  ") is out of range"), ptr));
14248  }
14249 
14250  // note: at performs range check
14251  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14252  break;
14253  }
14254 
14255  case detail::value_t::null:
14263  default:
14264  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14265  }
14266  }
14267 
14268  return *ptr;
14269  }
14270 
14284  template<typename BasicJsonType>
14285  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
14286  {
14287  for (const auto& reference_token : reference_tokens)
14288  {
14289  switch (ptr->type())
14290  {
14292  {
14293  // use unchecked object access
14294  ptr = &ptr->operator[](reference_token);
14295  break;
14296  }
14297 
14299  {
14300  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14301  {
14302  // "-" cannot be used for const access
14303  JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
14304  }
14305 
14306  // use unchecked array access
14307  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14308  break;
14309  }
14310 
14311  case detail::value_t::null:
14319  default:
14320  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14321  }
14322  }
14323 
14324  return *ptr;
14325  }
14326 
14333  template<typename BasicJsonType>
14334  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
14335  {
14336  for (const auto& reference_token : reference_tokens)
14337  {
14338  switch (ptr->type())
14339  {
14341  {
14342  // note: at performs range check
14343  ptr = &ptr->at(reference_token);
14344  break;
14345  }
14346 
14348  {
14349  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14350  {
14351  // "-" always fails the range check
14353  "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
14354  ") is out of range"), ptr));
14355  }
14356 
14357  // note: at performs range check
14358  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14359  break;
14360  }
14361 
14362  case detail::value_t::null:
14370  default:
14371  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14372  }
14373  }
14374 
14375  return *ptr;
14376  }
14377 
14382  template<typename BasicJsonType>
14383  bool contains(const BasicJsonType* ptr) const
14384  {
14385  for (const auto& reference_token : reference_tokens)
14386  {
14387  switch (ptr->type())
14388  {
14390  {
14391  if (!ptr->contains(reference_token))
14392  {
14393  // we did not find the key in the object
14394  return false;
14395  }
14396 
14397  ptr = &ptr->operator[](reference_token);
14398  break;
14399  }
14400 
14402  {
14403  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14404  {
14405  // "-" always fails the range check
14406  return false;
14407  }
14408  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
14409  {
14410  // invalid char
14411  return false;
14412  }
14413  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
14414  {
14415  if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
14416  {
14417  // first char should be between '1' and '9'
14418  return false;
14419  }
14420  for (std::size_t i = 1; i < reference_token.size(); i++)
14421  {
14422  if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
14423  {
14424  // other char should be between '0' and '9'
14425  return false;
14426  }
14427  }
14428  }
14429 
14430  const auto idx = array_index<BasicJsonType>(reference_token);
14431  if (idx >= ptr->size())
14432  {
14433  // index out of range
14434  return false;
14435  }
14436 
14437  ptr = &ptr->operator[](idx);
14438  break;
14439  }
14440 
14441  case detail::value_t::null:
14449  default:
14450  {
14451  // we do not expect primitive values if there is still a
14452  // reference token to process
14453  return false;
14454  }
14455  }
14456  }
14457 
14458  // no reference token left means we found a primitive value
14459  return true;
14460  }
14461 
14471  static std::vector<string_t> split(const string_t& reference_string)
14472  {
14473  std::vector<string_t> result;
14474 
14475  // special case: empty reference string -> no reference tokens
14476  if (reference_string.empty())
14477  {
14478  return result;
14479  }
14480 
14481  // check if nonempty reference string begins with slash
14482  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
14483  {
14484  JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
14485  }
14486 
14487  // extract the reference tokens:
14488  // - slash: position of the last read slash (or end of string)
14489  // - start: position after the previous slash
14490  for (
14491  // search for the first slash after the first character
14492  std::size_t slash = reference_string.find_first_of('/', 1),
14493  // set the beginning of the first reference token
14494  start = 1;
14495  // we can stop if start == 0 (if slash == string_t::npos)
14496  start != 0;
14497  // set the beginning of the next reference token
14498  // (will eventually be 0 if slash == string_t::npos)
14499  start = (slash == string_t::npos) ? 0 : slash + 1,
14500  // find next slash
14501  slash = reference_string.find_first_of('/', start))
14502  {
14503  // use the text between the beginning of the reference token
14504  // (start) and the last slash (slash).
14505  auto reference_token = reference_string.substr(start, slash - start);
14506 
14507  // check reference tokens are properly escaped
14508  for (std::size_t pos = reference_token.find_first_of('~');
14509  pos != string_t::npos;
14510  pos = reference_token.find_first_of('~', pos + 1))
14511  {
14512  JSON_ASSERT(reference_token[pos] == '~');
14513 
14514  // ~ must be followed by 0 or 1
14515  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
14516  (reference_token[pos + 1] != '0' &&
14517  reference_token[pos + 1] != '1')))
14518  {
14519  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
14520  }
14521  }
14522 
14523  // finally, store the reference token
14524  detail::unescape(reference_token);
14525  result.push_back(reference_token);
14526  }
14527 
14528  return result;
14529  }
14530 
14531  private:
14539  template<typename BasicJsonType>
14540  static void flatten(const string_t& reference_string,
14541  const BasicJsonType& value,
14542  BasicJsonType& result)
14543  {
14544  switch (value.type())
14545  {
14547  {
14548  if (value.m_data.m_value.array->empty())
14549  {
14550  // flatten empty array as null
14551  result[reference_string] = nullptr;
14552  }
14553  else
14554  {
14555  // iterate array and use index as reference string
14556  for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)
14557  {
14558  flatten(detail::concat(reference_string, '/', std::to_string(i)),
14559  value.m_data.m_value.array->operator[](i), result);
14560  }
14561  }
14562  break;
14563  }
14564 
14566  {
14567  if (value.m_data.m_value.object->empty())
14568  {
14569  // flatten empty object as null
14570  result[reference_string] = nullptr;
14571  }
14572  else
14573  {
14574  // iterate object and use keys as reference string
14575  for (const auto& element : *value.m_data.m_value.object)
14576  {
14577  flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
14578  }
14579  }
14580  break;
14581  }
14582 
14583  case detail::value_t::null:
14591  default:
14592  {
14593  // add primitive value with its reference string
14594  result[reference_string] = value;
14595  break;
14596  }
14597  }
14598  }
14599 
14610  template<typename BasicJsonType>
14611  static BasicJsonType
14612  unflatten(const BasicJsonType& value)
14613  {
14614  if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
14615  {
14616  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
14617  }
14618 
14619  BasicJsonType result;
14620 
14621  // iterate the JSON object values
14622  for (const auto& element : *value.m_data.m_value.object)
14623  {
14624  if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
14625  {
14626  JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
14627  }
14628 
14629  // assign value to reference pointed to by JSON pointer; Note that if
14630  // the JSON pointer is "" (i.e., points to the whole value), function
14631  // get_and_create returns a reference to result itself. An assignment
14632  // will then create a primitive value.
14633  json_pointer(element.first).get_and_create(result) = element.second;
14634  }
14635 
14636  return result;
14637  }
14638 
14639  // can't use conversion operator because of ambiguity
14641  {
14642  json_pointer<string_t> result;
14643  result.reference_tokens = reference_tokens;
14644  return result;
14645  }
14646 
14648  {
14649  json_pointer<string_t> result;
14650  result.reference_tokens = std::move(reference_tokens);
14651  return result;
14652  }
14653 
14654  public:
14655 #if JSON_HAS_THREE_WAY_COMPARISON
14656  template<typename RefStringTypeRhs>
14659  bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept
14660  {
14661  return reference_tokens == rhs.reference_tokens;
14662  }
14663 
14666  JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))
14667  bool operator==(const string_t& rhs) const
14668  {
14669  return *this == json_pointer(rhs);
14670  }
14671 
14673  template<typename RefStringTypeRhs>
14674  std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
14675  {
14676  return reference_tokens <=> rhs.reference_tokens; // *NOPAD*
14677  }
14678 #else
14679  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14682  // NOLINTNEXTLINE(readability-redundant-declaration)
14683  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14684  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14685 
14688  template<typename RefStringTypeLhs, typename StringType>
14689  // NOLINTNEXTLINE(readability-redundant-declaration)
14690  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14691  const StringType& rhs);
14692 
14695  template<typename RefStringTypeRhs, typename StringType>
14696  // NOLINTNEXTLINE(readability-redundant-declaration)
14697  friend bool operator==(const StringType& lhs,
14698  const json_pointer<RefStringTypeRhs>& rhs);
14699 
14702  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14703  // NOLINTNEXTLINE(readability-redundant-declaration)
14704  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14705  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14706 
14709  template<typename RefStringTypeLhs, typename StringType>
14710  // NOLINTNEXTLINE(readability-redundant-declaration)
14711  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14712  const StringType& rhs);
14713 
14716  template<typename RefStringTypeRhs, typename StringType>
14717  // NOLINTNEXTLINE(readability-redundant-declaration)
14718  friend bool operator!=(const StringType& lhs,
14719  const json_pointer<RefStringTypeRhs>& rhs);
14720 
14722  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14723  // NOLINTNEXTLINE(readability-redundant-declaration)
14724  friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
14725  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14726 #endif
14727 
14728  private:
14730  std::vector<string_t> reference_tokens;
14731 };
14732 
14733 #if !JSON_HAS_THREE_WAY_COMPARISON
14734 // functions cannot be defined inside class due to ODR violations
14735 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14737  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14738 {
14739  return lhs.reference_tokens == rhs.reference_tokens;
14740 }
14741 
14742 template<typename RefStringTypeLhs,
14743  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14745 inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14746  const StringType& rhs)
14747 {
14748  return lhs == json_pointer<RefStringTypeLhs>(rhs);
14749 }
14750 
14751 template<typename RefStringTypeRhs,
14752  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14754 inline bool operator==(const StringType& lhs,
14755  const json_pointer<RefStringTypeRhs>& rhs)
14756 {
14757  return json_pointer<RefStringTypeRhs>(lhs) == rhs;
14758 }
14759 
14760 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14762  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14763 {
14764  return !(lhs == rhs);
14765 }
14766 
14767 template<typename RefStringTypeLhs,
14768  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14770 inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14771  const StringType& rhs)
14772 {
14773  return !(lhs == rhs);
14774 }
14775 
14776 template<typename RefStringTypeRhs,
14777  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14779 inline bool operator!=(const StringType& lhs,
14780  const json_pointer<RefStringTypeRhs>& rhs)
14781 {
14782  return !(lhs == rhs);
14783 }
14784 
14785 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14787  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14788 {
14789  return lhs.reference_tokens < rhs.reference_tokens;
14790 }
14791 #endif
14792 
14794 
14795 // #include <nlohmann/detail/json_ref.hpp>
14796 // __ _____ _____ _____
14797 // __| | __| | | | JSON for Modern C++
14798 // | | |__ | | | | | | version 3.11.3
14799 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14800 //
14801 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
14802 // SPDX-License-Identifier: MIT
14803 
14804 
14805 
14806 #include <initializer_list>
14807 #include <utility>
14808 
14809 // #include <nlohmann/detail/abi_macros.hpp>
14810 
14811 // #include <nlohmann/detail/meta/type_traits.hpp>
14812 
14813 
14815 namespace detail
14816 {
14817 
14818 template<typename BasicJsonType>
14819 class json_ref
14820 {
14821  public:
14822  using value_type = BasicJsonType;
14823 
14825  : owned_value(std::move(value))
14826  {}
14827 
14829  : value_ref(&value)
14830  {}
14831 
14832  json_ref(std::initializer_list<json_ref> init)
14833  : owned_value(init)
14834  {}
14835 
14836  template <
14837  class... Args,
14838  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
14839  json_ref(Args && ... args)
14840  : owned_value(std::forward<Args>(args)...)
14841  {}
14842 
14843  // class should be movable only
14844  json_ref(json_ref&&) noexcept = default;
14845  json_ref(const json_ref&) = delete;
14846  json_ref& operator=(const json_ref&) = delete;
14847  json_ref& operator=(json_ref&&) = delete;
14848  ~json_ref() = default;
14849 
14850  value_type moved_or_copied() const
14851  {
14852  if (value_ref == nullptr)
14853  {
14854  return std::move(owned_value);
14855  }
14856  return *value_ref;
14857  }
14858 
14859  value_type const& operator*() const
14860  {
14861  return value_ref ? *value_ref : owned_value;
14862  }
14863 
14864  value_type const* operator->() const
14865  {
14866  return &** this;
14867  }
14868 
14869  private:
14870  mutable value_type owned_value = nullptr;
14871  value_type const* value_ref = nullptr;
14872 };
14873 
14874 } // namespace detail
14876 
14877 // #include <nlohmann/detail/macro_scope.hpp>
14878 
14879 // #include <nlohmann/detail/string_concat.hpp>
14880 
14881 // #include <nlohmann/detail/string_escape.hpp>
14882 
14883 // #include <nlohmann/detail/meta/cpp_future.hpp>
14884 
14885 // #include <nlohmann/detail/meta/type_traits.hpp>
14886 
14887 // #include <nlohmann/detail/output/binary_writer.hpp>
14888 // __ _____ _____ _____
14889 // __| | __| | | | JSON for Modern C++
14890 // | | |__ | | | | | | version 3.11.3
14891 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14892 //
14893 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
14894 // SPDX-License-Identifier: MIT
14895 
14896 
14897 
14898 #include <algorithm> // reverse
14899 #include <array> // array
14900 #include <map> // map
14901 #include <cmath> // isnan, isinf
14902 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
14903 #include <cstring> // memcpy
14904 #include <limits> // numeric_limits
14905 #include <string> // string
14906 #include <utility> // move
14907 #include <vector> // vector
14908 
14909 // #include <nlohmann/detail/input/binary_reader.hpp>
14910 
14911 // #include <nlohmann/detail/macro_scope.hpp>
14912 
14913 // #include <nlohmann/detail/output/output_adapters.hpp>
14914 // __ _____ _____ _____
14915 // __| | __| | | | JSON for Modern C++
14916 // | | |__ | | | | | | version 3.11.3
14917 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14918 //
14919 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
14920 // SPDX-License-Identifier: MIT
14921 
14922 
14923 
14924 #include <algorithm> // copy
14925 #include <cstddef> // size_t
14926 #include <iterator> // back_inserter
14927 #include <memory> // shared_ptr, make_shared
14928 #include <string> // basic_string
14929 #include <vector> // vector
14930 
14931 #ifndef JSON_NO_IO
14932  #include <ios> // streamsize
14933  #include <ostream> // basic_ostream
14934 #endif // JSON_NO_IO
14935 
14936 // #include <nlohmann/detail/macro_scope.hpp>
14937 
14938 
14940 namespace detail
14941 {
14942 
14944 template<typename CharType> struct output_adapter_protocol
14945 {
14946  virtual void write_character(CharType c) = 0;
14947  virtual void write_characters(const CharType* s, std::size_t length) = 0;
14948  virtual ~output_adapter_protocol() = default;
14949 
14950  output_adapter_protocol() = default;
14952  output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
14955 };
14956 
14958 template<typename CharType>
14959 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
14960 
14962 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
14964 {
14965  public:
14966  explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
14967  : v(vec)
14968  {}
14969 
14970  void write_character(CharType c) override
14971  {
14972  v.push_back(c);
14973  }
14974 
14976  void write_characters(const CharType* s, std::size_t length) override
14977  {
14978  v.insert(v.end(), s, s + length);
14979  }
14980 
14981  private:
14982  std::vector<CharType, AllocatorType>& v;
14983 };
14984 
14985 #ifndef JSON_NO_IO
14986 template<typename CharType>
14989 {
14990  public:
14991  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
14992  : stream(s)
14993  {}
14994 
14995  void write_character(CharType c) override
14996  {
14997  stream.put(c);
14998  }
14999 
15001  void write_characters(const CharType* s, std::size_t length) override
15002  {
15003  stream.write(s, static_cast<std::streamsize>(length));
15004  }
15005 
15006  private:
15007  std::basic_ostream<CharType>& stream;
15008 };
15009 #endif // JSON_NO_IO
15010 
15012 template<typename CharType, typename StringType = std::basic_string<CharType>>
15014 {
15015  public:
15016  explicit output_string_adapter(StringType& s) noexcept
15017  : str(s)
15018  {}
15019 
15020  void write_character(CharType c) override
15021  {
15022  str.push_back(c);
15023  }
15024 
15026  void write_characters(const CharType* s, std::size_t length) override
15027  {
15028  str.append(s, length);
15029  }
15030 
15031  private:
15032  StringType& str;
15033 };
15034 
15035 template<typename CharType, typename StringType = std::basic_string<CharType>>
15037 {
15038  public:
15039  template<typename AllocatorType = std::allocator<CharType>>
15040  output_adapter(std::vector<CharType, AllocatorType>& vec)
15041  : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
15042 
15043 #ifndef JSON_NO_IO
15044  output_adapter(std::basic_ostream<CharType>& s)
15045  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
15046 #endif // JSON_NO_IO
15047 
15048  output_adapter(StringType& s)
15049  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
15050 
15052  {
15053  return oa;
15054  }
15055 
15056  private:
15058 };
15059 
15060 } // namespace detail
15062 
15063 // #include <nlohmann/detail/string_concat.hpp>
15064 
15065 
15067 namespace detail
15068 {
15069 
15071 // binary writer //
15073 
15077 template<typename BasicJsonType, typename CharType>
15079 {
15080  using string_t = typename BasicJsonType::string_t;
15081  using binary_t = typename BasicJsonType::binary_t;
15082  using number_float_t = typename BasicJsonType::number_float_t;
15083 
15084  public:
15090  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
15091  {
15092  JSON_ASSERT(oa);
15093  }
15094 
15099  void write_bson(const BasicJsonType& j)
15100  {
15101  switch (j.type())
15102  {
15103  case value_t::object:
15104  {
15105  write_bson_object(*j.m_data.m_value.object);
15106  break;
15107  }
15108 
15109  case value_t::null:
15110  case value_t::array:
15111  case value_t::string:
15112  case value_t::boolean:
15113  case value_t::number_integer:
15114  case value_t::number_unsigned:
15115  case value_t::number_float:
15116  case value_t::binary:
15117  case value_t::discarded:
15118  default:
15119  {
15120  JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
15121  }
15122  }
15123  }
15124 
15128  void write_cbor(const BasicJsonType& j)
15129  {
15130  switch (j.type())
15131  {
15132  case value_t::null:
15133  {
15134  oa->write_character(to_char_type(0xF6));
15135  break;
15136  }
15137 
15138  case value_t::boolean:
15139  {
15140  oa->write_character(j.m_data.m_value.boolean
15141  ? to_char_type(0xF5)
15142  : to_char_type(0xF4));
15143  break;
15144  }
15145 
15146  case value_t::number_integer:
15147  {
15148  if (j.m_data.m_value.number_integer >= 0)
15149  {
15150  // CBOR does not differentiate between positive signed
15151  // integers and unsigned integers. Therefore, we used the
15152  // code from the value_t::number_unsigned case here.
15153  if (j.m_data.m_value.number_integer <= 0x17)
15154  {
15155  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15156  }
15157  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15158  {
15159  oa->write_character(to_char_type(0x18));
15160  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15161  }
15162  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
15163  {
15164  oa->write_character(to_char_type(0x19));
15165  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15166  }
15167  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
15168  {
15169  oa->write_character(to_char_type(0x1A));
15170  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15171  }
15172  else
15173  {
15174  oa->write_character(to_char_type(0x1B));
15175  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15176  }
15177  }
15178  else
15179  {
15180  // The conversions below encode the sign in the first
15181  // byte, and the value is converted to a positive number.
15182  const auto positive_number = -1 - j.m_data.m_value.number_integer;
15183  if (j.m_data.m_value.number_integer >= -24)
15184  {
15185  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
15186  }
15187  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
15188  {
15189  oa->write_character(to_char_type(0x38));
15190  write_number(static_cast<std::uint8_t>(positive_number));
15191  }
15192  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
15193  {
15194  oa->write_character(to_char_type(0x39));
15195  write_number(static_cast<std::uint16_t>(positive_number));
15196  }
15197  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
15198  {
15199  oa->write_character(to_char_type(0x3A));
15200  write_number(static_cast<std::uint32_t>(positive_number));
15201  }
15202  else
15203  {
15204  oa->write_character(to_char_type(0x3B));
15205  write_number(static_cast<std::uint64_t>(positive_number));
15206  }
15207  }
15208  break;
15209  }
15210 
15211  case value_t::number_unsigned:
15212  {
15213  if (j.m_data.m_value.number_unsigned <= 0x17)
15214  {
15215  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15216  }
15217  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15218  {
15219  oa->write_character(to_char_type(0x18));
15220  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15221  }
15222  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15223  {
15224  oa->write_character(to_char_type(0x19));
15225  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
15226  }
15227  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15228  {
15229  oa->write_character(to_char_type(0x1A));
15230  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
15231  }
15232  else
15233  {
15234  oa->write_character(to_char_type(0x1B));
15235  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
15236  }
15237  break;
15238  }
15239 
15240  case value_t::number_float:
15241  {
15242  if (std::isnan(j.m_data.m_value.number_float))
15243  {
15244  // NaN is 0xf97e00 in CBOR
15245  oa->write_character(to_char_type(0xF9));
15246  oa->write_character(to_char_type(0x7E));
15247  oa->write_character(to_char_type(0x00));
15248  }
15249  else if (std::isinf(j.m_data.m_value.number_float))
15250  {
15251  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
15252  oa->write_character(to_char_type(0xf9));
15253  oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
15254  oa->write_character(to_char_type(0x00));
15255  }
15256  else
15257  {
15258  write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::cbor);
15259  }
15260  break;
15261  }
15262 
15263  case value_t::string:
15264  {
15265  // step 1: write control byte and the string length
15266  const auto N = j.m_data.m_value.string->size();
15267  if (N <= 0x17)
15268  {
15269  write_number(static_cast<std::uint8_t>(0x60 + N));
15270  }
15271  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15272  {
15273  oa->write_character(to_char_type(0x78));
15274  write_number(static_cast<std::uint8_t>(N));
15275  }
15276  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15277  {
15278  oa->write_character(to_char_type(0x79));
15279  write_number(static_cast<std::uint16_t>(N));
15280  }
15281  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15282  {
15283  oa->write_character(to_char_type(0x7A));
15284  write_number(static_cast<std::uint32_t>(N));
15285  }
15286  // LCOV_EXCL_START
15287  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15288  {
15289  oa->write_character(to_char_type(0x7B));
15290  write_number(static_cast<std::uint64_t>(N));
15291  }
15292  // LCOV_EXCL_STOP
15293 
15294  // step 2: write the string
15295  oa->write_characters(
15296  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15297  j.m_data.m_value.string->size());
15298  break;
15299  }
15300 
15301  case value_t::array:
15302  {
15303  // step 1: write control byte and the array size
15304  const auto N = j.m_data.m_value.array->size();
15305  if (N <= 0x17)
15306  {
15307  write_number(static_cast<std::uint8_t>(0x80 + N));
15308  }
15309  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15310  {
15311  oa->write_character(to_char_type(0x98));
15312  write_number(static_cast<std::uint8_t>(N));
15313  }
15314  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15315  {
15316  oa->write_character(to_char_type(0x99));
15317  write_number(static_cast<std::uint16_t>(N));
15318  }
15319  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15320  {
15321  oa->write_character(to_char_type(0x9A));
15322  write_number(static_cast<std::uint32_t>(N));
15323  }
15324  // LCOV_EXCL_START
15325  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15326  {
15327  oa->write_character(to_char_type(0x9B));
15328  write_number(static_cast<std::uint64_t>(N));
15329  }
15330  // LCOV_EXCL_STOP
15331 
15332  // step 2: write each element
15333  for (const auto& el : *j.m_data.m_value.array)
15334  {
15335  write_cbor(el);
15336  }
15337  break;
15338  }
15339 
15340  case value_t::binary:
15341  {
15342  if (j.m_data.m_value.binary->has_subtype())
15343  {
15344  if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
15345  {
15346  write_number(static_cast<std::uint8_t>(0xd8));
15347  write_number(static_cast<std::uint8_t>(j.m_data.m_value.binary->subtype()));
15348  }
15349  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
15350  {
15351  write_number(static_cast<std::uint8_t>(0xd9));
15352  write_number(static_cast<std::uint16_t>(j.m_data.m_value.binary->subtype()));
15353  }
15354  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
15355  {
15356  write_number(static_cast<std::uint8_t>(0xda));
15357  write_number(static_cast<std::uint32_t>(j.m_data.m_value.binary->subtype()));
15358  }
15359  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
15360  {
15361  write_number(static_cast<std::uint8_t>(0xdb));
15362  write_number(static_cast<std::uint64_t>(j.m_data.m_value.binary->subtype()));
15363  }
15364  }
15365 
15366  // step 1: write control byte and the binary array size
15367  const auto N = j.m_data.m_value.binary->size();
15368  if (N <= 0x17)
15369  {
15370  write_number(static_cast<std::uint8_t>(0x40 + N));
15371  }
15372  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15373  {
15374  oa->write_character(to_char_type(0x58));
15375  write_number(static_cast<std::uint8_t>(N));
15376  }
15377  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15378  {
15379  oa->write_character(to_char_type(0x59));
15380  write_number(static_cast<std::uint16_t>(N));
15381  }
15382  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15383  {
15384  oa->write_character(to_char_type(0x5A));
15385  write_number(static_cast<std::uint32_t>(N));
15386  }
15387  // LCOV_EXCL_START
15388  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15389  {
15390  oa->write_character(to_char_type(0x5B));
15391  write_number(static_cast<std::uint64_t>(N));
15392  }
15393  // LCOV_EXCL_STOP
15394 
15395  // step 2: write each element
15396  oa->write_characters(
15397  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15398  N);
15399 
15400  break;
15401  }
15402 
15403  case value_t::object:
15404  {
15405  // step 1: write control byte and the object size
15406  const auto N = j.m_data.m_value.object->size();
15407  if (N <= 0x17)
15408  {
15409  write_number(static_cast<std::uint8_t>(0xA0 + N));
15410  }
15411  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15412  {
15413  oa->write_character(to_char_type(0xB8));
15414  write_number(static_cast<std::uint8_t>(N));
15415  }
15416  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15417  {
15418  oa->write_character(to_char_type(0xB9));
15419  write_number(static_cast<std::uint16_t>(N));
15420  }
15421  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15422  {
15423  oa->write_character(to_char_type(0xBA));
15424  write_number(static_cast<std::uint32_t>(N));
15425  }
15426  // LCOV_EXCL_START
15427  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15428  {
15429  oa->write_character(to_char_type(0xBB));
15430  write_number(static_cast<std::uint64_t>(N));
15431  }
15432  // LCOV_EXCL_STOP
15433 
15434  // step 2: write each element
15435  for (const auto& el : *j.m_data.m_value.object)
15436  {
15437  write_cbor(el.first);
15438  write_cbor(el.second);
15439  }
15440  break;
15441  }
15442 
15443  case value_t::discarded:
15444  default:
15445  break;
15446  }
15447  }
15448 
15452  void write_msgpack(const BasicJsonType& j)
15453  {
15454  switch (j.type())
15455  {
15456  case value_t::null: // nil
15457  {
15458  oa->write_character(to_char_type(0xC0));
15459  break;
15460  }
15461 
15462  case value_t::boolean: // true and false
15463  {
15464  oa->write_character(j.m_data.m_value.boolean
15465  ? to_char_type(0xC3)
15466  : to_char_type(0xC2));
15467  break;
15468  }
15469 
15470  case value_t::number_integer:
15471  {
15472  if (j.m_data.m_value.number_integer >= 0)
15473  {
15474  // MessagePack does not differentiate between positive
15475  // signed integers and unsigned integers. Therefore, we used
15476  // the code from the value_t::number_unsigned case here.
15477  if (j.m_data.m_value.number_unsigned < 128)
15478  {
15479  // positive fixnum
15480  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15481  }
15482  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15483  {
15484  // uint 8
15485  oa->write_character(to_char_type(0xCC));
15486  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15487  }
15488  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15489  {
15490  // uint 16
15491  oa->write_character(to_char_type(0xCD));
15492  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15493  }
15494  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15495  {
15496  // uint 32
15497  oa->write_character(to_char_type(0xCE));
15498  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15499  }
15500  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15501  {
15502  // uint 64
15503  oa->write_character(to_char_type(0xCF));
15504  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15505  }
15506  }
15507  else
15508  {
15509  if (j.m_data.m_value.number_integer >= -32)
15510  {
15511  // negative fixnum
15512  write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
15513  }
15514  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
15515  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15516  {
15517  // int 8
15518  oa->write_character(to_char_type(0xD0));
15519  write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
15520  }
15521  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
15522  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15523  {
15524  // int 16
15525  oa->write_character(to_char_type(0xD1));
15526  write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));
15527  }
15528  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
15529  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15530  {
15531  // int 32
15532  oa->write_character(to_char_type(0xD2));
15533  write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));
15534  }
15535  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
15536  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15537  {
15538  // int 64
15539  oa->write_character(to_char_type(0xD3));
15540  write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
15541  }
15542  }
15543  break;
15544  }
15545 
15546  case value_t::number_unsigned:
15547  {
15548  if (j.m_data.m_value.number_unsigned < 128)
15549  {
15550  // positive fixnum
15551  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15552  }
15553  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15554  {
15555  // uint 8
15556  oa->write_character(to_char_type(0xCC));
15557  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15558  }
15559  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15560  {
15561  // uint 16
15562  oa->write_character(to_char_type(0xCD));
15563  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15564  }
15565  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15566  {
15567  // uint 32
15568  oa->write_character(to_char_type(0xCE));
15569  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15570  }
15571  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15572  {
15573  // uint 64
15574  oa->write_character(to_char_type(0xCF));
15575  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15576  }
15577  break;
15578  }
15579 
15580  case value_t::number_float:
15581  {
15582  write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::msgpack);
15583  break;
15584  }
15585 
15586  case value_t::string:
15587  {
15588  // step 1: write control byte and the string length
15589  const auto N = j.m_data.m_value.string->size();
15590  if (N <= 31)
15591  {
15592  // fixstr
15593  write_number(static_cast<std::uint8_t>(0xA0 | N));
15594  }
15595  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15596  {
15597  // str 8
15598  oa->write_character(to_char_type(0xD9));
15599  write_number(static_cast<std::uint8_t>(N));
15600  }
15601  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15602  {
15603  // str 16
15604  oa->write_character(to_char_type(0xDA));
15605  write_number(static_cast<std::uint16_t>(N));
15606  }
15607  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15608  {
15609  // str 32
15610  oa->write_character(to_char_type(0xDB));
15611  write_number(static_cast<std::uint32_t>(N));
15612  }
15613 
15614  // step 2: write the string
15615  oa->write_characters(
15616  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15617  j.m_data.m_value.string->size());
15618  break;
15619  }
15620 
15621  case value_t::array:
15622  {
15623  // step 1: write control byte and the array size
15624  const auto N = j.m_data.m_value.array->size();
15625  if (N <= 15)
15626  {
15627  // fixarray
15628  write_number(static_cast<std::uint8_t>(0x90 | N));
15629  }
15630  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15631  {
15632  // array 16
15633  oa->write_character(to_char_type(0xDC));
15634  write_number(static_cast<std::uint16_t>(N));
15635  }
15636  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15637  {
15638  // array 32
15639  oa->write_character(to_char_type(0xDD));
15640  write_number(static_cast<std::uint32_t>(N));
15641  }
15642 
15643  // step 2: write each element
15644  for (const auto& el : *j.m_data.m_value.array)
15645  {
15646  write_msgpack(el);
15647  }
15648  break;
15649  }
15650 
15651  case value_t::binary:
15652  {
15653  // step 0: determine if the binary type has a set subtype to
15654  // determine whether or not to use the ext or fixext types
15655  const bool use_ext = j.m_data.m_value.binary->has_subtype();
15656 
15657  // step 1: write control byte and the byte string length
15658  const auto N = j.m_data.m_value.binary->size();
15659  if (N <= (std::numeric_limits<std::uint8_t>::max)())
15660  {
15661  std::uint8_t output_type{};
15662  bool fixed = true;
15663  if (use_ext)
15664  {
15665  switch (N)
15666  {
15667  case 1:
15668  output_type = 0xD4; // fixext 1
15669  break;
15670  case 2:
15671  output_type = 0xD5; // fixext 2
15672  break;
15673  case 4:
15674  output_type = 0xD6; // fixext 4
15675  break;
15676  case 8:
15677  output_type = 0xD7; // fixext 8
15678  break;
15679  case 16:
15680  output_type = 0xD8; // fixext 16
15681  break;
15682  default:
15683  output_type = 0xC7; // ext 8
15684  fixed = false;
15685  break;
15686  }
15687 
15688  }
15689  else
15690  {
15691  output_type = 0xC4; // bin 8
15692  fixed = false;
15693  }
15694 
15695  oa->write_character(to_char_type(output_type));
15696  if (!fixed)
15697  {
15698  write_number(static_cast<std::uint8_t>(N));
15699  }
15700  }
15701  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15702  {
15703  const std::uint8_t output_type = use_ext
15704  ? 0xC8 // ext 16
15705  : 0xC5; // bin 16
15706 
15707  oa->write_character(to_char_type(output_type));
15708  write_number(static_cast<std::uint16_t>(N));
15709  }
15710  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15711  {
15712  const std::uint8_t output_type = use_ext
15713  ? 0xC9 // ext 32
15714  : 0xC6; // bin 32
15715 
15716  oa->write_character(to_char_type(output_type));
15717  write_number(static_cast<std::uint32_t>(N));
15718  }
15719 
15720  // step 1.5: if this is an ext type, write the subtype
15721  if (use_ext)
15722  {
15723  write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));
15724  }
15725 
15726  // step 2: write the byte string
15727  oa->write_characters(
15728  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15729  N);
15730 
15731  break;
15732  }
15733 
15734  case value_t::object:
15735  {
15736  // step 1: write control byte and the object size
15737  const auto N = j.m_data.m_value.object->size();
15738  if (N <= 15)
15739  {
15740  // fixmap
15741  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
15742  }
15743  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15744  {
15745  // map 16
15746  oa->write_character(to_char_type(0xDE));
15747  write_number(static_cast<std::uint16_t>(N));
15748  }
15749  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15750  {
15751  // map 32
15752  oa->write_character(to_char_type(0xDF));
15753  write_number(static_cast<std::uint32_t>(N));
15754  }
15755 
15756  // step 2: write each element
15757  for (const auto& el : *j.m_data.m_value.object)
15758  {
15759  write_msgpack(el.first);
15760  write_msgpack(el.second);
15761  }
15762  break;
15763  }
15764 
15765  case value_t::discarded:
15766  default:
15767  break;
15768  }
15769  }
15770 
15778  void write_ubjson(const BasicJsonType& j, const bool use_count,
15779  const bool use_type, const bool add_prefix = true,
15780  const bool use_bjdata = false)
15781  {
15782  switch (j.type())
15783  {
15784  case value_t::null:
15785  {
15786  if (add_prefix)
15787  {
15788  oa->write_character(to_char_type('Z'));
15789  }
15790  break;
15791  }
15792 
15793  case value_t::boolean:
15794  {
15795  if (add_prefix)
15796  {
15797  oa->write_character(j.m_data.m_value.boolean
15798  ? to_char_type('T')
15799  : to_char_type('F'));
15800  }
15801  break;
15802  }
15803 
15804  case value_t::number_integer:
15805  {
15806  write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);
15807  break;
15808  }
15809 
15810  case value_t::number_unsigned:
15811  {
15812  write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);
15813  break;
15814  }
15815 
15816  case value_t::number_float:
15817  {
15818  write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);
15819  break;
15820  }
15821 
15822  case value_t::string:
15823  {
15824  if (add_prefix)
15825  {
15826  oa->write_character(to_char_type('S'));
15827  }
15828  write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
15829  oa->write_characters(
15830  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15831  j.m_data.m_value.string->size());
15832  break;
15833  }
15834 
15835  case value_t::array:
15836  {
15837  if (add_prefix)
15838  {
15839  oa->write_character(to_char_type('['));
15840  }
15841 
15842  bool prefix_required = true;
15843  if (use_type && !j.m_data.m_value.array->empty())
15844  {
15845  JSON_ASSERT(use_count);
15846  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15847  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
15848  [this, first_prefix, use_bjdata](const BasicJsonType & v)
15849  {
15850  return ubjson_prefix(v, use_bjdata) == first_prefix;
15851  });
15852 
15853  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15854 
15855  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15856  {
15857  prefix_required = false;
15858  oa->write_character(to_char_type('$'));
15859  oa->write_character(first_prefix);
15860  }
15861  }
15862 
15863  if (use_count)
15864  {
15865  oa->write_character(to_char_type('#'));
15866  write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
15867  }
15868 
15869  for (const auto& el : *j.m_data.m_value.array)
15870  {
15871  write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
15872  }
15873 
15874  if (!use_count)
15875  {
15876  oa->write_character(to_char_type(']'));
15877  }
15878 
15879  break;
15880  }
15881 
15882  case value_t::binary:
15883  {
15884  if (add_prefix)
15885  {
15886  oa->write_character(to_char_type('['));
15887  }
15888 
15889  if (use_type && !j.m_data.m_value.binary->empty())
15890  {
15891  JSON_ASSERT(use_count);
15892  oa->write_character(to_char_type('$'));
15893  oa->write_character('U');
15894  }
15895 
15896  if (use_count)
15897  {
15898  oa->write_character(to_char_type('#'));
15899  write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);
15900  }
15901 
15902  if (use_type)
15903  {
15904  oa->write_characters(
15905  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15906  j.m_data.m_value.binary->size());
15907  }
15908  else
15909  {
15910  for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
15911  {
15912  oa->write_character(to_char_type('U'));
15913  oa->write_character(j.m_data.m_value.binary->data()[i]);
15914  }
15915  }
15916 
15917  if (!use_count)
15918  {
15919  oa->write_character(to_char_type(']'));
15920  }
15921 
15922  break;
15923  }
15924 
15925  case value_t::object:
15926  {
15927  if (use_bjdata && j.m_data.m_value.object->size() == 3 && j.m_data.m_value.object->find("_ArrayType_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArraySize_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArrayData_") != j.m_data.m_value.object->end())
15928  {
15929  if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
15930  {
15931  break;
15932  }
15933  }
15934 
15935  if (add_prefix)
15936  {
15937  oa->write_character(to_char_type('{'));
15938  }
15939 
15940  bool prefix_required = true;
15941  if (use_type && !j.m_data.m_value.object->empty())
15942  {
15943  JSON_ASSERT(use_count);
15944  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15945  const bool same_prefix = std::all_of(j.begin(), j.end(),
15946  [this, first_prefix, use_bjdata](const BasicJsonType & v)
15947  {
15948  return ubjson_prefix(v, use_bjdata) == first_prefix;
15949  });
15950 
15951  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15952 
15953  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15954  {
15955  prefix_required = false;
15956  oa->write_character(to_char_type('$'));
15957  oa->write_character(first_prefix);
15958  }
15959  }
15960 
15961  if (use_count)
15962  {
15963  oa->write_character(to_char_type('#'));
15964  write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
15965  }
15966 
15967  for (const auto& el : *j.m_data.m_value.object)
15968  {
15969  write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
15970  oa->write_characters(
15971  reinterpret_cast<const CharType*>(el.first.c_str()),
15972  el.first.size());
15973  write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
15974  }
15975 
15976  if (!use_count)
15977  {
15978  oa->write_character(to_char_type('}'));
15979  }
15980 
15981  break;
15982  }
15983 
15984  case value_t::discarded:
15985  default:
15986  break;
15987  }
15988  }
15989 
15990  private:
15992  // BSON //
15994 
15999  static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
16000  {
16001  const auto it = name.find(static_cast<typename string_t::value_type>(0));
16002  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
16003  {
16004  JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
16005  static_cast<void>(j);
16006  }
16007 
16008  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
16009  }
16010 
16015  const std::uint8_t element_type)
16016  {
16017  oa->write_character(to_char_type(element_type)); // boolean
16018  oa->write_characters(
16019  reinterpret_cast<const CharType*>(name.c_str()),
16020  name.size() + 1u);
16021  }
16022 
16026  void write_bson_boolean(const string_t& name,
16027  const bool value)
16028  {
16029  write_bson_entry_header(name, 0x08);
16030  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
16031  }
16032 
16036  void write_bson_double(const string_t& name,
16037  const double value)
16038  {
16039  write_bson_entry_header(name, 0x01);
16040  write_number<double>(value, true);
16041  }
16042 
16046  static std::size_t calc_bson_string_size(const string_t& value)
16047  {
16048  return sizeof(std::int32_t) + value.size() + 1ul;
16049  }
16050 
16054  void write_bson_string(const string_t& name,
16055  const string_t& value)
16056  {
16057  write_bson_entry_header(name, 0x02);
16058 
16059  write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
16060  oa->write_characters(
16061  reinterpret_cast<const CharType*>(value.c_str()),
16062  value.size() + 1);
16063  }
16064 
16068  void write_bson_null(const string_t& name)
16069  {
16070  write_bson_entry_header(name, 0x0A);
16071  }
16072 
16076  static std::size_t calc_bson_integer_size(const std::int64_t value)
16077  {
16078  return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
16079  ? sizeof(std::int32_t)
16080  : sizeof(std::int64_t);
16081  }
16082 
16086  void write_bson_integer(const string_t& name,
16087  const std::int64_t value)
16088  {
16089  if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
16090  {
16091  write_bson_entry_header(name, 0x10); // int32
16092  write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
16093  }
16094  else
16095  {
16096  write_bson_entry_header(name, 0x12); // int64
16097  write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
16098  }
16099  }
16100 
16104  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
16105  {
16106  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16107  ? sizeof(std::int32_t)
16108  : sizeof(std::int64_t);
16109  }
16110 
16114  void write_bson_unsigned(const string_t& name,
16115  const BasicJsonType& j)
16116  {
16117  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16118  {
16119  write_bson_entry_header(name, 0x10 /* int32 */);
16120  write_number<std::int32_t>(static_cast<std::int32_t>(j.m_data.m_value.number_unsigned), true);
16121  }
16122  else if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16123  {
16124  write_bson_entry_header(name, 0x12 /* int64 */);
16125  write_number<std::int64_t>(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned), true);
16126  }
16127  else
16128  {
16129  JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
16130  }
16131  }
16132 
16137  const typename BasicJsonType::object_t& value)
16138  {
16139  write_bson_entry_header(name, 0x03); // object
16140  write_bson_object(value);
16141  }
16142 
16146  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
16147  {
16148  std::size_t array_index = 0ul;
16149 
16150  const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
16151  {
16152  return result + calc_bson_element_size(std::to_string(array_index++), el);
16153  });
16154 
16155  return sizeof(std::int32_t) + embedded_document_size + 1ul;
16156  }
16157 
16161  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
16162  {
16163  return sizeof(std::int32_t) + value.size() + 1ul;
16164  }
16165 
16169  void write_bson_array(const string_t& name,
16170  const typename BasicJsonType::array_t& value)
16171  {
16172  write_bson_entry_header(name, 0x04); // array
16173  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
16174 
16175  std::size_t array_index = 0ul;
16176 
16177  for (const auto& el : value)
16178  {
16179  write_bson_element(std::to_string(array_index++), el);
16180  }
16181 
16182  oa->write_character(to_char_type(0x00));
16183  }
16184 
16188  void write_bson_binary(const string_t& name,
16189  const binary_t& value)
16190  {
16191  write_bson_entry_header(name, 0x05);
16192 
16193  write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
16194  write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
16195 
16196  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
16197  }
16198 
16203  static std::size_t calc_bson_element_size(const string_t& name,
16204  const BasicJsonType& j)
16205  {
16206  const auto header_size = calc_bson_entry_header_size(name, j);
16207  switch (j.type())
16208  {
16209  case value_t::object:
16210  return header_size + calc_bson_object_size(*j.m_data.m_value.object);
16211 
16212  case value_t::array:
16213  return header_size + calc_bson_array_size(*j.m_data.m_value.array);
16214 
16215  case value_t::binary:
16216  return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);
16217 
16218  case value_t::boolean:
16219  return header_size + 1ul;
16220 
16221  case value_t::number_float:
16222  return header_size + 8ul;
16223 
16224  case value_t::number_integer:
16225  return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);
16226 
16227  case value_t::number_unsigned:
16228  return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);
16229 
16230  case value_t::string:
16231  return header_size + calc_bson_string_size(*j.m_data.m_value.string);
16232 
16233  case value_t::null:
16234  return header_size + 0ul;
16235 
16236  // LCOV_EXCL_START
16237  case value_t::discarded:
16238  default:
16239  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16240  return 0ul;
16241  // LCOV_EXCL_STOP
16242  }
16243  }
16244 
16251  void write_bson_element(const string_t& name,
16252  const BasicJsonType& j)
16253  {
16254  switch (j.type())
16255  {
16256  case value_t::object:
16257  return write_bson_object_entry(name, *j.m_data.m_value.object);
16258 
16259  case value_t::array:
16260  return write_bson_array(name, *j.m_data.m_value.array);
16261 
16262  case value_t::binary:
16263  return write_bson_binary(name, *j.m_data.m_value.binary);
16264 
16265  case value_t::boolean:
16266  return write_bson_boolean(name, j.m_data.m_value.boolean);
16267 
16268  case value_t::number_float:
16269  return write_bson_double(name, j.m_data.m_value.number_float);
16270 
16271  case value_t::number_integer:
16272  return write_bson_integer(name, j.m_data.m_value.number_integer);
16273 
16274  case value_t::number_unsigned:
16275  return write_bson_unsigned(name, j);
16276 
16277  case value_t::string:
16278  return write_bson_string(name, *j.m_data.m_value.string);
16279 
16280  case value_t::null:
16281  return write_bson_null(name);
16282 
16283  // LCOV_EXCL_START
16284  case value_t::discarded:
16285  default:
16286  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16287  return;
16288  // LCOV_EXCL_STOP
16289  }
16290  }
16291 
16298  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
16299  {
16300  const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
16301  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
16302  {
16303  return result += calc_bson_element_size(el.first, el.second);
16304  });
16305 
16306  return sizeof(std::int32_t) + document_size + 1ul;
16307  }
16308 
16313  void write_bson_object(const typename BasicJsonType::object_t& value)
16314  {
16315  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
16316 
16317  for (const auto& el : value)
16318  {
16319  write_bson_element(el.first, el.second);
16320  }
16321 
16322  oa->write_character(to_char_type(0x00));
16323  }
16324 
16326  // CBOR //
16328 
16329  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
16330  {
16331  return to_char_type(0xFA); // Single-Precision Float
16332  }
16333 
16334  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
16335  {
16336  return to_char_type(0xFB); // Double-Precision Float
16337  }
16338 
16340  // MsgPack //
16342 
16343  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
16344  {
16345  return to_char_type(0xCA); // float 32
16346  }
16347 
16348  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
16349  {
16350  return to_char_type(0xCB); // float 64
16351  }
16352 
16354  // UBJSON //
16356 
16357  // UBJSON: write number (floating point)
16358  template<typename NumberType, typename std::enable_if<
16360  void write_number_with_ubjson_prefix(const NumberType n,
16361  const bool add_prefix,
16362  const bool use_bjdata)
16363  {
16364  if (add_prefix)
16365  {
16366  oa->write_character(get_ubjson_float_prefix(n));
16367  }
16368  write_number(n, use_bjdata);
16369  }
16370 
16371  // UBJSON: write number (unsigned integer)
16372  template<typename NumberType, typename std::enable_if<
16373  std::is_unsigned<NumberType>::value, int>::type = 0>
16374  void write_number_with_ubjson_prefix(const NumberType n,
16375  const bool add_prefix,
16376  const bool use_bjdata)
16377  {
16378  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16379  {
16380  if (add_prefix)
16381  {
16382  oa->write_character(to_char_type('i')); // int8
16383  }
16384  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16385  }
16386  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
16387  {
16388  if (add_prefix)
16389  {
16390  oa->write_character(to_char_type('U')); // uint8
16391  }
16392  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16393  }
16394  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16395  {
16396  if (add_prefix)
16397  {
16398  oa->write_character(to_char_type('I')); // int16
16399  }
16400  write_number(static_cast<std::int16_t>(n), use_bjdata);
16401  }
16402  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
16403  {
16404  if (add_prefix)
16405  {
16406  oa->write_character(to_char_type('u')); // uint16 - bjdata only
16407  }
16408  write_number(static_cast<std::uint16_t>(n), use_bjdata);
16409  }
16410  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16411  {
16412  if (add_prefix)
16413  {
16414  oa->write_character(to_char_type('l')); // int32
16415  }
16416  write_number(static_cast<std::int32_t>(n), use_bjdata);
16417  }
16418  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
16419  {
16420  if (add_prefix)
16421  {
16422  oa->write_character(to_char_type('m')); // uint32 - bjdata only
16423  }
16424  write_number(static_cast<std::uint32_t>(n), use_bjdata);
16425  }
16426  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16427  {
16428  if (add_prefix)
16429  {
16430  oa->write_character(to_char_type('L')); // int64
16431  }
16432  write_number(static_cast<std::int64_t>(n), use_bjdata);
16433  }
16434  else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
16435  {
16436  if (add_prefix)
16437  {
16438  oa->write_character(to_char_type('M')); // uint64 - bjdata only
16439  }
16440  write_number(static_cast<std::uint64_t>(n), use_bjdata);
16441  }
16442  else
16443  {
16444  if (add_prefix)
16445  {
16446  oa->write_character(to_char_type('H')); // high-precision number
16447  }
16448 
16449  const auto number = BasicJsonType(n).dump();
16450  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16451  for (std::size_t i = 0; i < number.size(); ++i)
16452  {
16453  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16454  }
16455  }
16456  }
16457 
16458  // UBJSON: write number (signed integer)
16459  template < typename NumberType, typename std::enable_if <
16461  !std::is_floating_point<NumberType>::value, int >::type = 0 >
16462  void write_number_with_ubjson_prefix(const NumberType n,
16463  const bool add_prefix,
16464  const bool use_bjdata)
16465  {
16466  if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
16467  {
16468  if (add_prefix)
16469  {
16470  oa->write_character(to_char_type('i')); // int8
16471  }
16472  write_number(static_cast<std::int8_t>(n), use_bjdata);
16473  }
16474  else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
16475  {
16476  if (add_prefix)
16477  {
16478  oa->write_character(to_char_type('U')); // uint8
16479  }
16480  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16481  }
16482  else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
16483  {
16484  if (add_prefix)
16485  {
16486  oa->write_character(to_char_type('I')); // int16
16487  }
16488  write_number(static_cast<std::int16_t>(n), use_bjdata);
16489  }
16490  else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
16491  {
16492  if (add_prefix)
16493  {
16494  oa->write_character(to_char_type('u')); // uint16 - bjdata only
16495  }
16496  write_number(static_cast<uint16_t>(n), use_bjdata);
16497  }
16498  else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
16499  {
16500  if (add_prefix)
16501  {
16502  oa->write_character(to_char_type('l')); // int32
16503  }
16504  write_number(static_cast<std::int32_t>(n), use_bjdata);
16505  }
16506  else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
16507  {
16508  if (add_prefix)
16509  {
16510  oa->write_character(to_char_type('m')); // uint32 - bjdata only
16511  }
16512  write_number(static_cast<uint32_t>(n), use_bjdata);
16513  }
16514  else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
16515  {
16516  if (add_prefix)
16517  {
16518  oa->write_character(to_char_type('L')); // int64
16519  }
16520  write_number(static_cast<std::int64_t>(n), use_bjdata);
16521  }
16522  // LCOV_EXCL_START
16523  else
16524  {
16525  if (add_prefix)
16526  {
16527  oa->write_character(to_char_type('H')); // high-precision number
16528  }
16529 
16530  const auto number = BasicJsonType(n).dump();
16531  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16532  for (std::size_t i = 0; i < number.size(); ++i)
16533  {
16534  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16535  }
16536  }
16537  // LCOV_EXCL_STOP
16538  }
16539 
16543  CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
16544  {
16545  switch (j.type())
16546  {
16547  case value_t::null:
16548  return 'Z';
16549 
16550  case value_t::boolean:
16551  return j.m_data.m_value.boolean ? 'T' : 'F';
16552 
16553  case value_t::number_integer:
16554  {
16555  if ((std::numeric_limits<std::int8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
16556  {
16557  return 'i';
16558  }
16559  if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
16560  {
16561  return 'U';
16562  }
16563  if ((std::numeric_limits<std::int16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
16564  {
16565  return 'I';
16566  }
16567  if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
16568  {
16569  return 'u';
16570  }
16571  if ((std::numeric_limits<std::int32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
16572  {
16573  return 'l';
16574  }
16575  if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
16576  {
16577  return 'm';
16578  }
16579  if ((std::numeric_limits<std::int64_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
16580  {
16581  return 'L';
16582  }
16583  // anything else is treated as high-precision number
16584  return 'H'; // LCOV_EXCL_LINE
16585  }
16586 
16587  case value_t::number_unsigned:
16588  {
16589  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16590  {
16591  return 'i';
16592  }
16593  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
16594  {
16595  return 'U';
16596  }
16597  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16598  {
16599  return 'I';
16600  }
16601  if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
16602  {
16603  return 'u';
16604  }
16605  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16606  {
16607  return 'l';
16608  }
16609  if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
16610  {
16611  return 'm';
16612  }
16613  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16614  {
16615  return 'L';
16616  }
16617  if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16618  {
16619  return 'M';
16620  }
16621  // anything else is treated as high-precision number
16622  return 'H'; // LCOV_EXCL_LINE
16623  }
16624 
16625  case value_t::number_float:
16626  return get_ubjson_float_prefix(j.m_data.m_value.number_float);
16627 
16628  case value_t::string:
16629  return 'S';
16630 
16631  case value_t::array: // fallthrough
16632  case value_t::binary:
16633  return '[';
16634 
16635  case value_t::object:
16636  return '{';
16637 
16638  case value_t::discarded:
16639  default: // discarded values
16640  return 'N';
16641  }
16642  }
16643 
16644  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
16645  {
16646  return 'd'; // float 32
16647  }
16648 
16649  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
16650  {
16651  return 'D'; // float 64
16652  }
16653 
16657  bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
16658  {
16659  std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
16660  {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
16661  };
16662 
16663  string_t key = "_ArrayType_";
16664  auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
16665  if (it == bjdtype.end())
16666  {
16667  return true;
16668  }
16669  CharType dtype = it->second;
16670 
16671  key = "_ArraySize_";
16672  std::size_t len = (value.at(key).empty() ? 0 : 1);
16673  for (const auto& el : value.at(key))
16674  {
16675  len *= static_cast<std::size_t>(el.m_data.m_value.number_unsigned);
16676  }
16677 
16678  key = "_ArrayData_";
16679  if (value.at(key).size() != len)
16680  {
16681  return true;
16682  }
16683 
16684  oa->write_character('[');
16685  oa->write_character('$');
16686  oa->write_character(dtype);
16687  oa->write_character('#');
16688 
16689  key = "_ArraySize_";
16690  write_ubjson(value.at(key), use_count, use_type, true, true);
16691 
16692  key = "_ArrayData_";
16693  if (dtype == 'U' || dtype == 'C')
16694  {
16695  for (const auto& el : value.at(key))
16696  {
16697  write_number(static_cast<std::uint8_t>(el.m_data.m_value.number_unsigned), true);
16698  }
16699  }
16700  else if (dtype == 'i')
16701  {
16702  for (const auto& el : value.at(key))
16703  {
16704  write_number(static_cast<std::int8_t>(el.m_data.m_value.number_integer), true);
16705  }
16706  }
16707  else if (dtype == 'u')
16708  {
16709  for (const auto& el : value.at(key))
16710  {
16711  write_number(static_cast<std::uint16_t>(el.m_data.m_value.number_unsigned), true);
16712  }
16713  }
16714  else if (dtype == 'I')
16715  {
16716  for (const auto& el : value.at(key))
16717  {
16718  write_number(static_cast<std::int16_t>(el.m_data.m_value.number_integer), true);
16719  }
16720  }
16721  else if (dtype == 'm')
16722  {
16723  for (const auto& el : value.at(key))
16724  {
16725  write_number(static_cast<std::uint32_t>(el.m_data.m_value.number_unsigned), true);
16726  }
16727  }
16728  else if (dtype == 'l')
16729  {
16730  for (const auto& el : value.at(key))
16731  {
16732  write_number(static_cast<std::int32_t>(el.m_data.m_value.number_integer), true);
16733  }
16734  }
16735  else if (dtype == 'M')
16736  {
16737  for (const auto& el : value.at(key))
16738  {
16739  write_number(static_cast<std::uint64_t>(el.m_data.m_value.number_unsigned), true);
16740  }
16741  }
16742  else if (dtype == 'L')
16743  {
16744  for (const auto& el : value.at(key))
16745  {
16746  write_number(static_cast<std::int64_t>(el.m_data.m_value.number_integer), true);
16747  }
16748  }
16749  else if (dtype == 'd')
16750  {
16751  for (const auto& el : value.at(key))
16752  {
16753  write_number(static_cast<float>(el.m_data.m_value.number_float), true);
16754  }
16755  }
16756  else if (dtype == 'D')
16757  {
16758  for (const auto& el : value.at(key))
16759  {
16760  write_number(static_cast<double>(el.m_data.m_value.number_float), true);
16761  }
16762  }
16763  return false;
16764  }
16765 
16767  // Utility functions //
16769 
16770  /*
16771  @brief write a number to output input
16772  @param[in] n number of type @a NumberType
16773  @param[in] OutputIsLittleEndian Set to true if output data is
16774  required to be little endian
16775  @tparam NumberType the type of the number
16776 
16777  @note This function needs to respect the system's endianness, because bytes
16778  in CBOR, MessagePack, and UBJSON are stored in network order (big
16779  endian) and therefore need reordering on little endian systems.
16780  On the other hand, BSON and BJData use little endian and should reorder
16781  on big endian systems.
16782  */
16783  template<typename NumberType>
16784  void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
16785  {
16786  // step 1: write number to array of length NumberType
16787  std::array<CharType, sizeof(NumberType)> vec{};
16788  std::memcpy(vec.data(), &n, sizeof(NumberType));
16789 
16790  // step 2: write array to output (with possible reordering)
16791  if (is_little_endian != OutputIsLittleEndian)
16792  {
16793  // reverse byte order prior to conversion if necessary
16794  std::reverse(vec.begin(), vec.end());
16795  }
16796 
16797  oa->write_characters(vec.data(), sizeof(NumberType));
16798  }
16799 
16801  {
16802 #ifdef __GNUC__
16803 #pragma GCC diagnostic push
16804 #pragma GCC diagnostic ignored "-Wfloat-equal"
16805 #endif
16806  if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
16807  static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
16808  static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
16809  {
16810  oa->write_character(format == detail::input_format_t::cbor
16811  ? get_cbor_float_prefix(static_cast<float>(n))
16812  : get_msgpack_float_prefix(static_cast<float>(n)));
16813  write_number(static_cast<float>(n));
16814  }
16815  else
16816  {
16817  oa->write_character(format == detail::input_format_t::cbor
16818  ? get_cbor_float_prefix(n)
16819  : get_msgpack_float_prefix(n));
16820  write_number(n);
16821  }
16822 #ifdef __GNUC__
16823 #pragma GCC diagnostic pop
16824 #endif
16825  }
16826 
16827  public:
16828  // The following to_char_type functions are implement the conversion
16829  // between uint8_t and CharType. In case CharType is not unsigned,
16830  // such a conversion is required to allow values greater than 128.
16831  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
16832  template < typename C = CharType,
16834  static constexpr CharType to_char_type(std::uint8_t x) noexcept
16835  {
16836  return *reinterpret_cast<char*>(&x);
16837  }
16838 
16839  template < typename C = CharType,
16841  static CharType to_char_type(std::uint8_t x) noexcept
16842  {
16843  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
16844  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
16845  CharType result;
16846  std::memcpy(&result, &x, sizeof(x));
16847  return result;
16848  }
16849 
16850  template<typename C = CharType,
16852  static constexpr CharType to_char_type(std::uint8_t x) noexcept
16853  {
16854  return x;
16855  }
16856 
16857  template < typename InputCharType, typename C = CharType,
16858  enable_if_t <
16861  std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
16862  > * = nullptr >
16863  static constexpr CharType to_char_type(InputCharType x) noexcept
16864  {
16865  return x;
16866  }
16867 
16868  private:
16870  const bool is_little_endian = little_endianness();
16871 
16874 };
16875 
16876 } // namespace detail
16878 
16879 // #include <nlohmann/detail/output/output_adapters.hpp>
16880 
16881 // #include <nlohmann/detail/output/serializer.hpp>
16882 // __ _____ _____ _____
16883 // __| | __| | | | JSON for Modern C++
16884 // | | |__ | | | | | | version 3.11.3
16885 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
16886 //
16887 // SPDX-FileCopyrightText: 2008-2009 Björn Hoehrmann <bjoern@hoehrmann.de>
16888 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
16889 // SPDX-License-Identifier: MIT
16890 
16891 
16892 
16893 #include <algorithm> // reverse, remove, fill, find, none_of
16894 #include <array> // array
16895 #include <clocale> // localeconv, lconv
16896 #include <cmath> // labs, isfinite, isnan, signbit
16897 #include <cstddef> // size_t, ptrdiff_t
16898 #include <cstdint> // uint8_t
16899 #include <cstdio> // snprintf
16900 #include <limits> // numeric_limits
16901 #include <string> // string, char_traits
16902 #include <iomanip> // setfill, setw
16903 #include <type_traits> // is_same
16904 #include <utility> // move
16905 
16906 // #include <nlohmann/detail/conversions/to_chars.hpp>
16907 // __ _____ _____ _____
16908 // __| | __| | | | JSON for Modern C++
16909 // | | |__ | | | | | | version 3.11.3
16910 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
16911 //
16912 // SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>
16913 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
16914 // SPDX-License-Identifier: MIT
16915 
16916 
16917 
16918 #include <array> // array
16919 #include <cmath> // signbit, isfinite
16920 #include <cstdint> // intN_t, uintN_t
16921 #include <cstring> // memcpy, memmove
16922 #include <limits> // numeric_limits
16923 #include <type_traits> // conditional
16924 
16925 // #include <nlohmann/detail/macro_scope.hpp>
16926 
16927 
16929 namespace detail
16930 {
16931 
16951 namespace dtoa_impl
16952 {
16953 
16954 template<typename Target, typename Source>
16955 Target reinterpret_bits(const Source source)
16956 {
16957  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
16958 
16959  Target target;
16960  std::memcpy(&target, &source, sizeof(Source));
16961  return target;
16962 }
16963 
16964 struct diyfp // f * 2^e
16965 {
16966  static constexpr int kPrecision = 64; // = q
16967 
16968  std::uint64_t f = 0;
16969  int e = 0;
16970 
16971  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
16972 
16977  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
16978  {
16979  JSON_ASSERT(x.e == y.e);
16980  JSON_ASSERT(x.f >= y.f);
16981 
16982  return {x.f - y.f, x.e};
16983  }
16984 
16989  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
16990  {
16991  static_assert(kPrecision == 64, "internal error");
16992 
16993  // Computes:
16994  // f = round((x.f * y.f) / 2^q)
16995  // e = x.e + y.e + q
16996 
16997  // Emulate the 64-bit * 64-bit multiplication:
16998  //
16999  // p = u * v
17000  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
17001  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
17002  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
17003  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
17004  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
17005  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
17006  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
17007  //
17008  // (Since Q might be larger than 2^32 - 1)
17009  //
17010  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
17011  //
17012  // (Q_hi + H does not overflow a 64-bit int)
17013  //
17014  // = p_lo + 2^64 p_hi
17015 
17016  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
17017  const std::uint64_t u_hi = x.f >> 32u;
17018  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
17019  const std::uint64_t v_hi = y.f >> 32u;
17020 
17021  const std::uint64_t p0 = u_lo * v_lo;
17022  const std::uint64_t p1 = u_lo * v_hi;
17023  const std::uint64_t p2 = u_hi * v_lo;
17024  const std::uint64_t p3 = u_hi * v_hi;
17025 
17026  const std::uint64_t p0_hi = p0 >> 32u;
17027  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
17028  const std::uint64_t p1_hi = p1 >> 32u;
17029  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
17030  const std::uint64_t p2_hi = p2 >> 32u;
17031 
17032  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
17033 
17034  // The full product might now be computed as
17035  //
17036  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
17037  // p_lo = p0_lo + (Q << 32)
17038  //
17039  // But in this particular case here, the full p_lo is not required.
17040  // Effectively we only need to add the highest bit in p_lo to p_hi (and
17041  // Q_hi + 1 does not overflow).
17042 
17043  Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
17044 
17045  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
17046 
17047  return {h, x.e + y.e + 64};
17048  }
17049 
17054  static diyfp normalize(diyfp x) noexcept
17055  {
17056  JSON_ASSERT(x.f != 0);
17057 
17058  while ((x.f >> 63u) == 0)
17059  {
17060  x.f <<= 1u;
17061  x.e--;
17062  }
17063 
17064  return x;
17065  }
17066 
17071  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
17072  {
17073  const int delta = x.e - target_exponent;
17074 
17075  JSON_ASSERT(delta >= 0);
17076  JSON_ASSERT(((x.f << delta) >> delta) == x.f);
17077 
17078  return {x.f << delta, target_exponent};
17079  }
17080 };
17081 
17083 {
17087 };
17088 
17095 template<typename FloatType>
17097 {
17098  JSON_ASSERT(std::isfinite(value));
17099  JSON_ASSERT(value > 0);
17100 
17101  // Convert the IEEE representation into a diyfp.
17102  //
17103  // If v is denormal:
17104  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
17105  // If v is normalized:
17106  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
17107 
17108  static_assert(std::numeric_limits<FloatType>::is_iec559,
17109  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
17110 
17111  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
17112  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
17113  constexpr int kMinExp = 1 - kBias;
17114  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
17115 
17116  using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
17117 
17118  const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
17119  const std::uint64_t E = bits >> (kPrecision - 1);
17120  const std::uint64_t F = bits & (kHiddenBit - 1);
17121 
17122  const bool is_denormal = E == 0;
17123  const diyfp v = is_denormal
17124  ? diyfp(F, kMinExp)
17125  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
17126 
17127  // Compute the boundaries m- and m+ of the floating-point value
17128  // v = f * 2^e.
17129  //
17130  // Determine v- and v+, the floating-point predecessor and successor if v,
17131  // respectively.
17132  //
17133  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
17134  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
17135  //
17136  // v+ = v + 2^e
17137  //
17138  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
17139  // between m- and m+ round to v, regardless of how the input rounding
17140  // algorithm breaks ties.
17141  //
17142  // ---+-------------+-------------+-------------+-------------+--- (A)
17143  // v- m- v m+ v+
17144  //
17145  // -----------------+------+------+-------------+-------------+--- (B)
17146  // v- m- v m+ v+
17147 
17148  const bool lower_boundary_is_closer = F == 0 && E > 1;
17149  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
17150  const diyfp m_minus = lower_boundary_is_closer
17151  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
17152  : diyfp(2 * v.f - 1, v.e - 1); // (A)
17153 
17154  // Determine the normalized w+ = m+.
17155  const diyfp w_plus = diyfp::normalize(m_plus);
17156 
17157  // Determine w- = m- such that e_(w-) = e_(w+).
17158  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
17159 
17160  return {diyfp::normalize(v), w_minus, w_plus};
17161 }
17162 
17163 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
17164 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
17165 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
17166 //
17167 // alpha <= e = e_c + e_w + q <= gamma
17168 //
17169 // or
17170 //
17171 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
17172 // <= f_c * f_w * 2^gamma
17173 //
17174 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
17175 //
17176 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
17177 //
17178 // or
17179 //
17180 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
17181 //
17182 // The choice of (alpha,gamma) determines the size of the table and the form of
17183 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
17184 // in practice:
17185 //
17186 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
17187 // processed independently: An integral part p1, and a fractional part p2:
17188 //
17189 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
17190 // = (f div 2^-e) + (f mod 2^-e) * 2^e
17191 // = p1 + p2 * 2^e
17192 //
17193 // The conversion of p1 into decimal form requires a series of divisions and
17194 // modulos by (a power of) 10. These operations are faster for 32-bit than for
17195 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
17196 // achieved by choosing
17197 //
17198 // -e >= 32 or e <= -32 := gamma
17199 //
17200 // In order to convert the fractional part
17201 //
17202 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
17203 //
17204 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
17205 // d[-i] are extracted in order:
17206 //
17207 // (10 * p2) div 2^-e = d[-1]
17208 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
17209 //
17210 // The multiplication by 10 must not overflow. It is sufficient to choose
17211 //
17212 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
17213 //
17214 // Since p2 = f mod 2^-e < 2^-e,
17215 //
17216 // -e <= 60 or e >= -60 := alpha
17217 
17218 constexpr int kAlpha = -60;
17219 constexpr int kGamma = -32;
17220 
17221 struct cached_power // c = f * 2^e ~= 10^k
17222 {
17223  std::uint64_t f;
17224  int e;
17225  int k;
17226 };
17227 
17236 {
17237  // Now
17238  //
17239  // alpha <= e_c + e + q <= gamma (1)
17240  // ==> f_c * 2^alpha <= c * 2^e * 2^q
17241  //
17242  // and since the c's are normalized, 2^(q-1) <= f_c,
17243  //
17244  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
17245  // ==> 2^(alpha - e - 1) <= c
17246  //
17247  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
17248  //
17249  // k = ceil( log_10( 2^(alpha - e - 1) ) )
17250  // = ceil( (alpha - e - 1) * log_10(2) )
17251  //
17252  // From the paper:
17253  // "In theory the result of the procedure could be wrong since c is rounded,
17254  // and the computation itself is approximated [...]. In practice, however,
17255  // this simple function is sufficient."
17256  //
17257  // For IEEE double precision floating-point numbers converted into
17258  // normalized diyfp's w = f * 2^e, with q = 64,
17259  //
17260  // e >= -1022 (min IEEE exponent)
17261  // -52 (p - 1)
17262  // -52 (p - 1, possibly normalize denormal IEEE numbers)
17263  // -11 (normalize the diyfp)
17264  // = -1137
17265  //
17266  // and
17267  //
17268  // e <= +1023 (max IEEE exponent)
17269  // -52 (p - 1)
17270  // -11 (normalize the diyfp)
17271  // = 960
17272  //
17273  // This binary exponent range [-1137,960] results in a decimal exponent
17274  // range [-307,324]. One does not need to store a cached power for each
17275  // k in this range. For each such k it suffices to find a cached power
17276  // such that the exponent of the product lies in [alpha,gamma].
17277  // This implies that the difference of the decimal exponents of adjacent
17278  // table entries must be less than or equal to
17279  //
17280  // floor( (gamma - alpha) * log_10(2) ) = 8.
17281  //
17282  // (A smaller distance gamma-alpha would require a larger table.)
17283 
17284  // NB:
17285  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
17286 
17287  constexpr int kCachedPowersMinDecExp = -300;
17288  constexpr int kCachedPowersDecStep = 8;
17289 
17290  static constexpr std::array<cached_power, 79> kCachedPowers =
17291  {
17292  {
17293  { 0xAB70FE17C79AC6CA, -1060, -300 },
17294  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
17295  { 0xBE5691EF416BD60C, -1007, -284 },
17296  { 0x8DD01FAD907FFC3C, -980, -276 },
17297  { 0xD3515C2831559A83, -954, -268 },
17298  { 0x9D71AC8FADA6C9B5, -927, -260 },
17299  { 0xEA9C227723EE8BCB, -901, -252 },
17300  { 0xAECC49914078536D, -874, -244 },
17301  { 0x823C12795DB6CE57, -847, -236 },
17302  { 0xC21094364DFB5637, -821, -228 },
17303  { 0x9096EA6F3848984F, -794, -220 },
17304  { 0xD77485CB25823AC7, -768, -212 },
17305  { 0xA086CFCD97BF97F4, -741, -204 },
17306  { 0xEF340A98172AACE5, -715, -196 },
17307  { 0xB23867FB2A35B28E, -688, -188 },
17308  { 0x84C8D4DFD2C63F3B, -661, -180 },
17309  { 0xC5DD44271AD3CDBA, -635, -172 },
17310  { 0x936B9FCEBB25C996, -608, -164 },
17311  { 0xDBAC6C247D62A584, -582, -156 },
17312  { 0xA3AB66580D5FDAF6, -555, -148 },
17313  { 0xF3E2F893DEC3F126, -529, -140 },
17314  { 0xB5B5ADA8AAFF80B8, -502, -132 },
17315  { 0x87625F056C7C4A8B, -475, -124 },
17316  { 0xC9BCFF6034C13053, -449, -116 },
17317  { 0x964E858C91BA2655, -422, -108 },
17318  { 0xDFF9772470297EBD, -396, -100 },
17319  { 0xA6DFBD9FB8E5B88F, -369, -92 },
17320  { 0xF8A95FCF88747D94, -343, -84 },
17321  { 0xB94470938FA89BCF, -316, -76 },
17322  { 0x8A08F0F8BF0F156B, -289, -68 },
17323  { 0xCDB02555653131B6, -263, -60 },
17324  { 0x993FE2C6D07B7FAC, -236, -52 },
17325  { 0xE45C10C42A2B3B06, -210, -44 },
17326  { 0xAA242499697392D3, -183, -36 },
17327  { 0xFD87B5F28300CA0E, -157, -28 },
17328  { 0xBCE5086492111AEB, -130, -20 },
17329  { 0x8CBCCC096F5088CC, -103, -12 },
17330  { 0xD1B71758E219652C, -77, -4 },
17331  { 0x9C40000000000000, -50, 4 },
17332  { 0xE8D4A51000000000, -24, 12 },
17333  { 0xAD78EBC5AC620000, 3, 20 },
17334  { 0x813F3978F8940984, 30, 28 },
17335  { 0xC097CE7BC90715B3, 56, 36 },
17336  { 0x8F7E32CE7BEA5C70, 83, 44 },
17337  { 0xD5D238A4ABE98068, 109, 52 },
17338  { 0x9F4F2726179A2245, 136, 60 },
17339  { 0xED63A231D4C4FB27, 162, 68 },
17340  { 0xB0DE65388CC8ADA8, 189, 76 },
17341  { 0x83C7088E1AAB65DB, 216, 84 },
17342  { 0xC45D1DF942711D9A, 242, 92 },
17343  { 0x924D692CA61BE758, 269, 100 },
17344  { 0xDA01EE641A708DEA, 295, 108 },
17345  { 0xA26DA3999AEF774A, 322, 116 },
17346  { 0xF209787BB47D6B85, 348, 124 },
17347  { 0xB454E4A179DD1877, 375, 132 },
17348  { 0x865B86925B9BC5C2, 402, 140 },
17349  { 0xC83553C5C8965D3D, 428, 148 },
17350  { 0x952AB45CFA97A0B3, 455, 156 },
17351  { 0xDE469FBD99A05FE3, 481, 164 },
17352  { 0xA59BC234DB398C25, 508, 172 },
17353  { 0xF6C69A72A3989F5C, 534, 180 },
17354  { 0xB7DCBF5354E9BECE, 561, 188 },
17355  { 0x88FCF317F22241E2, 588, 196 },
17356  { 0xCC20CE9BD35C78A5, 614, 204 },
17357  { 0x98165AF37B2153DF, 641, 212 },
17358  { 0xE2A0B5DC971F303A, 667, 220 },
17359  { 0xA8D9D1535CE3B396, 694, 228 },
17360  { 0xFB9B7CD9A4A7443C, 720, 236 },
17361  { 0xBB764C4CA7A44410, 747, 244 },
17362  { 0x8BAB8EEFB6409C1A, 774, 252 },
17363  { 0xD01FEF10A657842C, 800, 260 },
17364  { 0x9B10A4E5E9913129, 827, 268 },
17365  { 0xE7109BFBA19C0C9D, 853, 276 },
17366  { 0xAC2820D9623BF429, 880, 284 },
17367  { 0x80444B5E7AA7CF85, 907, 292 },
17368  { 0xBF21E44003ACDD2D, 933, 300 },
17369  { 0x8E679C2F5E44FF8F, 960, 308 },
17370  { 0xD433179D9C8CB841, 986, 316 },
17371  { 0x9E19DB92B4E31BA9, 1013, 324 },
17372  }
17373  };
17374 
17375  // This computation gives exactly the same results for k as
17376  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
17377  // for |e| <= 1500, but doesn't require floating-point operations.
17378  // NB: log_10(2) ~= 78913 / 2^18
17379  JSON_ASSERT(e >= -1500);
17380  JSON_ASSERT(e <= 1500);
17381  const int f = kAlpha - e - 1;
17382  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
17383 
17384  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
17385  JSON_ASSERT(index >= 0);
17386  JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
17387 
17388  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
17389  JSON_ASSERT(kAlpha <= cached.e + e + 64);
17390  JSON_ASSERT(kGamma >= cached.e + e + 64);
17391 
17392  return cached;
17393 }
17394 
17399 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
17400 {
17401  // LCOV_EXCL_START
17402  if (n >= 1000000000)
17403  {
17404  pow10 = 1000000000;
17405  return 10;
17406  }
17407  // LCOV_EXCL_STOP
17408  if (n >= 100000000)
17409  {
17410  pow10 = 100000000;
17411  return 9;
17412  }
17413  if (n >= 10000000)
17414  {
17415  pow10 = 10000000;
17416  return 8;
17417  }
17418  if (n >= 1000000)
17419  {
17420  pow10 = 1000000;
17421  return 7;
17422  }
17423  if (n >= 100000)
17424  {
17425  pow10 = 100000;
17426  return 6;
17427  }
17428  if (n >= 10000)
17429  {
17430  pow10 = 10000;
17431  return 5;
17432  }
17433  if (n >= 1000)
17434  {
17435  pow10 = 1000;
17436  return 4;
17437  }
17438  if (n >= 100)
17439  {
17440  pow10 = 100;
17441  return 3;
17442  }
17443  if (n >= 10)
17444  {
17445  pow10 = 10;
17446  return 2;
17447  }
17448 
17449  pow10 = 1;
17450  return 1;
17451 }
17452 
17453 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
17454  std::uint64_t rest, std::uint64_t ten_k)
17455 {
17456  JSON_ASSERT(len >= 1);
17457  JSON_ASSERT(dist <= delta);
17458  JSON_ASSERT(rest <= delta);
17459  JSON_ASSERT(ten_k > 0);
17460 
17461  // <--------------------------- delta ---->
17462  // <---- dist --------->
17463  // --------------[------------------+-------------------]--------------
17464  // M- w M+
17465  //
17466  // ten_k
17467  // <------>
17468  // <---- rest ---->
17469  // --------------[------------------+----+--------------]--------------
17470  // w V
17471  // = buf * 10^k
17472  //
17473  // ten_k represents a unit-in-the-last-place in the decimal representation
17474  // stored in buf.
17475  // Decrement buf by ten_k while this takes buf closer to w.
17476 
17477  // The tests are written in this order to avoid overflow in unsigned
17478  // integer arithmetic.
17479 
17480  while (rest < dist
17481  && delta - rest >= ten_k
17482  && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
17483  {
17484  JSON_ASSERT(buf[len - 1] != '0');
17485  buf[len - 1]--;
17486  rest += ten_k;
17487  }
17488 }
17489 
17494 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
17495  diyfp M_minus, diyfp w, diyfp M_plus)
17496 {
17497  static_assert(kAlpha >= -60, "internal error");
17498  static_assert(kGamma <= -32, "internal error");
17499 
17500  // Generates the digits (and the exponent) of a decimal floating-point
17501  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
17502  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
17503  //
17504  // <--------------------------- delta ---->
17505  // <---- dist --------->
17506  // --------------[------------------+-------------------]--------------
17507  // M- w M+
17508  //
17509  // Grisu2 generates the digits of M+ from left to right and stops as soon as
17510  // V is in [M-,M+].
17511 
17512  JSON_ASSERT(M_plus.e >= kAlpha);
17513  JSON_ASSERT(M_plus.e <= kGamma);
17514 
17515  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
17516  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
17517 
17518  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
17519  //
17520  // M+ = f * 2^e
17521  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
17522  // = ((p1 ) * 2^-e + (p2 )) * 2^e
17523  // = p1 + p2 * 2^e
17524 
17525  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
17526 
17527  auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
17528  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
17529 
17530  // 1)
17531  //
17532  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
17533 
17534  JSON_ASSERT(p1 > 0);
17535 
17536  std::uint32_t pow10{};
17537  const int k = find_largest_pow10(p1, pow10);
17538 
17539  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
17540  //
17541  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
17542  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
17543  //
17544  // M+ = p1 + p2 * 2^e
17545  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
17546  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
17547  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
17548  //
17549  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
17550  //
17551  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
17552  //
17553  // but stop as soon as
17554  //
17555  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
17556 
17557  int n = k;
17558  while (n > 0)
17559  {
17560  // Invariants:
17561  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
17562  // pow10 = 10^(n-1) <= p1 < 10^n
17563  //
17564  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
17565  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
17566  //
17567  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
17568  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
17569  //
17570  JSON_ASSERT(d <= 9);
17571  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17572  //
17573  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
17574  //
17575  p1 = r;
17576  n--;
17577  //
17578  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
17579  // pow10 = 10^n
17580  //
17581 
17582  // Now check if enough digits have been generated.
17583  // Compute
17584  //
17585  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
17586  //
17587  // Note:
17588  // Since rest and delta share the same exponent e, it suffices to
17589  // compare the significands.
17590  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
17591  if (rest <= delta)
17592  {
17593  // V = buffer * 10^n, with M- <= V <= M+.
17594 
17595  decimal_exponent += n;
17596 
17597  // We may now just stop. But instead look if the buffer could be
17598  // decremented to bring V closer to w.
17599  //
17600  // pow10 = 10^n is now 1 ulp in the decimal representation V.
17601  // The rounding procedure works with diyfp's with an implicit
17602  // exponent of e.
17603  //
17604  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
17605  //
17606  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
17607  grisu2_round(buffer, length, dist, delta, rest, ten_n);
17608 
17609  return;
17610  }
17611 
17612  pow10 /= 10;
17613  //
17614  // pow10 = 10^(n-1) <= p1 < 10^n
17615  // Invariants restored.
17616  }
17617 
17618  // 2)
17619  //
17620  // The digits of the integral part have been generated:
17621  //
17622  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
17623  // = buffer + p2 * 2^e
17624  //
17625  // Now generate the digits of the fractional part p2 * 2^e.
17626  //
17627  // Note:
17628  // No decimal point is generated: the exponent is adjusted instead.
17629  //
17630  // p2 actually represents the fraction
17631  //
17632  // p2 * 2^e
17633  // = p2 / 2^-e
17634  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
17635  //
17636  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
17637  //
17638  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
17639  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
17640  //
17641  // using
17642  //
17643  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
17644  // = ( d) * 2^-e + ( r)
17645  //
17646  // or
17647  // 10^m * p2 * 2^e = d + r * 2^e
17648  //
17649  // i.e.
17650  //
17651  // M+ = buffer + p2 * 2^e
17652  // = buffer + 10^-m * (d + r * 2^e)
17653  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
17654  //
17655  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
17656 
17657  JSON_ASSERT(p2 > delta);
17658 
17659  int m = 0;
17660  for (;;)
17661  {
17662  // Invariant:
17663  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
17664  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
17665  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
17666  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
17667  //
17668  JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
17669  p2 *= 10;
17670  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
17671  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
17672  //
17673  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
17674  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
17675  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
17676  //
17677  JSON_ASSERT(d <= 9);
17678  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17679  //
17680  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
17681  //
17682  p2 = r;
17683  m++;
17684  //
17685  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
17686  // Invariant restored.
17687 
17688  // Check if enough digits have been generated.
17689  //
17690  // 10^-m * p2 * 2^e <= delta * 2^e
17691  // p2 * 2^e <= 10^m * delta * 2^e
17692  // p2 <= 10^m * delta
17693  delta *= 10;
17694  dist *= 10;
17695  if (p2 <= delta)
17696  {
17697  break;
17698  }
17699  }
17700 
17701  // V = buffer * 10^-m, with M- <= V <= M+.
17702 
17703  decimal_exponent -= m;
17704 
17705  // 1 ulp in the decimal representation is now 10^-m.
17706  // Since delta and dist are now scaled by 10^m, we need to do the
17707  // same with ulp in order to keep the units in sync.
17708  //
17709  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
17710  //
17711  const std::uint64_t ten_m = one.f;
17712  grisu2_round(buffer, length, dist, delta, p2, ten_m);
17713 
17714  // By construction this algorithm generates the shortest possible decimal
17715  // number (Loitsch, Theorem 6.2) which rounds back to w.
17716  // For an input number of precision p, at least
17717  //
17718  // N = 1 + ceil(p * log_10(2))
17719  //
17720  // decimal digits are sufficient to identify all binary floating-point
17721  // numbers (Matula, "In-and-Out conversions").
17722  // This implies that the algorithm does not produce more than N decimal
17723  // digits.
17724  //
17725  // N = 17 for p = 53 (IEEE double precision)
17726  // N = 9 for p = 24 (IEEE single precision)
17727 }
17728 
17735 inline void grisu2(char* buf, int& len, int& decimal_exponent,
17736  diyfp m_minus, diyfp v, diyfp m_plus)
17737 {
17738  JSON_ASSERT(m_plus.e == m_minus.e);
17739  JSON_ASSERT(m_plus.e == v.e);
17740 
17741  // --------(-----------------------+-----------------------)-------- (A)
17742  // m- v m+
17743  //
17744  // --------------------(-----------+-----------------------)-------- (B)
17745  // m- v m+
17746  //
17747  // First scale v (and m- and m+) such that the exponent is in the range
17748  // [alpha, gamma].
17749 
17750  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
17751 
17752  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
17753 
17754  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
17755  const diyfp w = diyfp::mul(v, c_minus_k);
17756  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
17757  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
17758 
17759  // ----(---+---)---------------(---+---)---------------(---+---)----
17760  // w- w w+
17761  // = c*m- = c*v = c*m+
17762  //
17763  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
17764  // w+ are now off by a small amount.
17765  // In fact:
17766  //
17767  // w - v * 10^k < 1 ulp
17768  //
17769  // To account for this inaccuracy, add resp. subtract 1 ulp.
17770  //
17771  // --------+---[---------------(---+---)---------------]---+--------
17772  // w- M- w M+ w+
17773  //
17774  // Now any number in [M-, M+] (bounds included) will round to w when input,
17775  // regardless of how the input rounding algorithm breaks ties.
17776  //
17777  // And digit_gen generates the shortest possible such number in [M-, M+].
17778  // Note that this does not mean that Grisu2 always generates the shortest
17779  // possible number in the interval (m-, m+).
17780  const diyfp M_minus(w_minus.f + 1, w_minus.e);
17781  const diyfp M_plus (w_plus.f - 1, w_plus.e );
17782 
17783  decimal_exponent = -cached.k; // = -(-k) = k
17784 
17785  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
17786 }
17787 
17793 template<typename FloatType>
17795 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
17796 {
17797  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
17798  "internal error: not enough precision");
17799 
17800  JSON_ASSERT(std::isfinite(value));
17801  JSON_ASSERT(value > 0);
17802 
17803  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
17804  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
17805  // decimal representations are not exactly "short".
17806  //
17807  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
17808  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
17809  // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
17810  // does.
17811  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
17812  // representation using the corresponding std::from_chars function recovers value exactly". That
17813  // indicates that single precision floating-point numbers should be recovered using
17814  // 'std::strtof'.
17815  //
17816  // NB: If the neighbors are computed for single-precision numbers, there is a single float
17817  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
17818  // value is off by 1 ulp.
17819 #if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)
17820  const boundaries w = compute_boundaries(static_cast<double>(value));
17821 #else
17822  const boundaries w = compute_boundaries(value);
17823 #endif
17824 
17825  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
17826 }
17827 
17835 inline char* append_exponent(char* buf, int e)
17836 {
17837  JSON_ASSERT(e > -1000);
17838  JSON_ASSERT(e < 1000);
17839 
17840  if (e < 0)
17841  {
17842  e = -e;
17843  *buf++ = '-';
17844  }
17845  else
17846  {
17847  *buf++ = '+';
17848  }
17849 
17850  auto k = static_cast<std::uint32_t>(e);
17851  if (k < 10)
17852  {
17853  // Always print at least two digits in the exponent.
17854  // This is for compatibility with printf("%g").
17855  *buf++ = '0';
17856  *buf++ = static_cast<char>('0' + k);
17857  }
17858  else if (k < 100)
17859  {
17860  *buf++ = static_cast<char>('0' + k / 10);
17861  k %= 10;
17862  *buf++ = static_cast<char>('0' + k);
17863  }
17864  else
17865  {
17866  *buf++ = static_cast<char>('0' + k / 100);
17867  k %= 100;
17868  *buf++ = static_cast<char>('0' + k / 10);
17869  k %= 10;
17870  *buf++ = static_cast<char>('0' + k);
17871  }
17872 
17873  return buf;
17874 }
17875 
17887 inline char* format_buffer(char* buf, int len, int decimal_exponent,
17888  int min_exp, int max_exp)
17889 {
17890  JSON_ASSERT(min_exp < 0);
17891  JSON_ASSERT(max_exp > 0);
17892 
17893  const int k = len;
17894  const int n = len + decimal_exponent;
17895 
17896  // v = buf * 10^(n-k)
17897  // k is the length of the buffer (number of decimal digits)
17898  // n is the position of the decimal point relative to the start of the buffer.
17899 
17900  if (k <= n && n <= max_exp)
17901  {
17902  // digits[000]
17903  // len <= max_exp + 2
17904 
17905  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
17906  // Make it look like a floating-point number (#362, #378)
17907  buf[n + 0] = '.';
17908  buf[n + 1] = '0';
17909  return buf + (static_cast<size_t>(n) + 2);
17910  }
17911 
17912  if (0 < n && n <= max_exp)
17913  {
17914  // dig.its
17915  // len <= max_digits10 + 1
17916 
17917  JSON_ASSERT(k > n);
17918 
17919  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
17920  buf[n] = '.';
17921  return buf + (static_cast<size_t>(k) + 1U);
17922  }
17923 
17924  if (min_exp < n && n <= 0)
17925  {
17926  // 0.[000]digits
17927  // len <= 2 + (-min_exp - 1) + max_digits10
17928 
17929  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
17930  buf[0] = '0';
17931  buf[1] = '.';
17932  std::memset(buf + 2, '0', static_cast<size_t>(-n));
17933  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
17934  }
17935 
17936  if (k == 1)
17937  {
17938  // dE+123
17939  // len <= 1 + 5
17940 
17941  buf += 1;
17942  }
17943  else
17944  {
17945  // d.igitsE+123
17946  // len <= max_digits10 + 1 + 5
17947 
17948  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
17949  buf[1] = '.';
17950  buf += 1 + static_cast<size_t>(k);
17951  }
17952 
17953  *buf++ = 'e';
17954  return append_exponent(buf, n - 1);
17955 }
17956 
17957 } // namespace dtoa_impl
17958 
17969 template<typename FloatType>
17972 char* to_chars(char* first, const char* last, FloatType value)
17973 {
17974  static_cast<void>(last); // maybe unused - fix warning
17975  JSON_ASSERT(std::isfinite(value));
17976 
17977  // Use signbit(value) instead of (value < 0) since signbit works for -0.
17978  if (std::signbit(value))
17979  {
17980  value = -value;
17981  *first++ = '-';
17982  }
17983 
17984 #ifdef __GNUC__
17985 #pragma GCC diagnostic push
17986 #pragma GCC diagnostic ignored "-Wfloat-equal"
17987 #endif
17988  if (value == 0) // +-0
17989  {
17990  *first++ = '0';
17991  // Make it look like a floating-point number (#362, #378)
17992  *first++ = '.';
17993  *first++ = '0';
17994  return first;
17995  }
17996 #ifdef __GNUC__
17997 #pragma GCC diagnostic pop
17998 #endif
17999 
18000  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
18001 
18002  // Compute v = buffer * 10^decimal_exponent.
18003  // The decimal digits are stored in the buffer, which needs to be interpreted
18004  // as an unsigned decimal integer.
18005  // len is the length of the buffer, i.e. the number of decimal digits.
18006  int len = 0;
18007  int decimal_exponent = 0;
18008  dtoa_impl::grisu2(first, len, decimal_exponent, value);
18009 
18010  JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
18011 
18012  // Format the buffer like printf("%.*g", prec, value)
18013  constexpr int kMinExp = -4;
18014  // Use digits10 here to increase compatibility with version 2.
18015  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
18016 
18017  JSON_ASSERT(last - first >= kMaxExp + 2);
18018  JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
18019  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
18020 
18021  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
18022 }
18023 
18024 } // namespace detail
18026 
18027 // #include <nlohmann/detail/exceptions.hpp>
18028 
18029 // #include <nlohmann/detail/macro_scope.hpp>
18030 
18031 // #include <nlohmann/detail/meta/cpp_future.hpp>
18032 
18033 // #include <nlohmann/detail/output/binary_writer.hpp>
18034 
18035 // #include <nlohmann/detail/output/output_adapters.hpp>
18036 
18037 // #include <nlohmann/detail/string_concat.hpp>
18038 
18039 // #include <nlohmann/detail/value_t.hpp>
18040 
18041 
18043 namespace detail
18044 {
18045 
18047 // serialization //
18049 
18052 {
18053  strict,
18054  replace,
18055  ignore
18056 };
18057 
18058 template<typename BasicJsonType>
18060 {
18061  using string_t = typename BasicJsonType::string_t;
18062  using number_float_t = typename BasicJsonType::number_float_t;
18063  using number_integer_t = typename BasicJsonType::number_integer_t;
18064  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18065  using binary_char_t = typename BasicJsonType::binary_t::value_type;
18066  static constexpr std::uint8_t UTF8_ACCEPT = 0;
18067  static constexpr std::uint8_t UTF8_REJECT = 1;
18068 
18069  public:
18075  serializer(output_adapter_t<char> s, const char ichar,
18076  error_handler_t error_handler_ = error_handler_t::strict)
18077  : o(std::move(s))
18078  , loc(std::localeconv())
18079  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
18080  , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
18081  , indent_char(ichar)
18082  , indent_string(512, indent_char)
18083  , error_handler(error_handler_)
18084  {}
18085 
18086  // delete because of pointer members
18087  serializer(const serializer&) = delete;
18088  serializer& operator=(const serializer&) = delete;
18089  serializer(serializer&&) = delete;
18090  serializer& operator=(serializer&&) = delete;
18091  ~serializer() = default;
18092 
18115  void dump(const BasicJsonType& val,
18116  const bool pretty_print,
18117  const bool ensure_ascii,
18118  const unsigned int indent_step,
18119  const unsigned int current_indent = 0)
18120  {
18121  switch (val.m_data.m_type)
18122  {
18123  case value_t::object:
18124  {
18125  if (val.m_data.m_value.object->empty())
18126  {
18127  o->write_characters("{}", 2);
18128  return;
18129  }
18130 
18131  if (pretty_print)
18132  {
18133  o->write_characters("{\n", 2);
18134 
18135  // variable to hold indentation for recursive calls
18136  const auto new_indent = current_indent + indent_step;
18137  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18138  {
18139  indent_string.resize(indent_string.size() * 2, ' ');
18140  }
18141 
18142  // first n-1 elements
18143  auto i = val.m_data.m_value.object->cbegin();
18144  for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18145  {
18146  o->write_characters(indent_string.c_str(), new_indent);
18147  o->write_character('\"');
18148  dump_escaped(i->first, ensure_ascii);
18149  o->write_characters("\": ", 3);
18150  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18151  o->write_characters(",\n", 2);
18152  }
18153 
18154  // last element
18155  JSON_ASSERT(i != val.m_data.m_value.object->cend());
18156  JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18157  o->write_characters(indent_string.c_str(), new_indent);
18158  o->write_character('\"');
18159  dump_escaped(i->first, ensure_ascii);
18160  o->write_characters("\": ", 3);
18161  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18162 
18163  o->write_character('\n');
18164  o->write_characters(indent_string.c_str(), current_indent);
18165  o->write_character('}');
18166  }
18167  else
18168  {
18169  o->write_character('{');
18170 
18171  // first n-1 elements
18172  auto i = val.m_data.m_value.object->cbegin();
18173  for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18174  {
18175  o->write_character('\"');
18176  dump_escaped(i->first, ensure_ascii);
18177  o->write_characters("\":", 2);
18178  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18179  o->write_character(',');
18180  }
18181 
18182  // last element
18183  JSON_ASSERT(i != val.m_data.m_value.object->cend());
18184  JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18185  o->write_character('\"');
18186  dump_escaped(i->first, ensure_ascii);
18187  o->write_characters("\":", 2);
18188  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18189 
18190  o->write_character('}');
18191  }
18192 
18193  return;
18194  }
18195 
18196  case value_t::array:
18197  {
18198  if (val.m_data.m_value.array->empty())
18199  {
18200  o->write_characters("[]", 2);
18201  return;
18202  }
18203 
18204  if (pretty_print)
18205  {
18206  o->write_characters("[\n", 2);
18207 
18208  // variable to hold indentation for recursive calls
18209  const auto new_indent = current_indent + indent_step;
18210  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18211  {
18212  indent_string.resize(indent_string.size() * 2, ' ');
18213  }
18214 
18215  // first n-1 elements
18216  for (auto i = val.m_data.m_value.array->cbegin();
18217  i != val.m_data.m_value.array->cend() - 1; ++i)
18218  {
18219  o->write_characters(indent_string.c_str(), new_indent);
18220  dump(*i, true, ensure_ascii, indent_step, new_indent);
18221  o->write_characters(",\n", 2);
18222  }
18223 
18224  // last element
18225  JSON_ASSERT(!val.m_data.m_value.array->empty());
18226  o->write_characters(indent_string.c_str(), new_indent);
18227  dump(val.m_data.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
18228 
18229  o->write_character('\n');
18230  o->write_characters(indent_string.c_str(), current_indent);
18231  o->write_character(']');
18232  }
18233  else
18234  {
18235  o->write_character('[');
18236 
18237  // first n-1 elements
18238  for (auto i = val.m_data.m_value.array->cbegin();
18239  i != val.m_data.m_value.array->cend() - 1; ++i)
18240  {
18241  dump(*i, false, ensure_ascii, indent_step, current_indent);
18242  o->write_character(',');
18243  }
18244 
18245  // last element
18246  JSON_ASSERT(!val.m_data.m_value.array->empty());
18247  dump(val.m_data.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
18248 
18249  o->write_character(']');
18250  }
18251 
18252  return;
18253  }
18254 
18255  case value_t::string:
18256  {
18257  o->write_character('\"');
18258  dump_escaped(*val.m_data.m_value.string, ensure_ascii);
18259  o->write_character('\"');
18260  return;
18261  }
18262 
18263  case value_t::binary:
18264  {
18265  if (pretty_print)
18266  {
18267  o->write_characters("{\n", 2);
18268 
18269  // variable to hold indentation for recursive calls
18270  const auto new_indent = current_indent + indent_step;
18271  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18272  {
18273  indent_string.resize(indent_string.size() * 2, ' ');
18274  }
18275 
18276  o->write_characters(indent_string.c_str(), new_indent);
18277 
18278  o->write_characters("\"bytes\": [", 10);
18279 
18280  if (!val.m_data.m_value.binary->empty())
18281  {
18282  for (auto i = val.m_data.m_value.binary->cbegin();
18283  i != val.m_data.m_value.binary->cend() - 1; ++i)
18284  {
18285  dump_integer(*i);
18286  o->write_characters(", ", 2);
18287  }
18288  dump_integer(val.m_data.m_value.binary->back());
18289  }
18290 
18291  o->write_characters("],\n", 3);
18292  o->write_characters(indent_string.c_str(), new_indent);
18293 
18294  o->write_characters("\"subtype\": ", 11);
18295  if (val.m_data.m_value.binary->has_subtype())
18296  {
18297  dump_integer(val.m_data.m_value.binary->subtype());
18298  }
18299  else
18300  {
18301  o->write_characters("null", 4);
18302  }
18303  o->write_character('\n');
18304  o->write_characters(indent_string.c_str(), current_indent);
18305  o->write_character('}');
18306  }
18307  else
18308  {
18309  o->write_characters("{\"bytes\":[", 10);
18310 
18311  if (!val.m_data.m_value.binary->empty())
18312  {
18313  for (auto i = val.m_data.m_value.binary->cbegin();
18314  i != val.m_data.m_value.binary->cend() - 1; ++i)
18315  {
18316  dump_integer(*i);
18317  o->write_character(',');
18318  }
18319  dump_integer(val.m_data.m_value.binary->back());
18320  }
18321 
18322  o->write_characters("],\"subtype\":", 12);
18323  if (val.m_data.m_value.binary->has_subtype())
18324  {
18325  dump_integer(val.m_data.m_value.binary->subtype());
18326  o->write_character('}');
18327  }
18328  else
18329  {
18330  o->write_characters("null}", 5);
18331  }
18332  }
18333  return;
18334  }
18335 
18336  case value_t::boolean:
18337  {
18338  if (val.m_data.m_value.boolean)
18339  {
18340  o->write_characters("true", 4);
18341  }
18342  else
18343  {
18344  o->write_characters("false", 5);
18345  }
18346  return;
18347  }
18348 
18349  case value_t::number_integer:
18350  {
18351  dump_integer(val.m_data.m_value.number_integer);
18352  return;
18353  }
18354 
18355  case value_t::number_unsigned:
18356  {
18357  dump_integer(val.m_data.m_value.number_unsigned);
18358  return;
18359  }
18360 
18361  case value_t::number_float:
18362  {
18363  dump_float(val.m_data.m_value.number_float);
18364  return;
18365  }
18366 
18367  case value_t::discarded:
18368  {
18369  o->write_characters("<discarded>", 11);
18370  return;
18371  }
18372 
18373  case value_t::null:
18374  {
18375  o->write_characters("null", 4);
18376  return;
18377  }
18378 
18379  default: // LCOV_EXCL_LINE
18380  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18381  }
18382  }
18383 
18399  void dump_escaped(const string_t& s, const bool ensure_ascii)
18400  {
18401  std::uint32_t codepoint{};
18402  std::uint8_t state = UTF8_ACCEPT;
18403  std::size_t bytes = 0; // number of bytes written to string_buffer
18404 
18405  // number of bytes written at the point of the last valid byte
18406  std::size_t bytes_after_last_accept = 0;
18407  std::size_t undumped_chars = 0;
18408 
18409  for (std::size_t i = 0; i < s.size(); ++i)
18410  {
18411  const auto byte = static_cast<std::uint8_t>(s[i]);
18412 
18413  switch (decode(state, codepoint, byte))
18414  {
18415  case UTF8_ACCEPT: // decode found a new code point
18416  {
18417  switch (codepoint)
18418  {
18419  case 0x08: // backspace
18420  {
18421  string_buffer[bytes++] = '\\';
18422  string_buffer[bytes++] = 'b';
18423  break;
18424  }
18425 
18426  case 0x09: // horizontal tab
18427  {
18428  string_buffer[bytes++] = '\\';
18429  string_buffer[bytes++] = 't';
18430  break;
18431  }
18432 
18433  case 0x0A: // newline
18434  {
18435  string_buffer[bytes++] = '\\';
18436  string_buffer[bytes++] = 'n';
18437  break;
18438  }
18439 
18440  case 0x0C: // formfeed
18441  {
18442  string_buffer[bytes++] = '\\';
18443  string_buffer[bytes++] = 'f';
18444  break;
18445  }
18446 
18447  case 0x0D: // carriage return
18448  {
18449  string_buffer[bytes++] = '\\';
18450  string_buffer[bytes++] = 'r';
18451  break;
18452  }
18453 
18454  case 0x22: // quotation mark
18455  {
18456  string_buffer[bytes++] = '\\';
18457  string_buffer[bytes++] = '\"';
18458  break;
18459  }
18460 
18461  case 0x5C: // reverse solidus
18462  {
18463  string_buffer[bytes++] = '\\';
18464  string_buffer[bytes++] = '\\';
18465  break;
18466  }
18467 
18468  default:
18469  {
18470  // escape control characters (0x00..0x1F) or, if
18471  // ensure_ascii parameter is used, non-ASCII characters
18472  if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
18473  {
18474  if (codepoint <= 0xFFFF)
18475  {
18476  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18477  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
18478  static_cast<std::uint16_t>(codepoint)));
18479  bytes += 6;
18480  }
18481  else
18482  {
18483  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18484  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
18485  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
18486  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
18487  bytes += 12;
18488  }
18489  }
18490  else
18491  {
18492  // copy byte to buffer (all previous bytes
18493  // been copied have in default case above)
18494  string_buffer[bytes++] = s[i];
18495  }
18496  break;
18497  }
18498  }
18499 
18500  // write buffer and reset index; there must be 13 bytes
18501  // left, as this is the maximal number of bytes to be
18502  // written ("\uxxxx\uxxxx\0") for one code point
18503  if (string_buffer.size() - bytes < 13)
18504  {
18505  o->write_characters(string_buffer.data(), bytes);
18506  bytes = 0;
18507  }
18508 
18509  // remember the byte position of this accept
18510  bytes_after_last_accept = bytes;
18511  undumped_chars = 0;
18512  break;
18513  }
18514 
18515  case UTF8_REJECT: // decode found invalid UTF-8 byte
18516  {
18517  switch (error_handler)
18518  {
18519  case error_handler_t::strict:
18520  {
18521  JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
18522  }
18523 
18524  case error_handler_t::ignore:
18525  case error_handler_t::replace:
18526  {
18527  // in case we saw this character the first time, we
18528  // would like to read it again, because the byte
18529  // may be OK for itself, but just not OK for the
18530  // previous sequence
18531  if (undumped_chars > 0)
18532  {
18533  --i;
18534  }
18535 
18536  // reset length buffer to the last accepted index;
18537  // thus removing/ignoring the invalid characters
18538  bytes = bytes_after_last_accept;
18539 
18540  if (error_handler == error_handler_t::replace)
18541  {
18542  // add a replacement character
18543  if (ensure_ascii)
18544  {
18545  string_buffer[bytes++] = '\\';
18546  string_buffer[bytes++] = 'u';
18547  string_buffer[bytes++] = 'f';
18548  string_buffer[bytes++] = 'f';
18549  string_buffer[bytes++] = 'f';
18550  string_buffer[bytes++] = 'd';
18551  }
18552  else
18553  {
18557  }
18558 
18559  // write buffer and reset index; there must be 13 bytes
18560  // left, as this is the maximal number of bytes to be
18561  // written ("\uxxxx\uxxxx\0") for one code point
18562  if (string_buffer.size() - bytes < 13)
18563  {
18564  o->write_characters(string_buffer.data(), bytes);
18565  bytes = 0;
18566  }
18567 
18568  bytes_after_last_accept = bytes;
18569  }
18570 
18571  undumped_chars = 0;
18572 
18573  // continue processing the string
18574  state = UTF8_ACCEPT;
18575  break;
18576  }
18577 
18578  default: // LCOV_EXCL_LINE
18579  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18580  }
18581  break;
18582  }
18583 
18584  default: // decode found yet incomplete multi-byte code point
18585  {
18586  if (!ensure_ascii)
18587  {
18588  // code point will not be escaped - copy byte to buffer
18589  string_buffer[bytes++] = s[i];
18590  }
18591  ++undumped_chars;
18592  break;
18593  }
18594  }
18595  }
18596 
18597  // we finished processing the string
18598  if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
18599  {
18600  // write buffer
18601  if (bytes > 0)
18602  {
18603  o->write_characters(string_buffer.data(), bytes);
18604  }
18605  }
18606  else
18607  {
18608  // we finish reading, but do not accept: string was incomplete
18609  switch (error_handler)
18610  {
18611  case error_handler_t::strict:
18612  {
18613  JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
18614  }
18615 
18616  case error_handler_t::ignore:
18617  {
18618  // write all accepted bytes
18619  o->write_characters(string_buffer.data(), bytes_after_last_accept);
18620  break;
18621  }
18622 
18623  case error_handler_t::replace:
18624  {
18625  // write all accepted bytes
18626  o->write_characters(string_buffer.data(), bytes_after_last_accept);
18627  // add a replacement character
18628  if (ensure_ascii)
18629  {
18630  o->write_characters("\\ufffd", 6);
18631  }
18632  else
18633  {
18634  o->write_characters("\xEF\xBF\xBD", 3);
18635  }
18636  break;
18637  }
18638 
18639  default: // LCOV_EXCL_LINE
18640  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18641  }
18642  }
18643  }
18644 
18645  private:
18654  inline unsigned int count_digits(number_unsigned_t x) noexcept
18655  {
18656  unsigned int n_digits = 1;
18657  for (;;)
18658  {
18659  if (x < 10)
18660  {
18661  return n_digits;
18662  }
18663  if (x < 100)
18664  {
18665  return n_digits + 1;
18666  }
18667  if (x < 1000)
18668  {
18669  return n_digits + 2;
18670  }
18671  if (x < 10000)
18672  {
18673  return n_digits + 3;
18674  }
18675  x = x / 10000u;
18676  n_digits += 4;
18677  }
18678  }
18679 
18685  static std::string hex_bytes(std::uint8_t byte)
18686  {
18687  std::string result = "FF";
18688  constexpr const char* nibble_to_hex = "0123456789ABCDEF";
18689  result[0] = nibble_to_hex[byte / 16];
18690  result[1] = nibble_to_hex[byte % 16];
18691  return result;
18692  }
18693 
18694  // templates to avoid warnings about useless casts
18696  bool is_negative_number(NumberType x)
18697  {
18698  return x < 0;
18699  }
18700 
18702  bool is_negative_number(NumberType /*unused*/)
18703  {
18704  return false;
18705  }
18706 
18716  template < typename NumberType, detail::enable_if_t <
18721  int > = 0 >
18722  void dump_integer(NumberType x)
18723  {
18724  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
18725  {
18726  {
18727  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
18728  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
18729  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
18730  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
18731  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
18732  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
18733  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
18734  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
18735  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
18736  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
18737  }
18738  };
18739 
18740  // special case for "0"
18741  if (x == 0)
18742  {
18743  o->write_character('0');
18744  return;
18745  }
18746 
18747  // use a pointer to fill the buffer
18748  auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18749 
18750  number_unsigned_t abs_value;
18751 
18752  unsigned int n_chars{};
18753 
18754  if (is_negative_number(x))
18755  {
18756  *buffer_ptr = '-';
18757  abs_value = remove_sign(static_cast<number_integer_t>(x));
18758 
18759  // account one more byte for the minus sign
18760  n_chars = 1 + count_digits(abs_value);
18761  }
18762  else
18763  {
18764  abs_value = static_cast<number_unsigned_t>(x);
18765  n_chars = count_digits(abs_value);
18766  }
18767 
18768  // spare 1 byte for '\0'
18769  JSON_ASSERT(n_chars < number_buffer.size() - 1);
18770 
18771  // jump to the end to generate the string from backward,
18772  // so we later avoid reversing the result
18773  buffer_ptr += n_chars;
18774 
18775  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
18776  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
18777  while (abs_value >= 100)
18778  {
18779  const auto digits_index = static_cast<unsigned>((abs_value % 100));
18780  abs_value /= 100;
18781  *(--buffer_ptr) = digits_to_99[digits_index][1];
18782  *(--buffer_ptr) = digits_to_99[digits_index][0];
18783  }
18784 
18785  if (abs_value >= 10)
18786  {
18787  const auto digits_index = static_cast<unsigned>(abs_value);
18788  *(--buffer_ptr) = digits_to_99[digits_index][1];
18789  *(--buffer_ptr) = digits_to_99[digits_index][0];
18790  }
18791  else
18792  {
18793  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
18794  }
18795 
18796  o->write_characters(number_buffer.data(), n_chars);
18797  }
18798 
18807  void dump_float(number_float_t x)
18808  {
18809  // NaN / inf
18810  if (!std::isfinite(x))
18811  {
18812  o->write_characters("null", 4);
18813  return;
18814  }
18815 
18816  // If number_float_t is an IEEE-754 single or double precision number,
18817  // use the Grisu2 algorithm to produce short numbers which are
18818  // guaranteed to round-trip, using strtof and strtod, resp.
18819  //
18820  // NB: The test below works if <long double> == <double>.
18821  static constexpr bool is_ieee_single_or_double
18822  = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
18823  (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
18824 
18825  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
18826  }
18827 
18828  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
18829  {
18830  auto* begin = number_buffer.data();
18831  auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
18832 
18833  o->write_characters(begin, static_cast<size_t>(end - begin));
18834  }
18835 
18836  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
18837  {
18838  // get number of digits for a float -> text -> float round-trip
18839  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
18840 
18841  // the actual conversion
18842  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18843  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
18844 
18845  // negative value indicates an error
18846  JSON_ASSERT(len > 0);
18847  // check if buffer was large enough
18848  JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
18849 
18850  // erase thousands separator
18851  if (thousands_sep != '\0')
18852  {
18853  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
18854  const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
18855  std::fill(end, number_buffer.end(), '\0');
18856  JSON_ASSERT((end - number_buffer.begin()) <= len);
18857  len = (end - number_buffer.begin());
18858  }
18859 
18860  // convert decimal point to '.'
18861  if (decimal_point != '\0' && decimal_point != '.')
18862  {
18863  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
18864  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
18865  if (dec_pos != number_buffer.end())
18866  {
18867  *dec_pos = '.';
18868  }
18869  }
18870 
18871  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
18872 
18873  // determine if we need to append ".0"
18874  const bool value_is_int_like =
18875  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
18876  [](char c)
18877  {
18878  return c == '.' || c == 'e';
18879  });
18880 
18881  if (value_is_int_like)
18882  {
18883  o->write_characters(".0", 2);
18884  }
18885  }
18886 
18908  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
18909  {
18910  static const std::array<std::uint8_t, 400> utf8d =
18911  {
18912  {
18913  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
18914  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
18915  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
18916  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
18917  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
18918  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
18919  8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
18920  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
18921  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
18922  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
18923  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
18924  1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
18925  1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
18926  1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
18927  }
18928  };
18929 
18930  JSON_ASSERT(byte < utf8d.size());
18931  const std::uint8_t type = utf8d[byte];
18932 
18933  codep = (state != UTF8_ACCEPT)
18934  ? (byte & 0x3fu) | (codep << 6u)
18935  : (0xFFu >> type) & (byte);
18936 
18937  const std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
18938  JSON_ASSERT(index < utf8d.size());
18939  state = utf8d[index];
18940  return state;
18941  }
18942 
18943  /*
18944  * Overload to make the compiler happy while it is instantiating
18945  * dump_integer for number_unsigned_t.
18946  * Must never be called.
18947  */
18948  number_unsigned_t remove_sign(number_unsigned_t x)
18949  {
18950  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18951  return x; // LCOV_EXCL_LINE
18952  }
18953 
18954  /*
18955  * Helper function for dump_integer
18956  *
18957  * This function takes a negative signed integer and returns its absolute
18958  * value as unsigned integer. The plus/minus shuffling is necessary as we can
18959  * not directly remove the sign of an arbitrary signed integer as the
18960  * absolute values of INT_MIN and INT_MAX are usually not the same. See
18961  * #1708 for details.
18962  */
18963  inline number_unsigned_t remove_sign(number_integer_t x) noexcept
18964  {
18965  JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
18966  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
18967  }
18968 
18969  private:
18971  output_adapter_t<char> o = nullptr;
18972 
18974  std::array<char, 64> number_buffer{{}};
18975 
18977  const std::lconv* loc = nullptr;
18979  const char thousands_sep = '\0';
18981  const char decimal_point = '\0';
18982 
18984  std::array<char, 512> string_buffer{{}};
18985 
18987  const char indent_char;
18990 
18993 };
18994 
18995 } // namespace detail
18997 
18998 // #include <nlohmann/detail/value_t.hpp>
18999 
19000 // #include <nlohmann/json_fwd.hpp>
19001 
19002 // #include <nlohmann/ordered_map.hpp>
19003 // __ _____ _____ _____
19004 // __| | __| | | | JSON for Modern C++
19005 // | | |__ | | | | | | version 3.11.3
19006 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
19007 //
19008 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
19009 // SPDX-License-Identifier: MIT
19010 
19011 
19012 
19013 #include <functional> // equal_to, less
19014 #include <initializer_list> // initializer_list
19015 #include <iterator> // input_iterator_tag, iterator_traits
19016 #include <memory> // allocator
19017 #include <stdexcept> // for out_of_range
19018 #include <type_traits> // enable_if, is_convertible
19019 #include <utility> // pair
19020 #include <vector> // vector
19021 
19022 // #include <nlohmann/detail/macro_scope.hpp>
19023 
19024 // #include <nlohmann/detail/meta/type_traits.hpp>
19025 
19026 
19028 
19031 template <class Key, class T, class IgnoredLess = std::less<Key>,
19032  class Allocator = std::allocator<std::pair<const Key, T>>>
19033  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
19034 {
19035  using key_type = Key;
19036  using mapped_type = T;
19037  using Container = std::vector<std::pair<const Key, T>, Allocator>;
19038  using iterator = typename Container::iterator;
19039  using const_iterator = typename Container::const_iterator;
19040  using size_type = typename Container::size_type;
19041  using value_type = typename Container::value_type;
19042 #ifdef JSON_HAS_CPP_14
19043  using key_compare = std::equal_to<>;
19044 #else
19045  using key_compare = std::equal_to<Key>;
19046 #endif
19047 
19048  // Explicit constructors instead of `using Container::Container`
19049  // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
19050  ordered_map() noexcept(noexcept(Container())) : Container{} {}
19051  explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
19052  template <class It>
19053  ordered_map(It first, It last, const Allocator& alloc = Allocator())
19054  : Container{first, last, alloc} {}
19055  ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
19056  : Container{init, alloc} {}
19057 
19058  std::pair<iterator, bool> emplace(const key_type& key, T&& t)
19059  {
19060  for (auto it = this->begin(); it != this->end(); ++it)
19061  {
19062  if (m_compare(it->first, key))
19063  {
19064  return {it, false};
19065  }
19066  }
19067  Container::emplace_back(key, std::forward<T>(t));
19068  return {std::prev(this->end()), true};
19069  }
19070 
19071  template<class KeyType, detail::enable_if_t<
19073  std::pair<iterator, bool> emplace(KeyType && key, T && t)
19074  {
19075  for (auto it = this->begin(); it != this->end(); ++it)
19076  {
19077  if (m_compare(it->first, key))
19078  {
19079  return {it, false};
19080  }
19081  }
19082  Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
19083  return {std::prev(this->end()), true};
19084  }
19085 
19087  {
19088  return emplace(key, T{}).first->second;
19089  }
19090 
19091  template<class KeyType, detail::enable_if_t<
19093  T & operator[](KeyType && key)
19094  {
19095  return emplace(std::forward<KeyType>(key), T{}).first->second;
19096  }
19097 
19098  const T& operator[](const key_type& key) const
19099  {
19100  return at(key);
19101  }
19102 
19103  template<class KeyType, detail::enable_if_t<
19105  const T & operator[](KeyType && key) const
19106  {
19107  return at(std::forward<KeyType>(key));
19108  }
19109 
19110  T& at(const key_type& key)
19111  {
19112  for (auto it = this->begin(); it != this->end(); ++it)
19113  {
19114  if (m_compare(it->first, key))
19115  {
19116  return it->second;
19117  }
19118  }
19119 
19120  JSON_THROW(std::out_of_range("key not found"));
19121  }
19122 
19123  template<class KeyType, detail::enable_if_t<
19125  T & at(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
19126  {
19127  for (auto it = this->begin(); it != this->end(); ++it)
19128  {
19129  if (m_compare(it->first, key))
19130  {
19131  return it->second;
19132  }
19133  }
19134 
19135  JSON_THROW(std::out_of_range("key not found"));
19136  }
19137 
19138  const T& at(const key_type& key) const
19139  {
19140  for (auto it = this->begin(); it != this->end(); ++it)
19141  {
19142  if (m_compare(it->first, key))
19143  {
19144  return it->second;
19145  }
19146  }
19147 
19148  JSON_THROW(std::out_of_range("key not found"));
19149  }
19150 
19151  template<class KeyType, detail::enable_if_t<
19153  const T & at(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)
19154  {
19155  for (auto it = this->begin(); it != this->end(); ++it)
19156  {
19157  if (m_compare(it->first, key))
19158  {
19159  return it->second;
19160  }
19161  }
19162 
19163  JSON_THROW(std::out_of_range("key not found"));
19164  }
19165 
19167  {
19168  for (auto it = this->begin(); it != this->end(); ++it)
19169  {
19170  if (m_compare(it->first, key))
19171  {
19172  // Since we cannot move const Keys, re-construct them in place
19173  for (auto next = it; ++next != this->end(); ++it)
19174  {
19175  it->~value_type(); // Destroy but keep allocation
19176  new (&*it) value_type{std::move(*next)};
19177  }
19178  Container::pop_back();
19179  return 1;
19180  }
19181  }
19182  return 0;
19183  }
19184 
19185  template<class KeyType, detail::enable_if_t<
19187  size_type erase(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
19188  {
19189  for (auto it = this->begin(); it != this->end(); ++it)
19190  {
19191  if (m_compare(it->first, key))
19192  {
19193  // Since we cannot move const Keys, re-construct them in place
19194  for (auto next = it; ++next != this->end(); ++it)
19195  {
19196  it->~value_type(); // Destroy but keep allocation
19197  new (&*it) value_type{std::move(*next)};
19198  }
19199  Container::pop_back();
19200  return 1;
19201  }
19202  }
19203  return 0;
19204  }
19205 
19207  {
19208  return erase(pos, std::next(pos));
19209  }
19210 
19212  {
19213  if (first == last)
19214  {
19215  return first;
19216  }
19217 
19218  const auto elements_affected = std::distance(first, last);
19219  const auto offset = std::distance(Container::begin(), first);
19220 
19221  // This is the start situation. We need to delete elements_affected
19222  // elements (3 in this example: e, f, g), and need to return an
19223  // iterator past the last deleted element (h in this example).
19224  // Note that offset is the distance from the start of the vector
19225  // to first. We will need this later.
19226 
19227  // [ a, b, c, d, e, f, g, h, i, j ]
19228  // ^ ^
19229  // first last
19230 
19231  // Since we cannot move const Keys, we re-construct them in place.
19232  // We start at first and re-construct (viz. copy) the elements from
19233  // the back of the vector. Example for first iteration:
19234 
19235  // ,--------.
19236  // v | destroy e and re-construct with h
19237  // [ a, b, c, d, e, f, g, h, i, j ]
19238  // ^ ^
19239  // it it + elements_affected
19240 
19241  for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
19242  {
19243  it->~value_type(); // destroy but keep allocation
19244  new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
19245  }
19246 
19247  // [ a, b, c, d, h, i, j, h, i, j ]
19248  // ^ ^
19249  // first last
19250 
19251  // remove the unneeded elements at the end of the vector
19252  Container::resize(this->size() - static_cast<size_type>(elements_affected));
19253 
19254  // [ a, b, c, d, h, i, j ]
19255  // ^ ^
19256  // first last
19257 
19258  // first is now pointing past the last deleted element, but we cannot
19259  // use this iterator, because it may have been invalidated by the
19260  // resize call. Instead, we can return begin() + offset.
19261  return Container::begin() + offset;
19262  }
19263 
19264  size_type count(const key_type& key) const
19265  {
19266  for (auto it = this->begin(); it != this->end(); ++it)
19267  {
19268  if (m_compare(it->first, key))
19269  {
19270  return 1;
19271  }
19272  }
19273  return 0;
19274  }
19275 
19276  template<class KeyType, detail::enable_if_t<
19278  size_type count(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)
19279  {
19280  for (auto it = this->begin(); it != this->end(); ++it)
19281  {
19282  if (m_compare(it->first, key))
19283  {
19284  return 1;
19285  }
19286  }
19287  return 0;
19288  }
19289 
19291  {
19292  for (auto it = this->begin(); it != this->end(); ++it)
19293  {
19294  if (m_compare(it->first, key))
19295  {
19296  return it;
19297  }
19298  }
19299  return Container::end();
19300  }
19301 
19302  template<class KeyType, detail::enable_if_t<
19304  iterator find(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
19305  {
19306  for (auto it = this->begin(); it != this->end(); ++it)
19307  {
19308  if (m_compare(it->first, key))
19309  {
19310  return it;
19311  }
19312  }
19313  return Container::end();
19314  }
19315 
19317  {
19318  for (auto it = this->begin(); it != this->end(); ++it)
19319  {
19320  if (m_compare(it->first, key))
19321  {
19322  return it;
19323  }
19324  }
19325  return Container::end();
19326  }
19327 
19328  std::pair<iterator, bool> insert( value_type&& value )
19329  {
19330  return emplace(value.first, std::move(value.second));
19331  }
19332 
19333  std::pair<iterator, bool> insert( const value_type& value )
19334  {
19335  for (auto it = this->begin(); it != this->end(); ++it)
19336  {
19337  if (m_compare(it->first, value.first))
19338  {
19339  return {it, false};
19340  }
19341  }
19342  Container::push_back(value);
19343  return {--this->end(), true};
19344  }
19345 
19346  template<typename InputIt>
19347  using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
19348  std::input_iterator_tag>::value>::type;
19349 
19350  template<typename InputIt, typename = require_input_iter<InputIt>>
19351  void insert(InputIt first, InputIt last)
19352  {
19353  for (auto it = first; it != last; ++it)
19354  {
19355  insert(*it);
19356  }
19357  }
19358 
19359 private:
19361 };
19362 
19364 
19365 
19366 #if defined(JSON_HAS_CPP_17)
19367  #if JSON_HAS_STATIC_RTTI
19368  #include <any>
19369  #endif
19370  #include <string_view>
19371 #endif
19372 
19379 
19399 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
19400  : public ::nlohmann::detail::json_base_class<CustomBaseClass>
19401 {
19402  private:
19403  template<detail::value_t> friend struct detail::external_constructor;
19404 
19405  template<typename>
19406  friend class ::nlohmann::json_pointer;
19407  // can be restored when json_pointer backwards compatibility is removed
19408  // friend ::nlohmann::json_pointer<StringType>;
19409 
19410  template<typename BasicJsonType, typename InputType>
19411  friend class ::nlohmann::detail::parser;
19412  friend ::nlohmann::detail::serializer<basic_json>;
19413  template<typename BasicJsonType>
19414  friend class ::nlohmann::detail::iter_impl;
19415  template<typename BasicJsonType, typename CharType>
19416  friend class ::nlohmann::detail::binary_writer;
19417  template<typename BasicJsonType, typename InputType, typename SAX>
19418  friend class ::nlohmann::detail::binary_reader;
19419  template<typename BasicJsonType>
19420  friend class ::nlohmann::detail::json_sax_dom_parser;
19421  template<typename BasicJsonType>
19422  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
19423  friend class ::nlohmann::detail::exception;
19424 
19427  using json_base_class_t = ::nlohmann::detail::json_base_class<CustomBaseClass>;
19428 
19430  // convenience aliases for types residing in namespace detail;
19431  using lexer = ::nlohmann::detail::lexer_base<basic_json>;
19432 
19433  template<typename InputAdapterType>
19434  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
19435  InputAdapterType adapter,
19437  const bool allow_exceptions = true,
19438  const bool ignore_comments = false
19439  )
19440  {
19441  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
19442  std::move(cb), allow_exceptions, ignore_comments);
19443  }
19444 
19445  private:
19446  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
19447  template<typename BasicJsonType>
19448  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
19449  template<typename BasicJsonType>
19450  using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
19451  template<typename Iterator>
19452  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
19453  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
19454 
19455  template<typename CharType>
19456  using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
19457 
19458  template<typename InputType>
19459  using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
19460  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
19461 
19463  using serializer = ::nlohmann::detail::serializer<basic_json>;
19464 
19465  public:
19468  using json_pointer = ::nlohmann::json_pointer<StringType>;
19469  template<typename T, typename SFINAE>
19470  using json_serializer = JSONSerializer<T, SFINAE>;
19476  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
19477 
19481 
19483  // exceptions //
19485 
19489 
19496 
19498 
19500  // container types //
19502 
19507 
19510 
19514  using const_reference = const value_type&;
19515 
19517  using difference_type = std::ptrdiff_t;
19519  using size_type = std::size_t;
19520 
19522  using allocator_type = AllocatorType<basic_json>;
19523 
19525  using pointer = typename std::allocator_traits<allocator_type>::pointer;
19527  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
19528 
19537 
19539 
19543  {
19544  return allocator_type();
19545  }
19546 
19550  static basic_json meta()
19551  {
19552  basic_json result;
19553 
19554  result["copyright"] = "(C) 2013-2023 Niels Lohmann";
19555  result["name"] = "JSON for Modern C++";
19556  result["url"] = "https://github.com/nlohmann/json";
19557  result["version"]["string"] =
19561  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
19562  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
19563  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
19564 
19565 #ifdef _WIN32
19566  result["platform"] = "win32";
19567 #elif defined __linux__
19568  result["platform"] = "linux";
19569 #elif defined __APPLE__
19570  result["platform"] = "apple";
19571 #elif defined __unix__
19572  result["platform"] = "unix";
19573 #else
19574  result["platform"] = "unknown";
19575 #endif
19576 
19577 #if defined(__ICC) || defined(__INTEL_COMPILER)
19578  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
19579 #elif defined(__clang__)
19580  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
19581 #elif defined(__GNUC__) || defined(__GNUG__)
19582  result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
19583  std::to_string(__GNUC__), '.',
19584  std::to_string(__GNUC_MINOR__), '.',
19585  std::to_string(__GNUC_PATCHLEVEL__))
19586  }
19587  };
19588 #elif defined(__HP_cc) || defined(__HP_aCC)
19589  result["compiler"] = "hp"
19590 #elif defined(__IBMCPP__)
19591  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
19592 #elif defined(_MSC_VER)
19593  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
19594 #elif defined(__PGI)
19595  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
19596 #elif defined(__SUNPRO_CC)
19597  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
19598 #else
19599  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
19600 #endif
19601 
19602 #if defined(_MSVC_LANG)
19603  result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
19604 #elif defined(__cplusplus)
19605  result["compiler"]["c++"] = std::to_string(__cplusplus);
19606 #else
19607  result["compiler"]["c++"] = "unknown";
19608 #endif
19609  return result;
19610  }
19611 
19613  // JSON value data types //
19615 
19620 
19625 #if defined(JSON_HAS_CPP_14)
19626  // use of transparent comparator avoids unnecessary repeated construction of temporaries
19627  // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
19628  using default_object_comparator_t = std::less<>;
19629 #else
19630  using default_object_comparator_t = std::less<StringType>;
19631 #endif
19632 
19635  using object_t = ObjectType<StringType,
19636  basic_json,
19638  AllocatorType<std::pair<const StringType,
19640 
19643  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
19644 
19647  using string_t = StringType;
19648 
19651  using boolean_t = BooleanType;
19652 
19655  using number_integer_t = NumberIntegerType;
19656 
19659  using number_unsigned_t = NumberUnsignedType;
19660 
19663  using number_float_t = NumberFloatType;
19664 
19667  using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
19668 
19672 
19674 
19675  private:
19676 
19678  template<typename T, typename... Args>
19680  static T* create(Args&& ... args)
19681  {
19682  AllocatorType<T> alloc;
19683  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
19684 
19685  auto deleter = [&](T * obj)
19686  {
19687  AllocatorTraits::deallocate(alloc, obj, 1);
19688  };
19689  std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
19690  AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
19691  JSON_ASSERT(obj != nullptr);
19692  return obj.release();
19693  }
19694 
19696  // JSON value storage //
19698 
19725  union json_value
19726  {
19728  object_t* object;
19743 
19745  json_value() = default;
19747  json_value(boolean_t v) noexcept : boolean(v) {}
19756  {
19757  switch (t)
19758  {
19759  case value_t::object:
19760  {
19761  object = create<object_t>();
19762  break;
19763  }
19764 
19765  case value_t::array:
19766  {
19767  array = create<array_t>();
19768  break;
19769  }
19770 
19771  case value_t::string:
19772  {
19773  string = create<string_t>("");
19774  break;
19775  }
19776 
19777  case value_t::binary:
19778  {
19779  binary = create<binary_t>();
19780  break;
19781  }
19782 
19783  case value_t::boolean:
19784  {
19785  boolean = static_cast<boolean_t>(false);
19786  break;
19787  }
19788 
19789  case value_t::number_integer:
19790  {
19791  number_integer = static_cast<number_integer_t>(0);
19792  break;
19793  }
19794 
19795  case value_t::number_unsigned:
19796  {
19797  number_unsigned = static_cast<number_unsigned_t>(0);
19798  break;
19799  }
19800 
19801  case value_t::number_float:
19802  {
19803  number_float = static_cast<number_float_t>(0.0);
19804  break;
19805  }
19806 
19807  case value_t::null:
19808  {
19809  object = nullptr; // silence warning, see #821
19810  break;
19811  }
19812 
19813  case value_t::discarded:
19814  default:
19815  {
19816  object = nullptr; // silence warning, see #821
19817  if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
19818  {
19819  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.3", nullptr)); // LCOV_EXCL_LINE
19820  }
19821  break;
19822  }
19823  }
19824  }
19825 
19828 
19830  json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
19831 
19833  json_value(const object_t& value) : object(create<object_t>(value)) {}
19834 
19836  json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
19837 
19839  json_value(const array_t& value) : array(create<array_t>(value)) {}
19840 
19842  json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
19843 
19845  json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
19846 
19848  json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
19849 
19852 
19854  json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
19855 
19857  {
19858  if (
19859  (t == value_t::object && object == nullptr) ||
19860  (t == value_t::array && array == nullptr) ||
19861  (t == value_t::string && string == nullptr) ||
19862  (t == value_t::binary && binary == nullptr)
19863  )
19864  {
19865  //not initialized (e.g. due to exception in the ctor)
19866  return;
19867  }
19868  if (t == value_t::array || t == value_t::object)
19869  {
19870  // flatten the current json_value to a heap-allocated stack
19871  std::vector<basic_json> stack;
19872 
19873  // move the top-level items to stack
19874  if (t == value_t::array)
19875  {
19876  stack.reserve(array->size());
19877  std::move(array->begin(), array->end(), std::back_inserter(stack));
19878  }
19879  else
19880  {
19881  stack.reserve(object->size());
19882  for (auto&& it : *object)
19883  {
19884  stack.push_back(std::move(it.second));
19885  }
19886  }
19887 
19888  while (!stack.empty())
19889  {
19890  // move the last item to local variable to be processed
19891  basic_json current_item(std::move(stack.back()));
19892  stack.pop_back();
19893 
19894  // if current_item is array/object, move
19895  // its children to the stack to be processed later
19896  if (current_item.is_array())
19897  {
19898  std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
19899 
19900  current_item.m_data.m_value.array->clear();
19901  }
19902  else if (current_item.is_object())
19903  {
19904  for (auto&& it : *current_item.m_data.m_value.object)
19905  {
19906  stack.push_back(std::move(it.second));
19907  }
19908 
19909  current_item.m_data.m_value.object->clear();
19910  }
19911 
19912  // it's now safe that current_item get destructed
19913  // since it doesn't have any children
19914  }
19915  }
19916 
19917  switch (t)
19918  {
19919  case value_t::object:
19920  {
19921  AllocatorType<object_t> alloc;
19922  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
19923  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
19924  break;
19925  }
19926 
19927  case value_t::array:
19928  {
19929  AllocatorType<array_t> alloc;
19930  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
19931  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
19932  break;
19933  }
19934 
19935  case value_t::string:
19936  {
19937  AllocatorType<string_t> alloc;
19938  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
19939  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
19940  break;
19941  }
19942 
19943  case value_t::binary:
19944  {
19945  AllocatorType<binary_t> alloc;
19946  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
19947  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
19948  break;
19949  }
19950 
19951  case value_t::null:
19952  case value_t::boolean:
19953  case value_t::number_integer:
19954  case value_t::number_unsigned:
19955  case value_t::number_float:
19956  case value_t::discarded:
19957  default:
19958  {
19959  break;
19960  }
19961  }
19962  }
19963  };
19964 
19965  private:
19984  void assert_invariant(bool check_parents = true) const noexcept
19985  {
19986  JSON_ASSERT(m_data.m_type != value_t::object || m_data.m_value.object != nullptr);
19987  JSON_ASSERT(m_data.m_type != value_t::array || m_data.m_value.array != nullptr);
19988  JSON_ASSERT(m_data.m_type != value_t::string || m_data.m_value.string != nullptr);
19989  JSON_ASSERT(m_data.m_type != value_t::binary || m_data.m_value.binary != nullptr);
19990 
19991 #if JSON_DIAGNOSTICS
19992  JSON_TRY
19993  {
19994  // cppcheck-suppress assertWithSideEffect
19995  JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
19996  {
19997  return j.m_parent == this;
19998  }));
19999  }
20000  JSON_CATCH(...) {} // LCOV_EXCL_LINE
20001 #endif
20002  static_cast<void>(check_parents);
20003  }
20004 
20006  {
20007 #if JSON_DIAGNOSTICS
20008  switch (m_data.m_type)
20009  {
20010  case value_t::array:
20011  {
20012  for (auto& element : *m_data.m_value.array)
20013  {
20014  element.m_parent = this;
20015  }
20016  break;
20017  }
20018 
20019  case value_t::object:
20020  {
20021  for (auto& element : *m_data.m_value.object)
20022  {
20023  element.second.m_parent = this;
20024  }
20025  break;
20026  }
20027 
20028  case value_t::null:
20029  case value_t::string:
20030  case value_t::boolean:
20031  case value_t::number_integer:
20032  case value_t::number_unsigned:
20033  case value_t::number_float:
20034  case value_t::binary:
20035  case value_t::discarded:
20036  default:
20037  break;
20038  }
20039 #endif
20040  }
20041 
20042  iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
20043  {
20044 #if JSON_DIAGNOSTICS
20045  for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
20046  {
20047  (it + i)->m_parent = this;
20048  }
20049 #else
20050  static_cast<void>(count_set_parents);
20051 #endif
20052  return it;
20053  }
20054 
20055  reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
20056  {
20057 #if JSON_DIAGNOSTICS
20058  if (old_capacity != static_cast<std::size_t>(-1))
20059  {
20060  // see https://github.com/nlohmann/json/issues/2838
20061  JSON_ASSERT(type() == value_t::array);
20062  if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
20063  {
20064  // capacity has changed: update all parents
20065  set_parents();
20066  return j;
20067  }
20068  }
20069 
20070  // ordered_json uses a vector internally, so pointers could have
20071  // been invalidated; see https://github.com/nlohmann/json/issues/2962
20072 #ifdef JSON_HEDLEY_MSVC_VERSION
20073 #pragma warning(push )
20074 #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
20075 #endif
20077  {
20078  set_parents();
20079  return j;
20080  }
20081 #ifdef JSON_HEDLEY_MSVC_VERSION
20082 #pragma warning( pop )
20083 #endif
20084 
20085  j.m_parent = this;
20086 #else
20087  static_cast<void>(j);
20088  static_cast<void>(old_capacity);
20089 #endif
20090  return j;
20091  }
20092 
20093  public:
20095  // JSON parser callback //
20097 
20101 
20105 
20107  // constructors //
20109 
20114 
20118  : m_data(v)
20119  {
20120  assert_invariant();
20121  }
20122 
20125  basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
20126  : basic_json(value_t::null)
20127  {
20128  assert_invariant();
20129  }
20130 
20133  template < typename CompatibleType,
20134  typename U = detail::uncvref_t<CompatibleType>,
20137  basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
20138  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
20139  std::forward<CompatibleType>(val))))
20140  {
20141  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
20142  set_parents();
20143  assert_invariant();
20144  }
20145 
20148  template < typename BasicJsonType,
20151  basic_json(const BasicJsonType& val)
20152  {
20153  using other_boolean_t = typename BasicJsonType::boolean_t;
20154  using other_number_float_t = typename BasicJsonType::number_float_t;
20155  using other_number_integer_t = typename BasicJsonType::number_integer_t;
20156  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
20157  using other_string_t = typename BasicJsonType::string_t;
20158  using other_object_t = typename BasicJsonType::object_t;
20159  using other_array_t = typename BasicJsonType::array_t;
20160  using other_binary_t = typename BasicJsonType::binary_t;
20161 
20162  switch (val.type())
20163  {
20164  case value_t::boolean:
20165  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
20166  break;
20167  case value_t::number_float:
20168  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
20169  break;
20170  case value_t::number_integer:
20171  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
20172  break;
20173  case value_t::number_unsigned:
20174  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
20175  break;
20176  case value_t::string:
20177  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
20178  break;
20179  case value_t::object:
20180  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
20181  break;
20182  case value_t::array:
20183  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
20184  break;
20185  case value_t::binary:
20186  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
20187  break;
20188  case value_t::null:
20189  *this = nullptr;
20190  break;
20191  case value_t::discarded:
20192  m_data.m_type = value_t::discarded;
20193  break;
20194  default: // LCOV_EXCL_LINE
20195  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
20196  }
20197  JSON_ASSERT(m_data.m_type == val.type());
20198  set_parents();
20199  assert_invariant();
20200  }
20201 
20205  bool type_deduction = true,
20206  value_t manual_type = value_t::array)
20207  {
20208  // check if each element is an array with two elements whose first
20209  // element is a string
20210  bool is_an_object = std::all_of(init.begin(), init.end(),
20211  [](const detail::json_ref<basic_json>& element_ref)
20212  {
20213  // The cast is to ensure op[size_type] is called, bearing in mind size_type may not be int;
20214  // (many string types can be constructed from 0 via its null-pointer guise, so we get a
20215  // broken call to op[key_type], the wrong semantics and a 4804 warning on Windows)
20216  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[static_cast<size_type>(0)].is_string();
20217  });
20218 
20219  // adjust type if type deduction is not wanted
20220  if (!type_deduction)
20221  {
20222  // if array is wanted, do not create an object though possible
20223  if (manual_type == value_t::array)
20224  {
20225  is_an_object = false;
20226  }
20227 
20228  // if object is wanted but impossible, throw an exception
20229  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
20230  {
20231  JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
20232  }
20233  }
20234 
20235  if (is_an_object)
20236  {
20237  // the initializer list is a list of pairs -> create object
20238  m_data.m_type = value_t::object;
20239  m_data.m_value = value_t::object;
20240 
20241  for (auto& element_ref : init)
20242  {
20243  auto element = element_ref.moved_or_copied();
20244  m_data.m_value.object->emplace(
20245  std::move(*((*element.m_data.m_value.array)[0].m_data.m_value.string)),
20246  std::move((*element.m_data.m_value.array)[1]));
20247  }
20248  }
20249  else
20250  {
20251  // the initializer list describes an array -> create array
20252  m_data.m_type = value_t::array;
20253  m_data.m_value.array = create<array_t>(init.begin(), init.end());
20254  }
20255 
20256  set_parents();
20257  assert_invariant();
20258  }
20259 
20263  static basic_json binary(const typename binary_t::container_type& init)
20264  {
20265  auto res = basic_json();
20266  res.m_data.m_type = value_t::binary;
20267  res.m_data.m_value = init;
20268  return res;
20269  }
20270 
20274  static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
20275  {
20276  auto res = basic_json();
20277  res.m_data.m_type = value_t::binary;
20278  res.m_data.m_value = binary_t(init, subtype);
20279  return res;
20280  }
20281 
20285  static basic_json binary(typename binary_t::container_type&& init)
20286  {
20287  auto res = basic_json();
20288  res.m_data.m_type = value_t::binary;
20289  res.m_data.m_value = std::move(init);
20290  return res;
20291  }
20292 
20296  static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
20297  {
20298  auto res = basic_json();
20299  res.m_data.m_type = value_t::binary;
20300  res.m_data.m_value = binary_t(std::move(init), subtype);
20301  return res;
20302  }
20303 
20308  {
20309  return basic_json(init, false, value_t::array);
20310  }
20311 
20316  {
20317  return basic_json(init, false, value_t::object);
20318  }
20319 
20322  basic_json(size_type cnt, const basic_json& val):
20323  m_data{cnt, val}
20324  {
20325  set_parents();
20326  assert_invariant();
20327  }
20328 
20331  template < class InputIT, typename std::enable_if <
20334  basic_json(InputIT first, InputIT last)
20335  {
20336  JSON_ASSERT(first.m_object != nullptr);
20337  JSON_ASSERT(last.m_object != nullptr);
20338 
20339  // make sure iterator fits the current value
20340  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20341  {
20342  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
20343  }
20344 
20345  // copy type from first iterator
20346  m_data.m_type = first.m_object->m_data.m_type;
20347 
20348  // check if iterator range is complete for primitive values
20349  switch (m_data.m_type)
20350  {
20351  case value_t::boolean:
20352  case value_t::number_float:
20353  case value_t::number_integer:
20354  case value_t::number_unsigned:
20355  case value_t::string:
20356  {
20357  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
20358  || !last.m_it.primitive_iterator.is_end()))
20359  {
20360  JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
20361  }
20362  break;
20363  }
20364 
20365  case value_t::null:
20366  case value_t::object:
20367  case value_t::array:
20368  case value_t::binary:
20369  case value_t::discarded:
20370  default:
20371  break;
20372  }
20373 
20374  switch (m_data.m_type)
20375  {
20376  case value_t::number_integer:
20377  {
20378  m_data.m_value.number_integer = first.m_object->m_data.m_value.number_integer;
20379  break;
20380  }
20381 
20382  case value_t::number_unsigned:
20383  {
20384  m_data.m_value.number_unsigned = first.m_object->m_data.m_value.number_unsigned;
20385  break;
20386  }
20387 
20388  case value_t::number_float:
20389  {
20390  m_data.m_value.number_float = first.m_object->m_data.m_value.number_float;
20391  break;
20392  }
20393 
20394  case value_t::boolean:
20395  {
20396  m_data.m_value.boolean = first.m_object->m_data.m_value.boolean;
20397  break;
20398  }
20399 
20400  case value_t::string:
20401  {
20402  m_data.m_value = *first.m_object->m_data.m_value.string;
20403  break;
20404  }
20405 
20406  case value_t::object:
20407  {
20408  m_data.m_value.object = create<object_t>(first.m_it.object_iterator,
20409  last.m_it.object_iterator);
20410  break;
20411  }
20412 
20413  case value_t::array:
20414  {
20415  m_data.m_value.array = create<array_t>(first.m_it.array_iterator,
20416  last.m_it.array_iterator);
20417  break;
20418  }
20419 
20420  case value_t::binary:
20421  {
20422  m_data.m_value = *first.m_object->m_data.m_value.binary;
20423  break;
20424  }
20425 
20426  case value_t::null:
20427  case value_t::discarded:
20428  default:
20429  JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
20430  }
20431 
20432  set_parents();
20433  assert_invariant();
20434  }
20435 
20437  // other constructors and destructor //
20439 
20440  template<typename JsonRef,
20442  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
20443  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
20444 
20447  basic_json(const basic_json& other)
20448  : json_base_class_t(other)
20449  {
20450  m_data.m_type = other.m_data.m_type;
20451  // check of passed value is valid
20452  other.assert_invariant();
20453 
20454  switch (m_data.m_type)
20455  {
20456  case value_t::object:
20457  {
20458  m_data.m_value = *other.m_data.m_value.object;
20459  break;
20460  }
20461 
20462  case value_t::array:
20463  {
20464  m_data.m_value = *other.m_data.m_value.array;
20465  break;
20466  }
20467 
20468  case value_t::string:
20469  {
20470  m_data.m_value = *other.m_data.m_value.string;
20471  break;
20472  }
20473 
20474  case value_t::boolean:
20475  {
20476  m_data.m_value = other.m_data.m_value.boolean;
20477  break;
20478  }
20479 
20480  case value_t::number_integer:
20481  {
20482  m_data.m_value = other.m_data.m_value.number_integer;
20483  break;
20484  }
20485 
20486  case value_t::number_unsigned:
20487  {
20488  m_data.m_value = other.m_data.m_value.number_unsigned;
20489  break;
20490  }
20491 
20492  case value_t::number_float:
20493  {
20494  m_data.m_value = other.m_data.m_value.number_float;
20495  break;
20496  }
20497 
20498  case value_t::binary:
20499  {
20500  m_data.m_value = *other.m_data.m_value.binary;
20501  break;
20502  }
20503 
20504  case value_t::null:
20505  case value_t::discarded:
20506  default:
20507  break;
20508  }
20509 
20510  set_parents();
20511  assert_invariant();
20512  }
20513 
20516  basic_json(basic_json&& other) noexcept
20517  : json_base_class_t(std::forward<json_base_class_t>(other)),
20518  m_data(std::move(other.m_data))
20519  {
20520  // check that passed value is valid
20521  other.assert_invariant(false);
20522 
20523  // invalidate payload
20524  other.m_data.m_type = value_t::null;
20525  other.m_data.m_value = {};
20526 
20527  set_parents();
20528  assert_invariant();
20529  }
20530 
20533  basic_json& operator=(basic_json other) noexcept (
20539  )
20540  {
20541  // check that passed value is valid
20542  other.assert_invariant();
20543 
20544  using std::swap;
20545  swap(m_data.m_type, other.m_data.m_type);
20546  swap(m_data.m_value, other.m_data.m_value);
20547  json_base_class_t::operator=(std::move(other));
20548 
20549  set_parents();
20550  assert_invariant();
20551  return *this;
20552  }
20553 
20556  ~basic_json() noexcept
20557  {
20558  assert_invariant(false);
20559  }
20560 
20562 
20563  public:
20565  // object inspection //
20567 
20571 
20574  string_t dump(const int indent = -1,
20575  const char indent_char = ' ',
20576  const bool ensure_ascii = false,
20577  const error_handler_t error_handler = error_handler_t::strict) const
20578  {
20579  string_t result;
20580  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
20581 
20582  if (indent >= 0)
20583  {
20584  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
20585  }
20586  else
20587  {
20588  s.dump(*this, false, ensure_ascii, 0);
20589  }
20590 
20591  return result;
20592  }
20593 
20596  constexpr value_t type() const noexcept
20597  {
20598  return m_data.m_type;
20599  }
20600 
20603  constexpr bool is_primitive() const noexcept
20604  {
20605  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20606  }
20607 
20610  constexpr bool is_structured() const noexcept
20611  {
20612  return is_array() || is_object();
20613  }
20614 
20617  constexpr bool is_null() const noexcept
20618  {
20619  return m_data.m_type == value_t::null;
20620  }
20621 
20624  constexpr bool is_boolean() const noexcept
20625  {
20626  return m_data.m_type == value_t::boolean;
20627  }
20628 
20631  constexpr bool is_number() const noexcept
20632  {
20633  return is_number_integer() || is_number_float();
20634  }
20635 
20638  constexpr bool is_number_integer() const noexcept
20639  {
20640  return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
20641  }
20642 
20645  constexpr bool is_number_unsigned() const noexcept
20646  {
20647  return m_data.m_type == value_t::number_unsigned;
20648  }
20649 
20652  constexpr bool is_number_float() const noexcept
20653  {
20654  return m_data.m_type == value_t::number_float;
20655  }
20656 
20659  constexpr bool is_object() const noexcept
20660  {
20661  return m_data.m_type == value_t::object;
20662  }
20663 
20666  constexpr bool is_array() const noexcept
20667  {
20668  return m_data.m_type == value_t::array;
20669  }
20670 
20673  constexpr bool is_string() const noexcept
20674  {
20675  return m_data.m_type == value_t::string;
20676  }
20677 
20680  constexpr bool is_binary() const noexcept
20681  {
20682  return m_data.m_type == value_t::binary;
20683  }
20684 
20687  constexpr bool is_discarded() const noexcept
20688  {
20689  return m_data.m_type == value_t::discarded;
20690  }
20691 
20694  constexpr operator value_t() const noexcept
20695  {
20696  return m_data.m_type;
20697  }
20698 
20700 
20701  private:
20703  // value access //
20705 
20707  boolean_t get_impl(boolean_t* /*unused*/) const
20708  {
20709  if (JSON_HEDLEY_LIKELY(is_boolean()))
20710  {
20711  return m_data.m_value.boolean;
20712  }
20713 
20714  JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
20715  }
20716 
20718  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20719  {
20720  return is_object() ? m_data.m_value.object : nullptr;
20721  }
20722 
20724  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20725  {
20726  return is_object() ? m_data.m_value.object : nullptr;
20727  }
20728 
20730  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20731  {
20732  return is_array() ? m_data.m_value.array : nullptr;
20733  }
20734 
20736  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20737  {
20738  return is_array() ? m_data.m_value.array : nullptr;
20739  }
20740 
20742  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20743  {
20744  return is_string() ? m_data.m_value.string : nullptr;
20745  }
20746 
20748  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20749  {
20750  return is_string() ? m_data.m_value.string : nullptr;
20751  }
20752 
20754  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20755  {
20756  return is_boolean() ? &m_data.m_value.boolean : nullptr;
20757  }
20758 
20760  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20761  {
20762  return is_boolean() ? &m_data.m_value.boolean : nullptr;
20763  }
20764 
20767  {
20768  return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
20769  }
20770 
20772  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20773  {
20774  return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
20775  }
20776 
20779  {
20780  return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
20781  }
20782 
20784  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20785  {
20786  return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
20787  }
20788 
20791  {
20792  return is_number_float() ? &m_data.m_value.number_float : nullptr;
20793  }
20794 
20796  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20797  {
20798  return is_number_float() ? &m_data.m_value.number_float : nullptr;
20799  }
20800 
20802  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20803  {
20804  return is_binary() ? m_data.m_value.binary : nullptr;
20805  }
20806 
20808  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20809  {
20810  return is_binary() ? m_data.m_value.binary : nullptr;
20811  }
20812 
20824  template<typename ReferenceType, typename ThisType>
20825  static ReferenceType get_ref_impl(ThisType& obj)
20826  {
20827  // delegate the call to get_ptr<>()
20828  auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20829 
20830  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20831  {
20832  return *ptr;
20833  }
20834 
20835  JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
20836  }
20837 
20838  public:
20842 
20845  template<typename PointerType, typename std::enable_if<
20846  std::is_pointer<PointerType>::value, int>::type = 0>
20847  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20848  {
20849  // delegate the call to get_impl_ptr<>()
20850  return get_impl_ptr(static_cast<PointerType>(nullptr));
20851  }
20852 
20855  template < typename PointerType, typename std::enable_if <
20857  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20858  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20859  {
20860  // delegate the call to get_impl_ptr<>() const
20861  return get_impl_ptr(static_cast<PointerType>(nullptr));
20862  }
20863 
20864  private:
20903  template < typename ValueType,
20907  int > = 0 >
20908  ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20909  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20910  {
20911  auto ret = ValueType();
20913  return ret;
20914  }
20915 
20946  template < typename ValueType,
20949  int > = 0 >
20950  ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20951  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20952  {
20954  }
20955 
20971  template < typename BasicJsonType,
20974  int > = 0 >
20975  BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20976  {
20977  return *this;
20978  }
20979 
20994  template<typename BasicJsonType,
20997  int> = 0>
20999  {
21000  return *this;
21001  }
21002 
21007  template<typename PointerType,
21010  int> = 0>
21011  constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
21012  -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
21013  {
21014  // delegate the call to get_ptr
21015  return get_ptr<PointerType>();
21016  }
21017 
21018  public:
21042  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
21043 #if defined(JSON_HAS_CPP_14)
21044  constexpr
21045 #endif
21046  auto get() const noexcept(
21047  noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
21048  -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
21049  {
21050  // we cannot static_assert on ValueTypeCV being non-const, because
21051  // there is support for get<const basic_json_t>(), which is why we
21052  // still need the uncvref
21054  "get() cannot be used with reference types, you might want to use get_ref()");
21055  return get_impl<ValueType>(detail::priority_tag<4> {});
21056  }
21057 
21085  template<typename PointerType, typename std::enable_if<
21086  std::is_pointer<PointerType>::value, int>::type = 0>
21087  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
21088  {
21089  // delegate the call to get_ptr
21090  return get_ptr<PointerType>();
21091  }
21092 
21095  template < typename ValueType,
21099  int > = 0 >
21100  ValueType & get_to(ValueType& v) const noexcept(noexcept(
21101  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
21102  {
21104  return v;
21105  }
21106 
21107  // specialization to allow calling get_to with a basic_json value
21108  // see https://github.com/nlohmann/json/issues/2175
21109  template<typename ValueType,
21112  int> = 0>
21113  ValueType & get_to(ValueType& v) const
21114  {
21115  v = *this;
21116  return v;
21117  }
21118 
21119  template <
21120  typename T, std::size_t N,
21121  typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21124  Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21125  noexcept(noexcept(JSONSerializer<Array>::from_json(
21126  std::declval<const basic_json_t&>(), v)))
21127  {
21129  return v;
21130  }
21131 
21134  template<typename ReferenceType, typename std::enable_if<
21136  ReferenceType get_ref()
21137  {
21138  // delegate call to get_ref_impl
21139  return get_ref_impl<ReferenceType>(*this);
21140  }
21141 
21144  template < typename ReferenceType, typename std::enable_if <
21146  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
21147  ReferenceType get_ref() const
21148  {
21149  // delegate call to get_ref_impl
21150  return get_ref_impl<ReferenceType>(*this);
21151  }
21152 
21182  template < typename ValueType, typename std::enable_if <
21190 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
21192 #endif
21193 #if defined(JSON_HAS_CPP_17) && JSON_HAS_STATIC_RTTI
21195 #endif
21197  >::value, int >::type = 0 >
21198  JSON_EXPLICIT operator ValueType() const
21199  {
21200  // delegate the call to get<>() const
21201  return get<ValueType>();
21202  }
21203 
21207  {
21208  if (!is_binary())
21209  {
21210  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21211  }
21212 
21213  return *get_ptr<binary_t*>();
21214  }
21215 
21218  const binary_t& get_binary() const
21219  {
21220  if (!is_binary())
21221  {
21222  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21223  }
21224 
21225  return *get_ptr<const binary_t*>();
21226  }
21227 
21229 
21231  // element access //
21233 
21237 
21241  {
21242  // at only works for arrays
21243  if (JSON_HEDLEY_LIKELY(is_array()))
21244  {
21245  JSON_TRY
21246  {
21247  return set_parent(m_data.m_value.array->at(idx));
21248  }
21249  JSON_CATCH (std::out_of_range&)
21250  {
21251  // create better exception explanation
21252  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21253  }
21254  }
21255  else
21256  {
21257  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21258  }
21259  }
21260 
21264  {
21265  // at only works for arrays
21266  if (JSON_HEDLEY_LIKELY(is_array()))
21267  {
21268  JSON_TRY
21269  {
21270  return m_data.m_value.array->at(idx);
21271  }
21272  JSON_CATCH (std::out_of_range&)
21273  {
21274  // create better exception explanation
21275  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21276  }
21277  }
21278  else
21279  {
21280  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21281  }
21282  }
21283 
21286  reference at(const typename object_t::key_type& key)
21287  {
21288  // at only works for objects
21289  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21290  {
21291  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21292  }
21293 
21294  auto it = m_data.m_value.object->find(key);
21295  if (it == m_data.m_value.object->end())
21296  {
21297  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21298  }
21299  return set_parent(it->second);
21300  }
21301 
21304  template<class KeyType, detail::enable_if_t<
21306  reference at(KeyType && key)
21307  {
21308  // at only works for objects
21309  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21310  {
21311  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21312  }
21313 
21314  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21315  if (it == m_data.m_value.object->end())
21316  {
21317  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21318  }
21319  return set_parent(it->second);
21320  }
21321 
21324  const_reference at(const typename object_t::key_type& key) const
21325  {
21326  // at only works for objects
21327  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21328  {
21329  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21330  }
21331 
21332  auto it = m_data.m_value.object->find(key);
21333  if (it == m_data.m_value.object->end())
21334  {
21335  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21336  }
21337  return it->second;
21338  }
21339 
21342  template<class KeyType, detail::enable_if_t<
21344  const_reference at(KeyType && key) const
21345  {
21346  // at only works for objects
21347  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21348  {
21349  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21350  }
21351 
21352  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21353  if (it == m_data.m_value.object->end())
21354  {
21355  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21356  }
21357  return it->second;
21358  }
21359 
21363  {
21364  // implicitly convert null value to an empty array
21365  if (is_null())
21366  {
21367  m_data.m_type = value_t::array;
21368  m_data.m_value.array = create<array_t>();
21369  assert_invariant();
21370  }
21371 
21372  // operator[] only works for arrays
21373  if (JSON_HEDLEY_LIKELY(is_array()))
21374  {
21375  // fill up array with null values if given idx is outside range
21376  if (idx >= m_data.m_value.array->size())
21377  {
21378 #if JSON_DIAGNOSTICS
21379  // remember array size & capacity before resizing
21380  const auto old_size = m_data.m_value.array->size();
21381  const auto old_capacity = m_data.m_value.array->capacity();
21382 #endif
21383  m_data.m_value.array->resize(idx + 1);
21384 
21385 #if JSON_DIAGNOSTICS
21386  if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
21387  {
21388  // capacity has changed: update all parents
21389  set_parents();
21390  }
21391  else
21392  {
21393  // set parent for values added above
21394  set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21395  }
21396 #endif
21397  assert_invariant();
21398  }
21399 
21400  return m_data.m_value.array->operator[](idx);
21401  }
21402 
21403  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21404  }
21405 
21409  {
21410  // const operator[] only works for arrays
21411  if (JSON_HEDLEY_LIKELY(is_array()))
21412  {
21413  return m_data.m_value.array->operator[](idx);
21414  }
21415 
21416  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21417  }
21418 
21421  reference operator[](typename object_t::key_type key)
21422  {
21423  // implicitly convert null value to an empty object
21424  if (is_null())
21425  {
21426  m_data.m_type = value_t::object;
21427  m_data.m_value.object = create<object_t>();
21428  assert_invariant();
21429  }
21430 
21431  // operator[] only works for objects
21432  if (JSON_HEDLEY_LIKELY(is_object()))
21433  {
21434  auto result = m_data.m_value.object->emplace(std::move(key), nullptr);
21435  return set_parent(result.first->second);
21436  }
21437 
21438  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21439  }
21440 
21443  const_reference operator[](const typename object_t::key_type& key) const
21444  {
21445  // const operator[] only works for objects
21446  if (JSON_HEDLEY_LIKELY(is_object()))
21447  {
21448  auto it = m_data.m_value.object->find(key);
21449  JSON_ASSERT(it != m_data.m_value.object->end());
21450  return it->second;
21451  }
21452 
21453  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21454  }
21455 
21456  // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
21457  // (they seemingly cannot be constrained to resolve the ambiguity)
21458  template<typename T>
21460  {
21461  return operator[](typename object_t::key_type(key));
21462  }
21463 
21464  template<typename T>
21466  {
21467  return operator[](typename object_t::key_type(key));
21468  }
21469 
21472  template<class KeyType, detail::enable_if_t<
21475  {
21476  // implicitly convert null value to an empty object
21477  if (is_null())
21478  {
21479  m_data.m_type = value_t::object;
21480  m_data.m_value.object = create<object_t>();
21481  assert_invariant();
21482  }
21483 
21484  // operator[] only works for objects
21485  if (JSON_HEDLEY_LIKELY(is_object()))
21486  {
21487  auto result = m_data.m_value.object->emplace(std::forward<KeyType>(key), nullptr);
21488  return set_parent(result.first->second);
21489  }
21490 
21491  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21492  }
21493 
21496  template<class KeyType, detail::enable_if_t<
21498  const_reference operator[](KeyType && key) const
21499  {
21500  // const operator[] only works for objects
21501  if (JSON_HEDLEY_LIKELY(is_object()))
21502  {
21503  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21504  JSON_ASSERT(it != m_data.m_value.object->end());
21505  return it->second;
21506  }
21507 
21508  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21509  }
21510 
21511  private:
21512  template<typename KeyType>
21513  using is_comparable_with_object_key = detail::is_comparable <
21514  object_comparator_t, const typename object_t::key_type&, KeyType >;
21515 
21516  template<typename ValueType>
21517  using value_return_type = std::conditional <
21519  string_t, typename std::decay<ValueType>::type >;
21520 
21521  public:
21524  template < class ValueType, detail::enable_if_t <
21527  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21528  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21529  {
21530  // value only works for objects
21531  if (JSON_HEDLEY_LIKELY(is_object()))
21532  {
21533  // if key is found, return value and given default value otherwise
21534  const auto it = find(key);
21535  if (it != end())
21536  {
21537  return it->template get<ValueType>();
21538  }
21539 
21540  return default_value;
21541  }
21542 
21543  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21544  }
21545 
21548  template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21552  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21553  ReturnType value(const typename object_t::key_type& key, ValueType && default_value) const
21554  {
21555  // value only works for objects
21556  if (JSON_HEDLEY_LIKELY(is_object()))
21557  {
21558  // if key is found, return value and given default value otherwise
21559  const auto it = find(key);
21560  if (it != end())
21561  {
21562  return it->template get<ReturnType>();
21563  }
21564 
21565  return std::forward<ValueType>(default_value);
21566  }
21567 
21568  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21569  }
21570 
21573  template < class ValueType, class KeyType, detail::enable_if_t <
21578  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21579  ValueType value(KeyType && key, const ValueType& default_value) const
21580  {
21581  // value only works for objects
21582  if (JSON_HEDLEY_LIKELY(is_object()))
21583  {
21584  // if key is found, return value and given default value otherwise
21585  const auto it = find(std::forward<KeyType>(key));
21586  if (it != end())
21587  {
21588  return it->template get<ValueType>();
21589  }
21590 
21591  return default_value;
21592  }
21593 
21594  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21595  }
21596 
21599  template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,
21605  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21606  ReturnType value(KeyType && key, ValueType && default_value) const
21607  {
21608  // value only works for objects
21609  if (JSON_HEDLEY_LIKELY(is_object()))
21610  {
21611  // if key is found, return value and given default value otherwise
21612  const auto it = find(std::forward<KeyType>(key));
21613  if (it != end())
21614  {
21615  return it->template get<ReturnType>();
21616  }
21617 
21618  return std::forward<ValueType>(default_value);
21619  }
21620 
21621  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21622  }
21623 
21626  template < class ValueType, detail::enable_if_t <
21628  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21629  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21630  {
21631  // value only works for objects
21632  if (JSON_HEDLEY_LIKELY(is_object()))
21633  {
21634  // if pointer resolves a value, return it or use default value
21635  JSON_TRY
21636  {
21637  return ptr.get_checked(this).template get<ValueType>();
21638  }
21640  {
21641  return default_value;
21642  }
21643  }
21644 
21645  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21646  }
21647 
21650  template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21653  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21654  ReturnType value(const json_pointer& ptr, ValueType && default_value) const
21655  {
21656  // value only works for objects
21657  if (JSON_HEDLEY_LIKELY(is_object()))
21658  {
21659  // if pointer resolves a value, return it or use default value
21660  JSON_TRY
21661  {
21662  return ptr.get_checked(this).template get<ReturnType>();
21663  }
21665  {
21666  return std::forward<ValueType>(default_value);
21667  }
21668  }
21669 
21670  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21671  }
21672 
21673  template < class ValueType, class BasicJsonType, detail::enable_if_t <
21676  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21677  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21678  ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
21679  {
21680  return value(ptr.convert(), default_value);
21681  }
21682 
21683  template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
21687  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21688  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21689  ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const
21690  {
21691  return value(ptr.convert(), std::forward<ValueType>(default_value));
21692  }
21693 
21696  reference front()
21697  {
21698  return *begin();
21699  }
21700 
21704  {
21705  return *cbegin();
21706  }
21707 
21711  {
21712  auto tmp = end();
21713  --tmp;
21714  return *tmp;
21715  }
21716 
21720  {
21721  auto tmp = cend();
21722  --tmp;
21723  return *tmp;
21724  }
21725 
21728  template < class IteratorType, detail::enable_if_t <
21731  IteratorType erase(IteratorType pos)
21732  {
21733  // make sure iterator fits the current value
21734  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21735  {
21736  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21737  }
21738 
21739  IteratorType result = end();
21740 
21741  switch (m_data.m_type)
21742  {
21743  case value_t::boolean:
21744  case value_t::number_float:
21745  case value_t::number_integer:
21746  case value_t::number_unsigned:
21747  case value_t::string:
21748  case value_t::binary:
21749  {
21750  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21751  {
21752  JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
21753  }
21754 
21755  if (is_string())
21756  {
21757  AllocatorType<string_t> alloc;
21758  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
21759  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
21760  m_data.m_value.string = nullptr;
21761  }
21762  else if (is_binary())
21763  {
21764  AllocatorType<binary_t> alloc;
21765  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
21766  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
21767  m_data.m_value.binary = nullptr;
21768  }
21769 
21770  m_data.m_type = value_t::null;
21771  assert_invariant();
21772  break;
21773  }
21774 
21775  case value_t::object:
21776  {
21777  result.m_it.object_iterator = m_data.m_value.object->erase(pos.m_it.object_iterator);
21778  break;
21779  }
21780 
21781  case value_t::array:
21782  {
21783  result.m_it.array_iterator = m_data.m_value.array->erase(pos.m_it.array_iterator);
21784  break;
21785  }
21786 
21787  case value_t::null:
21788  case value_t::discarded:
21789  default:
21790  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21791  }
21792 
21793  return result;
21794  }
21795 
21798  template < class IteratorType, detail::enable_if_t <
21801  IteratorType erase(IteratorType first, IteratorType last)
21802  {
21803  // make sure iterator fits the current value
21804  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21805  {
21806  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
21807  }
21808 
21809  IteratorType result = end();
21810 
21811  switch (m_data.m_type)
21812  {
21813  case value_t::boolean:
21814  case value_t::number_float:
21815  case value_t::number_integer:
21816  case value_t::number_unsigned:
21817  case value_t::string:
21818  case value_t::binary:
21819  {
21820  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21821  || !last.m_it.primitive_iterator.is_end()))
21822  {
21823  JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
21824  }
21825 
21826  if (is_string())
21827  {
21828  AllocatorType<string_t> alloc;
21829  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
21830  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
21831  m_data.m_value.string = nullptr;
21832  }
21833  else if (is_binary())
21834  {
21835  AllocatorType<binary_t> alloc;
21836  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
21837  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
21838  m_data.m_value.binary = nullptr;
21839  }
21840 
21841  m_data.m_type = value_t::null;
21842  assert_invariant();
21843  break;
21844  }
21845 
21846  case value_t::object:
21847  {
21848  result.m_it.object_iterator = m_data.m_value.object->erase(first.m_it.object_iterator,
21849  last.m_it.object_iterator);
21850  break;
21851  }
21852 
21853  case value_t::array:
21854  {
21855  result.m_it.array_iterator = m_data.m_value.array->erase(first.m_it.array_iterator,
21856  last.m_it.array_iterator);
21857  break;
21858  }
21859 
21860  case value_t::null:
21861  case value_t::discarded:
21862  default:
21863  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21864  }
21865 
21866  return result;
21867  }
21868 
21869  private:
21870  template < typename KeyType, detail::enable_if_t <
21873  {
21874  // this erase only works for objects
21875  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21876  {
21877  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21878  }
21879 
21880  return m_data.m_value.object->erase(std::forward<KeyType>(key));
21881  }
21882 
21883  template < typename KeyType, detail::enable_if_t <
21886  {
21887  // this erase only works for objects
21888  if (JSON_HEDLEY_UNLIKELY(!is_object()))
21889  {
21890  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21891  }
21892 
21893  const auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21894  if (it != m_data.m_value.object->end())
21895  {
21896  m_data.m_value.object->erase(it);
21897  return 1;
21898  }
21899  return 0;
21900  }
21901 
21902  public:
21903 
21906  size_type erase(const typename object_t::key_type& key)
21907  {
21908  // the indirection via erase_internal() is added to avoid making this
21909  // function a template and thus de-rank it during overload resolution
21910  return erase_internal(key);
21911  }
21912 
21915  template<class KeyType, detail::enable_if_t<
21917  size_type erase(KeyType && key)
21918  {
21919  return erase_internal(std::forward<KeyType>(key));
21920  }
21921 
21924  void erase(const size_type idx)
21925  {
21926  // this erase only works for arrays
21927  if (JSON_HEDLEY_LIKELY(is_array()))
21928  {
21929  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21930  {
21931  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21932  }
21933 
21934  m_data.m_value.array->erase(m_data.m_value.array->begin() + static_cast<difference_type>(idx));
21935  }
21936  else
21937  {
21938  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21939  }
21940  }
21941 
21943 
21945  // lookup //
21947 
21950 
21953  iterator find(const typename object_t::key_type& key)
21954  {
21955  auto result = end();
21956 
21957  if (is_object())
21958  {
21959  result.m_it.object_iterator = m_data.m_value.object->find(key);
21960  }
21961 
21962  return result;
21963  }
21964 
21967  const_iterator find(const typename object_t::key_type& key) const
21968  {
21969  auto result = cend();
21970 
21971  if (is_object())
21972  {
21973  result.m_it.object_iterator = m_data.m_value.object->find(key);
21974  }
21975 
21976  return result;
21977  }
21978 
21981  template<class KeyType, detail::enable_if_t<
21983  iterator find(KeyType && key)
21984  {
21985  auto result = end();
21986 
21987  if (is_object())
21988  {
21989  result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
21990  }
21991 
21992  return result;
21993  }
21994 
21997  template<class KeyType, detail::enable_if_t<
21999  const_iterator find(KeyType && key) const
22000  {
22001  auto result = cend();
22002 
22003  if (is_object())
22004  {
22005  result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
22006  }
22007 
22008  return result;
22009  }
22010 
22013  size_type count(const typename object_t::key_type& key) const
22014  {
22015  // return 0 for all nonobject types
22016  return is_object() ? m_data.m_value.object->count(key) : 0;
22017  }
22018 
22021  template<class KeyType, detail::enable_if_t<
22023  size_type count(KeyType && key) const
22024  {
22025  // return 0 for all nonobject types
22026  return is_object() ? m_data.m_value.object->count(std::forward<KeyType>(key)) : 0;
22027  }
22028 
22031  bool contains(const typename object_t::key_type& key) const
22032  {
22033  return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
22034  }
22035 
22038  template<class KeyType, detail::enable_if_t<
22040  bool contains(KeyType && key) const
22041  {
22042  return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
22043  }
22044 
22047  bool contains(const json_pointer& ptr) const
22048  {
22049  return ptr.contains(this);
22050  }
22051 
22053  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
22054  bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
22055  {
22056  return ptr.contains(this);
22057  }
22058 
22060 
22062  // iterators //
22064 
22067 
22070  iterator begin() noexcept
22071  {
22072  iterator result(this);
22073  result.set_begin();
22074  return result;
22075  }
22076 
22079  const_iterator begin() const noexcept
22080  {
22081  return cbegin();
22082  }
22083 
22086  const_iterator cbegin() const noexcept
22087  {
22088  const_iterator result(this);
22089  result.set_begin();
22090  return result;
22091  }
22092 
22095  iterator end() noexcept
22096  {
22097  iterator result(this);
22098  result.set_end();
22099  return result;
22100  }
22101 
22104  const_iterator end() const noexcept
22105  {
22106  return cend();
22107  }
22108 
22111  const_iterator cend() const noexcept
22112  {
22113  const_iterator result(this);
22114  result.set_end();
22115  return result;
22116  }
22117 
22120  reverse_iterator rbegin() noexcept
22121  {
22122  return reverse_iterator(end());
22123  }
22124 
22127  const_reverse_iterator rbegin() const noexcept
22128  {
22129  return crbegin();
22130  }
22131 
22134  reverse_iterator rend() noexcept
22135  {
22136  return reverse_iterator(begin());
22137  }
22138 
22141  const_reverse_iterator rend() const noexcept
22142  {
22143  return crend();
22144  }
22145 
22148  const_reverse_iterator crbegin() const noexcept
22149  {
22150  return const_reverse_iterator(cend());
22151  }
22152 
22155  const_reverse_iterator crend() const noexcept
22156  {
22157  return const_reverse_iterator(cbegin());
22158  }
22159 
22160  public:
22166  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22167  static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22168  {
22169  return ref.items();
22170  }
22171 
22177  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22178  static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22179  {
22180  return ref.items();
22181  }
22182 
22185  iteration_proxy<iterator> items() noexcept
22186  {
22187  return iteration_proxy<iterator>(*this);
22188  }
22189 
22192  iteration_proxy<const_iterator> items() const noexcept
22193  {
22194  return iteration_proxy<const_iterator>(*this);
22195  }
22196 
22198 
22200  // capacity //
22202 
22205 
22208  bool empty() const noexcept
22209  {
22210  switch (m_data.m_type)
22211  {
22212  case value_t::null:
22213  {
22214  // null values are empty
22215  return true;
22216  }
22217 
22218  case value_t::array:
22219  {
22220  // delegate call to array_t::empty()
22221  return m_data.m_value.array->empty();
22222  }
22223 
22224  case value_t::object:
22225  {
22226  // delegate call to object_t::empty()
22227  return m_data.m_value.object->empty();
22228  }
22229 
22230  case value_t::string:
22231  case value_t::boolean:
22232  case value_t::number_integer:
22233  case value_t::number_unsigned:
22234  case value_t::number_float:
22235  case value_t::binary:
22236  case value_t::discarded:
22237  default:
22238  {
22239  // all other types are nonempty
22240  return false;
22241  }
22242  }
22243  }
22244 
22247  size_type size() const noexcept
22248  {
22249  switch (m_data.m_type)
22250  {
22251  case value_t::null:
22252  {
22253  // null values are empty
22254  return 0;
22255  }
22256 
22257  case value_t::array:
22258  {
22259  // delegate call to array_t::size()
22260  return m_data.m_value.array->size();
22261  }
22262 
22263  case value_t::object:
22264  {
22265  // delegate call to object_t::size()
22266  return m_data.m_value.object->size();
22267  }
22268 
22269  case value_t::string:
22270  case value_t::boolean:
22271  case value_t::number_integer:
22272  case value_t::number_unsigned:
22273  case value_t::number_float:
22274  case value_t::binary:
22275  case value_t::discarded:
22276  default:
22277  {
22278  // all other types have size 1
22279  return 1;
22280  }
22281  }
22282  }
22283 
22286  size_type max_size() const noexcept
22287  {
22288  switch (m_data.m_type)
22289  {
22290  case value_t::array:
22291  {
22292  // delegate call to array_t::max_size()
22293  return m_data.m_value.array->max_size();
22294  }
22295 
22296  case value_t::object:
22297  {
22298  // delegate call to object_t::max_size()
22299  return m_data.m_value.object->max_size();
22300  }
22301 
22302  case value_t::null:
22303  case value_t::string:
22304  case value_t::boolean:
22305  case value_t::number_integer:
22306  case value_t::number_unsigned:
22307  case value_t::number_float:
22308  case value_t::binary:
22309  case value_t::discarded:
22310  default:
22311  {
22312  // all other types have max_size() == size()
22313  return size();
22314  }
22315  }
22316  }
22317 
22319 
22321  // modifiers //
22323 
22326 
22329  void clear() noexcept
22330  {
22331  switch (m_data.m_type)
22332  {
22333  case value_t::number_integer:
22334  {
22335  m_data.m_value.number_integer = 0;
22336  break;
22337  }
22338 
22339  case value_t::number_unsigned:
22340  {
22341  m_data.m_value.number_unsigned = 0;
22342  break;
22343  }
22344 
22345  case value_t::number_float:
22346  {
22347  m_data.m_value.number_float = 0.0;
22348  break;
22349  }
22350 
22351  case value_t::boolean:
22352  {
22353  m_data.m_value.boolean = false;
22354  break;
22355  }
22356 
22357  case value_t::string:
22358  {
22359  m_data.m_value.string->clear();
22360  break;
22361  }
22362 
22363  case value_t::binary:
22364  {
22365  m_data.m_value.binary->clear();
22366  break;
22367  }
22368 
22369  case value_t::array:
22370  {
22371  m_data.m_value.array->clear();
22372  break;
22373  }
22374 
22375  case value_t::object:
22376  {
22377  m_data.m_value.object->clear();
22378  break;
22379  }
22380 
22381  case value_t::null:
22382  case value_t::discarded:
22383  default:
22384  break;
22385  }
22386  }
22387 
22390  void push_back(basic_json&& val)
22391  {
22392  // push_back only works for null objects or arrays
22393  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22394  {
22395  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22396  }
22397 
22398  // transform null object into an array
22399  if (is_null())
22400  {
22401  m_data.m_type = value_t::array;
22402  m_data.m_value = value_t::array;
22403  assert_invariant();
22404  }
22405 
22406  // add element to array (move semantics)
22407  const auto old_capacity = m_data.m_value.array->capacity();
22408  m_data.m_value.array->push_back(std::move(val));
22409  set_parent(m_data.m_value.array->back(), old_capacity);
22410  // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
22411  }
22412 
22416  {
22417  push_back(std::move(val));
22418  return *this;
22419  }
22420 
22423  void push_back(const basic_json& val)
22424  {
22425  // push_back only works for null objects or arrays
22426  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22427  {
22428  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22429  }
22430 
22431  // transform null object into an array
22432  if (is_null())
22433  {
22434  m_data.m_type = value_t::array;
22435  m_data.m_value = value_t::array;
22436  assert_invariant();
22437  }
22438 
22439  // add element to array
22440  const auto old_capacity = m_data.m_value.array->capacity();
22441  m_data.m_value.array->push_back(val);
22442  set_parent(m_data.m_value.array->back(), old_capacity);
22443  }
22444 
22448  {
22449  push_back(val);
22450  return *this;
22451  }
22452 
22455  void push_back(const typename object_t::value_type& val)
22456  {
22457  // push_back only works for null objects or objects
22458  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22459  {
22460  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22461  }
22462 
22463  // transform null object into an object
22464  if (is_null())
22465  {
22466  m_data.m_type = value_t::object;
22467  m_data.m_value = value_t::object;
22468  assert_invariant();
22469  }
22470 
22471  // add element to object
22472  auto res = m_data.m_value.object->insert(val);
22473  set_parent(res.first->second);
22474  }
22475 
22478  reference operator+=(const typename object_t::value_type& val)
22479  {
22480  push_back(val);
22481  return *this;
22482  }
22483 
22487  {
22488  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22489  {
22490  basic_json&& key = init.begin()->moved_or_copied();
22491  push_back(typename object_t::value_type(
22492  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22493  }
22494  else
22495  {
22496  push_back(basic_json(init));
22497  }
22498  }
22499 
22503  {
22504  push_back(init);
22505  return *this;
22506  }
22507 
22510  template<class... Args>
22511  reference emplace_back(Args&& ... args)
22512  {
22513  // emplace_back only works for null objects or arrays
22514  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22515  {
22516  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
22517  }
22518 
22519  // transform null object into an array
22520  if (is_null())
22521  {
22522  m_data.m_type = value_t::array;
22523  m_data.m_value = value_t::array;
22524  assert_invariant();
22525  }
22526 
22527  // add element to array (perfect forwarding)
22528  const auto old_capacity = m_data.m_value.array->capacity();
22529  m_data.m_value.array->emplace_back(std::forward<Args>(args)...);
22530  return set_parent(m_data.m_value.array->back(), old_capacity);
22531  }
22532 
22535  template<class... Args>
22536  std::pair<iterator, bool> emplace(Args&& ... args)
22537  {
22538  // emplace only works for null objects or arrays
22539  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22540  {
22541  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
22542  }
22543 
22544  // transform null object into an object
22545  if (is_null())
22546  {
22547  m_data.m_type = value_t::object;
22548  m_data.m_value = value_t::object;
22549  assert_invariant();
22550  }
22551 
22552  // add element to array (perfect forwarding)
22553  auto res = m_data.m_value.object->emplace(std::forward<Args>(args)...);
22554  set_parent(res.first->second);
22555 
22556  // create result iterator and set iterator to the result of emplace
22557  auto it = begin();
22558  it.m_it.object_iterator = res.first;
22559 
22560  // return pair of iterator and boolean
22561  return {it, res.second};
22562  }
22563 
22567  template<typename... Args>
22569  {
22570  iterator result(this);
22571  JSON_ASSERT(m_data.m_value.array != nullptr);
22572 
22573  auto insert_pos = std::distance(m_data.m_value.array->begin(), pos.m_it.array_iterator);
22574  m_data.m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22575  result.m_it.array_iterator = m_data.m_value.array->begin() + insert_pos;
22576 
22577  // This could have been written as:
22578  // result.m_it.array_iterator = m_data.m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22579  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22580 
22581  set_parents();
22582  return result;
22583  }
22584 
22588  {
22589  // insert only works for arrays
22590  if (JSON_HEDLEY_LIKELY(is_array()))
22591  {
22592  // check if iterator pos fits to this JSON value
22593  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22594  {
22595  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22596  }
22597 
22598  // insert to array and return iterator
22599  return insert_iterator(pos, val);
22600  }
22601 
22602  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22603  }
22604 
22608  {
22609  return insert(pos, val);
22610  }
22611 
22615  {
22616  // insert only works for arrays
22617  if (JSON_HEDLEY_LIKELY(is_array()))
22618  {
22619  // check if iterator pos fits to this JSON value
22620  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22621  {
22622  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22623  }
22624 
22625  // insert to array and return iterator
22626  return insert_iterator(pos, cnt, val);
22627  }
22628 
22629  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22630  }
22631 
22635  {
22636  // insert only works for arrays
22637  if (JSON_HEDLEY_UNLIKELY(!is_array()))
22638  {
22639  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22640  }
22641 
22642  // check if iterator pos fits to this JSON value
22643  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22644  {
22645  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22646  }
22647 
22648  // check if range iterators belong to the same JSON object
22649  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22650  {
22651  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22652  }
22653 
22654  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22655  {
22656  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
22657  }
22658 
22659  // insert to array and return iterator
22660  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22661  }
22662 
22666  {
22667  // insert only works for arrays
22668  if (JSON_HEDLEY_UNLIKELY(!is_array()))
22669  {
22670  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22671  }
22672 
22673  // check if iterator pos fits to this JSON value
22674  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22675  {
22676  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22677  }
22678 
22679  // insert to array and return iterator
22680  return insert_iterator(pos, ilist.begin(), ilist.end());
22681  }
22682 
22686  {
22687  // insert only works for objects
22688  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22689  {
22690  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22691  }
22692 
22693  // check if range iterators belong to the same JSON object
22694  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22695  {
22696  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22697  }
22698 
22699  // passed iterators must belong to objects
22700  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22701  {
22702  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
22703  }
22704 
22705  m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22706  }
22707 
22710  void update(const_reference j, bool merge_objects = false)
22711  {
22712  update(j.begin(), j.end(), merge_objects);
22713  }
22714 
22717  void update(const_iterator first, const_iterator last, bool merge_objects = false)
22718  {
22719  // implicitly convert null value to an empty object
22720  if (is_null())
22721  {
22722  m_data.m_type = value_t::object;
22723  m_data.m_value.object = create<object_t>();
22724  assert_invariant();
22725  }
22726 
22727  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22728  {
22729  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
22730  }
22731 
22732  // check if range iterators belong to the same JSON object
22733  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22734  {
22735  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22736  }
22737 
22738  // passed iterators must belong to objects
22739  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22740  {
22741  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
22742  }
22743 
22744  for (auto it = first; it != last; ++it)
22745  {
22746  if (merge_objects && it.value().is_object())
22747  {
22748  auto it2 = m_data.m_value.object->find(it.key());
22749  if (it2 != m_data.m_value.object->end())
22750  {
22751  it2->second.update(it.value(), true);
22752  continue;
22753  }
22754  }
22755  m_data.m_value.object->operator[](it.key()) = it.value();
22756 #if JSON_DIAGNOSTICS
22757  m_data.m_value.object->operator[](it.key()).m_parent = this;
22758 #endif
22759  }
22760  }
22761 
22764  void swap(reference other) noexcept (
22767  std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22769  )
22770  {
22771  std::swap(m_data.m_type, other.m_data.m_type);
22772  std::swap(m_data.m_value, other.m_data.m_value);
22773 
22774  set_parents();
22775  other.set_parents();
22776  assert_invariant();
22777  }
22778 
22781  friend void swap(reference left, reference right) noexcept (
22784  std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22786  )
22787  {
22788  left.swap(right);
22789  }
22790 
22793  void swap(array_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22794  {
22795  // swap only works for arrays
22796  if (JSON_HEDLEY_LIKELY(is_array()))
22797  {
22798  using std::swap;
22799  swap(*(m_data.m_value.array), other);
22800  }
22801  else
22802  {
22803  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
22804  }
22805  }
22806 
22809  void swap(object_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22810  {
22811  // swap only works for objects
22812  if (JSON_HEDLEY_LIKELY(is_object()))
22813  {
22814  using std::swap;
22815  swap(*(m_data.m_value.object), other);
22816  }
22817  else
22818  {
22819  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
22820  }
22821  }
22822 
22825  void swap(string_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22826  {
22827  // swap only works for strings
22828  if (JSON_HEDLEY_LIKELY(is_string()))
22829  {
22830  using std::swap;
22831  swap(*(m_data.m_value.string), other);
22832  }
22833  else
22834  {
22835  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
22836  }
22837  }
22838 
22841  void swap(binary_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22842  {
22843  // swap only works for strings
22844  if (JSON_HEDLEY_LIKELY(is_binary()))
22845  {
22846  using std::swap;
22847  swap(*(m_data.m_value.binary), other);
22848  }
22849  else
22850  {
22851  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
22852  }
22853  }
22854 
22857  void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
22858  {
22859  // swap only works for strings
22860  if (JSON_HEDLEY_LIKELY(is_binary()))
22861  {
22862  using std::swap;
22863  swap(*(m_data.m_value.binary), other);
22864  }
22865  else
22866  {
22867  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
22868  }
22869  }
22870 
22872 
22874  // lexicographical comparison operators //
22876 
22879 
22880  // note parentheses around operands are necessary; see
22881  // https://github.com/nlohmann/json/issues/1530
22882 #define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
22883  const auto lhs_type = lhs.type(); \
22884  const auto rhs_type = rhs.type(); \
22885  \
22886  if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
22887  { \
22888  switch (lhs_type) \
22889  { \
22890  case value_t::array: \
22891  return (*lhs.m_data.m_value.array) op (*rhs.m_data.m_value.array); \
22892  \
22893  case value_t::object: \
22894  return (*lhs.m_data.m_value.object) op (*rhs.m_data.m_value.object); \
22895  \
22896  case value_t::null: \
22897  return (null_result); \
22898  \
22899  case value_t::string: \
22900  return (*lhs.m_data.m_value.string) op (*rhs.m_data.m_value.string); \
22901  \
22902  case value_t::boolean: \
22903  return (lhs.m_data.m_value.boolean) op (rhs.m_data.m_value.boolean); \
22904  \
22905  case value_t::number_integer: \
22906  return (lhs.m_data.m_value.number_integer) op (rhs.m_data.m_value.number_integer); \
22907  \
22908  case value_t::number_unsigned: \
22909  return (lhs.m_data.m_value.number_unsigned) op (rhs.m_data.m_value.number_unsigned); \
22910  \
22911  case value_t::number_float: \
22912  return (lhs.m_data.m_value.number_float) op (rhs.m_data.m_value.number_float); \
22913  \
22914  case value_t::binary: \
22915  return (*lhs.m_data.m_value.binary) op (*rhs.m_data.m_value.binary); \
22916  \
22917  case value_t::discarded: \
22918  default: \
22919  return (unordered_result); \
22920  } \
22921  } \
22922  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
22923  { \
22924  return static_cast<number_float_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_float; \
22925  } \
22926  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
22927  { \
22928  return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_integer); \
22929  } \
22930  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
22931  { \
22932  return static_cast<number_float_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_float; \
22933  } \
22934  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
22935  { \
22936  return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_unsigned); \
22937  } \
22938  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
22939  { \
22940  return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \
22941  } \
22942  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
22943  { \
22944  return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \
22945  } \
22946  else if(compares_unordered(lhs, rhs))\
22947  {\
22948  return (unordered_result);\
22949  }\
22950  \
22951  return (default_result);
22952 
22954  // returns true if:
22955  // - any operand is NaN and the other operand is of number type
22956  // - any operand is discarded
22957  // in legacy mode, discarded values are considered ordered if
22958  // an operation is computed as an odd number of inverses of others
22959  static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
22960  {
22961  if ((lhs.is_number_float() && std::isnan(lhs.m_data.m_value.number_float) && rhs.is_number())
22962  || (rhs.is_number_float() && std::isnan(rhs.m_data.m_value.number_float) && lhs.is_number()))
22963  {
22964  return true;
22965  }
22966 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22967  return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
22968 #else
22969  static_cast<void>(inverse);
22970  return lhs.is_discarded() || rhs.is_discarded();
22971 #endif
22972  }
22973 
22974  private:
22975  bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
22976  {
22977  return compares_unordered(*this, rhs, inverse);
22978  }
22979 
22980  public:
22981 #if JSON_HAS_THREE_WAY_COMPARISON
22982  bool operator==(const_reference rhs) const noexcept
22985  {
22986 #ifdef __GNUC__
22987 #pragma GCC diagnostic push
22988 #pragma GCC diagnostic ignored "-Wfloat-equal"
22989 #endif
22990  const_reference lhs = *this;
22991  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
22992 #ifdef __GNUC__
22993 #pragma GCC diagnostic pop
22994 #endif
22995  }
22996 
22999  template<typename ScalarType>
23000  requires std::is_scalar_v<ScalarType>
23001  bool operator==(ScalarType rhs) const noexcept
23002  {
23003  return *this == basic_json(rhs);
23004  }
23005 
23008  bool operator!=(const_reference rhs) const noexcept
23009  {
23010  if (compares_unordered(rhs, true))
23011  {
23012  return false;
23013  }
23014  return !operator==(rhs);
23015  }
23016 
23019  std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
23020  {
23021  const_reference lhs = *this;
23022  // default_result is used if we cannot compare values. In that case,
23023  // we compare types.
23024  JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD*
23025  std::partial_ordering::equivalent,
23026  std::partial_ordering::unordered,
23027  lhs_type <=> rhs_type) // *NOPAD*
23028  }
23029 
23032  template<typename ScalarType>
23033  requires std::is_scalar_v<ScalarType>
23034  std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
23035  {
23036  return *this <=> basic_json(rhs); // *NOPAD*
23037  }
23038 
23039 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
23040  // all operators that are computed as an odd number of inverses of others
23041  // need to be overloaded to emulate the legacy comparison behavior
23042 
23046  bool operator<=(const_reference rhs) const noexcept
23047  {
23048  if (compares_unordered(rhs, true))
23049  {
23050  return false;
23051  }
23052  return !(rhs < *this);
23053  }
23054 
23057  template<typename ScalarType>
23058  requires std::is_scalar_v<ScalarType>
23059  bool operator<=(ScalarType rhs) const noexcept
23060  {
23061  return *this <= basic_json(rhs);
23062  }
23063 
23067  bool operator>=(const_reference rhs) const noexcept
23068  {
23069  if (compares_unordered(rhs, true))
23070  {
23071  return false;
23072  }
23073  return !(*this < rhs);
23074  }
23075 
23078  template<typename ScalarType>
23079  requires std::is_scalar_v<ScalarType>
23080  bool operator>=(ScalarType rhs) const noexcept
23081  {
23082  return *this >= basic_json(rhs);
23083  }
23084 #endif
23085 #else
23086  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23089  {
23090 #ifdef __GNUC__
23091 #pragma GCC diagnostic push
23092 #pragma GCC diagnostic ignored "-Wfloat-equal"
23093 #endif
23094  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
23095 #ifdef __GNUC__
23096 #pragma GCC diagnostic pop
23097 #endif
23098  }
23099 
23102  template<typename ScalarType, typename std::enable_if<
23103  std::is_scalar<ScalarType>::value, int>::type = 0>
23104  friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23105  {
23106  return lhs == basic_json(rhs);
23107  }
23108 
23111  template<typename ScalarType, typename std::enable_if<
23112  std::is_scalar<ScalarType>::value, int>::type = 0>
23113  friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23114  {
23115  return basic_json(lhs) == rhs;
23116  }
23117 
23120  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23121  {
23122  if (compares_unordered(lhs, rhs, true))
23123  {
23124  return false;
23125  }
23126  return !(lhs == rhs);
23127  }
23128 
23131  template<typename ScalarType, typename std::enable_if<
23132  std::is_scalar<ScalarType>::value, int>::type = 0>
23133  friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23134  {
23135  return lhs != basic_json(rhs);
23136  }
23137 
23140  template<typename ScalarType, typename std::enable_if<
23141  std::is_scalar<ScalarType>::value, int>::type = 0>
23142  friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23143  {
23144  return basic_json(lhs) != rhs;
23145  }
23146 
23149  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23150  {
23151  // default_result is used if we cannot compare values. In that case,
23152  // we compare types. Note we have to call the operator explicitly,
23153  // because MSVC has problems otherwise.
23154  JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))
23155  }
23156 
23159  template<typename ScalarType, typename std::enable_if<
23160  std::is_scalar<ScalarType>::value, int>::type = 0>
23161  friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23162  {
23163  return lhs < basic_json(rhs);
23164  }
23165 
23168  template<typename ScalarType, typename std::enable_if<
23169  std::is_scalar<ScalarType>::value, int>::type = 0>
23170  friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
23171  {
23172  return basic_json(lhs) < rhs;
23173  }
23174 
23177  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
23178  {
23179  if (compares_unordered(lhs, rhs, true))
23180  {
23181  return false;
23182  }
23183  return !(rhs < lhs);
23184  }
23185 
23188  template<typename ScalarType, typename std::enable_if<
23189  std::is_scalar<ScalarType>::value, int>::type = 0>
23190  friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
23191  {
23192  return lhs <= basic_json(rhs);
23193  }
23194 
23197  template<typename ScalarType, typename std::enable_if<
23198  std::is_scalar<ScalarType>::value, int>::type = 0>
23199  friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
23200  {
23201  return basic_json(lhs) <= rhs;
23202  }
23203 
23206  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23207  {
23208  // double inverse
23209  if (compares_unordered(lhs, rhs))
23210  {
23211  return false;
23212  }
23213  return !(lhs <= rhs);
23214  }
23215 
23218  template<typename ScalarType, typename std::enable_if<
23219  std::is_scalar<ScalarType>::value, int>::type = 0>
23220  friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
23221  {
23222  return lhs > basic_json(rhs);
23223  }
23224 
23227  template<typename ScalarType, typename std::enable_if<
23228  std::is_scalar<ScalarType>::value, int>::type = 0>
23229  friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
23230  {
23231  return basic_json(lhs) > rhs;
23232  }
23233 
23236  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23237  {
23238  if (compares_unordered(lhs, rhs, true))
23239  {
23240  return false;
23241  }
23242  return !(lhs < rhs);
23243  }
23244 
23247  template<typename ScalarType, typename std::enable_if<
23248  std::is_scalar<ScalarType>::value, int>::type = 0>
23249  friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
23250  {
23251  return lhs >= basic_json(rhs);
23252  }
23253 
23256  template<typename ScalarType, typename std::enable_if<
23257  std::is_scalar<ScalarType>::value, int>::type = 0>
23258  friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
23259  {
23260  return basic_json(lhs) >= rhs;
23261  }
23262 #endif
23263 
23264 #undef JSON_IMPLEMENT_OPERATOR
23265 
23267 
23269  // serialization //
23271 
23274 #ifndef JSON_NO_IO
23275  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23278  {
23279  // read width member and use it as indentation parameter if nonzero
23280  const bool pretty_print = o.width() > 0;
23281  const auto indentation = pretty_print ? o.width() : 0;
23282 
23283  // reset width to 0 for subsequent calls to this stream
23284  o.width(0);
23285 
23286  // do the actual serialization
23287  serializer s(detail::output_adapter<char>(o), o.fill());
23288  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23289  return o;
23290  }
23291 
23298  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23299  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23300  {
23301  return o << j;
23302  }
23303 #endif // JSON_NO_IO
23304 
23307  // deserialization //
23309 
23312 
23315  template<typename InputType>
23317  static basic_json parse(InputType&& i,
23318  const parser_callback_t cb = nullptr,
23319  const bool allow_exceptions = true,
23320  const bool ignore_comments = false)
23321  {
23322  basic_json result;
23323  parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23324  return result;
23325  }
23326 
23329  template<typename IteratorType>
23331  static basic_json parse(IteratorType first,
23332  IteratorType last,
23333  const parser_callback_t cb = nullptr,
23334  const bool allow_exceptions = true,
23335  const bool ignore_comments = false)
23336  {
23337  basic_json result;
23338  parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23339  return result;
23340  }
23341 
23343  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23345  const parser_callback_t cb = nullptr,
23346  const bool allow_exceptions = true,
23347  const bool ignore_comments = false)
23348  {
23349  basic_json result;
23350  parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23351  return result;
23352  }
23353 
23356  template<typename InputType>
23357  static bool accept(InputType&& i,
23358  const bool ignore_comments = false)
23359  {
23360  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23361  }
23362 
23365  template<typename IteratorType>
23366  static bool accept(IteratorType first, IteratorType last,
23367  const bool ignore_comments = false)
23368  {
23369  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23370  }
23371 
23373  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23374  static bool accept(detail::span_input_adapter&& i,
23375  const bool ignore_comments = false)
23376  {
23377  return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23378  }
23379 
23382  template <typename InputType, typename SAX>
23384  static bool sax_parse(InputType&& i, SAX* sax,
23386  const bool strict = true,
23387  const bool ignore_comments = false)
23388  {
23389  auto ia = detail::input_adapter(std::forward<InputType>(i));
23390  return format == input_format_t::json
23391  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23392  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23393  }
23394 
23397  template<class IteratorType, class SAX>
23399  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23401  const bool strict = true,
23402  const bool ignore_comments = false)
23403  {
23404  auto ia = detail::input_adapter(std::move(first), std::move(last));
23405  return format == input_format_t::json
23406  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23407  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23408  }
23409 
23415  template <typename SAX>
23416  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23418  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23420  const bool strict = true,
23421  const bool ignore_comments = false)
23422  {
23423  auto ia = i.get();
23424  return format == input_format_t::json
23425  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23426  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23427  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23428  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23429  }
23430 #ifndef JSON_NO_IO
23431  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23438  friend std::istream& operator<<(basic_json& j, std::istream& i)
23439  {
23440  return operator>>(i, j);
23441  }
23442 
23445  friend std::istream& operator>>(std::istream& i, basic_json& j)
23446  {
23447  parser(detail::input_adapter(i)).parse(false, j);
23448  return i;
23449  }
23450 #endif // JSON_NO_IO
23451 
23454  // convenience functions //
23456 
23460  const char* type_name() const noexcept
23461  {
23462  switch (m_data.m_type)
23463  {
23464  case value_t::null:
23465  return "null";
23466  case value_t::object:
23467  return "object";
23468  case value_t::array:
23469  return "array";
23470  case value_t::string:
23471  return "string";
23472  case value_t::boolean:
23473  return "boolean";
23474  case value_t::binary:
23475  return "binary";
23476  case value_t::discarded:
23477  return "discarded";
23478  case value_t::number_integer:
23479  case value_t::number_unsigned:
23480  case value_t::number_float:
23481  default:
23482  return "number";
23483  }
23484  }
23485 
23488  // member variables //
23490 
23491  struct data
23492  {
23494  value_t m_type = value_t::null;
23495 
23497  json_value m_value = {};
23498 
23499  data(const value_t v)
23500  : m_type(v), m_value(v)
23501  {
23502  }
23503 
23504  data(size_type cnt, const basic_json& val)
23505  : m_type(value_t::array)
23506  {
23507  m_value.array = create<array_t>(cnt, val);
23508  }
23509 
23510  data() noexcept = default;
23511  data(data&&) noexcept = default;
23512  data(const data&) noexcept = delete;
23513  data& operator=(data&&) noexcept = delete;
23514  data& operator=(const data&) noexcept = delete;
23515 
23516  ~data() noexcept
23517  {
23518  m_value.destroy(m_type);
23519  }
23520  };
23521 
23522  data m_data = {};
23523 
23524 #if JSON_DIAGNOSTICS
23525  basic_json* m_parent = nullptr;
23527 #endif
23528 
23530  // binary serialization/deserialization //
23532 
23535 
23536  public:
23539  static std::vector<std::uint8_t> to_cbor(const basic_json& j)
23540  {
23541  std::vector<std::uint8_t> result;
23542  to_cbor(j, result);
23543  return result;
23544  }
23545 
23549  {
23550  binary_writer<std::uint8_t>(o).write_cbor(j);
23551  }
23552 
23556  {
23557  binary_writer<char>(o).write_cbor(j);
23558  }
23559 
23562  static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
23563  {
23564  std::vector<std::uint8_t> result;
23565  to_msgpack(j, result);
23566  return result;
23567  }
23568 
23572  {
23573  binary_writer<std::uint8_t>(o).write_msgpack(j);
23574  }
23575 
23579  {
23580  binary_writer<char>(o).write_msgpack(j);
23581  }
23582 
23585  static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
23586  const bool use_size = false,
23587  const bool use_type = false)
23588  {
23589  std::vector<std::uint8_t> result;
23590  to_ubjson(j, result, use_size, use_type);
23591  return result;
23592  }
23593 
23597  const bool use_size = false, const bool use_type = false)
23598  {
23599  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
23600  }
23601 
23605  const bool use_size = false, const bool use_type = false)
23606  {
23607  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23608  }
23609 
23612  static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
23613  const bool use_size = false,
23614  const bool use_type = false)
23615  {
23616  std::vector<std::uint8_t> result;
23617  to_bjdata(j, result, use_size, use_type);
23618  return result;
23619  }
23620 
23624  const bool use_size = false, const bool use_type = false)
23625  {
23626  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
23627  }
23628 
23632  const bool use_size = false, const bool use_type = false)
23633  {
23634  binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
23635  }
23636 
23639  static std::vector<std::uint8_t> to_bson(const basic_json& j)
23640  {
23641  std::vector<std::uint8_t> result;
23642  to_bson(j, result);
23643  return result;
23644  }
23645 
23649  {
23650  binary_writer<std::uint8_t>(o).write_bson(j);
23651  }
23652 
23656  {
23657  binary_writer<char>(o).write_bson(j);
23658  }
23659 
23662  template<typename InputType>
23664  static basic_json from_cbor(InputType&& i,
23665  const bool strict = true,
23666  const bool allow_exceptions = true,
23667  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23668  {
23669  basic_json result;
23670  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23671  auto ia = detail::input_adapter(std::forward<InputType>(i));
23672  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23673  return res ? result : basic_json(value_t::discarded);
23674  }
23675 
23678  template<typename IteratorType>
23680  static basic_json from_cbor(IteratorType first, IteratorType last,
23681  const bool strict = true,
23682  const bool allow_exceptions = true,
23683  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23684  {
23685  basic_json result;
23686  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23687  auto ia = detail::input_adapter(std::move(first), std::move(last));
23688  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23689  return res ? result : basic_json(value_t::discarded);
23690  }
23691 
23692  template<typename T>
23694  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23695  static basic_json from_cbor(const T* ptr, std::size_t len,
23696  const bool strict = true,
23697  const bool allow_exceptions = true,
23698  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23699  {
23700  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23701  }
23702 
23704  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23705  static basic_json from_cbor(detail::span_input_adapter&& i,
23706  const bool strict = true,
23707  const bool allow_exceptions = true,
23708  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23709  {
23710  basic_json result;
23711  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23712  auto ia = i.get();
23713  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23714  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23715  return res ? result : basic_json(value_t::discarded);
23716  }
23717 
23720  template<typename InputType>
23722  static basic_json from_msgpack(InputType&& i,
23723  const bool strict = true,
23724  const bool allow_exceptions = true)
23725  {
23726  basic_json result;
23727  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23728  auto ia = detail::input_adapter(std::forward<InputType>(i));
23729  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23730  return res ? result : basic_json(value_t::discarded);
23731  }
23732 
23735  template<typename IteratorType>
23737  static basic_json from_msgpack(IteratorType first, IteratorType last,
23738  const bool strict = true,
23739  const bool allow_exceptions = true)
23740  {
23741  basic_json result;
23742  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23743  auto ia = detail::input_adapter(std::move(first), std::move(last));
23744  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23745  return res ? result : basic_json(value_t::discarded);
23746  }
23747 
23748  template<typename T>
23750  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23751  static basic_json from_msgpack(const T* ptr, std::size_t len,
23752  const bool strict = true,
23753  const bool allow_exceptions = true)
23754  {
23755  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
23756  }
23757 
23759  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23760  static basic_json from_msgpack(detail::span_input_adapter&& i,
23761  const bool strict = true,
23762  const bool allow_exceptions = true)
23763  {
23764  basic_json result;
23765  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23766  auto ia = i.get();
23767  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23768  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23769  return res ? result : basic_json(value_t::discarded);
23770  }
23771 
23774  template<typename InputType>
23776  static basic_json from_ubjson(InputType&& i,
23777  const bool strict = true,
23778  const bool allow_exceptions = true)
23779  {
23780  basic_json result;
23781  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23782  auto ia = detail::input_adapter(std::forward<InputType>(i));
23783  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23784  return res ? result : basic_json(value_t::discarded);
23785  }
23786 
23789  template<typename IteratorType>
23791  static basic_json from_ubjson(IteratorType first, IteratorType last,
23792  const bool strict = true,
23793  const bool allow_exceptions = true)
23794  {
23795  basic_json result;
23796  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23797  auto ia = detail::input_adapter(std::move(first), std::move(last));
23798  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23799  return res ? result : basic_json(value_t::discarded);
23800  }
23801 
23802  template<typename T>
23804  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23805  static basic_json from_ubjson(const T* ptr, std::size_t len,
23806  const bool strict = true,
23807  const bool allow_exceptions = true)
23808  {
23809  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
23810  }
23811 
23813  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23814  static basic_json from_ubjson(detail::span_input_adapter&& i,
23815  const bool strict = true,
23816  const bool allow_exceptions = true)
23817  {
23818  basic_json result;
23819  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23820  auto ia = i.get();
23821  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23822  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23823  return res ? result : basic_json(value_t::discarded);
23824  }
23825 
23828  template<typename InputType>
23830  static basic_json from_bjdata(InputType&& i,
23831  const bool strict = true,
23832  const bool allow_exceptions = true)
23833  {
23834  basic_json result;
23835  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23836  auto ia = detail::input_adapter(std::forward<InputType>(i));
23837  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23838  return res ? result : basic_json(value_t::discarded);
23839  }
23840 
23843  template<typename IteratorType>
23845  static basic_json from_bjdata(IteratorType first, IteratorType last,
23846  const bool strict = true,
23847  const bool allow_exceptions = true)
23848  {
23849  basic_json result;
23850  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23851  auto ia = detail::input_adapter(std::move(first), std::move(last));
23852  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23853  return res ? result : basic_json(value_t::discarded);
23854  }
23855 
23858  template<typename InputType>
23860  static basic_json from_bson(InputType&& i,
23861  const bool strict = true,
23862  const bool allow_exceptions = true)
23863  {
23864  basic_json result;
23865  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23866  auto ia = detail::input_adapter(std::forward<InputType>(i));
23867  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23868  return res ? result : basic_json(value_t::discarded);
23869  }
23870 
23873  template<typename IteratorType>
23875  static basic_json from_bson(IteratorType first, IteratorType last,
23876  const bool strict = true,
23877  const bool allow_exceptions = true)
23878  {
23879  basic_json result;
23880  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23881  auto ia = detail::input_adapter(std::move(first), std::move(last));
23882  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23883  return res ? result : basic_json(value_t::discarded);
23884  }
23885 
23886  template<typename T>
23888  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23889  static basic_json from_bson(const T* ptr, std::size_t len,
23890  const bool strict = true,
23891  const bool allow_exceptions = true)
23892  {
23893  return from_bson(ptr, ptr + len, strict, allow_exceptions);
23894  }
23895 
23897  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23898  static basic_json from_bson(detail::span_input_adapter&& i,
23899  const bool strict = true,
23900  const bool allow_exceptions = true)
23901  {
23902  basic_json result;
23903  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23904  auto ia = i.get();
23905  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23906  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23907  return res ? result : basic_json(value_t::discarded);
23908  }
23910 
23912  // JSON Pointer support //
23914 
23917 
23921  {
23922  return ptr.get_unchecked(this);
23923  }
23924 
23926  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23927  reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23928  {
23929  return ptr.get_unchecked(this);
23930  }
23931 
23935  {
23936  return ptr.get_unchecked(this);
23937  }
23938 
23940  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23941  const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23942  {
23943  return ptr.get_unchecked(this);
23944  }
23945 
23948  reference at(const json_pointer& ptr)
23949  {
23950  return ptr.get_checked(this);
23951  }
23952 
23954  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23955  reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23956  {
23957  return ptr.get_checked(this);
23958  }
23959 
23962  const_reference at(const json_pointer& ptr) const
23963  {
23964  return ptr.get_checked(this);
23965  }
23966 
23968  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23969  const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23970  {
23971  return ptr.get_checked(this);
23972  }
23973 
23976  basic_json flatten() const
23977  {
23978  basic_json result(value_t::object);
23979  json_pointer::flatten("", *this, result);
23980  return result;
23981  }
23982 
23985  basic_json unflatten() const
23986  {
23987  return json_pointer::unflatten(*this);
23988  }
23989 
23991 
23993  // JSON Patch functions //
23995 
23998 
24001  void patch_inplace(const basic_json& json_patch)
24002  {
24003  basic_json& result = *this;
24004  // the valid JSON Patch operations
24005  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24006 
24007  const auto get_op = [](const std::string & op)
24008  {
24009  if (op == "add")
24010  {
24011  return patch_operations::add;
24012  }
24013  if (op == "remove")
24014  {
24015  return patch_operations::remove;
24016  }
24017  if (op == "replace")
24018  {
24019  return patch_operations::replace;
24020  }
24021  if (op == "move")
24022  {
24023  return patch_operations::move;
24024  }
24025  if (op == "copy")
24026  {
24027  return patch_operations::copy;
24028  }
24029  if (op == "test")
24030  {
24031  return patch_operations::test;
24032  }
24033 
24034  return patch_operations::invalid;
24035  };
24036 
24037  // wrapper for "add" operation; add value at ptr
24038  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
24039  {
24040  // adding to the root of the target document means replacing it
24041  if (ptr.empty())
24042  {
24043  result = val;
24044  return;
24045  }
24046 
24047  // make sure the top element of the pointer exists
24048  json_pointer const top_pointer = ptr.top();
24049  if (top_pointer != ptr)
24050  {
24051  result.at(top_pointer);
24052  }
24053 
24054  // get reference to parent of JSON pointer ptr
24055  const auto last_path = ptr.back();
24056  ptr.pop_back();
24057  // parent must exist when performing patch add per RFC6902 specs
24058  basic_json& parent = result.at(ptr);
24059 
24060  switch (parent.m_data.m_type)
24061  {
24062  case value_t::null:
24063  case value_t::object:
24064  {
24065  // use operator[] to add value
24066  parent[last_path] = val;
24067  break;
24068  }
24069 
24070  case value_t::array:
24071  {
24072  if (last_path == "-")
24073  {
24074  // special case: append to back
24075  parent.push_back(val);
24076  }
24077  else
24078  {
24079  const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
24080  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24081  {
24082  // avoid undefined behavior
24083  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
24084  }
24085 
24086  // default case: insert add offset
24087  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24088  }
24089  break;
24090  }
24091 
24092  // if there exists a parent it cannot be primitive
24093  case value_t::string: // LCOV_EXCL_LINE
24094  case value_t::boolean: // LCOV_EXCL_LINE
24095  case value_t::number_integer: // LCOV_EXCL_LINE
24096  case value_t::number_unsigned: // LCOV_EXCL_LINE
24097  case value_t::number_float: // LCOV_EXCL_LINE
24098  case value_t::binary: // LCOV_EXCL_LINE
24099  case value_t::discarded: // LCOV_EXCL_LINE
24100  default: // LCOV_EXCL_LINE
24101  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
24102  }
24103  };
24104 
24105  // wrapper for "remove" operation; remove value at ptr
24106  const auto operation_remove = [this, & result](json_pointer & ptr)
24107  {
24108  // get reference to parent of JSON pointer ptr
24109  const auto last_path = ptr.back();
24110  ptr.pop_back();
24111  basic_json& parent = result.at(ptr);
24112 
24113  // remove child
24114  if (parent.is_object())
24115  {
24116  // perform range check
24117  auto it = parent.find(last_path);
24118  if (JSON_HEDLEY_LIKELY(it != parent.end()))
24119  {
24120  parent.erase(it);
24121  }
24122  else
24123  {
24124  JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
24125  }
24126  }
24127  else if (parent.is_array())
24128  {
24129  // note erase performs range check
24130  parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
24131  }
24132  };
24133 
24134  // type check: top level value must be an array
24135  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24136  {
24137  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
24138  }
24139 
24140  // iterate and apply the operations
24141  for (const auto& val : json_patch)
24142  {
24143  // wrapper to get a value for an operation
24144  const auto get_value = [&val](const std::string & op,
24145  const std::string & member,
24146  bool string_type) -> basic_json &
24147  {
24148  // find value
24149  auto it = val.m_data.m_value.object->find(member);
24150 
24151  // context-sensitive error message
24152  const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
24153 
24154  // check if desired value is present
24155  if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))
24156  {
24157  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24158  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
24159  }
24160 
24161  // check if result is of type string
24162  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24163  {
24164  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24165  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
24166  }
24167 
24168  // no error: return value
24169  return it->second;
24170  };
24171 
24172  // type check: every element of the array must be an object
24173  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24174  {
24175  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
24176  }
24177 
24178  // collect mandatory members
24179  const auto op = get_value("op", "op", true).template get<std::string>();
24180  const auto path = get_value(op, "path", true).template get<std::string>();
24181  json_pointer ptr(path);
24182 
24183  switch (get_op(op))
24184  {
24185  case patch_operations::add:
24186  {
24187  operation_add(ptr, get_value("add", "value", false));
24188  break;
24189  }
24190 
24191  case patch_operations::remove:
24192  {
24193  operation_remove(ptr);
24194  break;
24195  }
24196 
24197  case patch_operations::replace:
24198  {
24199  // the "path" location must exist - use at()
24200  result.at(ptr) = get_value("replace", "value", false);
24201  break;
24202  }
24203 
24204  case patch_operations::move:
24205  {
24206  const auto from_path = get_value("move", "from", true).template get<std::string>();
24207  json_pointer from_ptr(from_path);
24208 
24209  // the "from" location must exist - use at()
24210  basic_json const v = result.at(from_ptr);
24211 
24212  // The move operation is functionally identical to a
24213  // "remove" operation on the "from" location, followed
24214  // immediately by an "add" operation at the target
24215  // location with the value that was just removed.
24216  operation_remove(from_ptr);
24217  operation_add(ptr, v);
24218  break;
24219  }
24220 
24221  case patch_operations::copy:
24222  {
24223  const auto from_path = get_value("copy", "from", true).template get<std::string>();
24224  const json_pointer from_ptr(from_path);
24225 
24226  // the "from" location must exist - use at()
24227  basic_json const v = result.at(from_ptr);
24228 
24229  // The copy is functionally identical to an "add"
24230  // operation at the target location using the value
24231  // specified in the "from" member.
24232  operation_add(ptr, v);
24233  break;
24234  }
24235 
24236  case patch_operations::test:
24237  {
24238  bool success = false;
24239  JSON_TRY
24240  {
24241  // check if "value" matches the one at "path"
24242  // the "path" location must exist - use at()
24243  success = (result.at(ptr) == get_value("test", "value", false));
24244  }
24245  JSON_INTERNAL_CATCH (out_of_range&)
24246  {
24247  // ignore out of range errors: success remains false
24248  }
24249 
24250  // throw an exception if test fails
24251  if (JSON_HEDLEY_UNLIKELY(!success))
24252  {
24253  JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
24254  }
24255 
24256  break;
24257  }
24258 
24259  case patch_operations::invalid:
24260  default:
24261  {
24262  // op must be "add", "remove", "replace", "move", "copy", or
24263  // "test"
24264  JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
24265  }
24266  }
24267  }
24268  }
24269 
24272  basic_json patch(const basic_json& json_patch) const
24273  {
24274  basic_json result = *this;
24275  result.patch_inplace(json_patch);
24276  return result;
24277  }
24278 
24282  static basic_json diff(const basic_json& source, const basic_json& target,
24283  const std::string& path = "")
24284  {
24285  // the patch
24286  basic_json result(value_t::array);
24287 
24288  // if the values are the same, return empty patch
24289  if (source == target)
24290  {
24291  return result;
24292  }
24293 
24294  if (source.type() != target.type())
24295  {
24296  // different types: replace value
24297  result.push_back(
24298  {
24299  {"op", "replace"}, {"path", path}, {"value", target}
24300  });
24301  return result;
24302  }
24303 
24304  switch (source.type())
24305  {
24306  case value_t::array:
24307  {
24308  // first pass: traverse common elements
24309  std::size_t i = 0;
24310  while (i < source.size() && i < target.size())
24311  {
24312  // recursive call to compare array values at index i
24313  auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
24314  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24315  ++i;
24316  }
24317 
24318  // We now reached the end of at least one array
24319  // in a second pass, traverse the remaining elements
24320 
24321  // remove my remaining elements
24322  const auto end_index = static_cast<difference_type>(result.size());
24323  while (i < source.size())
24324  {
24325  // add operations in reverse order to avoid invalid
24326  // indices
24327  result.insert(result.begin() + end_index, object(
24328  {
24329  {"op", "remove"},
24330  {"path", detail::concat(path, '/', std::to_string(i))}
24331  }));
24332  ++i;
24333  }
24334 
24335  // add other remaining elements
24336  while (i < target.size())
24337  {
24338  result.push_back(
24339  {
24340  {"op", "add"},
24341  {"path", detail::concat(path, "/-")},
24342  {"value", target[i]}
24343  });
24344  ++i;
24345  }
24346 
24347  break;
24348  }
24349 
24350  case value_t::object:
24351  {
24352  // first pass: traverse this object's elements
24353  for (auto it = source.cbegin(); it != source.cend(); ++it)
24354  {
24355  // escape the key name to be used in a JSON patch
24356  const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24357 
24358  if (target.find(it.key()) != target.end())
24359  {
24360  // recursive call to compare object values at key it
24361  auto temp_diff = diff(it.value(), target[it.key()], path_key);
24362  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24363  }
24364  else
24365  {
24366  // found a key that is not in o -> remove it
24367  result.push_back(object(
24368  {
24369  {"op", "remove"}, {"path", path_key}
24370  }));
24371  }
24372  }
24373 
24374  // second pass: traverse other object's elements
24375  for (auto it = target.cbegin(); it != target.cend(); ++it)
24376  {
24377  if (source.find(it.key()) == source.end())
24378  {
24379  // found a key that is not in this -> add it
24380  const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24381  result.push_back(
24382  {
24383  {"op", "add"}, {"path", path_key},
24384  {"value", it.value()}
24385  });
24386  }
24387  }
24388 
24389  break;
24390  }
24391 
24392  case value_t::null:
24393  case value_t::string:
24394  case value_t::boolean:
24395  case value_t::number_integer:
24396  case value_t::number_unsigned:
24397  case value_t::number_float:
24398  case value_t::binary:
24399  case value_t::discarded:
24400  default:
24401  {
24402  // both primitive type: replace value
24403  result.push_back(
24404  {
24405  {"op", "replace"}, {"path", path}, {"value", target}
24406  });
24407  break;
24408  }
24409  }
24410 
24411  return result;
24412  }
24414 
24416  // JSON Merge Patch functions //
24418 
24421 
24424  void merge_patch(const basic_json& apply_patch)
24425  {
24426  if (apply_patch.is_object())
24427  {
24428  if (!is_object())
24429  {
24430  *this = object();
24431  }
24432  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24433  {
24434  if (it.value().is_null())
24435  {
24436  erase(it.key());
24437  }
24438  else
24439  {
24440  operator[](it.key()).merge_patch(it.value());
24441  }
24442  }
24443  }
24444  else
24445  {
24446  *this = apply_patch;
24447  }
24448  }
24449 
24451 };
24452 
24456 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
24457 {
24458  return j.dump();
24459 }
24460 
24461 inline namespace literals
24462 {
24463 inline namespace json_literals
24464 {
24465 
24469 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
24470  inline nlohmann::json operator ""_json(const char* s, std::size_t n)
24471 #else
24472  inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24473 #endif
24474 {
24475  return nlohmann::json::parse(s, s + n);
24476 }
24477 
24481 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
24482  inline nlohmann::json::json_pointer operator ""_json_pointer(const char* s, std::size_t n)
24483 #else
24484  inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
24485 #endif
24486 {
24487  return nlohmann::json::json_pointer(std::string(s, n));
24488 }
24489 
24490 } // namespace json_literals
24491 } // namespace literals
24493 
24495 // nonmember support //
24497 
24498 namespace std // NOLINT(cert-dcl58-cpp)
24499 {
24500 
24504 struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp)
24505 {
24506  std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
24507  {
24508  return nlohmann::detail::hash(j);
24509  }
24510 };
24511 
24512 // specialization for std::less<value_t>
24513 template<>
24514 struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
24515 {
24521  ::nlohmann::detail::value_t rhs) const noexcept
24522  {
24523 #if JSON_HAS_THREE_WAY_COMPARISON
24524  return std::is_lt(lhs <=> rhs); // *NOPAD*
24525 #else
24527 #endif
24528  }
24529 };
24530 
24531 // C++20 prohibit function specialization in the std namespace.
24532 #ifndef JSON_HAS_CPP_20
24533 
24537 inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp)
24538  is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
24540 {
24541  j1.swap(j2);
24542 }
24543 
24544 #endif
24545 
24546 } // namespace std
24547 
24548 #if JSON_USE_GLOBAL_UDLS
24549  #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
24550  using nlohmann::literals::json_literals::operator ""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24551  using nlohmann::literals::json_literals::operator ""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24552  #else
24553  using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24554  using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24555  #endif
24556 #endif
24557 
24558 // #include <nlohmann/detail/macro_unscope.hpp>
24559 // __ _____ _____ _____
24560 // __| | __| | | | JSON for Modern C++
24561 // | | |__ | | | | | | version 3.11.3
24562 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
24563 //
24564 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
24565 // SPDX-License-Identifier: MIT
24566 
24567 
24568 
24569 // restore clang diagnostic settings
24570 #if defined(__clang__)
24571  #pragma clang diagnostic pop
24572 #endif
24573 
24574 // clean up
24575 #undef JSON_ASSERT
24576 #undef JSON_INTERNAL_CATCH
24577 #undef JSON_THROW
24578 #undef JSON_PRIVATE_UNLESS_TESTED
24579 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24580 #undef NLOHMANN_BASIC_JSON_TPL
24581 #undef JSON_EXPLICIT
24582 #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
24583 #undef JSON_INLINE_VARIABLE
24584 #undef JSON_NO_UNIQUE_ADDRESS
24585 #undef JSON_DISABLE_ENUM_SERIALIZATION
24586 #undef JSON_USE_GLOBAL_UDLS
24587 
24588 #ifndef JSON_TEST_KEEP_MACROS
24589  #undef JSON_CATCH
24590  #undef JSON_TRY
24591  #undef JSON_HAS_CPP_11
24592  #undef JSON_HAS_CPP_14
24593  #undef JSON_HAS_CPP_17
24594  #undef JSON_HAS_CPP_20
24595  #undef JSON_HAS_FILESYSTEM
24596  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
24597  #undef JSON_HAS_THREE_WAY_COMPARISON
24598  #undef JSON_HAS_RANGES
24599  #undef JSON_HAS_STATIC_RTTI
24600  #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
24601 #endif
24602 
24603 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
24604 // __ _____ _____ _____
24605 // __| | __| | | | JSON for Modern C++
24606 // | | |__ | | | | | | version 3.11.3
24607 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
24608 //
24609 // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
24610 // SPDX-License-Identifier: MIT
24611 
24612 
24613 
24614 #undef JSON_HEDLEY_ALWAYS_INLINE
24615 #undef JSON_HEDLEY_ARM_VERSION
24616 #undef JSON_HEDLEY_ARM_VERSION_CHECK
24617 #undef JSON_HEDLEY_ARRAY_PARAM
24618 #undef JSON_HEDLEY_ASSUME
24619 #undef JSON_HEDLEY_BEGIN_C_DECLS
24620 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24621 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24622 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24623 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24624 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24625 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
24626 #undef JSON_HEDLEY_CLANG_HAS_WARNING
24627 #undef JSON_HEDLEY_COMPCERT_VERSION
24628 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24629 #undef JSON_HEDLEY_CONCAT
24630 #undef JSON_HEDLEY_CONCAT3
24631 #undef JSON_HEDLEY_CONCAT3_EX
24632 #undef JSON_HEDLEY_CONCAT_EX
24633 #undef JSON_HEDLEY_CONST
24634 #undef JSON_HEDLEY_CONSTEXPR
24635 #undef JSON_HEDLEY_CONST_CAST
24636 #undef JSON_HEDLEY_CPP_CAST
24637 #undef JSON_HEDLEY_CRAY_VERSION
24638 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
24639 #undef JSON_HEDLEY_C_DECL
24640 #undef JSON_HEDLEY_DEPRECATED
24641 #undef JSON_HEDLEY_DEPRECATED_FOR
24642 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24643 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24644 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24645 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24646 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24647 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
24648 #undef JSON_HEDLEY_DIAGNOSTIC_POP
24649 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24650 #undef JSON_HEDLEY_DMC_VERSION
24651 #undef JSON_HEDLEY_DMC_VERSION_CHECK
24652 #undef JSON_HEDLEY_EMPTY_BASES
24653 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24654 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24655 #undef JSON_HEDLEY_END_C_DECLS
24656 #undef JSON_HEDLEY_FLAGS
24657 #undef JSON_HEDLEY_FLAGS_CAST
24658 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24659 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
24660 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24661 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24662 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
24663 #undef JSON_HEDLEY_GCC_HAS_FEATURE
24664 #undef JSON_HEDLEY_GCC_HAS_WARNING
24665 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24666 #undef JSON_HEDLEY_GCC_VERSION
24667 #undef JSON_HEDLEY_GCC_VERSION_CHECK
24668 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24669 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24670 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24671 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24672 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24673 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
24674 #undef JSON_HEDLEY_GNUC_HAS_WARNING
24675 #undef JSON_HEDLEY_GNUC_VERSION
24676 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
24677 #undef JSON_HEDLEY_HAS_ATTRIBUTE
24678 #undef JSON_HEDLEY_HAS_BUILTIN
24679 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24680 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24681 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24682 #undef JSON_HEDLEY_HAS_EXTENSION
24683 #undef JSON_HEDLEY_HAS_FEATURE
24684 #undef JSON_HEDLEY_HAS_WARNING
24685 #undef JSON_HEDLEY_IAR_VERSION
24686 #undef JSON_HEDLEY_IAR_VERSION_CHECK
24687 #undef JSON_HEDLEY_IBM_VERSION
24688 #undef JSON_HEDLEY_IBM_VERSION_CHECK
24689 #undef JSON_HEDLEY_IMPORT
24690 #undef JSON_HEDLEY_INLINE
24691 #undef JSON_HEDLEY_INTEL_CL_VERSION
24692 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
24693 #undef JSON_HEDLEY_INTEL_VERSION
24694 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
24695 #undef JSON_HEDLEY_IS_CONSTANT
24696 #undef JSON_HEDLEY_IS_CONSTEXPR_
24697 #undef JSON_HEDLEY_LIKELY
24698 #undef JSON_HEDLEY_MALLOC
24699 #undef JSON_HEDLEY_MCST_LCC_VERSION
24700 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
24701 #undef JSON_HEDLEY_MESSAGE
24702 #undef JSON_HEDLEY_MSVC_VERSION
24703 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
24704 #undef JSON_HEDLEY_NEVER_INLINE
24705 #undef JSON_HEDLEY_NON_NULL
24706 #undef JSON_HEDLEY_NO_ESCAPE
24707 #undef JSON_HEDLEY_NO_RETURN
24708 #undef JSON_HEDLEY_NO_THROW
24709 #undef JSON_HEDLEY_NULL
24710 #undef JSON_HEDLEY_PELLES_VERSION
24711 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
24712 #undef JSON_HEDLEY_PGI_VERSION
24713 #undef JSON_HEDLEY_PGI_VERSION_CHECK
24714 #undef JSON_HEDLEY_PREDICT
24715 #undef JSON_HEDLEY_PRINTF_FORMAT
24716 #undef JSON_HEDLEY_PRIVATE
24717 #undef JSON_HEDLEY_PUBLIC
24718 #undef JSON_HEDLEY_PURE
24719 #undef JSON_HEDLEY_REINTERPRET_CAST
24720 #undef JSON_HEDLEY_REQUIRE
24721 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24722 #undef JSON_HEDLEY_REQUIRE_MSG
24723 #undef JSON_HEDLEY_RESTRICT
24724 #undef JSON_HEDLEY_RETURNS_NON_NULL
24725 #undef JSON_HEDLEY_SENTINEL
24726 #undef JSON_HEDLEY_STATIC_ASSERT
24727 #undef JSON_HEDLEY_STATIC_CAST
24728 #undef JSON_HEDLEY_STRINGIFY
24729 #undef JSON_HEDLEY_STRINGIFY_EX
24730 #undef JSON_HEDLEY_SUNPRO_VERSION
24731 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24732 #undef JSON_HEDLEY_TINYC_VERSION
24733 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
24734 #undef JSON_HEDLEY_TI_ARMCL_VERSION
24735 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24736 #undef JSON_HEDLEY_TI_CL2000_VERSION
24737 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24738 #undef JSON_HEDLEY_TI_CL430_VERSION
24739 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24740 #undef JSON_HEDLEY_TI_CL6X_VERSION
24741 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24742 #undef JSON_HEDLEY_TI_CL7X_VERSION
24743 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24744 #undef JSON_HEDLEY_TI_CLPRU_VERSION
24745 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24746 #undef JSON_HEDLEY_TI_VERSION
24747 #undef JSON_HEDLEY_TI_VERSION_CHECK
24748 #undef JSON_HEDLEY_UNAVAILABLE
24749 #undef JSON_HEDLEY_UNLIKELY
24750 #undef JSON_HEDLEY_UNPREDICTABLE
24751 #undef JSON_HEDLEY_UNREACHABLE
24752 #undef JSON_HEDLEY_UNREACHABLE_RETURN
24753 #undef JSON_HEDLEY_VERSION
24754 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24755 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
24756 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
24757 #undef JSON_HEDLEY_VERSION_ENCODE
24758 #undef JSON_HEDLEY_WARNING
24759 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
24760 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
24761 #undef JSON_HEDLEY_FALL_THROUGH
24762 
24763 
24764 
24765 #endif // INCLUDE_NLOHMANN_JSON_HPP_
detail::serializer::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:18064
byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5907
detail::iteration_proxy_value::iterator_category
std::input_iterator_tag iterator_category
Definition: json.hpp:5192
detail::binary_reader::get_bson_binary
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:9389
basic_json::to_ubjson
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23596
detail::primitive_iterator_t::is_begin
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:12762
detail::json_sax_acceptor::start_object
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7333
detail::iter_impl::set_end
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:13109
cx::size
constexpr auto size(const C &c) -> decltype(c.size())
Definition: wildcards.hpp:636
detail::position_t
struct to capture the start position of the current token
Definition: json.hpp:3035
detail::value_t::discarded
@ discarded
discarded by the parser callback function
basic_json::at
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:21324
lexyd::bits
constexpr auto bits(Bits...)
Matches the specific bit pattern.
Definition: bits.hpp:136
basic_json::get_impl
ValueType get_impl(detail::priority_tag< 0 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition: json.hpp:20908
JSON_INLINE_VARIABLE
#define JSON_INLINE_VARIABLE
Definition: json.hpp:2499
json_sax::operator=
json_sax & operator=(const json_sax &)=default
lexyd::position
constexpr auto position
Produces an iterator to the current reader position without parsing anything.
Definition: position.hpp:79
detail::json_reverse_iterator::operator--
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.hpp:13697
detail::char_traits< signed char >::char_type
signed char char_type
Definition: json.hpp:3635
detail::position_t::lines_read
std::size_t lines_read
the number of lines read
Definition: json.hpp:3042
detail::input_stream_adapter::char_type
char char_type
Definition: json.hpp:6228
json_pointer::push_back
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13988
detail::iter_impl::iter_impl
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:13043
detail::dtoa_impl::get_cached_power_for_binary_exponent
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:17235
NLOHMANN_BASIC_JSON_TPL_DECLARATION
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2596
detail::wide_string_input_adapter::fill_buffer
void fill_buffer()
Definition: json.hpp:6468
detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:5542
basic_json::destroy
void destroy(value_t t)
Definition: json.hpp:19856
detail::from_json_tuple_impl_base
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:5004
JSON_HEDLEY_DIAGNOSTIC_POP
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:1103
detail::dtoa_impl::append_exponent
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:17835
detail::binary_reader::exception_message
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition: json.hpp:12058
detail::void_t
typename make_void< Ts... >::type void_t
Definition: json.hpp:255
basic_json::operator>>
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:23445
BT::enable_if
typename std::enable_if< Predicate::value >::type * enable_if
Definition: basic_types.h:305
detail::binary_writer::write_bson_binary
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition: json.hpp:16188
detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:5532
detail::get_arithmetic_value
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:4678
detail::iteration_proxy_value::iteration_proxy_value
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:5209
detail::value_in_range_of_impl1< OfType, T, true >::test
static constexpr bool test(T)
Definition: json.hpp:4143
basic_json::basic_json
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:20151
detail::iteration_proxy_value::operator++
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:5234
detail::dtoa_impl::cached_power::e
int e
Definition: json.hpp:17224
detail::parser::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:12231
detail::external_constructor< value_t::object >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:5602
basic_json::get_ref
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:21147
detail::json_sax_dom_callback_parser::number_float
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:7032
detail::number_integer_function_t
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:9043
lexyd::token
constexpr auto token(Rule)
Turns the arbitrary rule into a token by matching it without producing any values.
Definition: dsl/token.hpp:214
detail::type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:4540
detail::has_to_json< BasicJsonType, T, enable_if_t< !is_basic_json< T >::value > >::serializer
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3572
detail::input_format_t
input_format_t
the supported input formats
Definition: json.hpp:6176
detail::file_input_adapter
Definition: json.hpp:6187
detail::lexer_base::token_type
token_type
token types for the parser
Definition: json.hpp:7410
detail::json_sax_dom_parser::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:6805
json_sax::json_sax
json_sax()=default
detail::binary_reader::json_sax_t
SAX json_sax_t
Definition: json.hpp:9218
ordered_map::size_type
typename Container::size_type size_type
Definition: json.hpp:19040
basic_json::basic_json
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value from compatible types
Definition: json.hpp:20137
detail::iter_impl::object_t
typename BasicJsonType::object_t object_t
Definition: json.hpp:12925
basic_json::count
size_type count(const typename object_t::key_type &key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:22013
detail::nonesuch
Definition: json.hpp:266
lexyd::bytes
constexpr auto bytes
Matches N arbitrary bytes.
Definition: byte.hpp:55
detail::primitive_iterator_t::set_begin
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:12750
detail::value_t::boolean
@ boolean
boolean value
basic_json::binary_reader
::nlohmann::detail::binary_reader< basic_json, InputType > binary_reader
Definition: json.hpp:19459
detail::binary_writer::write_bson
void write_bson(const BasicJsonType &j)
Definition: json.hpp:15099
detail::binary_writer::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:15082
basic_json::json_serializer
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:19470
basic_json::to_ubjson
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23604
detail::exception::diagnostics
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.hpp:4398
basic_json::difference_type
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:19517
basic_json::object_t
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:19639
detail::lexer::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:7485
detail::lexer::scan
token_type scan()
Definition: json.hpp:8881
basic_json::basic_json
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:20447
detail::output_vector_adapter
output adapter for byte vectors
Definition: json.hpp:14963
detail::lexer::ia
InputAdapterType ia
input adapter
Definition: json.hpp:8971
json_sax::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6671
detail::binary_reader::get_ubjson_array
bool get_ubjson_array()
Definition: json.hpp:11626
detail::iteration_proxy_value
Definition: json.hpp:5185
std::tuple_element< N, ::nlohmann::detail::iteration_proxy_value< IteratorType > >::type
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:5380
detail::binary_writer::get_cbor_float_prefix
static constexpr CharType get_cbor_float_prefix(double)
Definition: json.hpp:16334
detail::from_json_array_impl
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:4821
detail::binary_writer::calc_bson_entry_header_size
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition: json.hpp:15999
detail::lexer::next_byte_in_range
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:7589
detail::lexer::scan_comment
bool scan_comment()
scan a comment
Definition: json.hpp:8216
detail::index_sequence
integer_sequence< size_t, Ints... > index_sequence
Definition: json.hpp:3137
detail::is_constructible_array_type_impl< BasicJsonType, ConstructibleArrayType, enable_if_t< !std::is_same< ConstructibleArrayType, typename BasicJsonType::value_type >::value &&!is_compatible_string_type< BasicJsonType, ConstructibleArrayType >::value &&is_default_constructible< ConstructibleArrayType >::value &&(std::is_move_assignable< ConstructibleArrayType >::value||std::is_copy_assignable< ConstructibleArrayType >::value)&&is_detected< iterator_t, ConstructibleArrayType >::value &&is_iterator_traits< iterator_traits< detected_t< iterator_t, ConstructibleArrayType > > >::value &&is_detected< range_value_t, ConstructibleArrayType >::value &&!std::is_same< ConstructibleArrayType, detected_t< range_value_t, ConstructibleArrayType > >::value &&is_complete_type< detected_t< range_value_t, ConstructibleArrayType > >::value > >::value_type
range_value_t< ConstructibleArrayType > value_type
Definition: json.hpp:3890
detail::iter_impl::iterator_category
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:12941
basic_json::is_structured
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:20610
detail::dtoa_impl::diyfp::diyfp
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:16971
detail::json_sax_acceptor::binary
bool binary(binary_t &)
Definition: json.hpp:7328
detail::dtoa_impl::diyfp::normalize_to
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:17071
detail::negation
Definition: json.hpp:3667
basic_json::from_msgpack
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:23737
detail::binary_reader::sax_parse
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:9249
detail::json_sax_acceptor::start_array
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7348
basic_json::find
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.hpp:21999
detail::iteration_proxy_value::string_type
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:5193
basic_json::json_value
json_value(value_t t)
constructor for empty values of a given type
Definition: json.hpp:19755
detail::is_constructible_object_type
Definition: json.hpp:3812
basic_json::find
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.hpp:21967
basic_json::get_ref_impl
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.hpp:20825
detail::has_from_json
Definition: json.hpp:3527
detail::iterator_input_adapter::current
IteratorType current
Definition: json.hpp:6302
detail::json_sax_dom_parser::number_unsigned
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6842
basic_json::number_unsigned
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.hpp:19740
detail::json_reverse_iterator::reference
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:13675
detail::json_ref::json_ref
json_ref(value_type &&value)
Definition: json.hpp:14824
detail::iteration_proxy_value::empty_str
string_type empty_str
an empty string (to return a reference for primitive values)
Definition: json.hpp:5205
detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:5567
detail::iterator_types< It, void_t< typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category > >::iterator_category
typename It::iterator_category iterator_category
Definition: json.hpp:3284
magic_enum::char_type
string_view::value_type char_type
Definition: magic_enum.hpp:145
detail::is_sax
Definition: json.hpp:9085
detail::is_constructible
Definition: json.hpp:3692
detail::output_adapter
Definition: json.hpp:15036
json_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:6674
detail::lexer::scan_number
token_type scan_number()
scan a number literal
Definition: json.hpp:8341
detail::is_json_ref
Definition: json.hpp:3486
ordered_map::operator[]
const T & operator[](KeyType &&key) const
Definition: json.hpp:19105
detail::never_out_of_range
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:4078
detail::json_ref::json_ref
json_ref(const value_type &value)
Definition: json.hpp:14828
detail::iteration_proxy_value::iteration_proxy_value
iteration_proxy_value()=default
detail::to_json_fn
Definition: json.hpp:5799
JSON_HEDLEY_PURE
#define JSON_HEDLEY_PURE
Definition: json.hpp:1787
detail::value_in_range_of_impl2< OfType, T, true, true >::test
static constexpr bool test(T val)
Definition: json.hpp:4118
basic_json::json_value
json_value(const string_t &value)
constructor for strings
Definition: json.hpp:19827
detail::parser::accept
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:12321
byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5902
JSON_HEDLEY_UNLIKELY
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1714
lexy::forward
constexpr auto forward
A callback that just forwards an existing object.
Definition: forward.hpp:47
detail::char_traits< signed char >::to_int_type
static int_type to_int_type(char_type c) noexcept
Definition: json.hpp:3639
detail::iterator_input_adapter::iterator_input_adapter
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6285
detail::iterator_traits
Definition: json.hpp:3290
detail::json_sax_acceptor::number_unsigned
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:7313
detail::has_erase_with_key_type
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:4028
basic_json::operator[]
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.hpp:21421
detail::binary_writer::calc_bson_binary_size
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition: json.hpp:16161
detail::iter_impl::operator+
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:13501
detail::serializer::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:18063
detail::binary_reader::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:9216
basic_json::basic_json_t
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition: json.hpp:19426
basic_json::diff
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:24282
detail::impl::is_transparent
constexpr bool is_transparent()
Definition: json.hpp:4194
detail::wide_string_input_adapter::utf8_bytes_index
std::size_t utf8_bytes_index
index to the utf8_codes array for the next valid byte
Definition: json.hpp:6477
detail::iter_impl::operator++
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:13245
ordered_map::erase
size_type erase(KeyType &&key)
Definition: json.hpp:19187
basic_json::at
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:21286
json_pointer
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition: json.hpp:3416
detail::file_input_adapter::char_type
char char_type
Definition: json.hpp:6190
lexyd::n_digits
constexpr auto n_digits
Matches exactly N digits.
Definition: digit.hpp:630
detail::concat_length
std::size_t concat_length()
Definition: json.hpp:4234
basic_json::get_impl
ValueType get_impl(detail::priority_tag< 1 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition: json.hpp:20950
basic_json::set_parent
reference set_parent(reference j, std::size_t old_capacity=static_cast< std::size_t >(-1))
Definition: json.hpp:20055
basic_json::is_number_integer
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:20638
detail::binary_reader::get_ubjson_size_value
bool get_ubjson_size_value(std::size_t &result, bool &is_ndarray, char_int_type prefix=0)
Definition: json.hpp:11153
detail::iter_impl::BasicJsonType
friend BasicJsonType
Definition: json.hpp:12921
detail::char_traits< unsigned char >::int_type
uint64_t int_type
Definition: json.hpp:3612
basic_json::is_number_unsigned
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:20645
basic_json::binary_t
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:19667
detail::input_stream_adapter::get_character
std::char_traits< char >::int_type get_character()
Definition: json.hpp:6259
basic_json::at
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.hpp:21306
BT::Expected
nonstd::expected< T, std::string > Expected
Definition: basic_types.h:85
detail::binary_reader::get_cbor_string
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition: json.hpp:10055
detail::binary_reader::get_ubjson_ndarray_size
bool get_ubjson_ndarray_size(std::vector< size_t > &dim)
Definition: json.hpp:11088
detail::binary_writer::write_bson_element
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition: json.hpp:16251
detail::dtoa_impl::find_largest_pow10
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:17399
detail::iterator_types< It, void_t< typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category > >::reference
typename It::reference reference
Definition: json.hpp:3283
basic_json::swap
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:22841
detail::is_sax::exception_t
typename BasicJsonType::exception exception_t
Definition: json.hpp:9096
basic_json::data
data(const value_t v)
Definition: json.hpp:23499
detail::serializer::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:18062
detail::error_handler_t::replace
@ replace
replace invalid UTF-8 sequences with U+FFFD
detail::is_usable_as_basic_json_key_type
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:4016
basic_json::operator[]
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.hpp:21443
basic_json::get_impl_ptr
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.hpp:20724
detail::has_non_default_from_json< BasicJsonType, T, enable_if_t< !is_basic_json< T >::value > >::serializer
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3557
JSON_CATCH
#define JSON_CATCH(exception)
Definition: json.hpp:2525
detail::wide_string_input_adapter::char_type
char char_type
Definition: json.hpp:6442
JSON_INTERNAL_CATCH
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2526
detail::iter_impl::reference
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:12955
detail::binary_reader::get
char_int_type get()
get next character from the input
Definition: json.hpp:11896
basic_json::to_cbor
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23548
literals
Definition: json.hpp:24461
detail::is_range
Definition: json.hpp:3725
json_sax::key
virtual bool key(string_t &val)=0
an object key was read
byte_container_with_subtype::has_subtype
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5953
detail::primitive_iterator_t::operator+=
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:12821
basic_json::erase
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:21924
detail::json_sax_dom_callback_parser::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6986
basic_json::swap
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:22857
detail::external_constructor< value_t::string >::construct
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:5458
detail::iter_impl::array_t
typename BasicJsonType::array_t array_t
Definition: json.hpp:12926
basic_json::json_value
json_value(array_t &&value)
constructor for rvalue arrays
Definition: json.hpp:19842
basic_json::back
reference back()
access the last element
Definition: json.hpp:21710
basic_json::parser_callback_t
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:20104
detail::parse_event_t::array_start
@ array_start
the parser read [ and started to process a JSON array
detail::lexer::skip_whitespace
void skip_whitespace()
Definition: json.hpp:8872
basic_json::iter_impl
::nlohmann::detail::iter_impl< BasicJsonType > iter_impl
Definition: json.hpp:19450
byte_container_with_subtype
an internal type for a backed binary type
Definition: json.hpp:5890
detail::binary_writer::write_bson_double
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition: json.hpp:16036
detail::iteration_proxy_value::difference_type
std::ptrdiff_t difference_type
Definition: json.hpp:5188
detail::binary_writer::write_ubjson
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true, const bool use_bjdata=false)
Definition: json.hpp:15778
basic_json::from_bson
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:23860
detail::iterator_input_adapter_factory< IteratorType, enable_if_t< is_iterator_of_multibyte< IteratorType >::value > >::create
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6513
basic_json::get
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:21087
detail::value_t::number_unsigned
@ number_unsigned
number value (unsigned integer)
detail::json_reverse_iterator::base_iterator
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:13673
cx::cbegin
constexpr auto cbegin(const C &c) -> decltype(cx::begin(c))
Definition: wildcards.hpp:681
detail::json_sax_acceptor::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:7296
detail::cbor_tag_handler_t::ignore
@ ignore
ignore tags
detail::iterator_input_adapter::get_character
char_traits< char_type >::int_type get_character()
Definition: json.hpp:6289
detail::out_of_range
exception indicating access out of the defined range
Definition: json.hpp:4557
json_sax::start_object
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
detail::input_stream_adapter
Definition: json.hpp:6225
detail::is_iterator_traits
Definition: json.hpp:3707
detail::json_sax_dom_parser::string
bool string(string_t &val)
Definition: json.hpp:6854
detail::json_sax_dom_parser::boolean
bool boolean(bool val)
Definition: json.hpp:6830
detail::json_sax_dom_callback_parser::string
bool string(string_t &val)
Definition: json.hpp:7038
detail::index_sequence_for
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3199
zmq::operator>
bool operator>(const detail::socket_base &a, const detail::socket_base &b) ZMQ_NOTHROW
Definition: 3rdparty/cppzmq/zmq.hpp:2125
detail::exception::what
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:4375
detail::dtoa_impl::kAlpha
constexpr int kAlpha
Definition: json.hpp:17218
detail::iteration_proxy_value::operator=
iteration_proxy_value & operator=(iteration_proxy_value const &)=default
detail::iter_impl::operator>=
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:13435
detail::binary_writer::write_cbor
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:15128
detail::is_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9092
detail::binary_writer::write_bson_null
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition: json.hpp:16068
ordered_map::at
const T & at(const key_type &key) const
Definition: json.hpp:19138
magic_enum::detail::subtype
constexpr enum_subtype subtype(std::true_type) noexcept
Definition: magic_enum.hpp:777
detail::binary_reader::get_ignore_noop
char_int_type get_ignore_noop()
Definition: json.hpp:11905
detail::iteration_proxy::operator=
iteration_proxy & operator=(iteration_proxy const &)=default
JSON_EXPLICIT
#define JSON_EXPLICIT
Definition: json.hpp:2823
basic_json::set_parents
iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
Definition: json.hpp:20042
detail::binary_writer::get_msgpack_float_prefix
static constexpr CharType get_msgpack_float_prefix(float)
Definition: json.hpp:16343
basic_json::operator[]
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:21362
detail::binary_writer::get_cbor_float_prefix
static constexpr CharType get_cbor_float_prefix(float)
Definition: json.hpp:16329
detail::wide_string_input_adapter::base_adapter
BaseInputAdapter base_adapter
Definition: json.hpp:6465
detail::value_t::binary
@ binary
binary array (ordered collection of bytes)
basic_json::binary
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition: json.hpp:20285
basic_json::reverse_iterator
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:19534
basic_json::basic_json
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:20125
basic_json::json_value
json_value(const array_t &value)
constructor for arrays
Definition: json.hpp:19839
json_pointer::string_t
typename string_t_helper< RefStringType >::type string_t
Definition: json.hpp:13863
detail::binary_writer
serialization to CBOR and MessagePack values
Definition: json.hpp:15078
detail::dtoa_impl::diyfp::mul
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:16989
detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::difference_type
ptrdiff_t difference_type
Definition: json.hpp:3305
basic_json::string
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:19732
detail::json_sax_dom_parser::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6802
basic_json::get_impl_ptr
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:20796
detail::wide_string_input_adapter::utf8_bytes
std::array< std::char_traits< char >::int_type, 4 > utf8_bytes
a buffer for UTF-8 bytes
Definition: json.hpp:6474
detail::binary_writer::write_bson_object_entry
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition: json.hpp:16136
json_sax::end_array
virtual bool end_array()=0
the end of an array was read
detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::pointer
T * pointer
Definition: json.hpp:3306
basic_json::value
ReturnType value(const json_pointer &ptr, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21654
detail::output_stream_adapter::write_character
void write_character(CharType c) override
Definition: json.hpp:14995
basic_json::is_number
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:20631
detail::impl::is_c_string
constexpr bool is_c_string()
Definition: json.hpp:4166
detail::iter_impl::value
reference value() const
return the value of an iterator
Definition: json.hpp:13606
detail::lexer::get_number_unsigned
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8790
basic_json::is_discarded
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:20687
detail::parser::m_lexer
lexer_t m_lexer
the lexer
Definition: json.hpp:12681
detail::make_void
Definition: json.hpp:251
basic_json::type
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:20596
detail::value_t::number_float
@ number_float
number value (floating-point)
basic_json::push_back
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22455
detail::mapped_type_t
typename T::mapped_type mapped_type_t
Definition: json.hpp:3496
JSON_HEDLEY_DIAGNOSTIC_PUSH
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:1102
detail::input_format_t::ubjson
@ ubjson
json_pointer::string_t_helper
Definition: json.hpp:13850
cx::empty
constexpr auto empty(const C &c) -> decltype(c.empty())
Definition: wildcards.hpp:646
ordered_map::erase
size_type erase(const key_type &key)
Definition: json.hpp:19166
detail::primitive_iterator_t::operator-=
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:12827
basic_json::merge_patch
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:24424
detail::iterator_t
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3744
detail
detail namespace with internal helper functions
Definition: json.hpp:248
detail::external_constructor< value_t::string >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:5438
detail::binary_reader::get_number
bool get_number(const input_format_t format, NumberType &result)
Definition: json.hpp:11932
detail::json_sax_dom_parser::start_object
bool start_object(std::size_t len)
Definition: json.hpp:6866
basic_json::to_bjdata
static void to_bjdata(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23631
detail::iterator_input_adapter::char_type
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:6283
basic_json::json_reverse_iterator
::nlohmann::detail::json_reverse_iterator< Base > json_reverse_iterator
Definition: json.hpp:19453
ordered_map::find
const_iterator find(const key_type &key) const
Definition: json.hpp:19316
detail::external_constructor< value_t::binary >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:5480
detail::parser::exception_message
std::string exception_message(const token_type expected, const std::string &context)
Definition: json.hpp:12646
json_pointer::json_pointer
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.hpp:13867
zmq::operator>=
bool operator>=(const detail::socket_base &a, const detail::socket_base &b) ZMQ_NOTHROW
Definition: 3rdparty/cppzmq/zmq.hpp:2133
detail::null_function_t
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:9035
detail::primitive_iterator_t::get_value
constexpr difference_type get_value() const noexcept
Definition: json.hpp:12744
detail::primitive_iterator_t::operator-
constexpr friend difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12790
detail::is_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9093
basic_json::swap
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&//NOLINT(cppcoreguidelines-noexcept-swap, performance-noexcept-swap) std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22764
basic_json::meta
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:19550
basic_json
namespace for Niels Lohmann
Definition: json.hpp:3411
lexy::_detail::next
constexpr Iterator next(Iterator iter)
Definition: iterator.hpp:38
detail::binary_reader::get_msgpack_array
bool get_msgpack_array(const std::size_t len)
Definition: json.hpp:10915
detail::value_in_range_of_impl2< OfType, T, true, false >::test
static constexpr bool test(T val)
Definition: json.hpp:4098
detail::external_constructor< value_t::number_integer >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:5519
detail::json_sax_dom_callback_parser::root
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:7269
byte_container_with_subtype::operator==
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5925
json_sax
SAX interface.
Definition: json.hpp:6669
basic_json::from_bjdata
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:23830
basic_json::get_impl_ptr
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.hpp:20742
detail::detector< Default, void_t< Op< Args... > >, Op, Args... >::type
Op< Args... > type
Definition: json.hpp:290
detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::iterator_category
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3303
detail::dtoa_impl::grisu2_digit_gen
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:17494
std::less< ::nlohmann::detail::value_t >::operator()
bool operator()(::nlohmann::detail::value_t lhs, ::nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:24520
detail::iter_impl::operator=
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:13053
detail::is_compatible_string_type
Definition: json.hpp:3817
basic_json::binary
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:20296
detail::char_traits< unsigned char >::char_type
unsigned char char_type
Definition: json.hpp:3611
detail::parse_error::create
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:4482
basic_json::at
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23962
basic_json::get_binary
binary_t & get_binary()
get a binary value
Definition: json.hpp:21206
detail::external_constructor< value_t::number_unsigned >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:5506
detail::identity_tag
Definition: json.hpp:4615
detail::is_comparable
Definition: json.hpp:3977
byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5912
basic_json::operator[]
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:23920
basic_json::get_impl
constexpr auto get_impl(detail::priority_tag< 4 >) const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:21011
detail::escape
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2990
json_pointer::operator/
friend json_pointer operator/(const json_pointer &lhs, string_t token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:13936
detail::binary_reader::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9215
json_pointer::get_and_create
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition: json.hpp:14079
detail::binary_writer::write_bson_array
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition: json.hpp:16169
detail::is_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:9094
SafeAny::details::is_same
constexpr bool is_same()
Definition: convert_impl.hpp:58
magic_enum::detail::value
constexpr E value(std::size_t i) noexcept
Definition: magic_enum.hpp:664
detail::json_sax_dom_parser::number_float
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6848
ordered_map::operator[]
T & operator[](const key_type &key)
Definition: json.hpp:19086
json_pointer::back
const string_t & back() const
return last reference token
Definition: json.hpp:13976
detail::json_sax_dom_parser::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6806
detail::parse_error_function_t
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.hpp:9082
detail::dtoa_impl::diyfp::sub
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:16977
detail::integer_sequence::size
static constexpr std::size_t size() noexcept
Definition: json.hpp:3125
detail::iterator_types< It, void_t< typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category > >::pointer
typename It::pointer pointer
Definition: json.hpp:3282
detail::json_sax_dom_callback_parser::parse_error
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:7171
detail::binary_writer::get_ubjson_float_prefix
static constexpr CharType get_ubjson_float_prefix(double)
Definition: json.hpp:16649
detail::json_sax_dom_callback_parser::boolean
bool boolean(bool val)
Definition: json.hpp:7014
adl_serializer::from_json
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:5837
JSON_HEDLEY_WARN_UNUSED_RESULT
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1448
detail::lexer::reset
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: json.hpp:8692
json_pointer::push_back
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13995
detail::input_format_t::bson
@ bson
ordered_map::at
T & at(const key_type &key)
Definition: json.hpp:19110
detail::lexer::char_int_type
typename char_traits< char_type >::int_type char_int_type
Definition: json.hpp:7490
basic_json::get_impl_ptr
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.hpp:20736
basic_json::assert_invariant
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition: json.hpp:19984
detail::value_in_range_of_impl2< OfType, T, false, false >::test
static constexpr bool test(T val)
Definition: json.hpp:4088
detail::lexer::get_number_float
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8796
basic_json::is_number_float
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:20652
detail::actual_object_comparator_t
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.hpp:3596
detail::lexer_base::token_type_name
JSON_HEDLEY_RETURNS_NON_NULL static const JSON_HEDLEY_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:7434
detail::external_constructor
Definition: json.hpp:5419
detail::is_range::t_ref
typename std::add_lvalue_reference< T >::type t_ref
Definition: json.hpp:3728
basic_json::value
ValueType value(KeyType &&key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21579
detail::number_unsigned_function_t
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:9047
detail::iterator_input_adapter_factory
Definition: json.hpp:6483
detail::output_adapter_t
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:14959
detail::binary_reader::get_cbor_object
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:10284
ordered_map::find
iterator find(const key_type &key)
Definition: json.hpp:19290
detail::key_function_t
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:9067
detail::contiguous_bytes_input_adapter
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:6578
json_pointer::reference_tokens
result reference_tokens
Definition: json.hpp:14065
detail::is_sax_static_asserts::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9126
detail::wide_string_input_helper< BaseInputAdapter, 4 >::fill_buffer
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:6321
detail::number_float_function_t
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:9051
detail::lexer::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:7486
detail::lexer::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:7487
detail::binary_reader::char_type
typename InputAdapterType::char_type char_type
Definition: json.hpp:9219
detail::wide_string_input_helper< BaseInputAdapter, 2 >::fill_buffer
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:6379
detail::external_constructor< value_t::object >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:5612
cx::end
constexpr auto end(const C &c) -> decltype(c.end())
Definition: wildcards.hpp:686
detail::binary_reader::get_bson_string
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:9367
detail::dtoa_impl::boundaries::minus
diyfp minus
Definition: json.hpp:17085
detail::lexer::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:7488
basic_json::insert
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.hpp:22614
detail::iterator_input_adapter_factory::iterator_type
IteratorType iterator_type
Definition: json.hpp:6485
detail::is_compatible_integer_type_impl< RealIntegerType, CompatibleNumberIntegerType, enable_if_t< std::is_integral< RealIntegerType >::value &&std::is_integral< CompatibleNumberIntegerType >::value &&!std::is_same< bool, CompatibleNumberIntegerType >::value > >::CompatibleLimits
std::numeric_limits< CompatibleNumberIntegerType > CompatibleLimits
Definition: json.hpp:3919
basic_json::from_bson
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:23875
detail::json_sax_dom_parser::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6803
detail::binary_writer::write_number
void write_number(const NumberType n, const bool OutputIsLittleEndian=false)
Definition: json.hpp:16784
detail::external_constructor< value_t::binary >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:5471
detail::char_traits< unsigned char >::eof
static constexpr int_type eof() noexcept
Definition: json.hpp:3625
ordered_map::erase
iterator erase(iterator pos)
Definition: json.hpp:19206
detail::void
j template void())
Definition: json.hpp:4893
ordered_map::iterator
typename Container::iterator iterator
Definition: json.hpp:19038
detail::string_can_append_iter
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition: json.hpp:4281
detail::output_vector_adapter::output_vector_adapter
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:14966
detail::utility_internal::Gen
Definition: json.hpp:3161
basic_json::JSON_HEDLEY_DEPRECATED_FOR
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:23954
detail::utility_internal::Gen::type
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:3164
json_pointer::string_t_helper< NLOHMANN_BASIC_JSON_TPL >::type
StringType type
Definition: json.hpp:13858
basic_json::boolean_t
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:19651
detail::iterator_input_adapter_factory::adapter_type
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:6487
detail::binary_reader::get_msgpack_binary
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition: json.hpp:10804
json_sax::null
virtual bool null()=0
a null value was read
NLOHMANN_JSON_NAMESPACE_END
#define NLOHMANN_JSON_NAMESPACE_END
Definition: json.hpp:144
detail::binary_writer::ubjson_prefix
CharType ubjson_prefix(const BasicJsonType &j, const bool use_bjdata) const noexcept
determine the type prefix of container values
Definition: json.hpp:16543
detail::is_complete_type
Definition: json.hpp:3754
basic_json::iteration_proxy
::nlohmann::detail::iteration_proxy< Iterator > iteration_proxy
Definition: json.hpp:19452
detail::dtoa_impl::reinterpret_bits
Target reinterpret_bits(const Source source)
Definition: json.hpp:16955
detail::is_ordered_map::two::x
char x[2]
Definition: json.hpp:4039
detail::dtoa_impl::diyfp::normalize
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:17054
basic_json::get_impl_ptr
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.hpp:20766
NLOHMANN_BASIC_JSON_TPL
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2606
detail::binary_writer::to_char_type
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:16863
detail::primitive_iterator_t::operator--
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:12808
json_sax::binary
virtual bool binary(binary_t &val)=0
a binary value was read
basic_json::insert_iterator
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:22568
detail::input_format_t::msgpack
@ msgpack
lexy::callback
constexpr auto callback(Fns &&... fns)
Creates a callback.
Definition: adapter.hpp:21
JSON_IMPLEMENT_OPERATOR
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition: json.hpp:22882
detail::is_c_string
Definition: json.hpp:4181
basic_json::json_value
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.hpp:19749
NLOHMANN_JSON_VERSION_PATCH
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:70
basic_json::from_cbor
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:23664
NLOHMANN_CAN_CALL_STD_FUNC_IMPL
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition: json.hpp:2786
detail::nonesuch::nonesuch
nonesuch()=delete
detail::iteration_proxy::iteration_proxy
iteration_proxy()=default
detail::json_reverse_iterator::operator++
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.hpp:13685
detail::binary_writer::to_char_type
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16841
detail::json_reverse_iterator::json_reverse_iterator
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:13682
detail::replace_substring
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition: json.hpp:2971
detail::iter_impl::operator+=
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13444
detail::char_traits< signed char >::to_char_type
static char_type to_char_type(int_type i) noexcept
Definition: json.hpp:3644
detail::detect_erase_with_key_type
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.hpp:4019
detail::cbor_tag_handler_t::store
@ store
store tags as binary type
detail::binary_writer::write_bson_boolean
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition: json.hpp:16026
detail::dtoa_impl::cached_power
Definition: json.hpp:17221
byte_container_with_subtype::container_type
BinaryType container_type
Definition: json.hpp:5893
detail::output_string_adapter::str
StringType & str
Definition: json.hpp:15032
detail::binary_writer::calc_bson_element_size
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition: json.hpp:16203
detail::parser::token_type
typename lexer_t::token_type token_type
Definition: json.hpp:12235
detail::is_sax_static_asserts::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9123
detail::output_string_adapter::output_string_adapter
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:15016
basic_json::basic_json
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:20204
detail::parse_event_t::object_start
@ object_start
the parser read { and started to process a JSON object
detail::binary_reader::ia
InputAdapterType ia
input adapter
Definition: json.hpp:12098
detail::value_in_range_of
constexpr bool value_in_range_of(T val)
Definition: json.hpp:4150
detail::is_sax_static_asserts::exception_t
typename BasicJsonType::exception exception_t
Definition: json.hpp:9127
detail::binary_reader::parse_bson_element_list
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition: json.hpp:9496
detail::detect_string_can_append_op
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.hpp:4278
detail::lexer::token_type
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:7493
detail::is_ordered_map::value
@ value
Definition: json.hpp:4045
detail::json_reverse_iterator::operator-
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:13727
detail::output_adapter_protocol
abstract output adapter interface
Definition: json.hpp:14944
detail::json_sax_dom_parser::root
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:6970
detail::iteration_proxy_value::array_index_last
std::size_t array_index_last
last stringified array index
Definition: json.hpp:5201
basic_json::JSON_HEDLEY_DEPRECATED_FOR
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:23926
detail::is_detected_exact
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:309
byte_container_with_subtype::subtype_type
std::uint64_t subtype_type
Definition: json.hpp:5894
basic_json::value_return_type
std::conditional< detail::is_c_string_uncvref< ValueType >::value, string_t, typename std::decay< ValueType >::type > value_return_type
Definition: json.hpp:21519
basic_json::m_value
json_value m_value
the value of the current element
Definition: json.hpp:23497
adl_serializer
namespace for Niels Lohmann
Definition: json.hpp:3395
adl_serializer::to_json
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:5857
detail::is_transparent
Definition: json.hpp:4203
ordered_map::key_type
Key key_type
Definition: json.hpp:19035
basic_json::operator+=
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:22502
detail::binary_reader::char_int_type
typename char_traits< char_type >::int_type char_int_type
Definition: json.hpp:9220
basic_json::push_back
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:22486
detail::exception::m
std::runtime_error m
an exception object as storage for error messages
Definition: json.hpp:4464
detail::is_basic_json_context
Definition: json.hpp:3472
detail::parser::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:12232
zmq::operator<<
std::ostream & operator<<(std::ostream &os, const message_t &msg)
Definition: 3rdparty/cppzmq/zmq.hpp:2709
cx::cend
constexpr auto cend(const C &c) -> decltype(cx::end(c))
Definition: wildcards.hpp:706
detail::json_sax_dom_callback_parser::number_integer
bool number_integer(number_integer_t val)
Definition: json.hpp:7020
detail::json_sax_dom_parser::binary
bool binary(binary_t &val)
Definition: json.hpp:6860
detail::json_reverse_iterator::operator++
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:13691
detail::cbor_tag_handler_t
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:9184
lexy::parse
constexpr auto parse(const Input &input, const ErrorCallback &callback)
Parses the production into a value, invoking the callback on error.
Definition: parse.hpp:171
basic_json::allocator_type
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:19522
JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition: json.hpp:77
basic_json::from_ubjson
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:23791
detail::json_ref::operator*
value_type const & operator*() const
Definition: json.hpp:14859
detail::json_default_base
Default base class of the basic_json class.
Definition: json.hpp:13788
basic_json::type_name
const JSON_HEDLEY_RETURNS_NON_NULL char * type_name() const noexcept
return the type as string
Definition: json.hpp:23460
detail::conjunction< B >
Definition: json.hpp:3661
detail::pointer_t
typename T::pointer pointer_t
Definition: json.hpp:3508
detail::lexer::get_decimal_point
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.hpp:7515
ordered_map
a minimal map-like container that preserves insertion order
Definition: json.hpp:3427
basic_json::JSON_HEDLEY_DEPRECATED_FOR
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:23940
detail::lexer::skip_bom
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8858
basic_json::basic_json
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:20334
detail::binary_reader::get_string
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition: json.hpp:11975
detail::range_value_t
value_type_t< iterator_traits< iterator_t< T > >> range_value_t
Definition: json.hpp:3747
basic_json::number_integer
number_integer_t number_integer
number (integer)
Definition: json.hpp:19738
detail::is_getable
Definition: json.hpp:3534
JSON_HEDLEY_CONST
#define JSON_HEDLEY_CONST
Definition: json.hpp:1818
basic_json::get_impl_ptr
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.hpp:20730
detail::span_input_adapter::span_input_adapter
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:6613
ordered_map::insert
void insert(InputIt first, InputIt last)
Definition: json.hpp:19351
detail::parser
syntax analysis
Definition: json.hpp:12228
detail::value_t::string
@ string
string value
basic_json::operator[]
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.hpp:21498
detail::span_input_adapter
Definition: json.hpp:6604
detail::span_input_adapter::get
contiguous_bytes_input_adapter && get()
Definition: json.hpp:6623
basic_json::number_integer_t
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:19655
json_pointer::operator/
friend json_pointer operator/(const json_pointer &lhs, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:13943
detail::dtoa_impl::format_buffer
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:17887
detail::from_json_fn
Definition: json.hpp:5098
detail::lexer
lexical analysis
Definition: json.hpp:7483
json_sax::parse_error
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
json_pointer::contains
bool contains(const BasicJsonType *ptr) const
Definition: json.hpp:14383
detail::input_format_t::json
@ json
detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:5554
detail::make_integer_sequence
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3183
basic_json::get_ptr
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20847
basic_json::from_bjdata
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:23845
basic_json::patch
basic_json patch(const basic_json &json_patch) const
applies a JSON patch to a copy of the current object
Definition: json.hpp:24272
detail::serializer
Definition: json.hpp:18059
detail::integer_sequence
Definition: json.hpp:3122
detail::is_ordered_map::two
Definition: json.hpp:4037
basic_json::size_type
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:19519
adl_serializer::from_json
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:5847
basic_json::array
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:20307
basic_json::from_msgpack
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:23722
detail::iter_impl::operator==
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:13337
detail::iteration_proxy::begin
iteration_proxy_value< IteratorType > begin() const noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:5326
detail::value_in_range_of_impl2< OfType, T, false, true >::test
static constexpr bool test(T val)
Definition: json.hpp:4108
detail::is_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9095
ordered_map::value_type
typename Container::value_type value_type
Definition: json.hpp:19041
basic_json::get_impl_ptr
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:20784
basic_json::is_null
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:20617
detail::static_const::value
static constexpr JSON_INLINE_VARIABLE T value
Definition: json.hpp:3213
basic_json::at
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.hpp:21344
detail::parser::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:12233
JSON_THROW
#define JSON_THROW(exception)
Definition: json.hpp:2523
basic_json::contains
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:22040
basic_json::get_to
ValueType & get_to(ValueType &v) const
Definition: json.hpp:21113
detail::binary_writer::binary_writer
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:15090
detail::iterator_input_adapter
Definition: json.hpp:6280
detail::iter_impl::operator+
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:13490
detail::json_sax_acceptor::end_object
bool end_object()
Definition: json.hpp:7343
lexy::buffer
buffer(const CharT *, const CharT *) -> buffer< deduce_encoding< CharT >>
detail::serializer::indent_char
const char indent_char
the indentation character
Definition: json.hpp:18987
basic_json::erase
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:21906
detail::external_constructor< value_t::object >::construct
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:5623
JSON_PRIVATE_UNLESS_TESTED
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2559
ordered_map::ordered_map
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.hpp:19055
detail::json_sax_dom_parser::start_array
bool start_array(std::size_t len)
Definition: json.hpp:6898
detail::iterator_types< It, void_t< typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category > >::value_type
typename It::value_type value_type
Definition: json.hpp:3281
detail::binary_reader::parse_bson_element_internal
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:9416
json_pointer::convert
json_pointer< string_t > convert() const &
Definition: json.hpp:14640
byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5919
detail::iteration_proxy_value::value
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:5299
detail::detected_or_t
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:306
detail::binary_writer::write_bson_object
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition: json.hpp:16313
basic_json::to_msgpack
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23571
detail::iter_impl::operator--
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:13296
detail::iter_impl::operator*
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:13148
detail::detect_string_can_append_iter
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.hpp:4284
detail::output_stream_adapter
output adapter for output streams
Definition: json.hpp:14988
basic_json::get_to
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:21124
basic_json::data
data(size_type cnt, const basic_json &val)
Definition: json.hpp:23504
json_pointer::array_index
static BasicJsonType::size_type array_index(const string_t &s)
Definition: json.hpp:14019
basic_json::get_impl_ptr
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.hpp:20754
detail::char_traits< unsigned char >::to_char_type
static char_type to_char_type(int_type i) noexcept
Definition: json.hpp:3620
detail::dtoa_impl::diyfp
Definition: json.hpp:16964
basic_json::push_back
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:22423
ordered_map::insert
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:19328
detail::dtoa_impl::boundaries::plus
diyfp plus
Definition: json.hpp:17086
detail::wide_string_input_adapter::get_character
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6447
detail::from_json_tuple_impl
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 >>, priority_tag< 0 >)
Definition: json.hpp:5010
basic_json::get_impl_ptr
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition: json.hpp:20772
ordered_map::operator[]
T & operator[](KeyType &&key)
Definition: json.hpp:19093
basic_json::is_primitive
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:20603
JSON_HEDLEY_RETURNS_NON_NULL
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:2047
detail::primitive_iterator_t::operator<
constexpr friend bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12778
JSON_HEDLEY_NON_NULL
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1606
detail::parse_event_t::object_end
@ object_end
the parser read } and finished processing a JSON object
basic_json::at
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:21263
basic_json::insert
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.hpp:22685
detail::json_sax_dom_callback_parser::json_sax_dom_callback_parser
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.hpp:6993
basic_json::get_impl_ptr
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition: json.hpp:20802
detail::static_const
Definition: json.hpp:3211
detail::has_to_json
Definition: json.hpp:3567
json_pointer::get_unchecked
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: json.hpp:14159
ordered_map::ordered_map
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:19053
detail::to_json
void to_json(BasicJsonType &j, const T &b)
Definition: json.hpp:5774
detail::lexer::char_type
typename InputAdapterType::char_type char_type
Definition: json.hpp:7489
detail::dtoa_impl::compute_boundaries
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:17096
json_pointer::operator/
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:13928
detail::iter_impl
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:12915
basic_json::pointer
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:19525
byte_container_with_subtype::clear_subtype
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5960
detail::json_sax_dom_callback_parser::start_object
bool start_object(std::size_t len)
Definition: json.hpp:7050
detail::input_stream_adapter::~input_stream_adapter
~input_stream_adapter()
Definition: json.hpp:6230
detail::little_endianness
static bool little_endianness(int num=1) noexcept
determine system byte order
Definition: json.hpp:9198
json_pointer::get_checked
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: json.hpp:14227
detail::int_to_string
void int_to_string(string_type &target, std::size_t value)
Definition: json.hpp:5179
detail::input_stream_adapter::sb
std::streambuf * sb
Definition: json.hpp:6273
ordered_map::const_iterator
typename Container::const_iterator const_iterator
Definition: json.hpp:19039
detail::to_json_tuple_impl
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:5780
detail::output_vector_adapter::write_character
void write_character(CharType c) override
Definition: json.hpp:14970
detail::json_ref::json_ref
json_ref(Args &&... args)
Definition: json.hpp:14839
basic_json::to_bson
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition: json.hpp:23639
detail::json_sax_dom_parser::key
bool key(string_t &val)
Definition: json.hpp:6878
detail::detector::value_t
std::false_type value_t
Definition: json.hpp:282
detail::char_traits< signed char >::eof
static constexpr int_type eof() noexcept
Definition: json.hpp:3649
basic_json::back
const_reference back() const
access the last element
Definition: json.hpp:21719
basic_json::binary
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:20274
detail::json_sax_dom_callback_parser::handle_value
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition: json.hpp:7205
detail::binary_reader::get_cbor_binary
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition: json.hpp:10151
detail::value_t::number_integer
@ number_integer
number value (signed integer)
detail::json_sax_dom_parser::parse_error
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6921
detail::internal_iterator
an iterator value
Definition: json.hpp:12848
detail::other_error::create
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4578
detail::invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:4522
basic_json::string_t
StringType string_t
a type for a string
Definition: json.hpp:19647
detail::parser::parse
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:12261
ordered_map::at
T & at(KeyType &&key)
Definition: json.hpp:19125
basic_json::operator[]
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23934
detail::detected_t
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:300
detail::iter_impl::value_type
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:12944
detail::file_input_adapter::get_character
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6206
ordered_map::ordered_map
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.hpp:19051
detail::binary_writer::write_bson_string
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition: json.hpp:16054
ordered_map::insert
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:19333
basic_json::m_data
data m_data
Definition: json.hpp:23522
basic_json::insert
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.hpp:22634
detail::iteration_proxy_value::anchor
IteratorType anchor
the iterator
Definition: json.hpp:5197
detail::binary_writer::write_bson_unsigned
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition: json.hpp:16114
detail::is_compatible_object_type_impl
Definition: json.hpp:3761
basic_json::default_object_comparator_t
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:19630
detail::end_object_function_t
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:9070
detail::value_t::null
@ null
null value
ordered_map::count
size_type count(KeyType &&key) const
Definition: json.hpp:19278
detail::to_json_fn::operator()
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:5802
basic_json::from_ubjson
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:23776
detail::primitive_iterator_t::operator--
primitive_iterator_t operator--(int) &noexcept
Definition: json.hpp:12814
detail::is_sax_static_asserts
Definition: json.hpp:9116
detail::binary_writer::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:15081
detail::internal_iterator::primitive_iterator
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:12855
detail::binary_reader::parse_bson_internal
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition: json.hpp:9312
JSON_TRY
#define JSON_TRY
Definition: json.hpp:2524
detail::make_void::type
void type
Definition: json.hpp:253
json_pointer::empty
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:14002
byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5897
lexyd::member
constexpr auto member
Definition: member.hpp:92
detail::detector
Definition: json.hpp:280
cx::prev
constexpr It prev(It it)
Definition: wildcards.hpp:631
detail::parse_event_t::array_end
@ array_end
the parser read ] and finished processing a JSON array
detail::to_chars
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:17972
detail::input_format_t::cbor
@ cbor
detail::iter_impl::operator>
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:13426
detail::binary_writer::calc_bson_unsigned_size
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition: json.hpp:16104
to_string
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:24456
detail::binary_function_t
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:9059
basic_json::to_bjdata
static void to_bjdata(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23623
detail::is_constructible_object_type_impl< BasicJsonType, ConstructibleObjectType, enable_if_t< is_detected< mapped_type_t, ConstructibleObjectType >::value &&is_detected< key_type_t, ConstructibleObjectType >::value > >::object_t
typename BasicJsonType::object_t object_t
Definition: json.hpp:3793
json_sax::number_unsigned
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
detail::from_json
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:4664
basic_json::operator+=
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22415
detail::input_stream_adapter::input_stream_adapter
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:6249
detail::iterator_input_adapter_factory::create
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6489
detail::iter_impl::operator--
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.hpp:13285
lexy::_detail::make_tuple
constexpr auto make_tuple(Args &&... args)
Definition: tuple.hpp:106
basic_json::boolean
boolean_t boolean
boolean
Definition: json.hpp:19736
detail::binary_reader::bjd_type
std::pair< char_int_type, string_t > bjd_type
Definition: json.hpp:12139
basic_json::binary
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:20263
detail::json_ref::moved_or_copied
value_type moved_or_copied() const
Definition: json.hpp:14850
json_pointer::reference_tokens
std::vector< string_t > reference_tokens
the reference tokens
Definition: json.hpp:14730
basic_json::swap
void swap(object_t &other)
exchanges the values
Definition: json.hpp:22809
detail::iterator_input_adapter_factory< IteratorType, enable_if_t< is_iterator_of_multibyte< IteratorType >::value > >::char_type
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6509
basic_json::value
ReturnType value(const typename object_t::key_type &key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:21553
detail::binary_reader::get_ubjson_size_type
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:11376
lexyd::digits
constexpr auto digits
Matches a non-empty list of digits.
Definition: digit.hpp:531
json_pointer::split
static std::vector< string_t > split(const string_t &reference_string)
split the string input to reference tokens
Definition: json.hpp:14471
basic_json::const_iterator
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:19532
detail::iter_impl::operator-=
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:13481
detail::from_json
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.hpp:5069
detail::value_in_range_of_impl1
Definition: json.hpp:4129
detail::dtoa_impl::boundaries::w
diyfp w
Definition: json.hpp:17084
detail::json_ref::operator->
value_type const * operator->() const
Definition: json.hpp:14864
basic_json::find
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.hpp:21983
basic_json::get_impl_ptr
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.hpp:20718
detail::iteration_proxy::container
IteratorType::pointer container
the container to iterate
Definition: json.hpp:5310
detail::binary_writer::write_bson_integer
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition: json.hpp:16086
basic_json::to_msgpack
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23578
basic_json::basic_json
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:20117
basic_json::update
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22710
detail::value_t::array
@ array
array (ordered collection of values)
json_pointer::operator/=
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:13913
detail::json_sax_dom_parser::json_sax_dom_parser
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:6813
basic_json::~basic_json
~basic_json() noexcept
destructor
Definition: json.hpp:20556
detail::out_of_range::create
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4561
basic_json::get_impl_ptr
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:20778
detail::position_t::chars_read_total
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:3038
ordered_map::erase
iterator erase(iterator first, iterator last)
Definition: json.hpp:19211
basic_json::json_value
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition: json.hpp:19845
basic_json::insert
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.hpp:22587
detail::binary_reader::get_ubjson_string
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition: json.hpp:10993
magic_enum::detail::n
constexpr auto n() noexcept
Definition: magic_enum.hpp:417
detail::binary_writer::calc_bson_object_size
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition: json.hpp:16298
detail::binary_reader::get_msgpack_object
bool get_msgpack_object(const std::size_t len)
Definition: json.hpp:10937
detail::json_sax_acceptor::end_array
bool end_array()
Definition: json.hpp:7353
ordered_map::find
iterator find(KeyType &&key)
Definition: json.hpp:19304
detail::output_string_adapter
output adapter for basic_string
Definition: json.hpp:15013
detail::iter_impl::operator-
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:13523
JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
Definition: json.hpp:12119
detail::iter_impl::other_iter_impl
friend other_iter_impl
allow basic_json to access private members
Definition: json.hpp:12920
detail::dtoa_impl::diyfp::f
std::uint64_t f
Definition: json.hpp:16968
detail::is_json_iterator_of
Definition: json.hpp:3956
detail::json_sax_dom_callback_parser::number_unsigned
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:7026
detail::value_t::object
@ object
object (unordered set of name/value pairs)
detail::nonesuch::~nonesuch
~nonesuch()=delete
detail::same_sign
std::integral_constant< bool, all_signed< Types... >::value||all_unsigned< Types... >::value > same_sign
Definition: json.hpp:4073
detail::end_array_function_t
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:9077
detail::string_function_t
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:9055
detail::dtoa_impl::kGamma
constexpr int kGamma
Definition: json.hpp:17219
detail::wide_string_input_adapter::wide_string_input_adapter
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:6444
detail::is_constructible_string_type::laundered_type
ConstructibleStringType laundered_type
Definition: json.hpp:3830
detail::input_stream_adapter::input_stream_adapter
input_stream_adapter(std::istream &i)
Definition: json.hpp:6240
detail::is_compatible_object_type
Definition: json.hpp:3780
detail::json_sax_dom_parser::end_array
bool end_array()
Definition: json.hpp:6910
detail::error_handler_t
error_handler_t
how to treat decoding errors
Definition: json.hpp:18051
detail::iterator_input_adapter_factory::char_type
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6486
detail::dtoa_impl::boundaries
Definition: json.hpp:17082
detail::iteration_proxy::iteration_proxy
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:5316
detail::binary_reader
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:9211
detail::is_compatible_array_type_impl
Definition: json.hpp:3841
basic_json::iterator
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:19530
detail::iter_impl::operator-
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13512
basic_json::from_cbor
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:23680
detail::output_stream_adapter::output_stream_adapter
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:14991
detail::get
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:5342
lexy::op
typename LEXY_DECAY_DECLTYPE(Operator)::op_tag_type op
Definition: operator.hpp:41
detail::parser::get_token
token_type get_token()
get next token from lexer
Definition: json.hpp:12641
detail::iterator_types
Definition: json.hpp:3272
detail::json_sax_acceptor::boolean
bool boolean(bool)
Definition: json.hpp:7303
detail::unescape
static void unescape(StringType &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:3005
f
static FILE * f
Definition: minitrace.cpp:74
detail::binary_reader::parse_cbor_internal
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:9564
detail::is_compatible_integer_type_impl
Definition: json.hpp:3908
detail::exception::id
const int id
the id of the exception
Definition: json.hpp:4381
ordered_map::count
size_type count(const key_type &key) const
Definition: json.hpp:19264
json_pointer::result
return result
Definition: json.hpp:14066
detail::parse_error::parse_error
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition: json.hpp:4510
ordered_map::emplace
std::pair< iterator, bool > emplace(KeyType &&key, T &&t)
Definition: json.hpp:19073
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
operator==
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14736
detail::parser::parser
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.hpp:12239
basic_json::number_float_t
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:19663
basic_json::get_impl
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:20707
json_sax::number_integer
virtual bool number_integer(number_integer_t val)=0
an integer number was read
detail::value_type_t
typename T::value_type value_type_t
Definition: json.hpp:3502
detail::iteration_proxy_value::operator==
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:5251
detail::detector::type
Default type
Definition: json.hpp:283
detail::iter_impl::iter_impl
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:13018
basic_json::get_allocator
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:19542
basic_json::get_impl_ptr
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:20790
detail::is_sax::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9091
detail::json_reverse_iterator
a template for a reverse iterator class
Definition: json.hpp:13668
detail::is_sax_static_asserts::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:9125
detail::primitive_iterator_t::operator+
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:12783
detail::container_input_adapter_factory_impl::container_input_adapter_factory< ContainerType, void_t< decltype(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))> >::adapter_type
decltype(input_adapter(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))) adapter_type
Definition: json.hpp:6544
basic_json::JSON_HEDLEY_DEPRECATED_FOR
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:21677
detail::json_sax_dom_parser::number_integer
bool number_integer(number_integer_t val)
Definition: json.hpp:6836
detail::is_constructible_array_type_impl
Definition: json.hpp:3863
basic_json::value
ReturnType value(KeyType &&key, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21606
detail::actual_object_comparator::object_t
typename BasicJsonType::object_t object_t
Definition: json.hpp:3589
detail::json_reverse_iterator::operator[]
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13733
detail::binary_reader::get_token_string
std::string get_token_string() const
Definition: json.hpp:12045
detail::input_adapter
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6521
detail::iter_impl::operator<=
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:13417
detail::binary_reader::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9214
detail::char_traits< signed char >::int_type
uint64_t int_type
Definition: json.hpp:3636
detail::string_can_append
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition: json.hpp:4269
detail::file_input_adapter::m_file
std::FILE * m_file
the file pointer to read from
Definition: json.hpp:6213
detail::internal_iterator::array_iterator
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:12853
detail::input_stream_adapter::is
std::istream * is
the associated input stream
Definition: json.hpp:6272
detail::from_json_fn::operator()
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:5101
basic_json::json_value
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition: json.hpp:19851
detail::json_sax_dom_parser::handle_value
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition: json.hpp:6947
basic_json::to_msgpack
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23562
detail::uncvref_t
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:3081
detail::concat
OutStringType concat(Args &&... args)
Definition: json.hpp:4349
detail::binary_reader::get_ubjson_value
bool get_ubjson_value(const char_int_type prefix)
Definition: json.hpp:11443
detail::wide_string_input_adapter
Definition: json.hpp:6439
detail::key_type_t
typename T::key_type key_type_t
Definition: json.hpp:3499
basic_json::get_impl
BasicJsonType get_impl(detail::priority_tag< 2 >) const
get special-case overload
Definition: json.hpp:20975
detail::error_handler_t::strict
@ strict
throw a type_error exception in case of invalid UTF-8
detail::is_ordered_map::one
char one
Definition: json.hpp:4035
detail::iter_impl::operator[]
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13552
detail::primitive_iterator_t::operator++
primitive_iterator_t operator++(int) &noexcept
Definition: json.hpp:12801
json_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6673
detail::value_in_range_of_impl1< OfType, T, false >::test
static constexpr bool test(T val)
Definition: json.hpp:4134
basic_json::basic_json
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:20516
detail::output_vector_adapter::v
std::vector< CharType, AllocatorType > & v
Definition: json.hpp:14982
detail::is_range::is_iterator_begin
static constexpr auto is_iterator_begin
Definition: json.hpp:3736
basic_json::get_impl
basic_json get_impl(detail::priority_tag< 3 >) const
get special-case overload
Definition: json.hpp:20998
detail::detect_string_can_append_data
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.hpp:4290
detail::is_compatible_object_type_impl< BasicJsonType, CompatibleObjectType, enable_if_t< is_detected< mapped_type_t, CompatibleObjectType >::value &&is_detected< key_type_t, CompatibleObjectType >::value > >::object_t
typename BasicJsonType::object_t object_t
Definition: json.hpp:3769
json_pointer::unflatten
static BasicJsonType unflatten(const BasicJsonType &value)
Definition: json.hpp:14612
basic_json::swap
void swap(string_t &other)
exchanges the values
Definition: json.hpp:22825
basic_json::find
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.hpp:21953
detail::lexer::get_number_integer
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8784
basic_json::json_value
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.hpp:19751
detail::is_iterator_of_multibyte::value_type
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:6498
detail::get_template_function
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3523
ordered_map::key_compare
std::equal_to< Key > key_compare
Definition: json.hpp:19045
detail::has_key_compare
Definition: json.hpp:3583
basic_json::output_adapter_t
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition: json.hpp:19456
basic_json::swap
void swap(array_t &other)
exchanges the values
Definition: json.hpp:22793
operator<
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14786
detail::is_specialization_of
Definition: json.hpp:3967
detail::hash
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:6022
detail::json_sax_acceptor::key
bool key(string_t &)
Definition: json.hpp:7338
basic_json::primitive_iterator_t
::nlohmann::detail::primitive_iterator_t primitive_iterator_t
Definition: json.hpp:19446
JSON_HEDLEY_LIKELY
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1713
detail::serializer::dump
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:18115
detail::is_ordered_map
Definition: json.hpp:4033
detail::wide_string_input_adapter::utf8_bytes_filled
std::size_t utf8_bytes_filled
number of valid bytes in the utf8_codes array
Definition: json.hpp:6479
detail::reference_t
typename T::reference reference_t
Definition: json.hpp:3511
detail::json_sax_acceptor::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:7292
detail::conditional_static_cast
T conditional_static_cast(U value)
Definition: json.hpp:4050
basic_json::update
void update(const_iterator first, const_iterator last, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22717
detail::json_reverse_iterator::value
reference value() const
return the value of an iterator
Definition: json.hpp:13746
detail::priority_tag
Definition: json.hpp:3206
detail::lexer::scan_string
token_type scan_string()
scan a string literal
Definition: json.hpp:7626
basic_json::get_ptr
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20858
json_sax::string
virtual bool string(string_t &val)=0
a string value was read
detail::is_constructible_string_type
Definition: json.hpp:3824
detail::binary_reader::get_cbor_array
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:10246
json_pointer::operator/=
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:13903
basic_json::value
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21528
json
basic_json<> json
default specialization
Definition: json.hpp:3422
basic_json::parser
static ::nlohmann::detail::parser< basic_json, InputAdapterType > parser(InputAdapterType adapter, detail::parser_callback_t< basic_json >cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
Definition: json.hpp:19434
lexyd::operator-
constexpr auto operator-(C c) -> _ccomp< decltype(_make_char_class(c))>
Definition: char_class.hpp:484
basic_json::operator[]
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:21408
basic_json::get_impl_ptr
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition: json.hpp:20808
detail::json_sax_dom_parser::end_object
bool end_object()
Definition: json.hpp:6888
lexy_ext::tokens
auto tokens(const lexy::parse_tree< Reader, TokenKind, MemoryResource > &tree, typename lexy::parse_tree< Reader, TokenKind, MemoryResource >::node node)
Definition: parse_tree_algorithm.hpp:15
detail::serializer::indent_string
string_t indent_string
the indentation string
Definition: json.hpp:18989
detail::serializer::error_handler
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:18992
detail::json_reverse_iterator::difference_type
std::ptrdiff_t difference_type
Definition: json.hpp:13671
lexy::_detail::is_constructible
constexpr auto is_constructible
Definition: object.hpp:18
std
Definition: std.hpp:30
detail::invalid_iterator::create
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4526
detail::dtoa_impl::cached_power::f
std::uint64_t f
Definition: json.hpp:17223
lexy::construct
constexpr auto construct
A callback that constructs an object of type T by forwarding the arguments.
Definition: object.hpp:57
detail::json_sax_acceptor::number_integer
bool number_integer(number_integer_t)
Definition: json.hpp:7308
detail::binary_writer::write_compact_float
void write_compact_float(const number_float_t n, detail::input_format_t format)
Definition: json.hpp:16800
detail::json_reverse_iterator::operator+=
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13709
detail::has_from_json< BasicJsonType, T, enable_if_t< !is_basic_json< T >::value > >::serializer
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3542
detail::binary_writer::to_char_type
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16834
detail::actual_object_comparator::type
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition: json.hpp:3592
detail::container_input_adapter_factory_impl::container_input_adapter_factory
Definition: json.hpp:6538
basic_json::get
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 >
get a (pointer) value (explicit)
Definition: json.hpp:21046
detail::to_json
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5642
detail::is_basic_json
Definition: json.hpp:3463
detail::is_range::sentinel
detected_t< result_of_end, t_ref > sentinel
Definition: json.hpp:3731
basic_json::contains
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:22047
detail::binary_writer::write_msgpack
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:15452
detail::is_default_constructible
Definition: json.hpp:3673
detail::operator<
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:2902
basic_json::erase
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:21801
detail::string_can_append_data
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition: json.hpp:4287
detail::parse_error
exception indicating a parse error
Definition: json.hpp:4469
SafeAny::details::is_integer
constexpr bool is_integer()
Definition: convert_impl.hpp:31
detail::other_error
exception indicating other library errors
Definition: json.hpp:4574
lexy::_detail::cp_error::success
@ success
detail::parser_callback_t
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:12220
basic_json::number_float
number_float_t number_float
number (floating-point)
Definition: json.hpp:19742
detail::serializer::binary_char_t
typename BasicJsonType::binary_t::value_type binary_char_t
Definition: json.hpp:18065
detail::json_reverse_iterator::operator--
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:13703
byte_container_with_subtype::set_subtype
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5938
basic_json::to_cbor
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23555
json_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6675
basic_json::swap
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&//NOLINT(cppcoreguidelines-noexcept-swap, performance-noexcept-swap) std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22781
detail::iteration_proxy
proxy class for the items() function
Definition: json.hpp:5306
detail::iter_impl::operator!=
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:13373
detail::binary_reader::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9213
lexyd::byte
constexpr auto byte
Matches an arbitrary byte.
Definition: byte.hpp:51
basic_json::internal_iterator
::nlohmann::detail::internal_iterator< BasicJsonType > internal_iterator
Definition: json.hpp:19448
basic_json::basic_json
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:20322
detail::primitive_iterator_t::is_end
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:12768
detail::is_detected
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:294
ordered_map::emplace
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:19058
basic_json::insert
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.hpp:22607
JSON_HEDLEY_DEPRECATED_FOR
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.hpp:1396
detail::lexer::add
void add(char_int_type c)
add a character to token_buffer
Definition: json.hpp:8773
detail::json_sax_dom_callback_parser
Definition: json.hpp:6982
detail::is_constructible_array_type
Definition: json.hpp:3903
detail::priority_tag< 0 >
Definition: json.hpp:3207
detail::binary_writer::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:15080
ordered_map::at
const T & at(KeyType &&key) const
Definition: json.hpp:19153
detail::binary_reader::get_bson_cstr
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition: json.hpp:9337
detail::json_sax_acceptor::string
bool string(string_t &)
Definition: json.hpp:7323
json_pointer::operator/=
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:13921
byte_container_with_subtype::m_has_subtype
bool m_has_subtype
Definition: json.hpp:5968
basic_json::get_to
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:21100
detail::binary_writer::write_number_with_ubjson_prefix
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix, const bool use_bjdata)
Definition: json.hpp:16360
detail::binary_writer::calc_bson_integer_size
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition: json.hpp:16076
ordered_map::ordered_map
ordered_map() noexcept(noexcept(Container()))
Definition: json.hpp:19050
detail::json_reverse_iterator::operator-
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13721
detail::lexer::get_string
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8802
basic_json::json_value
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition: json.hpp:19848
detail::type_error::create
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4544
basic_json::to_bson
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:23655
detail::lexer::get_token_string
std::string get_token_string() const
Definition: json.hpp:8820
detail::lexer::get_position
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8812
detail::actual_object_comparator::object_comparator_t
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.hpp:3590
detail::json_sax_dom_callback_parser::binary
bool binary(binary_t &val)
Definition: json.hpp:7044
basic_json::is_string
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:20673
detail::binary_writer::write_bson_entry_header
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition: json.hpp:16014
detail::to_json_function
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3517
JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
Definition: json.hpp:12116
detail::json_sax_dom_callback_parser::key
bool key(string_t &val)
Definition: json.hpp:7068
detail::wide_string_input_helper
Definition: json.hpp:6315
detail::binary_reader::get_binary
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition: json.hpp:12008
detail::is_detected_convertible
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:313
basic_json::operator=
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value &&std::is_nothrow_move_assignable< json_base_class_t >::value)
copy assignment
Definition: json.hpp:20533
NLOHMANN_JSON_VERSION_MAJOR
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:68
detail::nonesuch::operator=
void operator=(nonesuch const &)=delete
detail::iter_impl::pointer
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:12950
detail::dtoa_impl::grisu2_round
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.hpp:17453
lexy::operator>>
constexpr auto operator>>(Sink sink, Callback cb)
Composes a sink with a callback.
Definition: composition.hpp:113
detail::lexer::get
char_int_type get()
Definition: json.hpp:8709
detail::position_t::chars_read_current_line
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:3040
detail::lexer::lexer
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:7495
lexy::_detail::error
constexpr bool error
Definition: config.hpp:39
detail::value_in_range_of_impl2
Definition: json.hpp:4083
detail::is_detected_lazy
Definition: json.hpp:297
detail::has_non_default_from_json
Definition: json.hpp:3552
detail::iter_impl::difference_type
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:12946
basic_json::get_impl_ptr
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.hpp:20748
detail::iteration_proxy_value::operator++
iteration_proxy_value operator++(int) &
Definition: json.hpp:5242
detail::iteration_proxy_value::operator!=
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:5257
basic_json::dump
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:20574
basic_json::is_array
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:20666
detail::detect_string_can_append
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.hpp:4272
detail::json_sax_dom_callback_parser::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6985
detail::json_ref
Definition: json.hpp:3483
NLOHMANN_JSON_VERSION_MINOR
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:69
detail::json_reverse_iterator::json_reverse_iterator
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:13678
json_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6672
basic_json::operator[]
reference operator[](KeyType &&key)
access specified object element
Definition: json.hpp:21474
json_pointer::convert
json_pointer< string_t > convert() &&
Definition: json.hpp:14647
detail::difference_type_t
typename T::difference_type difference_type_t
Definition: json.hpp:3505
detail::json_base_class
typename std::conditional< std::is_same< T, void >::value, json_default_base, T >::type json_base_class
Definition: json.hpp:13795
detail::json_sax_acceptor::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:7295
ordered_map::Container
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:19037
basic_json::json_base_class_t
::nlohmann::detail::json_base_class< CustomBaseClass > json_base_class_t
Definition: json.hpp:19427
detail::json_sax_dom_callback_parser::end_array
bool end_array()
Definition: json.hpp:7138
basic_json::erase_internal
size_type erase_internal(KeyType &&key)
Definition: json.hpp:21872
basic_json::emplace_back
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:22511
detail::iteration_proxy_value::key
const string_type & key() const
return key of the iterator
Definition: json.hpp:5263
basic_json::operator+=
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22478
detail::binary_writer::calc_bson_array_size
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition: json.hpp:16146
basic_json::json_value
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition: json.hpp:19854
detail::primitive_iterator_t::difference_type
std::ptrdiff_t difference_type
Definition: json.hpp:12735
detail::json_sax_dom_callback_parser::parse_event_t
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:6991
detail::json_reverse_iterator::operator+
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:13715
ordered_map::mapped_type
T mapped_type
Definition: json.hpp:19036
detail::detect_key_compare
typename T::key_compare detect_key_compare
Definition: json.hpp:3580
basic_json::is_binary
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:20680
byte_container_with_subtype::m_subtype
subtype_type m_subtype
Definition: json.hpp:5967
basic_json::is_boolean
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:20624
detail::value_t
value_t
the JSON type enumeration
Definition: json.hpp:2872
detail::dtoa_impl::grisu2
void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
Definition: json.hpp:17795
detail::lexer::unget
void unget()
unget current character (read it again on next get)
Definition: json.hpp:8746
detail::bool_constant
std::integral_constant< bool, Value > bool_constant
Definition: json.hpp:4156
basic_json::get_binary
const binary_t & get_binary() const
get a binary value
Definition: json.hpp:21218
json_pointer::to_string
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:13873
detail::actual_object_comparator
Definition: json.hpp:3587
basic_json::binary
binary_t * binary
binary (stored with pointer to save storage)
Definition: json.hpp:19734
detail::is_range::iterator
detected_t< result_of_begin, t_ref > iterator
Definition: json.hpp:3730
detail::binary_reader::parse_bson_array
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition: json.hpp:9534
basic_json::object_comparator_t
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.hpp:19671
basic_json::binary_writer
::nlohmann::detail::binary_writer< basic_json, CharType > binary_writer
Definition: json.hpp:19460
detail::binary_writer::calc_bson_string_size
static std::size_t calc_bson_string_size(const string_t &value)
Definition: json.hpp:16046
detail::exception::name
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:4387
basic_json::get_impl_ptr
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.hpp:20760
json_pointer::get_checked
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition: json.hpp:14334
detail::is_sax_static_asserts::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9122
detail::input_stream_adapter::operator=
input_stream_adapter & operator=(input_stream_adapter &)=delete
detail::binary_reader::binary_reader
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition: json.hpp:9228
std::hash< nlohmann::NLOHMANN_BASIC_JSON_TPL >::operator()
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.hpp:24506
basic_json::emplace
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:22536
SafeAny::details::is_signed
constexpr bool is_signed()
Definition: convert_impl.hpp:52
detail::is_iterator_of_multibyte
Definition: json.hpp:6496
detail::json_sax_dom_callback_parser::parser_callback_t
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:6990
detail::iterator_types< It, void_t< typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category > >::difference_type
typename It::difference_type difference_type
Definition: json.hpp:3280
detail::binary_reader::get_ubjson_object
bool get_ubjson_object()
Definition: json.hpp:11734
lexyd::operator+
constexpr auto operator+(Rule rule, _br< Condition, R... >)
Definition: branch.hpp:72
detail::iter_impl::operator<
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:13382
basic_json::operator[]
const_reference operator[](T *key) const
Definition: json.hpp:21465
detail::json_sax_acceptor::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:7294
detail::serializer::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:18061
basic_json::contains
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition: json.hpp:22031
basic_json::to_bson
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:23648
json_pointer::pop_back
void pop_back()
remove last reference token
Definition: json.hpp:13964
detail::binary_reader::parse_ubjson_internal
bool parse_ubjson_internal(const bool get_char=true)
Definition: json.hpp:10974
lexyd::binary
_d< 2 > binary
Definition: digit.hpp:54
detail::iter_impl::key
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:13590
detail::json_sax_acceptor::parse_error
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:7358
basic_json::to_ubjson
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23585
std::swap
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression, cppcoreguidelines-noexcept-swap, performance-noexcept-swap) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:24537
detail::binary_reader::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9217
detail::is_compatible_integer_type_impl< RealIntegerType, CompatibleNumberIntegerType, enable_if_t< std::is_integral< RealIntegerType >::value &&std::is_integral< CompatibleNumberIntegerType >::value &&!std::is_same< bool, CompatibleNumberIntegerType >::value > >::RealLimits
std::numeric_limits< RealIntegerType > RealLimits
Definition: json.hpp:3918
detail::primitive_iterator_t::set_end
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:12756
detail::lexer::get_codepoint
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: json.hpp:7541
basic_json::object
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:20315
detail::json_sax_dom_callback_parser::end_object
bool end_object()
Definition: json.hpp:7085
detail::iter_impl::m_it
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:13615
detail::parse_error::create
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4490
detail::external_constructor< value_t::boolean >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:5425
detail::is_compatible_string_type::value
static constexpr auto value
Definition: json.hpp:3819
detail::binary_writer::write_bjdata_ndarray
bool write_bjdata_ndarray(const typename BasicJsonType::object_t &value, const bool use_count, const bool use_type)
Definition: json.hpp:16657
detail::output_adapter::output_adapter
output_adapter(StringType &s)
Definition: json.hpp:15048
basic_json::to_bjdata
static std::vector< std::uint8_t > to_bjdata(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23612
detail::span_input_adapter::ia
contiguous_bytes_input_adapter ia
Definition: json.hpp:6629
basic_json::initializer_list_t
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:19476
detail::json_sax_dom_callback_parser::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6987
detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:5583
detail::is_getable::value
static constexpr bool value
Definition: json.hpp:3536
detail::parse_error::position_string
static std::string position_string(const position_t &pos)
Definition: json.hpp:4513
detail::is_sax_static_asserts::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9124
detail::container_input_adapter_factory_impl::container_input_adapter_factory< ContainerType, void_t< decltype(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))> >::create
static adapter_type create(const ContainerType &container)
Definition: json.hpp:6546
detail::output_stream_adapter::stream
std::basic_ostream< CharType > & stream
Definition: json.hpp:15007
basic_json::operator+=
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:22447
detail::binary_reader::get_msgpack_string
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition: json.hpp:10721
detail::exception
general exception of the basic_json class
Definition: json.hpp:4371
detail::file_input_adapter::file_input_adapter
file_input_adapter(std::FILE *f) noexcept
Definition: json.hpp:6193
basic_json::count
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:22023
basic_json::front
const_reference front() const
access the first element
Definition: json.hpp:21703
json_sax::start_array
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
basic_json::erase
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition: json.hpp:21917
detail::json_sax_acceptor
Definition: json.hpp:7289
detail::exception::diagnostics
static std::string diagnostics(std::nullptr_t)
Definition: json.hpp:4392
detail::dtoa_impl::cached_power::k
int k
Definition: json.hpp:17225
detail::string_can_append_op
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition: json.hpp:4275
detail::iter_impl::operator++
iter_impl operator++(int) &
post-increment (it++)
Definition: json.hpp:13234
detail::json_sax_dom_parser::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6804
detail::utility_internal::Extend
Definition: json.hpp:3143
json_pointer::parent_pointer
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:13950
detail::char_traits< unsigned char >::to_int_type
static int_type to_int_type(char_type c) noexcept
Definition: json.hpp:3615
detail::integer_sequence::value_type
T value_type
Definition: json.hpp:3124
detail::binary_reader::parse_msgpack_internal
bool parse_msgpack_internal()
Definition: json.hpp:10340
operator!=
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14761
detail::binary_writer::get_ubjson_float_prefix
static constexpr CharType get_ubjson_float_prefix(float)
Definition: json.hpp:16644
detail::detect_is_transparent
typename T::is_transparent detect_is_transparent
Definition: json.hpp:3986
lexy::_detail::skip_whitespace
constexpr auto skip_whitespace(ws_handler< Handler > &&handler, Reader &reader)
Definition: whitespace.hpp:112
detail::json_sax_dom_callback_parser::start_array
bool start_array(std::size_t len)
Definition: json.hpp:7121
basic_json::json_value
json_value(object_t &&value)
constructor for rvalue objects
Definition: json.hpp:19836
basic_json::get_ref
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:21136
basic_json::operator[]
reference operator[](T *key)
Definition: json.hpp:21459
JSON_ASSERT
#define JSON_ASSERT(x)
Definition: json.hpp:2552
byte_container_with_subtype::subtype
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5946
lexy::_detail::declval
std::add_rvalue_reference_t< T > declval()
detail::is_compatible_array_type
Definition: json.hpp:3859
detail::combine
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:6004
detail::primitive_iterator_t
Definition: json.hpp:12732
basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21731
basic_json::basic_json
basic_json(const JsonRef &ref)
Definition: json.hpp:20443
detail::json_sax_dom_callback_parser::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6989
detail::iter_impl::operator->
pointer operator->() const
dereference the iterator
Definition: json.hpp:13192
basic_json::array
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:19730
basic_json::create
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition: json.hpp:19680
detail::is_ordered_map::test
static one test(decltype(&C::capacity))
detail::json_sax_dom_callback_parser::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:6988
lexyd::eof
constexpr auto eof
Matches EOF.
Definition: eof.hpp:72
basic_json::json_value
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.hpp:19753
detail::char_traits
Definition: json.hpp:3604
json_pointer::flatten
static void flatten(const string_t &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition: json.hpp:14540
detail::is_compatible_type_impl
Definition: json.hpp:3934
basic_json::insert
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.hpp:22665
detail::iterator_input_adapter_factory< IteratorType, enable_if_t< is_iterator_of_multibyte< IteratorType >::value > >::iterator_type
IteratorType iterator_type
Definition: json.hpp:6508
detail::lexer::get_error_message
constexpr const JSON_HEDLEY_RETURNS_NON_NULL char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8845
basic_json::array_t
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:19643
detail::is_constructible_object_type_impl
Definition: json.hpp:3785
detail::output_adapter::output_adapter
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:15040
basic_json::json_value
json_value(const object_t &value)
constructor for objects
Definition: json.hpp:19833
lexyd::p
constexpr auto p
Parses the production.
Definition: production.hpp:127
NLOHMANN_JSON_NAMESPACE_BEGIN
#define NLOHMANN_JSON_NAMESPACE_BEGIN
Definition: json.hpp:134
basic_json::at
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:21240
ordered_map::operator[]
const T & operator[](const key_type &key) const
Definition: json.hpp:19098
byte_container_with_subtype::operator!=
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5931
detail::external_constructor< value_t::string >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:5447
basic_json::json_pointer
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:19468
detail::json_ref::value_type
BasicJsonType value_type
Definition: json.hpp:14822
detail::start_object_function_t
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:9063
detail::primitive_iterator_t::operator==
constexpr friend bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12773
detail::serializer::serializer
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:18075
detail::lexer_base
Definition: json.hpp:7406
basic_json::value
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21629
detail::from_json_function
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3520
detail::binary_writer::get_msgpack_float_prefix
static constexpr CharType get_msgpack_float_prefix(double)
Definition: json.hpp:16348
detail::iteration_proxy::end
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:5332
detail::json_sax_acceptor::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:7293
detail::span_input_adapter::span_input_adapter
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6620
basic_json::number_unsigned_t
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:19659
detail::iter_impl::operator=
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:13028
detail::is_compatible_type
Definition: json.hpp:3946
detail::iterator_category_t
typename T::iterator_category iterator_category_t
Definition: json.hpp:3514
detail::json_sax_dom_callback_parser::is_errored
constexpr bool is_errored() const
Definition: json.hpp:7183
json_sax::number_float
virtual bool number_float(number_float_t val, const string_t &s)=0
a floating-point number was read
basic_json::const_reverse_iterator
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:19536
detail::make_array
constexpr std::array< T, sizeof...(Args)> make_array(Args &&... args)
Definition: json.hpp:3222
detail::is_range::value
static constexpr bool value
Definition: json.hpp:3740
detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::reference
T & reference
Definition: json.hpp:3307
lexyd::find
constexpr auto find(Literals... literals)
Recovers once it finds one of the given literal tokens (without consuming them).
Definition: recover.hpp:124
detail::parser::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:12230
detail::parse_event_t
parse_event_t
Definition: json.hpp:12202
detail::start_array_function_t
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:9074
basic_json::const_pointer
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:19527
basic_json::json_value
json_value(string_t &&value)
constructor for rvalue strings
Definition: json.hpp:19830
basic_json::to_cbor
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23539
detail::output_adapter::output_adapter
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:15044
detail::dtoa_impl::diyfp::e
int e
Definition: json.hpp:16969
detail::json_sax_dom_parser::is_errored
constexpr bool is_errored() const
Definition: json.hpp:6933
json_sax::end_object
virtual bool end_object()=0
the end of an object was read
basic_json::set_parents
void set_parents()
Definition: json.hpp:20005
json_sax::boolean
virtual bool boolean(bool val)=0
a boolean value was read
detail::iterator_input_adapter::empty
bool empty() const
Definition: json.hpp:6308
detail::primitive_iterator_t::operator++
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:12795
detail::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3095
detail::binary_reader::get_ubjson_high_precision_number
bool get_ubjson_high_precision_number()
Definition: json.hpp:11817
detail::is_compatible_integer_type
Definition: json.hpp:3929
detail::conjunction
Definition: json.hpp:3660
detail::make_index_sequence
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3191
basic_json::json_value
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.hpp:19747
basic_json::is_object
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:20659
detail::detector< Default, void_t< Op< Args... > >, Op, Args... >::value_t
std::true_type value_t
Definition: json.hpp:289
JSON_NO_UNIQUE_ADDRESS
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.hpp:2505
detail::json_sax_acceptor::number_float
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:7318
detail::iterator_input_adapter::end
IteratorType end
Definition: json.hpp:6303
detail::from_json_inplace_array_impl
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:4904
detail::json_reverse_iterator::key
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:13739
detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::value_type
T value_type
Definition: json.hpp:3304
detail::iteration_proxy_value::array_index
std::size_t array_index
an index for arrays (used to create key names)
Definition: json.hpp:5199
detail::parse_error::byte
const std::size_t byte
byte index of the parse error
Definition: json.hpp:4507
detail::is_constructible_string_type::value
static constexpr auto value
Definition: json.hpp:3833
detail::iteration_proxy_value::array_index_str
string_type array_index_str
a string representation of the array index
Definition: json.hpp:5203
detail::output_string_adapter::write_character
void write_character(CharType c) override
Definition: json.hpp:15020
zmq::operator<=
bool operator<=(const detail::socket_base &a, const detail::socket_base &b) ZMQ_NOTHROW
Definition: 3rdparty/cppzmq/zmq.hpp:2129
json_pointer::string_t_helper::type
T type
Definition: json.hpp:13852
detail::json_sax_dom_parser
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:6799
detail::concat_into
void concat_into(OutStringType &)
Definition: json.hpp:4265
detail::is_usable_as_key_type
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:4000
detail::input_format_t::bjdata
@ bjdata
detail::is_constructible_tuple
Definition: json.hpp:3950
lexy::_detail::type_name
constexpr const char * type_name()
Definition: type_name.hpp:96
detail::external_constructor< value_t::number_float >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:5493
detail::json_ref::json_ref
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:14832
detail::boolean_function_t
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:9039
json_pointer::get_unchecked
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition: json.hpp:14285


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:07