Goby3  3.1.4
2024.02.22
json.hpp
Go to the documentation of this file.
1 // __ _____ _____ _____
2 // __| | __| | | | JSON for Modern C++
3 // | | |__ | | | | | | version 3.11.2
4 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5 //
6 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7 // SPDX-License-Identifier: MIT
8 
9 /****************************************************************************\
10  * Note on documentation: The source files contain links to the online *
11  * documentation of the public API at https://json.nlohmann.me. This URL *
12  * contains the most recent documentation and should also be applicable to *
13  * previous versions; documentation for deprecated functions is not *
14  * removed, but marked deprecated. See "Generate documentation" section in *
15  * file docs/README.md. *
16 \****************************************************************************/
17 
18 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
19 #define INCLUDE_NLOHMANN_JSON_HPP_
20 
21 #include <algorithm> // all_of, find, for_each
22 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
23 #include <functional> // hash, less
24 #include <initializer_list> // initializer_list
25 #ifndef JSON_NO_IO
26  #include <iosfwd> // istream, ostream
27 #endif // JSON_NO_IO
28 #include <iterator> // random_access_iterator_tag
29 #include <memory> // unique_ptr
30 #include <numeric> // accumulate
31 #include <string> // string, stoi, to_string
32 #include <utility> // declval, forward, move, pair, swap
33 #include <vector> // vector
34 
35 // #include <nlohmann/adl_serializer.hpp>
36 // __ _____ _____ _____
37 // __| | __| | | | JSON for Modern C++
38 // | | |__ | | | | | | version 3.11.2
39 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
40 //
41 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
42 // SPDX-License-Identifier: MIT
43 
44 
45 
46 #include <utility>
47 
48 // #include <nlohmann/detail/abi_macros.hpp>
49 // __ _____ _____ _____
50 // __| | __| | | | JSON for Modern C++
51 // | | |__ | | | | | | version 3.11.2
52 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
53 //
54 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
55 // SPDX-License-Identifier: MIT
56 
57 
58 
59 // This file contains all macro definitions affecting or depending on the ABI
60 
61 #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
62  #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
63  #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 2
64  #warning "Already included a different version of the library!"
65  #endif
66  #endif
67 #endif
68 
69 #define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
70 #define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum)
71 #define NLOHMANN_JSON_VERSION_PATCH 2 // NOLINT(modernize-macro-to-enum)
72 
73 #ifndef JSON_DIAGNOSTICS
74  #define JSON_DIAGNOSTICS 0
75 #endif
76 
77 #ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
78  #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
79 #endif
80 
81 #if JSON_DIAGNOSTICS
82  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
83 #else
84  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
85 #endif
86 
87 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
88  #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
89 #else
90  #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
91 #endif
92 
93 #ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
94  #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
95 #endif
96 
97 // Construct the namespace ABI tags component
98 #define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
99 #define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
100  NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
101 
102 #define NLOHMANN_JSON_ABI_TAGS \
103  NLOHMANN_JSON_ABI_TAGS_CONCAT( \
104  NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
105  NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
106 
107 // Construct the namespace version component
108 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
109  _v ## major ## _ ## minor ## _ ## patch
110 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
111  NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
112 
113 #if NLOHMANN_JSON_NAMESPACE_NO_VERSION
114 #define NLOHMANN_JSON_NAMESPACE_VERSION
115 #else
116 #define NLOHMANN_JSON_NAMESPACE_VERSION \
117  NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
118  NLOHMANN_JSON_VERSION_MINOR, \
119  NLOHMANN_JSON_VERSION_PATCH)
120 #endif
121 
122 // Combine namespace components
123 #define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
124 #define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
125  NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
126 
127 #ifndef NLOHMANN_JSON_NAMESPACE
128 #define NLOHMANN_JSON_NAMESPACE \
129  nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
130  NLOHMANN_JSON_ABI_TAGS, \
131  NLOHMANN_JSON_NAMESPACE_VERSION)
132 #endif
133 
134 #ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
135 #define NLOHMANN_JSON_NAMESPACE_BEGIN \
136  namespace nlohmann \
137  { \
138  inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
139  NLOHMANN_JSON_ABI_TAGS, \
140  NLOHMANN_JSON_NAMESPACE_VERSION) \
141  {
142 #endif
143 
144 #ifndef NLOHMANN_JSON_NAMESPACE_END
145 #define NLOHMANN_JSON_NAMESPACE_END \
146  } /* namespace (inline namespace) NOLINT(readability/namespace) */ \
147  } // namespace nlohmann
148 #endif
149 
150 // #include <nlohmann/detail/conversions/from_json.hpp>
151 // __ _____ _____ _____
152 // __| | __| | | | JSON for Modern C++
153 // | | |__ | | | | | | version 3.11.2
154 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
155 //
156 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
157 // SPDX-License-Identifier: MIT
158 
159 
160 
161 #include <algorithm> // transform
162 #include <array> // array
163 #include <forward_list> // forward_list
164 #include <iterator> // inserter, front_inserter, end
165 #include <map> // map
166 #include <string> // string
167 #include <tuple> // tuple, make_tuple
168 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
169 #include <unordered_map> // unordered_map
170 #include <utility> // pair, declval
171 #include <valarray> // valarray
172 
173 // #include <nlohmann/detail/exceptions.hpp>
174 // __ _____ _____ _____
175 // __| | __| | | | JSON for Modern C++
176 // | | |__ | | | | | | version 3.11.2
177 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
178 //
179 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
180 // SPDX-License-Identifier: MIT
181 
182 
183 
184 #include <cstddef> // nullptr_t
185 #include <exception> // exception
186 #include <stdexcept> // runtime_error
187 #include <string> // to_string
188 #include <vector> // vector
189 
190 // #include <nlohmann/detail/value_t.hpp>
191 // __ _____ _____ _____
192 // __| | __| | | | JSON for Modern C++
193 // | | |__ | | | | | | version 3.11.2
194 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
195 //
196 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
197 // SPDX-License-Identifier: MIT
198 
199 
200 
201 #include <array> // array
202 #include <cstddef> // size_t
203 #include <cstdint> // uint8_t
204 #include <string> // string
205 
206 // #include <nlohmann/detail/macro_scope.hpp>
207 // __ _____ _____ _____
208 // __| | __| | | | JSON for Modern C++
209 // | | |__ | | | | | | version 3.11.2
210 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
211 //
212 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
213 // SPDX-License-Identifier: MIT
214 
215 
216 
217 #include <utility> // declval, pair
218 // #include <nlohmann/detail/meta/detected.hpp>
219 // __ _____ _____ _____
220 // __| | __| | | | JSON for Modern C++
221 // | | |__ | | | | | | version 3.11.2
222 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
223 //
224 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
225 // SPDX-License-Identifier: MIT
226 
227 
228 
229 #include <type_traits>
230 
231 // #include <nlohmann/detail/meta/void_t.hpp>
232 // __ _____ _____ _____
233 // __| | __| | | | JSON for Modern C++
234 // | | |__ | | | | | | version 3.11.2
235 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
236 //
237 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
238 // SPDX-License-Identifier: MIT
239 
240 
241 
242 // #include <nlohmann/detail/abi_macros.hpp>
243 
244 
246 namespace detail
247 {
248 
249 template<typename ...Ts> struct make_void
250 {
251  using type = void;
252 };
253 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
254 
255 } // namespace detail
257 
258 
260 namespace detail
261 {
262 
263 // https://en.cppreference.com/w/cpp/experimental/is_detected
264 struct nonesuch
265 {
266  nonesuch() = delete;
267  ~nonesuch() = delete;
268  nonesuch(nonesuch const&) = delete;
269  nonesuch(nonesuch const&&) = delete;
270  void operator=(nonesuch const&) = delete;
271  void operator=(nonesuch&&) = delete;
272 };
273 
274 template<class Default,
275  class AlwaysVoid,
276  template<class...> class Op,
277  class... Args>
278 struct detector
279 {
280  using value_t = std::false_type;
281  using type = Default;
282 };
283 
284 template<class Default, template<class...> class Op, class... Args>
285 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
286 {
287  using value_t = std::true_type;
288  using type = Op<Args...>;
289 };
290 
291 template<template<class...> class Op, class... Args>
292 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
293 
294 template<template<class...> class Op, class... Args>
295 struct is_detected_lazy : is_detected<Op, Args...> { };
296 
297 template<template<class...> class Op, class... Args>
298 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
299 
300 template<class Default, template<class...> class Op, class... Args>
301 using detected_or = detector<Default, void, Op, Args...>;
302 
303 template<class Default, template<class...> class Op, class... Args>
304 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
305 
306 template<class Expected, template<class...> class Op, class... Args>
307 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
308 
309 template<class To, template<class...> class Op, class... Args>
311  std::is_convertible<detected_t<Op, Args...>, To>;
312 
313 } // namespace detail
315 
316 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
317 
318 
319 // __ _____ _____ _____
320 // __| | __| | | | JSON for Modern C++
321 // | | |__ | | | | | | version 3.11.2
322 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
323 //
324 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
325 // SPDX-FileCopyrightText: 2016-2021 Evan Nemerson <evan@nemerson.com>
326 // SPDX-License-Identifier: MIT
327 
328 /* Hedley - https://nemequ.github.io/hedley
329  * Created by Evan Nemerson <evan@nemerson.com>
330  */
331 
332 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
333 #if defined(JSON_HEDLEY_VERSION)
334  #undef JSON_HEDLEY_VERSION
335 #endif
336 #define JSON_HEDLEY_VERSION 15
337 
338 #if defined(JSON_HEDLEY_STRINGIFY_EX)
339  #undef JSON_HEDLEY_STRINGIFY_EX
340 #endif
341 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
342 
343 #if defined(JSON_HEDLEY_STRINGIFY)
344  #undef JSON_HEDLEY_STRINGIFY
345 #endif
346 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
347 
348 #if defined(JSON_HEDLEY_CONCAT_EX)
349  #undef JSON_HEDLEY_CONCAT_EX
350 #endif
351 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
352 
353 #if defined(JSON_HEDLEY_CONCAT)
354  #undef JSON_HEDLEY_CONCAT
355 #endif
356 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
357 
358 #if defined(JSON_HEDLEY_CONCAT3_EX)
359  #undef JSON_HEDLEY_CONCAT3_EX
360 #endif
361 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
362 
363 #if defined(JSON_HEDLEY_CONCAT3)
364  #undef JSON_HEDLEY_CONCAT3
365 #endif
366 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
367 
368 #if defined(JSON_HEDLEY_VERSION_ENCODE)
369  #undef JSON_HEDLEY_VERSION_ENCODE
370 #endif
371 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
372 
373 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
374  #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
375 #endif
376 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
377 
378 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
379  #undef JSON_HEDLEY_VERSION_DECODE_MINOR
380 #endif
381 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
382 
383 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
384  #undef JSON_HEDLEY_VERSION_DECODE_REVISION
385 #endif
386 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
387 
388 #if defined(JSON_HEDLEY_GNUC_VERSION)
389  #undef JSON_HEDLEY_GNUC_VERSION
390 #endif
391 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
392  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
393 #elif defined(__GNUC__)
394  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
395 #endif
396 
397 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
398  #undef JSON_HEDLEY_GNUC_VERSION_CHECK
399 #endif
400 #if defined(JSON_HEDLEY_GNUC_VERSION)
401  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
402 #else
403  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
404 #endif
405 
406 #if defined(JSON_HEDLEY_MSVC_VERSION)
407  #undef JSON_HEDLEY_MSVC_VERSION
408 #endif
409 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
410  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
411 #elif defined(_MSC_FULL_VER) && !defined(__ICL)
412  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
413 #elif defined(_MSC_VER) && !defined(__ICL)
414  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
415 #endif
416 
417 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
418  #undef JSON_HEDLEY_MSVC_VERSION_CHECK
419 #endif
420 #if !defined(JSON_HEDLEY_MSVC_VERSION)
421  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
422 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
423  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
424 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
425  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
426 #else
427  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
428 #endif
429 
430 #if defined(JSON_HEDLEY_INTEL_VERSION)
431  #undef JSON_HEDLEY_INTEL_VERSION
432 #endif
433 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
434  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
435 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
436  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
437 #endif
438 
439 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
440  #undef JSON_HEDLEY_INTEL_VERSION_CHECK
441 #endif
442 #if defined(JSON_HEDLEY_INTEL_VERSION)
443  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
444 #else
445  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
446 #endif
447 
448 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
449  #undef JSON_HEDLEY_INTEL_CL_VERSION
450 #endif
451 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
452  #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
453 #endif
454 
455 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
456  #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
457 #endif
458 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
459  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
460 #else
461  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
462 #endif
463 
464 #if defined(JSON_HEDLEY_PGI_VERSION)
465  #undef JSON_HEDLEY_PGI_VERSION
466 #endif
467 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
468  #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
469 #endif
470 
471 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
472  #undef JSON_HEDLEY_PGI_VERSION_CHECK
473 #endif
474 #if defined(JSON_HEDLEY_PGI_VERSION)
475  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
476 #else
477  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
478 #endif
479 
480 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
481  #undef JSON_HEDLEY_SUNPRO_VERSION
482 #endif
483 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
484  #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)
485 #elif defined(__SUNPRO_C)
486  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
487 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
488  #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)
489 #elif defined(__SUNPRO_CC)
490  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
491 #endif
492 
493 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
494  #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
495 #endif
496 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
497  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
498 #else
499  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
500 #endif
501 
502 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
503  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
504 #endif
505 #if defined(__EMSCRIPTEN__)
506  #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
507 #endif
508 
509 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
510  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
511 #endif
512 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
513  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
514 #else
515  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
516 #endif
517 
518 #if defined(JSON_HEDLEY_ARM_VERSION)
519  #undef JSON_HEDLEY_ARM_VERSION
520 #endif
521 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
522  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
523 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
524  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
525 #endif
526 
527 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
528  #undef JSON_HEDLEY_ARM_VERSION_CHECK
529 #endif
530 #if defined(JSON_HEDLEY_ARM_VERSION)
531  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
532 #else
533  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
534 #endif
535 
536 #if defined(JSON_HEDLEY_IBM_VERSION)
537  #undef JSON_HEDLEY_IBM_VERSION
538 #endif
539 #if defined(__ibmxl__)
540  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
541 #elif defined(__xlC__) && defined(__xlC_ver__)
542  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
543 #elif defined(__xlC__)
544  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
545 #endif
546 
547 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
548  #undef JSON_HEDLEY_IBM_VERSION_CHECK
549 #endif
550 #if defined(JSON_HEDLEY_IBM_VERSION)
551  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
552 #else
553  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
554 #endif
555 
556 #if defined(JSON_HEDLEY_TI_VERSION)
557  #undef JSON_HEDLEY_TI_VERSION
558 #endif
559 #if \
560  defined(__TI_COMPILER_VERSION__) && \
561  ( \
562  defined(__TMS470__) || defined(__TI_ARM__) || \
563  defined(__MSP430__) || \
564  defined(__TMS320C2000__) \
565  )
566 #if (__TI_COMPILER_VERSION__ >= 16000000)
567  #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
568 #endif
569 #endif
570 
571 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
572  #undef JSON_HEDLEY_TI_VERSION_CHECK
573 #endif
574 #if defined(JSON_HEDLEY_TI_VERSION)
575  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
576 #else
577  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
578 #endif
579 
580 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
581  #undef JSON_HEDLEY_TI_CL2000_VERSION
582 #endif
583 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
584  #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
585 #endif
586 
587 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
588  #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
589 #endif
590 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
591  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
592 #else
593  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
594 #endif
595 
596 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
597  #undef JSON_HEDLEY_TI_CL430_VERSION
598 #endif
599 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
600  #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
601 #endif
602 
603 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
604  #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
605 #endif
606 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
607  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
608 #else
609  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
610 #endif
611 
612 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
613  #undef JSON_HEDLEY_TI_ARMCL_VERSION
614 #endif
615 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
616  #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
617 #endif
618 
619 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
620  #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
621 #endif
622 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
623  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
624 #else
625  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
626 #endif
627 
628 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
629  #undef JSON_HEDLEY_TI_CL6X_VERSION
630 #endif
631 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
632  #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
633 #endif
634 
635 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
636  #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
637 #endif
638 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
639  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
640 #else
641  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
642 #endif
643 
644 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
645  #undef JSON_HEDLEY_TI_CL7X_VERSION
646 #endif
647 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
648  #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
649 #endif
650 
651 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
652  #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
653 #endif
654 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
655  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
656 #else
657  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
658 #endif
659 
660 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
661  #undef JSON_HEDLEY_TI_CLPRU_VERSION
662 #endif
663 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
664  #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
665 #endif
666 
667 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
668  #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
669 #endif
670 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
671  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
672 #else
673  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
674 #endif
675 
676 #if defined(JSON_HEDLEY_CRAY_VERSION)
677  #undef JSON_HEDLEY_CRAY_VERSION
678 #endif
679 #if defined(_CRAYC)
680  #if defined(_RELEASE_PATCHLEVEL)
681  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
682  #else
683  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
684  #endif
685 #endif
686 
687 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
688  #undef JSON_HEDLEY_CRAY_VERSION_CHECK
689 #endif
690 #if defined(JSON_HEDLEY_CRAY_VERSION)
691  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
692 #else
693  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
694 #endif
695 
696 #if defined(JSON_HEDLEY_IAR_VERSION)
697  #undef JSON_HEDLEY_IAR_VERSION
698 #endif
699 #if defined(__IAR_SYSTEMS_ICC__)
700  #if __VER__ > 1000
701  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
702  #else
703  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
704  #endif
705 #endif
706 
707 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
708  #undef JSON_HEDLEY_IAR_VERSION_CHECK
709 #endif
710 #if defined(JSON_HEDLEY_IAR_VERSION)
711  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
712 #else
713  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
714 #endif
715 
716 #if defined(JSON_HEDLEY_TINYC_VERSION)
717  #undef JSON_HEDLEY_TINYC_VERSION
718 #endif
719 #if defined(__TINYC__)
720  #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
721 #endif
722 
723 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
724  #undef JSON_HEDLEY_TINYC_VERSION_CHECK
725 #endif
726 #if defined(JSON_HEDLEY_TINYC_VERSION)
727  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
728 #else
729  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
730 #endif
731 
732 #if defined(JSON_HEDLEY_DMC_VERSION)
733  #undef JSON_HEDLEY_DMC_VERSION
734 #endif
735 #if defined(__DMC__)
736  #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
737 #endif
738 
739 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
740  #undef JSON_HEDLEY_DMC_VERSION_CHECK
741 #endif
742 #if defined(JSON_HEDLEY_DMC_VERSION)
743  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
744 #else
745  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
746 #endif
747 
748 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
749  #undef JSON_HEDLEY_COMPCERT_VERSION
750 #endif
751 #if defined(__COMPCERT_VERSION__)
752  #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
753 #endif
754 
755 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
756  #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
757 #endif
758 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
759  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
760 #else
761  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
762 #endif
763 
764 #if defined(JSON_HEDLEY_PELLES_VERSION)
765  #undef JSON_HEDLEY_PELLES_VERSION
766 #endif
767 #if defined(__POCC__)
768  #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
769 #endif
770 
771 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
772  #undef JSON_HEDLEY_PELLES_VERSION_CHECK
773 #endif
774 #if defined(JSON_HEDLEY_PELLES_VERSION)
775  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
776 #else
777  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
778 #endif
779 
780 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
781  #undef JSON_HEDLEY_MCST_LCC_VERSION
782 #endif
783 #if defined(__LCC__) && defined(__LCC_MINOR__)
784  #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
785 #endif
786 
787 #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
788  #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
789 #endif
790 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
791  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
792 #else
793  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
794 #endif
795 
796 #if defined(JSON_HEDLEY_GCC_VERSION)
797  #undef JSON_HEDLEY_GCC_VERSION
798 #endif
799 #if \
800  defined(JSON_HEDLEY_GNUC_VERSION) && \
801  !defined(__clang__) && \
802  !defined(JSON_HEDLEY_INTEL_VERSION) && \
803  !defined(JSON_HEDLEY_PGI_VERSION) && \
804  !defined(JSON_HEDLEY_ARM_VERSION) && \
805  !defined(JSON_HEDLEY_CRAY_VERSION) && \
806  !defined(JSON_HEDLEY_TI_VERSION) && \
807  !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
808  !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
809  !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
810  !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
811  !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
812  !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
813  !defined(__COMPCERT__) && \
814  !defined(JSON_HEDLEY_MCST_LCC_VERSION)
815  #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
816 #endif
817 
818 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
819  #undef JSON_HEDLEY_GCC_VERSION_CHECK
820 #endif
821 #if defined(JSON_HEDLEY_GCC_VERSION)
822  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
823 #else
824  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
825 #endif
826 
827 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
828  #undef JSON_HEDLEY_HAS_ATTRIBUTE
829 #endif
830 #if \
831  defined(__has_attribute) && \
832  ( \
833  (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
834  )
835 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
836 #else
837 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
838 #endif
839 
840 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
841  #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
842 #endif
843 #if defined(__has_attribute)
844  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
845 #else
846  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
847 #endif
848 
849 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
850  #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
851 #endif
852 #if defined(__has_attribute)
853  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
854 #else
855  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
856 #endif
857 
858 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
859  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
860 #endif
861 #if \
862  defined(__has_cpp_attribute) && \
863  defined(__cplusplus) && \
864  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
865  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
866 #else
867  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
868 #endif
869 
870 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
871  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
872 #endif
873 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
874  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
875 #elif \
876  !defined(JSON_HEDLEY_PGI_VERSION) && \
877  !defined(JSON_HEDLEY_IAR_VERSION) && \
878  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
879  (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
880  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
881 #else
882  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
883 #endif
884 
885 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
886  #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
887 #endif
888 #if defined(__has_cpp_attribute) && defined(__cplusplus)
889  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
890 #else
891  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
892 #endif
893 
894 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
895  #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
896 #endif
897 #if defined(__has_cpp_attribute) && defined(__cplusplus)
898  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
899 #else
900  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
901 #endif
902 
903 #if defined(JSON_HEDLEY_HAS_BUILTIN)
904  #undef JSON_HEDLEY_HAS_BUILTIN
905 #endif
906 #if defined(__has_builtin)
907  #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
908 #else
909  #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
910 #endif
911 
912 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
913  #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
914 #endif
915 #if defined(__has_builtin)
916  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
917 #else
918  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
919 #endif
920 
921 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
922  #undef JSON_HEDLEY_GCC_HAS_BUILTIN
923 #endif
924 #if defined(__has_builtin)
925  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
926 #else
927  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
928 #endif
929 
930 #if defined(JSON_HEDLEY_HAS_FEATURE)
931  #undef JSON_HEDLEY_HAS_FEATURE
932 #endif
933 #if defined(__has_feature)
934  #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
935 #else
936  #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
937 #endif
938 
939 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
940  #undef JSON_HEDLEY_GNUC_HAS_FEATURE
941 #endif
942 #if defined(__has_feature)
943  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
944 #else
945  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
946 #endif
947 
948 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
949  #undef JSON_HEDLEY_GCC_HAS_FEATURE
950 #endif
951 #if defined(__has_feature)
952  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
953 #else
954  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
955 #endif
956 
957 #if defined(JSON_HEDLEY_HAS_EXTENSION)
958  #undef JSON_HEDLEY_HAS_EXTENSION
959 #endif
960 #if defined(__has_extension)
961  #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
962 #else
963  #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
964 #endif
965 
966 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
967  #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
968 #endif
969 #if defined(__has_extension)
970  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
971 #else
972  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
973 #endif
974 
975 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
976  #undef JSON_HEDLEY_GCC_HAS_EXTENSION
977 #endif
978 #if defined(__has_extension)
979  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
980 #else
981  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
982 #endif
983 
984 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
985  #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
986 #endif
987 #if defined(__has_declspec_attribute)
988  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
989 #else
990  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
991 #endif
992 
993 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
994  #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
995 #endif
996 #if defined(__has_declspec_attribute)
997  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
998 #else
999  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1000 #endif
1001 
1002 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
1003  #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
1004 #endif
1005 #if defined(__has_declspec_attribute)
1006  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1007 #else
1008  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1009 #endif
1010 
1011 #if defined(JSON_HEDLEY_HAS_WARNING)
1012  #undef JSON_HEDLEY_HAS_WARNING
1013 #endif
1014 #if defined(__has_warning)
1015  #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
1016 #else
1017  #define JSON_HEDLEY_HAS_WARNING(warning) (0)
1018 #endif
1019 
1020 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
1021  #undef JSON_HEDLEY_GNUC_HAS_WARNING
1022 #endif
1023 #if defined(__has_warning)
1024  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1025 #else
1026  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1027 #endif
1028 
1029 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
1030  #undef JSON_HEDLEY_GCC_HAS_WARNING
1031 #endif
1032 #if defined(__has_warning)
1033  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1034 #else
1035  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1036 #endif
1037 
1038 #if \
1039  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1040  defined(__clang__) || \
1041  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1042  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1043  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1044  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1045  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1046  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1047  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1048  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1049  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1050  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
1051  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1052  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1053  JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
1054  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
1055  JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
1056  (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
1057  #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
1058 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1059  #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
1060 #else
1061  #define JSON_HEDLEY_PRAGMA(value)
1062 #endif
1063 
1064 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
1065  #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
1066 #endif
1067 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
1068  #undef JSON_HEDLEY_DIAGNOSTIC_POP
1069 #endif
1070 #if defined(__clang__)
1071  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
1072  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
1073 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1074  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1075  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1076 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1077  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
1078  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
1079 #elif \
1080  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1081  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1082  #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
1083  #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
1084 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
1085  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
1086  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
1087 #elif \
1088  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1089  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1090  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
1091  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1092  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1093  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1094  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
1095  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
1096 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1097  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1098  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1099 #else
1100  #define JSON_HEDLEY_DIAGNOSTIC_PUSH
1101  #define JSON_HEDLEY_DIAGNOSTIC_POP
1102 #endif
1103 
1104 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
1105  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1106 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1107  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
1108 #endif
1109 #if defined(__cplusplus)
1110 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
1111 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
1112 # if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
1113 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1114  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1115  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1116  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1117  _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
1118  xpr \
1119  JSON_HEDLEY_DIAGNOSTIC_POP
1120 # else
1121 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1122  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1123  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1124  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1125  xpr \
1126  JSON_HEDLEY_DIAGNOSTIC_POP
1127 # endif
1128 # else
1129 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1130  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1131  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1132  xpr \
1133  JSON_HEDLEY_DIAGNOSTIC_POP
1134 # endif
1135 # endif
1136 #endif
1137 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1138  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1139 #endif
1140 
1141 #if defined(JSON_HEDLEY_CONST_CAST)
1142  #undef JSON_HEDLEY_CONST_CAST
1143 #endif
1144 #if defined(__cplusplus)
1145 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1146 #elif \
1147  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1148  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1149  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1150 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1151  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1152  JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1153  ((T) (expr)); \
1154  JSON_HEDLEY_DIAGNOSTIC_POP \
1155  }))
1156 #else
1157 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1158 #endif
1159 
1160 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
1161  #undef JSON_HEDLEY_REINTERPRET_CAST
1162 #endif
1163 #if defined(__cplusplus)
1164  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1165 #else
1166  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1167 #endif
1168 
1169 #if defined(JSON_HEDLEY_STATIC_CAST)
1170  #undef JSON_HEDLEY_STATIC_CAST
1171 #endif
1172 #if defined(__cplusplus)
1173  #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1174 #else
1175  #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1176 #endif
1177 
1178 #if defined(JSON_HEDLEY_CPP_CAST)
1179  #undef JSON_HEDLEY_CPP_CAST
1180 #endif
1181 #if defined(__cplusplus)
1182 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1183 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1184  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1185  _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1186  ((T) (expr)) \
1187  JSON_HEDLEY_DIAGNOSTIC_POP
1188 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1189 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1190  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1191  _Pragma("diag_suppress=Pe137") \
1192  JSON_HEDLEY_DIAGNOSTIC_POP
1193 # else
1194 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1195 # endif
1196 #else
1197 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1198 #endif
1199 
1200 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1201  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1202 #endif
1203 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1204  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1205 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1206  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1207 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1208  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1209 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1210  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1211 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1212  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1213 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1214  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1215 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1216  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1217 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1218  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1219 #elif \
1220  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1221  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1222  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1223  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1225  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1227  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1229  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1230  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1231  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1232 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1233  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1234 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1235  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1236 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1237  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1238 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1239  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1240 #else
1241  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1242 #endif
1243 
1244 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1245  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1246 #endif
1247 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1248  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1249 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1250  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1251 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1252  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1253 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1254  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1255 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1256  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1257 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1258  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1259 #elif \
1260  JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1261  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1262  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1263  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1264  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1265 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1266  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1267 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1268  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1269 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1270  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1271 #else
1272  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1273 #endif
1274 
1275 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1276  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1277 #endif
1278 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1279  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1280 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1281  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1282 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1283  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1284 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1285  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1286 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1287  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1288 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1289  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1290 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1291  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1292 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1293  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1294 #elif \
1295  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1296  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1297  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1298  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1299 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1300  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1301 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1302  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1303 #else
1304  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1305 #endif
1306 
1307 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1308  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1309 #endif
1310 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1311  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1312 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1313  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1314 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1315  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1316 #else
1317  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1318 #endif
1319 
1320 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1321  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1322 #endif
1323 #if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1324  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1325 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1326  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1327 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1328  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1329 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1330  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1331 #else
1332  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1333 #endif
1334 
1335 #if defined(JSON_HEDLEY_DEPRECATED)
1336  #undef JSON_HEDLEY_DEPRECATED
1337 #endif
1338 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1339  #undef JSON_HEDLEY_DEPRECATED_FOR
1340 #endif
1341 #if \
1342  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1343  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1344  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1345  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1346 #elif \
1347  (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1348  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1349  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1350  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1351  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1352  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1353  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1354  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1355  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1356  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1357  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1358  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1359  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1360  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1361 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1362  #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1363  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1364 #elif \
1365  JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1366  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1367  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1368  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1369  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1370  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1371  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1372  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1373  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1374  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1375  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1376  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1377  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1378  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1379  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1380  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1381  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1382  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1383 #elif \
1384  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1385  JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1386  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1387  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1388  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1389 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1390  #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1391  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1392 #else
1393  #define JSON_HEDLEY_DEPRECATED(since)
1394  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1395 #endif
1396 
1397 #if defined(JSON_HEDLEY_UNAVAILABLE)
1398  #undef JSON_HEDLEY_UNAVAILABLE
1399 #endif
1400 #if \
1401  JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1402  JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1403  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1404  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1405  #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1406 #else
1407  #define JSON_HEDLEY_UNAVAILABLE(available_since)
1408 #endif
1409 
1410 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1411  #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1412 #endif
1413 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1414  #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1415 #endif
1416 #if \
1417  JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1418  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1419  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1420  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1421  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1422  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1423  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1424  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1425  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1426  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1427  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1428  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1429  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1430  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1431  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1432  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1433  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1434  #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1435  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1436 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1437  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1438  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1439 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1440  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1441  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1442 #elif defined(_Check_return_) /* SAL */
1443  #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1444  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1445 #else
1446  #define JSON_HEDLEY_WARN_UNUSED_RESULT
1447  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1448 #endif
1449 
1450 #if defined(JSON_HEDLEY_SENTINEL)
1451  #undef JSON_HEDLEY_SENTINEL
1452 #endif
1453 #if \
1454  JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1455  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1456  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1457  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1458  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1459  #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1460 #else
1461  #define JSON_HEDLEY_SENTINEL(position)
1462 #endif
1463 
1464 #if defined(JSON_HEDLEY_NO_RETURN)
1465  #undef JSON_HEDLEY_NO_RETURN
1466 #endif
1467 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1468  #define JSON_HEDLEY_NO_RETURN __noreturn
1469 #elif \
1470  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1471  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1472  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1473 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1474  #define JSON_HEDLEY_NO_RETURN _Noreturn
1475 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1476  #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1477 #elif \
1478  JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1479  JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1480  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1481  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1482  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1483  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1484  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1485  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1486  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1487  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1488  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1489  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1490  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1491  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1492  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1493  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1494  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1495  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1496 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1497  #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1498 #elif \
1499  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1500  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1501  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1502 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1503  #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1504 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1505  #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1506 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1507  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1508 #else
1509  #define JSON_HEDLEY_NO_RETURN
1510 #endif
1511 
1512 #if defined(JSON_HEDLEY_NO_ESCAPE)
1513  #undef JSON_HEDLEY_NO_ESCAPE
1514 #endif
1515 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1516  #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1517 #else
1518  #define JSON_HEDLEY_NO_ESCAPE
1519 #endif
1520 
1521 #if defined(JSON_HEDLEY_UNREACHABLE)
1522  #undef JSON_HEDLEY_UNREACHABLE
1523 #endif
1524 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1525  #undef JSON_HEDLEY_UNREACHABLE_RETURN
1526 #endif
1527 #if defined(JSON_HEDLEY_ASSUME)
1528  #undef JSON_HEDLEY_ASSUME
1529 #endif
1530 #if \
1531  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1532  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1533  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1534  #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1535 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1536  #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1537 #elif \
1538  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1539  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1540  #if defined(__cplusplus)
1541  #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1542  #else
1543  #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1544  #endif
1545 #endif
1546 #if \
1547  (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1548  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1549  JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1550  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1551  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1552  JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1553  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1554  #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1555 #elif defined(JSON_HEDLEY_ASSUME)
1556  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1557 #endif
1558 #if !defined(JSON_HEDLEY_ASSUME)
1559  #if defined(JSON_HEDLEY_UNREACHABLE)
1560  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1561  #else
1562  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1563  #endif
1564 #endif
1565 #if defined(JSON_HEDLEY_UNREACHABLE)
1566  #if \
1567  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1568  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1569  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1570  #else
1571  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1572  #endif
1573 #else
1574  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1575 #endif
1576 #if !defined(JSON_HEDLEY_UNREACHABLE)
1577  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1578 #endif
1579 
1581 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1582  #pragma clang diagnostic ignored "-Wpedantic"
1583 #endif
1584 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1585  #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1586 #endif
1587 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1588  #if defined(__clang__)
1589  #pragma clang diagnostic ignored "-Wvariadic-macros"
1590  #elif defined(JSON_HEDLEY_GCC_VERSION)
1591  #pragma GCC diagnostic ignored "-Wvariadic-macros"
1592  #endif
1593 #endif
1594 #if defined(JSON_HEDLEY_NON_NULL)
1595  #undef JSON_HEDLEY_NON_NULL
1596 #endif
1597 #if \
1598  JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1599  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1600  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1601  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1602  #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1603 #else
1604  #define JSON_HEDLEY_NON_NULL(...)
1605 #endif
1607 
1608 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1609  #undef JSON_HEDLEY_PRINTF_FORMAT
1610 #endif
1611 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1612  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1613 #elif 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__(gnu_printf, string_idx, first_to_check)))
1615 #elif \
1616  JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1617  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1618  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1619  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1620  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1621  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1622  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1624  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1625  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1626  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1627  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1628  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1629  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1630  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1631  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1632  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1633  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1634 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1635  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1636 #else
1637  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1638 #endif
1639 
1640 #if defined(JSON_HEDLEY_CONSTEXPR)
1641  #undef JSON_HEDLEY_CONSTEXPR
1642 #endif
1643 #if defined(__cplusplus)
1644  #if __cplusplus >= 201103L
1645  #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1646  #endif
1647 #endif
1648 #if !defined(JSON_HEDLEY_CONSTEXPR)
1649  #define JSON_HEDLEY_CONSTEXPR
1650 #endif
1651 
1652 #if defined(JSON_HEDLEY_PREDICT)
1653  #undef JSON_HEDLEY_PREDICT
1654 #endif
1655 #if defined(JSON_HEDLEY_LIKELY)
1656  #undef JSON_HEDLEY_LIKELY
1657 #endif
1658 #if defined(JSON_HEDLEY_UNLIKELY)
1659  #undef JSON_HEDLEY_UNLIKELY
1660 #endif
1661 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1662  #undef JSON_HEDLEY_UNPREDICTABLE
1663 #endif
1664 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1665  #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1666 #endif
1667 #if \
1668  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1669  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1670  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1671 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1672 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1673 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1674 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1675 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1676 #elif \
1677  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1678  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1679  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1680  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1681  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1682  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1683  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1684  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1685  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1686  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1687  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1688  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1689  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1690  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1691  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1692  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1693 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1694  (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1695 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1696  (__extension__ ({ \
1697  double hedley_probability_ = (probability); \
1698  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1699  }))
1700 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1701  (__extension__ ({ \
1702  double hedley_probability_ = (probability); \
1703  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1704  }))
1705 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1706 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1707 #else
1708 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1709 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1710 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1711 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1712 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1713 #endif
1714 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1715  #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1716 #endif
1717 
1718 #if defined(JSON_HEDLEY_MALLOC)
1719  #undef JSON_HEDLEY_MALLOC
1720 #endif
1721 #if \
1722  JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1723  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1724  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1725  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1726  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1727  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1728  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1729  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1730  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1731  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1732  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1733  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1734  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1735  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1736  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1737  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1738  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1739  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1740  #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1741 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1742  #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1743 #elif \
1744  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1745  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1746  #define JSON_HEDLEY_MALLOC __declspec(restrict)
1747 #else
1748  #define JSON_HEDLEY_MALLOC
1749 #endif
1750 
1751 #if defined(JSON_HEDLEY_PURE)
1752  #undef JSON_HEDLEY_PURE
1753 #endif
1754 #if \
1755  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1756  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1757  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1758  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1759  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1760  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1761  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1762  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1763  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1764  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1765  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1766  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1767  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1768  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1769  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1770  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1771  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1772  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1773  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1774 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1775 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1776 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1777 #elif defined(__cplusplus) && \
1778  ( \
1779  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1780  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1781  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1782  )
1783 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1784 #else
1785 # define JSON_HEDLEY_PURE
1786 #endif
1787 
1788 #if defined(JSON_HEDLEY_CONST)
1789  #undef JSON_HEDLEY_CONST
1790 #endif
1791 #if \
1792  JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1793  JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1794  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1795  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1796  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1797  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1798  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1799  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1800  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1801  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1802  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1803  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1804  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1805  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1806  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1807  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1808  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1809  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1810  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1811  #define JSON_HEDLEY_CONST __attribute__((__const__))
1812 #elif \
1813  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1814  #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1815 #else
1816  #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1817 #endif
1818 
1819 #if defined(JSON_HEDLEY_RESTRICT)
1820  #undef JSON_HEDLEY_RESTRICT
1821 #endif
1822 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1823  #define JSON_HEDLEY_RESTRICT restrict
1824 #elif \
1825  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1826  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1827  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1828  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1829  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1830  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1831  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1832  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1833  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1834  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1835  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1836  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1837  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1838  defined(__clang__) || \
1839  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1840  #define JSON_HEDLEY_RESTRICT __restrict
1841 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1842  #define JSON_HEDLEY_RESTRICT _Restrict
1843 #else
1844  #define JSON_HEDLEY_RESTRICT
1845 #endif
1846 
1847 #if defined(JSON_HEDLEY_INLINE)
1848  #undef JSON_HEDLEY_INLINE
1849 #endif
1850 #if \
1851  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1852  (defined(__cplusplus) && (__cplusplus >= 199711L))
1853  #define JSON_HEDLEY_INLINE inline
1854 #elif \
1855  defined(JSON_HEDLEY_GCC_VERSION) || \
1856  JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1857  #define JSON_HEDLEY_INLINE __inline__
1858 #elif \
1859  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1860  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1861  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1862  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1863  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1864  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1865  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1866  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1867  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1868  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1869  #define JSON_HEDLEY_INLINE __inline
1870 #else
1871  #define JSON_HEDLEY_INLINE
1872 #endif
1873 
1874 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1875  #undef JSON_HEDLEY_ALWAYS_INLINE
1876 #endif
1877 #if \
1878  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1879  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1880  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1881  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1882  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1883  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1884  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1885  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1886  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1887  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1888  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1889  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1890  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1891  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1892  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1893  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1894  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1895  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1896  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1897 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1898 #elif \
1899  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1900  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1901 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1902 #elif defined(__cplusplus) && \
1903  ( \
1904  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1905  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1906  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1907  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1908  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1909  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1910  )
1911 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1912 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1913 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1914 #else
1915 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1916 #endif
1917 
1918 #if defined(JSON_HEDLEY_NEVER_INLINE)
1919  #undef JSON_HEDLEY_NEVER_INLINE
1920 #endif
1921 #if \
1922  JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1923  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1924  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1925  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1926  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1927  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1928  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1929  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1930  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1931  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1932  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1933  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1934  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1935  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1936  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1937  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1938  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1939  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1940  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1941  #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1942 #elif \
1943  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1944  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1945  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1946 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1947  #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1948 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1949  #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1950 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1951  #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1952 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1953  #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1954 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1955  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1956 #else
1957  #define JSON_HEDLEY_NEVER_INLINE
1958 #endif
1959 
1960 #if defined(JSON_HEDLEY_PRIVATE)
1961  #undef JSON_HEDLEY_PRIVATE
1962 #endif
1963 #if defined(JSON_HEDLEY_PUBLIC)
1964  #undef JSON_HEDLEY_PUBLIC
1965 #endif
1966 #if defined(JSON_HEDLEY_IMPORT)
1967  #undef JSON_HEDLEY_IMPORT
1968 #endif
1969 #if defined(_WIN32) || defined(__CYGWIN__)
1970 # define JSON_HEDLEY_PRIVATE
1971 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1972 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1973 #else
1974 # if \
1975  JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1976  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1977  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1978  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1979  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1980  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1981  ( \
1982  defined(__TI_EABI__) && \
1983  ( \
1984  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1985  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1986  ) \
1987  ) || \
1988  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1989 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1990 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1991 # else
1992 # define JSON_HEDLEY_PRIVATE
1993 # define JSON_HEDLEY_PUBLIC
1994 # endif
1995 # define JSON_HEDLEY_IMPORT extern
1996 #endif
1997 
1998 #if defined(JSON_HEDLEY_NO_THROW)
1999  #undef JSON_HEDLEY_NO_THROW
2000 #endif
2001 #if \
2002  JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
2003  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
2004  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2005  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2006  #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
2007 #elif \
2008  JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
2009  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
2010  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
2011  #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
2012 #else
2013  #define JSON_HEDLEY_NO_THROW
2014 #endif
2015 
2016 #if defined(JSON_HEDLEY_FALL_THROUGH)
2017  #undef JSON_HEDLEY_FALL_THROUGH
2018 #endif
2019 #if \
2020  JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
2021  JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
2022  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2023  #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
2024 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
2025  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
2026 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
2027  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
2028 #elif defined(__fallthrough) /* SAL */
2029  #define JSON_HEDLEY_FALL_THROUGH __fallthrough
2030 #else
2031  #define JSON_HEDLEY_FALL_THROUGH
2032 #endif
2033 
2034 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
2035  #undef JSON_HEDLEY_RETURNS_NON_NULL
2036 #endif
2037 #if \
2038  JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
2039  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2040  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2041  #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
2042 #elif defined(_Ret_notnull_) /* SAL */
2043  #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
2044 #else
2045  #define JSON_HEDLEY_RETURNS_NON_NULL
2046 #endif
2047 
2048 #if defined(JSON_HEDLEY_ARRAY_PARAM)
2049  #undef JSON_HEDLEY_ARRAY_PARAM
2050 #endif
2051 #if \
2052  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
2053  !defined(__STDC_NO_VLA__) && \
2054  !defined(__cplusplus) && \
2055  !defined(JSON_HEDLEY_PGI_VERSION) && \
2056  !defined(JSON_HEDLEY_TINYC_VERSION)
2057  #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
2058 #else
2059  #define JSON_HEDLEY_ARRAY_PARAM(name)
2060 #endif
2061 
2062 #if defined(JSON_HEDLEY_IS_CONSTANT)
2063  #undef JSON_HEDLEY_IS_CONSTANT
2064 #endif
2065 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
2066  #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
2067 #endif
2068 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
2069  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
2070 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2071  #undef JSON_HEDLEY_IS_CONSTEXPR_
2072 #endif
2073 #if \
2074  JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
2075  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2076  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2077  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
2078  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2079  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2080  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
2081  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
2082  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2083  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2084  #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
2085 #endif
2086 #if !defined(__cplusplus)
2087 # if \
2088  JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
2089  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2090  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2091  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2092  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2093  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
2094  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
2095 #if defined(__INTPTR_TYPE__)
2096  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
2097 #else
2098  #include <stdint.h>
2099  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
2100 #endif
2101 # elif \
2102  ( \
2103  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
2104  !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
2105  !defined(JSON_HEDLEY_PGI_VERSION) && \
2106  !defined(JSON_HEDLEY_IAR_VERSION)) || \
2107  (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
2108  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2109  JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
2110  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
2111  JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
2112 #if defined(__INTPTR_TYPE__)
2113  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
2114 #else
2115  #include <stdint.h>
2116  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
2117 #endif
2118 # elif \
2119  defined(JSON_HEDLEY_GCC_VERSION) || \
2120  defined(JSON_HEDLEY_INTEL_VERSION) || \
2121  defined(JSON_HEDLEY_TINYC_VERSION) || \
2122  defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
2123  JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
2124  defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
2125  defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
2126  defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
2127  defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
2128  defined(__clang__)
2129 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2130  sizeof(void) != \
2131  sizeof(*( \
2132  1 ? \
2133  ((void*) ((expr) * 0L) ) : \
2134 ((struct { char v[sizeof(void) * 2]; } *) 1) \
2135  ) \
2136  ) \
2137  )
2138 # endif
2139 #endif
2140 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2141  #if !defined(JSON_HEDLEY_IS_CONSTANT)
2142  #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2143  #endif
2144  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2145 #else
2146  #if !defined(JSON_HEDLEY_IS_CONSTANT)
2147  #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2148  #endif
2149  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2150 #endif
2151 
2152 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2153  #undef JSON_HEDLEY_BEGIN_C_DECLS
2154 #endif
2155 #if defined(JSON_HEDLEY_END_C_DECLS)
2156  #undef JSON_HEDLEY_END_C_DECLS
2157 #endif
2158 #if defined(JSON_HEDLEY_C_DECL)
2159  #undef JSON_HEDLEY_C_DECL
2160 #endif
2161 #if defined(__cplusplus)
2162  #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2163  #define JSON_HEDLEY_END_C_DECLS }
2164  #define JSON_HEDLEY_C_DECL extern "C"
2165 #else
2166  #define JSON_HEDLEY_BEGIN_C_DECLS
2167  #define JSON_HEDLEY_END_C_DECLS
2168  #define JSON_HEDLEY_C_DECL
2169 #endif
2170 
2171 #if defined(JSON_HEDLEY_STATIC_ASSERT)
2172  #undef JSON_HEDLEY_STATIC_ASSERT
2173 #endif
2174 #if \
2175  !defined(__cplusplus) && ( \
2176  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2177  (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2178  JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2179  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2180  defined(_Static_assert) \
2181  )
2182 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2183 #elif \
2184  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2185  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2186  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2187 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2188 #else
2189 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2190 #endif
2191 
2192 #if defined(JSON_HEDLEY_NULL)
2193  #undef JSON_HEDLEY_NULL
2194 #endif
2195 #if defined(__cplusplus)
2196  #if __cplusplus >= 201103L
2197  #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2198  #elif defined(NULL)
2199  #define JSON_HEDLEY_NULL NULL
2200  #else
2201  #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2202  #endif
2203 #elif defined(NULL)
2204  #define JSON_HEDLEY_NULL NULL
2205 #else
2206  #define JSON_HEDLEY_NULL ((void*) 0)
2207 #endif
2208 
2209 #if defined(JSON_HEDLEY_MESSAGE)
2210  #undef JSON_HEDLEY_MESSAGE
2211 #endif
2212 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2213 # define JSON_HEDLEY_MESSAGE(msg) \
2214  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2215  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2216  JSON_HEDLEY_PRAGMA(message msg) \
2217  JSON_HEDLEY_DIAGNOSTIC_POP
2218 #elif \
2219  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2220  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2221 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2222 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2223 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2224 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2225 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2226 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2227 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2228 #else
2229 # define JSON_HEDLEY_MESSAGE(msg)
2230 #endif
2231 
2232 #if defined(JSON_HEDLEY_WARNING)
2233  #undef JSON_HEDLEY_WARNING
2234 #endif
2235 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2236 # define JSON_HEDLEY_WARNING(msg) \
2237  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2238  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2239  JSON_HEDLEY_PRAGMA(clang warning msg) \
2240  JSON_HEDLEY_DIAGNOSTIC_POP
2241 #elif \
2242  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2243  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2244  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2245 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2246 #elif \
2247  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2248  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2249 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2250 #else
2251 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2252 #endif
2253 
2254 #if defined(JSON_HEDLEY_REQUIRE)
2255  #undef JSON_HEDLEY_REQUIRE
2256 #endif
2257 #if defined(JSON_HEDLEY_REQUIRE_MSG)
2258  #undef JSON_HEDLEY_REQUIRE_MSG
2259 #endif
2260 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2261 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2262 # define JSON_HEDLEY_REQUIRE(expr) \
2263  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2264  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2265  __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2266  JSON_HEDLEY_DIAGNOSTIC_POP
2267 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2268  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2269  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2270  __attribute__((diagnose_if(!(expr), msg, "error"))) \
2271  JSON_HEDLEY_DIAGNOSTIC_POP
2272 # else
2273 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2274 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2275 # endif
2276 #else
2277 # define JSON_HEDLEY_REQUIRE(expr)
2278 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2279 #endif
2280 
2281 #if defined(JSON_HEDLEY_FLAGS)
2282  #undef JSON_HEDLEY_FLAGS
2283 #endif
2284 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2285  #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2286 #else
2287  #define JSON_HEDLEY_FLAGS
2288 #endif
2289 
2290 #if defined(JSON_HEDLEY_FLAGS_CAST)
2291  #undef JSON_HEDLEY_FLAGS_CAST
2292 #endif
2293 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2294 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2295  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2296  _Pragma("warning(disable:188)") \
2297  ((T) (expr)); \
2298  JSON_HEDLEY_DIAGNOSTIC_POP \
2299  }))
2300 #else
2301 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2302 #endif
2303 
2304 #if defined(JSON_HEDLEY_EMPTY_BASES)
2305  #undef JSON_HEDLEY_EMPTY_BASES
2306 #endif
2307 #if \
2308  (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2309  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2310  #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2311 #else
2312  #define JSON_HEDLEY_EMPTY_BASES
2313 #endif
2314 
2315 /* Remaining macros are deprecated. */
2316 
2317 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2318  #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2319 #endif
2320 #if defined(__clang__)
2321  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2322 #else
2323  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2324 #endif
2325 
2326 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2327  #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2328 #endif
2329 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2330 
2331 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2332  #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2333 #endif
2334 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2335 
2336 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2337  #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2338 #endif
2339 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2340 
2341 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2342  #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2343 #endif
2344 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2345 
2346 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2347  #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2348 #endif
2349 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2350 
2351 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2352  #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2353 #endif
2354 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2355 
2356 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2357  #undef JSON_HEDLEY_CLANG_HAS_WARNING
2358 #endif
2359 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2360 
2361 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2362 
2363 
2364 // This file contains all internal macro definitions (except those affecting ABI)
2365 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2366 
2367 // #include <nlohmann/detail/abi_macros.hpp>
2368 
2369 
2370 // exclude unsupported compilers
2371 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2372  #if defined(__clang__)
2373  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2374  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2375  #endif
2376  #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2377  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2378  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2379  #endif
2380  #endif
2381 #endif
2382 
2383 // C++ language standard detection
2384 // if the user manually specified the used c++ version this is skipped
2385 #if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2386  #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2387  #define JSON_HAS_CPP_20
2388  #define JSON_HAS_CPP_17
2389  #define JSON_HAS_CPP_14
2390  #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2391  #define JSON_HAS_CPP_17
2392  #define JSON_HAS_CPP_14
2393  #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2394  #define JSON_HAS_CPP_14
2395  #endif
2396  // the cpp 11 flag is always specified because it is the minimal required version
2397  #define JSON_HAS_CPP_11
2398 #endif
2399 
2400 #ifdef __has_include
2401  #if __has_include(<version>)
2402  #include <version>
2403  #endif
2404 #endif
2405 
2406 #if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2407  #ifdef JSON_HAS_CPP_17
2408  #if defined(__cpp_lib_filesystem)
2409  #define JSON_HAS_FILESYSTEM 1
2410  #elif defined(__cpp_lib_experimental_filesystem)
2411  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2412  #elif !defined(__has_include)
2413  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2414  #elif __has_include(<filesystem>)
2415  #define JSON_HAS_FILESYSTEM 1
2416  #elif __has_include(<experimental/filesystem>)
2417  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2418  #endif
2419 
2420  // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2421  #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2422  #undef JSON_HAS_FILESYSTEM
2423  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2424  #endif
2425 
2426  // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2427  #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2428  #undef JSON_HAS_FILESYSTEM
2429  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2430  #endif
2431 
2432  // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2433  #if defined(__clang_major__) && __clang_major__ < 7
2434  #undef JSON_HAS_FILESYSTEM
2435  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2436  #endif
2437 
2438  // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2439  #if defined(_MSC_VER) && _MSC_VER < 1914
2440  #undef JSON_HAS_FILESYSTEM
2441  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2442  #endif
2443 
2444  // no filesystem support before iOS 13
2445  #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2446  #undef JSON_HAS_FILESYSTEM
2447  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2448  #endif
2449 
2450  // no filesystem support before macOS Catalina
2451  #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2452  #undef JSON_HAS_FILESYSTEM
2453  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2454  #endif
2455  #endif
2456 #endif
2457 
2458 #ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2459  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2460 #endif
2461 
2462 #ifndef JSON_HAS_FILESYSTEM
2463  #define JSON_HAS_FILESYSTEM 0
2464 #endif
2465 
2466 #ifndef JSON_HAS_THREE_WAY_COMPARISON
2467  #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
2468  && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
2469  #define JSON_HAS_THREE_WAY_COMPARISON 1
2470  #else
2471  #define JSON_HAS_THREE_WAY_COMPARISON 0
2472  #endif
2473 #endif
2474 
2475 #ifndef JSON_HAS_RANGES
2476  // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error
2477  #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427
2478  #define JSON_HAS_RANGES 0
2479  #elif defined(__cpp_lib_ranges)
2480  #define JSON_HAS_RANGES 1
2481  #else
2482  #define JSON_HAS_RANGES 0
2483  #endif
2484 #endif
2485 
2486 #ifdef JSON_HAS_CPP_17
2487  #define JSON_INLINE_VARIABLE inline
2488 #else
2489  #define JSON_INLINE_VARIABLE
2490 #endif
2491 
2492 #if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2493  #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2494 #else
2495  #define JSON_NO_UNIQUE_ADDRESS
2496 #endif
2497 
2498 // disable documentation warnings on clang
2499 #if defined(__clang__)
2500  #pragma clang diagnostic push
2501  #pragma clang diagnostic ignored "-Wdocumentation"
2502  #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2503 #endif
2504 
2505 // allow disabling exceptions
2506 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2507  #define JSON_THROW(exception) throw exception
2508  #define JSON_TRY try
2509  #define JSON_CATCH(exception) catch(exception)
2510  #define JSON_INTERNAL_CATCH(exception) catch(exception)
2511 #else
2512  #include <cstdlib>
2513  #define JSON_THROW(exception) std::abort()
2514  #define JSON_TRY if(true)
2515  #define JSON_CATCH(exception) if(false)
2516  #define JSON_INTERNAL_CATCH(exception) if(false)
2517 #endif
2518 
2519 // override exception macros
2520 #if defined(JSON_THROW_USER)
2521  #undef JSON_THROW
2522  #define JSON_THROW JSON_THROW_USER
2523 #endif
2524 #if defined(JSON_TRY_USER)
2525  #undef JSON_TRY
2526  #define JSON_TRY JSON_TRY_USER
2527 #endif
2528 #if defined(JSON_CATCH_USER)
2529  #undef JSON_CATCH
2530  #define JSON_CATCH JSON_CATCH_USER
2531  #undef JSON_INTERNAL_CATCH
2532  #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2533 #endif
2534 #if defined(JSON_INTERNAL_CATCH_USER)
2535  #undef JSON_INTERNAL_CATCH
2536  #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2537 #endif
2538 
2539 // allow overriding assert
2540 #if !defined(JSON_ASSERT)
2541  #include <cassert> // assert
2542  #define JSON_ASSERT(x) assert(x)
2543 #endif
2544 
2545 // allow to access some private functions (needed by the test suite)
2546 #if defined(JSON_TESTS_PRIVATE)
2547  #define JSON_PRIVATE_UNLESS_TESTED public
2548 #else
2549  #define JSON_PRIVATE_UNLESS_TESTED private
2550 #endif
2551 
2557 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2558  template<typename BasicJsonType> \
2559  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2560  { \
2561  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2562  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2563  auto it = std::find_if(std::begin(m), std::end(m), \
2564  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2565  { \
2566  return ej_pair.first == e; \
2567  }); \
2568  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2569  } \
2570  template<typename BasicJsonType> \
2571  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2572  { \
2573  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2574  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2575  auto it = std::find_if(std::begin(m), std::end(m), \
2576  [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2577  { \
2578  return ej_pair.second == j; \
2579  }); \
2580  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2581  }
2582 
2583 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2584 // may be removed in the future once the class is split.
2585 
2586 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2587  template<template<typename, typename, typename...> class ObjectType, \
2588  template<typename, typename...> class ArrayType, \
2589  class StringType, class BooleanType, class NumberIntegerType, \
2590  class NumberUnsignedType, class NumberFloatType, \
2591  template<typename> class AllocatorType, \
2592  template<typename, typename = void> class JSONSerializer, \
2593  class BinaryType>
2594 
2595 #define NLOHMANN_BASIC_JSON_TPL \
2596  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2597  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2598  AllocatorType, JSONSerializer, BinaryType>
2599 
2600 // Macros to simplify conversion from/to types
2601 
2602 #define NLOHMANN_JSON_EXPAND( x ) x
2603 #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
2604 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2605  NLOHMANN_JSON_PASTE64, \
2606  NLOHMANN_JSON_PASTE63, \
2607  NLOHMANN_JSON_PASTE62, \
2608  NLOHMANN_JSON_PASTE61, \
2609  NLOHMANN_JSON_PASTE60, \
2610  NLOHMANN_JSON_PASTE59, \
2611  NLOHMANN_JSON_PASTE58, \
2612  NLOHMANN_JSON_PASTE57, \
2613  NLOHMANN_JSON_PASTE56, \
2614  NLOHMANN_JSON_PASTE55, \
2615  NLOHMANN_JSON_PASTE54, \
2616  NLOHMANN_JSON_PASTE53, \
2617  NLOHMANN_JSON_PASTE52, \
2618  NLOHMANN_JSON_PASTE51, \
2619  NLOHMANN_JSON_PASTE50, \
2620  NLOHMANN_JSON_PASTE49, \
2621  NLOHMANN_JSON_PASTE48, \
2622  NLOHMANN_JSON_PASTE47, \
2623  NLOHMANN_JSON_PASTE46, \
2624  NLOHMANN_JSON_PASTE45, \
2625  NLOHMANN_JSON_PASTE44, \
2626  NLOHMANN_JSON_PASTE43, \
2627  NLOHMANN_JSON_PASTE42, \
2628  NLOHMANN_JSON_PASTE41, \
2629  NLOHMANN_JSON_PASTE40, \
2630  NLOHMANN_JSON_PASTE39, \
2631  NLOHMANN_JSON_PASTE38, \
2632  NLOHMANN_JSON_PASTE37, \
2633  NLOHMANN_JSON_PASTE36, \
2634  NLOHMANN_JSON_PASTE35, \
2635  NLOHMANN_JSON_PASTE34, \
2636  NLOHMANN_JSON_PASTE33, \
2637  NLOHMANN_JSON_PASTE32, \
2638  NLOHMANN_JSON_PASTE31, \
2639  NLOHMANN_JSON_PASTE30, \
2640  NLOHMANN_JSON_PASTE29, \
2641  NLOHMANN_JSON_PASTE28, \
2642  NLOHMANN_JSON_PASTE27, \
2643  NLOHMANN_JSON_PASTE26, \
2644  NLOHMANN_JSON_PASTE25, \
2645  NLOHMANN_JSON_PASTE24, \
2646  NLOHMANN_JSON_PASTE23, \
2647  NLOHMANN_JSON_PASTE22, \
2648  NLOHMANN_JSON_PASTE21, \
2649  NLOHMANN_JSON_PASTE20, \
2650  NLOHMANN_JSON_PASTE19, \
2651  NLOHMANN_JSON_PASTE18, \
2652  NLOHMANN_JSON_PASTE17, \
2653  NLOHMANN_JSON_PASTE16, \
2654  NLOHMANN_JSON_PASTE15, \
2655  NLOHMANN_JSON_PASTE14, \
2656  NLOHMANN_JSON_PASTE13, \
2657  NLOHMANN_JSON_PASTE12, \
2658  NLOHMANN_JSON_PASTE11, \
2659  NLOHMANN_JSON_PASTE10, \
2660  NLOHMANN_JSON_PASTE9, \
2661  NLOHMANN_JSON_PASTE8, \
2662  NLOHMANN_JSON_PASTE7, \
2663  NLOHMANN_JSON_PASTE6, \
2664  NLOHMANN_JSON_PASTE5, \
2665  NLOHMANN_JSON_PASTE4, \
2666  NLOHMANN_JSON_PASTE3, \
2667  NLOHMANN_JSON_PASTE2, \
2668  NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2669 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2670 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2671 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2672 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2673 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2674 #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)
2675 #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)
2676 #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)
2677 #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)
2678 #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)
2679 #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)
2680 #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)
2681 #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)
2682 #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)
2683 #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)
2684 #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)
2685 #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)
2686 #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)
2687 #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)
2688 #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)
2689 #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)
2690 #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)
2691 #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)
2692 #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)
2693 #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)
2694 #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)
2695 #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)
2696 #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)
2697 #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)
2698 #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)
2699 #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)
2700 #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)
2701 #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)
2702 #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)
2703 #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)
2704 #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)
2705 #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)
2706 #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)
2707 #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)
2708 #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)
2709 #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)
2710 #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)
2711 #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)
2712 #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)
2713 #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)
2714 #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)
2715 #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)
2716 #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)
2717 #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)
2718 #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)
2719 #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)
2720 #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)
2721 #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)
2722 #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)
2723 #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)
2724 #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)
2725 #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)
2726 #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)
2727 #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)
2728 #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)
2729 #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)
2730 #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)
2731 #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)
2732 
2733 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2734 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2735 #define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2736 
2742 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2743  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__)) } \
2744  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__)) }
2745 
2746 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2747  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__)) } \
2748  friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2749 
2755 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2756  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__)) } \
2757  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__)) }
2758 
2759 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2760  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__)) } \
2761  inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2762 
2763 
2764 // inspired from https://stackoverflow.com/a/26745591
2765 // allows to call any std function as if (e.g. with begin):
2766 // using std::begin; begin(x);
2767 //
2768 // it allows using the detected idiom to retrieve the return type
2769 // of such an expression
2770 #define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2771  namespace detail { \
2772  using std::std_name; \
2773  \
2774  template<typename... T> \
2775  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2776  } \
2777  \
2778  namespace detail2 { \
2779  struct std_name##_tag \
2780  { \
2781  }; \
2782  \
2783  template<typename... T> \
2784  std_name##_tag std_name(T&&...); \
2785  \
2786  template<typename... T> \
2787  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2788  \
2789  template<typename... T> \
2790  struct would_call_std_##std_name \
2791  { \
2792  static constexpr auto const value = ::nlohmann::detail:: \
2793  is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2794  }; \
2795  } /* namespace detail2 */ \
2796  \
2797  template<typename... T> \
2798  struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2799  { \
2800  }
2801 
2802 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2803  #define JSON_USE_IMPLICIT_CONVERSIONS 1
2804 #endif
2805 
2806 #if JSON_USE_IMPLICIT_CONVERSIONS
2807  #define JSON_EXPLICIT
2808 #else
2809  #define JSON_EXPLICIT explicit
2810 #endif
2811 
2812 #ifndef JSON_DISABLE_ENUM_SERIALIZATION
2813  #define JSON_DISABLE_ENUM_SERIALIZATION 0
2814 #endif
2815 
2816 #ifndef JSON_USE_GLOBAL_UDLS
2817  #define JSON_USE_GLOBAL_UDLS 1
2818 #endif
2819 
2820 #if JSON_HAS_THREE_WAY_COMPARISON
2821  #include <compare> // partial_ordering
2822 #endif
2823 
2825 namespace detail
2826 {
2827 
2829 // JSON type enumeration //
2831 
2856 enum class value_t : std::uint8_t
2857 {
2858  null,
2859  object,
2860  array,
2861  string,
2862  boolean,
2863  number_integer,
2864  number_unsigned,
2865  number_float,
2866  binary,
2867  discarded
2868 };
2869 
2883 #if JSON_HAS_THREE_WAY_COMPARISON
2884  inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
2885 #else
2886  inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2887 #endif
2888 {
2889  static constexpr std::array<std::uint8_t, 9> order = {{
2890  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2891  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
2892  6 /* binary */
2893  }
2894  };
2895 
2896  const auto l_index = static_cast<std::size_t>(lhs);
2897  const auto r_index = static_cast<std::size_t>(rhs);
2898 #if JSON_HAS_THREE_WAY_COMPARISON
2899  if (l_index < order.size() && r_index < order.size())
2900  {
2901  return order[l_index] <=> order[r_index]; // *NOPAD*
2902  }
2903  return std::partial_ordering::unordered;
2904 #else
2905  return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
2906 #endif
2907 }
2908 
2909 // GCC selects the built-in operator< over an operator rewritten from
2910 // a user-defined spaceship operator
2911 // Clang, MSVC, and ICC select the rewritten candidate
2912 // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
2913 #if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
2914 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2915 {
2916  return std::is_lt(lhs <=> rhs); // *NOPAD*
2917 }
2918 #endif
2919 
2920 } // namespace detail
2922 
2923 // #include <nlohmann/detail/string_escape.hpp>
2924 // __ _____ _____ _____
2925 // __| | __| | | | JSON for Modern C++
2926 // | | |__ | | | | | | version 3.11.2
2927 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
2928 //
2929 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
2930 // SPDX-License-Identifier: MIT
2931 
2932 
2933 
2934 // #include <nlohmann/detail/abi_macros.hpp>
2935 
2936 
2938 namespace detail
2939 {
2940 
2954 template<typename StringType>
2955 inline void replace_substring(StringType& s, const StringType& f,
2956  const StringType& t)
2957 {
2958  JSON_ASSERT(!f.empty());
2959  for (auto pos = s.find(f); // find first occurrence of f
2960  pos != StringType::npos; // make sure f was found
2961  s.replace(pos, f.size(), t), // replace with t, and
2962  pos = s.find(f, pos + t.size())) // find next occurrence of f
2963  {}
2964 }
2965 
2973 template<typename StringType>
2974 inline StringType escape(StringType s)
2975 {
2976  replace_substring(s, StringType{"~"}, StringType{"~0"});
2977  replace_substring(s, StringType{"/"}, StringType{"~1"});
2978  return s;
2979 }
2980 
2988 template<typename StringType>
2989 static void unescape(StringType& s)
2990 {
2991  replace_substring(s, StringType{"~1"}, StringType{"/"});
2992  replace_substring(s, StringType{"~0"}, StringType{"~"});
2993 }
2994 
2995 } // namespace detail
2997 
2998 // #include <nlohmann/detail/input/position_t.hpp>
2999 // __ _____ _____ _____
3000 // __| | __| | | | JSON for Modern C++
3001 // | | |__ | | | | | | version 3.11.2
3002 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3003 //
3004 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3005 // SPDX-License-Identifier: MIT
3006 
3007 
3008 
3009 #include <cstddef> // size_t
3010 
3011 // #include <nlohmann/detail/abi_macros.hpp>
3012 
3013 
3015 namespace detail
3016 {
3017 
3020 {
3022  std::size_t chars_read_total = 0;
3024  std::size_t chars_read_current_line = 0;
3026  std::size_t lines_read = 0;
3027 
3029  constexpr operator size_t() const
3030  {
3031  return chars_read_total;
3032  }
3033 };
3034 
3035 } // namespace detail
3037 
3038 // #include <nlohmann/detail/macro_scope.hpp>
3039 
3040 // #include <nlohmann/detail/meta/cpp_future.hpp>
3041 // __ _____ _____ _____
3042 // __| | __| | | | JSON for Modern C++
3043 // | | |__ | | | | | | version 3.11.2
3044 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3045 //
3046 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3047 // SPDX-FileCopyrightText: 2018 The Abseil Authors
3048 // SPDX-License-Identifier: MIT
3049 
3050 
3051 
3052 #include <array> // array
3053 #include <cstddef> // size_t
3054 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3055 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3056 
3057 // #include <nlohmann/detail/macro_scope.hpp>
3058 
3059 
3061 namespace detail
3062 {
3063 
3064 template<typename T>
3066 
3067 #ifdef JSON_HAS_CPP_14
3068 
3069 // the following utilities are natively available in C++14
3070 using std::enable_if_t;
3071 using std::index_sequence;
3074 
3075 #else
3076 
3077 // alias templates to reduce boilerplate
3078 template<bool B, typename T = void>
3080 
3081 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3082 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3083 
3085 
3086 // integer_sequence
3087 //
3088 // Class template representing a compile-time integer sequence. An instantiation
3089 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3090 // type through its template arguments (which is a common need when
3091 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3092 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3093 //
3094 // Example:
3095 //
3096 // template< class T, T... Ints >
3097 // void user_function(integer_sequence<T, Ints...>);
3098 //
3099 // int main()
3100 // {
3101 // // user_function's `T` will be deduced to `int` and `Ints...`
3102 // // will be deduced to `0, 1, 2, 3, 4`.
3103 // user_function(make_integer_sequence<int, 5>());
3104 // }
3105 template <typename T, T... Ints>
3107 {
3108  using value_type = T;
3109  static constexpr std::size_t size() noexcept
3110  {
3111  return sizeof...(Ints);
3112  }
3113 };
3114 
3115 // index_sequence
3116 //
3117 // A helper template for an `integer_sequence` of `size_t`,
3118 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3119 // `std::index_sequence`.
3120 template <size_t... Ints>
3121 using index_sequence = integer_sequence<size_t, Ints...>;
3122 
3123 namespace utility_internal
3124 {
3125 
3126 template <typename Seq, size_t SeqSize, size_t Rem>
3127 struct Extend;
3128 
3129 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3130 template <typename T, T... Ints, size_t SeqSize>
3131 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3132 {
3133  using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3134 };
3135 
3136 template <typename T, T... Ints, size_t SeqSize>
3137 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3138 {
3139  using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3140 };
3141 
3142 // Recursion helper for 'make_integer_sequence<T, N>'.
3143 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3144 template <typename T, size_t N>
3145 struct Gen
3146 {
3147  using type =
3148  typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3149 };
3150 
3151 template <typename T>
3152 struct Gen<T, 0>
3153 {
3155 };
3156 
3157 } // namespace utility_internal
3158 
3159 // Compile-time sequences of integers
3160 
3161 // make_integer_sequence
3162 //
3163 // This template alias is equivalent to
3164 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3165 // replacement for C++14's `std::make_integer_sequence`.
3166 template <typename T, T N>
3168 
3169 // make_index_sequence
3170 //
3171 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3172 // and is designed to be a drop-in replacement for C++14's
3173 // `std::make_index_sequence`.
3174 template <size_t N>
3176 
3177 // index_sequence_for
3178 //
3179 // Converts a typename pack into an index sequence of the same length, and
3180 // is designed to be a drop-in replacement for C++14's
3181 // `std::index_sequence_for()`
3182 template <typename... Ts>
3184 
3186 
3187 #endif
3188 
3189 // dispatch utility (taken from ranges-v3)
3190 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3191 template<> struct priority_tag<0> {};
3192 
3193 // taken from ranges-v3
3194 template<typename T>
3196 {
3197  static JSON_INLINE_VARIABLE constexpr T value{};
3198 };
3199 
3200 #ifndef JSON_HAS_CPP_17
3201  template<typename T>
3202  constexpr T static_const<T>::value;
3203 #endif
3204 
3205 template<typename T, typename... Args>
3206 inline constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args)
3207 {
3208  return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}};
3209 }
3210 
3211 } // namespace detail
3213 
3214 // #include <nlohmann/detail/meta/type_traits.hpp>
3215 // __ _____ _____ _____
3216 // __| | __| | | | JSON for Modern C++
3217 // | | |__ | | | | | | version 3.11.2
3218 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3219 //
3220 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3221 // SPDX-License-Identifier: MIT
3222 
3223 
3224 
3225 #include <limits> // numeric_limits
3226 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3227 #include <utility> // declval
3228 #include <tuple> // tuple
3229 
3230 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3231 // __ _____ _____ _____
3232 // __| | __| | | | JSON for Modern C++
3233 // | | |__ | | | | | | version 3.11.2
3234 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3235 //
3236 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3237 // SPDX-License-Identifier: MIT
3238 
3239 
3240 
3241 #include <iterator> // random_access_iterator_tag
3242 
3243 // #include <nlohmann/detail/abi_macros.hpp>
3244 
3245 // #include <nlohmann/detail/meta/void_t.hpp>
3246 
3247 // #include <nlohmann/detail/meta/cpp_future.hpp>
3248 
3249 
3251 namespace detail
3252 {
3253 
3254 template<typename It, typename = void>
3255 struct iterator_types {};
3256 
3257 template<typename It>
3259  It,
3260  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3261  typename It::reference, typename It::iterator_category >>
3262 {
3263  using difference_type = typename It::difference_type;
3264  using value_type = typename It::value_type;
3265  using pointer = typename It::pointer;
3266  using reference = typename It::reference;
3267  using iterator_category = typename It::iterator_category;
3268 };
3269 
3270 // This is required as some compilers implement std::iterator_traits in a way that
3271 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3272 template<typename T, typename = void>
3274 {
3275 };
3276 
3277 template<typename T>
3278 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3279  : iterator_types<T>
3280 {
3281 };
3282 
3283 template<typename T>
3285 {
3286  using iterator_category = std::random_access_iterator_tag;
3287  using value_type = T;
3288  using difference_type = ptrdiff_t;
3289  using pointer = T*;
3290  using reference = T&;
3291 };
3292 
3293 } // namespace detail
3295 
3296 // #include <nlohmann/detail/macro_scope.hpp>
3297 
3298 // #include <nlohmann/detail/meta/call_std/begin.hpp>
3299 // __ _____ _____ _____
3300 // __| | __| | | | JSON for Modern C++
3301 // | | |__ | | | | | | version 3.11.2
3302 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3303 //
3304 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3305 // SPDX-License-Identifier: MIT
3306 
3307 
3308 
3309 // #include <nlohmann/detail/macro_scope.hpp>
3310 
3311 
3313 
3315 
3317 
3318 // #include <nlohmann/detail/meta/call_std/end.hpp>
3319 // __ _____ _____ _____
3320 // __| | __| | | | JSON for Modern C++
3321 // | | |__ | | | | | | version 3.11.2
3322 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3323 //
3324 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3325 // SPDX-License-Identifier: MIT
3326 
3327 
3328 
3329 // #include <nlohmann/detail/macro_scope.hpp>
3330 
3331 
3333 
3335 
3337 
3338 // #include <nlohmann/detail/meta/cpp_future.hpp>
3339 
3340 // #include <nlohmann/detail/meta/detected.hpp>
3341 
3342 // #include <nlohmann/json_fwd.hpp>
3343 // __ _____ _____ _____
3344 // __| | __| | | | JSON for Modern C++
3345 // | | |__ | | | | | | version 3.11.2
3346 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3347 //
3348 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3349 // SPDX-License-Identifier: MIT
3350 
3351 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3352  #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3353 
3354  #include <cstdint> // int64_t, uint64_t
3355  #include <map> // map
3356  #include <memory> // allocator
3357  #include <string> // string
3358  #include <vector> // vector
3359 
3360  // #include <nlohmann/detail/abi_macros.hpp>
3361 
3362 
3369 
3377  template<typename T = void, typename SFINAE = void>
3379 
3382  template<template<typename U, typename V, typename... Args> class ObjectType =
3383  std::map,
3384  template<typename U, typename... Args> class ArrayType = std::vector,
3385  class StringType = std::string, class BooleanType = bool,
3386  class NumberIntegerType = std::int64_t,
3387  class NumberUnsignedType = std::uint64_t,
3388  class NumberFloatType = double,
3389  template<typename U> class AllocatorType = std::allocator,
3390  template<typename T, typename SFINAE = void> class JSONSerializer =
3392  class BinaryType = std::vector<std::uint8_t>>
3393  class basic_json;
3394 
3397  template<typename RefStringType>
3399 
3405 
3408  template<class Key, class T, class IgnoredLess, class Allocator>
3409  struct ordered_map;
3410 
3414 
3416 
3417 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3418 
3419 
3429 namespace detail
3430 {
3431 
3433 // helpers //
3435 
3436 // Note to maintainers:
3437 //
3438 // Every trait in this file expects a non CV-qualified type.
3439 // The only exceptions are in the 'aliases for detected' section
3440 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3441 //
3442 // In this case, T has to be properly CV-qualified to constraint the function arguments
3443 // (e.g. to_json(BasicJsonType&, const T&))
3444 
3445 template<typename> struct is_basic_json : std::false_type {};
3446 
3448 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3449 
3450 // used by exceptions create() member functions
3451 // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3452 // false_type otherwise
3453 template<typename BasicJsonContext>
3455  std::integral_constant < bool,
3456  is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3457  || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3458 {};
3459 
3461 // json_ref helpers //
3463 
3464 template<typename>
3465 class json_ref;
3466 
3467 template<typename>
3468 struct is_json_ref : std::false_type {};
3469 
3470 template<typename T>
3471 struct is_json_ref<json_ref<T>> : std::true_type {};
3472 
3474 // aliases for detected //
3476 
3477 template<typename T>
3478 using mapped_type_t = typename T::mapped_type;
3479 
3480 template<typename T>
3481 using key_type_t = typename T::key_type;
3482 
3483 template<typename T>
3484 using value_type_t = typename T::value_type;
3485 
3486 template<typename T>
3487 using difference_type_t = typename T::difference_type;
3488 
3489 template<typename T>
3490 using pointer_t = typename T::pointer;
3491 
3492 template<typename T>
3493 using reference_t = typename T::reference;
3494 
3495 template<typename T>
3496 using iterator_category_t = typename T::iterator_category;
3497 
3498 template<typename T, typename... Args>
3499 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3500 
3501 template<typename T, typename... Args>
3502 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3503 
3504 template<typename T, typename U>
3505 using get_template_function = decltype(std::declval<T>().template get<U>());
3506 
3507 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3508 template<typename BasicJsonType, typename T, typename = void>
3509 struct has_from_json : std::false_type {};
3510 
3511 // trait checking if j.get<T> is valid
3512 // use this trait instead of std::is_constructible or std::is_convertible,
3513 // both rely on, or make use of implicit conversions, and thus fail when T
3514 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3515 template <typename BasicJsonType, typename T>
3517 {
3519 };
3520 
3521 template<typename BasicJsonType, typename T>
3522 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3523 {
3524  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3525 
3526  static constexpr bool value =
3528  const BasicJsonType&, T&>::value;
3529 };
3530 
3531 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3532 // this overload is used for non-default-constructible user-defined-types
3533 template<typename BasicJsonType, typename T, typename = void>
3534 struct has_non_default_from_json : std::false_type {};
3535 
3536 template<typename BasicJsonType, typename T>
3537 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3538 {
3539  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3540 
3541  static constexpr bool value =
3543  const BasicJsonType&>::value;
3544 };
3545 
3546 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3547 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3548 template<typename BasicJsonType, typename T, typename = void>
3549 struct has_to_json : std::false_type {};
3550 
3551 template<typename BasicJsonType, typename T>
3552 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3553 {
3554  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3555 
3556  static constexpr bool value =
3558  T>::value;
3559 };
3560 
3561 template<typename T>
3562 using detect_key_compare = typename T::key_compare;
3563 
3564 template<typename T>
3565 struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3566 
3567 // obtains the actual object key comparator
3568 template<typename BasicJsonType>
3570 {
3571  using object_t = typename BasicJsonType::object_t;
3572  using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3573  using type = typename std::conditional < has_key_compare<object_t>::value,
3574  typename object_t::key_compare, object_comparator_t>::type;
3575 };
3576 
3577 template<typename BasicJsonType>
3579 
3581 // is_ functions //
3583 
3584 // https://en.cppreference.com/w/cpp/types/conjunction
3585 template<class...> struct conjunction : std::true_type { };
3586 template<class B> struct conjunction<B> : B { };
3587 template<class B, class... Bn>
3588 struct conjunction<B, Bn...>
3589 : std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
3590 
3591 // https://en.cppreference.com/w/cpp/types/negation
3592 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3593 
3594 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3595 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3596 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3597 template <typename T>
3598 struct is_default_constructible : std::is_default_constructible<T> {};
3599 
3600 template <typename T1, typename T2>
3601 struct is_default_constructible<std::pair<T1, T2>>
3602  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3603 
3604 template <typename T1, typename T2>
3605 struct is_default_constructible<const std::pair<T1, T2>>
3606  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3607 
3608 template <typename... Ts>
3609 struct is_default_constructible<std::tuple<Ts...>>
3610  : conjunction<is_default_constructible<Ts>...> {};
3611 
3612 template <typename... Ts>
3613 struct is_default_constructible<const std::tuple<Ts...>>
3614  : conjunction<is_default_constructible<Ts>...> {};
3615 
3616 
3617 template <typename T, typename... Args>
3618 struct is_constructible : std::is_constructible<T, Args...> {};
3619 
3620 template <typename T1, typename T2>
3621 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3622 
3623 template <typename T1, typename T2>
3624 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3625 
3626 template <typename... Ts>
3627 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3628 
3629 template <typename... Ts>
3630 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3631 
3632 
3633 template<typename T, typename = void>
3634 struct is_iterator_traits : std::false_type {};
3635 
3636 template<typename T>
3638 {
3639  private:
3640  using traits = iterator_traits<T>;
3641 
3642  public:
3643  static constexpr auto value =
3649 };
3650 
3651 template<typename T>
3652 struct is_range
3653 {
3654  private:
3655  using t_ref = typename std::add_lvalue_reference<T>::type;
3656 
3657  using iterator = detected_t<result_of_begin, t_ref>;
3658  using sentinel = detected_t<result_of_end, t_ref>;
3659 
3660  // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3661  // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3662  // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3663  static constexpr auto is_iterator_begin =
3665 
3666  public:
3667  static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3668 };
3669 
3670 template<typename R>
3671 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3672 
3673 template<typename T>
3675 
3676 // The following implementation of is_complete_type is taken from
3677 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3678 // and is written by Xiang Fan who agreed to using it in this library.
3679 
3680 template<typename T, typename = void>
3681 struct is_complete_type : std::false_type {};
3682 
3683 template<typename T>
3684 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3685 
3686 template<typename BasicJsonType, typename CompatibleObjectType,
3687  typename = void>
3688 struct is_compatible_object_type_impl : std::false_type {};
3689 
3690 template<typename BasicJsonType, typename CompatibleObjectType>
3692  BasicJsonType, CompatibleObjectType,
3693  enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3694  is_detected<key_type_t, CompatibleObjectType>::value >>
3695 {
3696  using object_t = typename BasicJsonType::object_t;
3697 
3698  // macOS's is_constructible does not play well with nonesuch...
3699  static constexpr bool value =
3700  is_constructible<typename object_t::key_type,
3701  typename CompatibleObjectType::key_type>::value &&
3702  is_constructible<typename object_t::mapped_type,
3703  typename CompatibleObjectType::mapped_type>::value;
3704 };
3705 
3706 template<typename BasicJsonType, typename CompatibleObjectType>
3708  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3709 
3710 template<typename BasicJsonType, typename ConstructibleObjectType,
3711  typename = void>
3712 struct is_constructible_object_type_impl : std::false_type {};
3713 
3714 template<typename BasicJsonType, typename ConstructibleObjectType>
3716  BasicJsonType, ConstructibleObjectType,
3717  enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3718  is_detected<key_type_t, ConstructibleObjectType>::value >>
3719 {
3720  using object_t = typename BasicJsonType::object_t;
3721 
3722  static constexpr bool value =
3724  (std::is_move_assignable<ConstructibleObjectType>::value ||
3725  std::is_copy_assignable<ConstructibleObjectType>::value) &&
3726  (is_constructible<typename ConstructibleObjectType::key_type,
3727  typename object_t::key_type>::value &&
3728  std::is_same <
3729  typename object_t::mapped_type,
3730  typename ConstructibleObjectType::mapped_type >::value)) ||
3731  (has_from_json<BasicJsonType,
3732  typename ConstructibleObjectType::mapped_type>::value ||
3734  BasicJsonType,
3735  typename ConstructibleObjectType::mapped_type >::value);
3736 };
3737 
3738 template<typename BasicJsonType, typename ConstructibleObjectType>
3740  : is_constructible_object_type_impl<BasicJsonType,
3741  ConstructibleObjectType> {};
3742 
3743 template<typename BasicJsonType, typename CompatibleStringType>
3745 {
3746  static constexpr auto value =
3748 };
3749 
3750 template<typename BasicJsonType, typename ConstructibleStringType>
3752 {
3753  // launder type through decltype() to fix compilation failure on ICPC
3754 #ifdef __INTEL_COMPILER
3755  using laundered_type = decltype(std::declval<ConstructibleStringType>());
3756 #else
3757  using laundered_type = ConstructibleStringType;
3758 #endif
3759 
3760  static constexpr auto value =
3761  conjunction <
3763  is_detected_exact<typename BasicJsonType::string_t::value_type,
3765 };
3766 
3767 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3768 struct is_compatible_array_type_impl : std::false_type {};
3769 
3770 template<typename BasicJsonType, typename CompatibleArrayType>
3772  BasicJsonType, CompatibleArrayType,
3773  enable_if_t <
3774  is_detected<iterator_t, CompatibleArrayType>::value&&
3775  is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3776 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3777 // c.f. https://github.com/nlohmann/json/pull/3073
3778  !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3779 {
3780  static constexpr bool value =
3781  is_constructible<BasicJsonType,
3783 };
3784 
3785 template<typename BasicJsonType, typename CompatibleArrayType>
3787  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3788 
3789 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3790 struct is_constructible_array_type_impl : std::false_type {};
3791 
3792 template<typename BasicJsonType, typename ConstructibleArrayType>
3794  BasicJsonType, ConstructibleArrayType,
3795  enable_if_t<std::is_same<ConstructibleArrayType,
3796  typename BasicJsonType::value_type>::value >>
3797  : std::true_type {};
3798 
3799 template<typename BasicJsonType, typename ConstructibleArrayType>
3801  BasicJsonType, ConstructibleArrayType,
3802  enable_if_t < !std::is_same<ConstructibleArrayType,
3803  typename BasicJsonType::value_type>::value&&
3804  !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3805  is_default_constructible<ConstructibleArrayType>::value&&
3806 (std::is_move_assignable<ConstructibleArrayType>::value ||
3807  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3808 is_detected<iterator_t, ConstructibleArrayType>::value&&
3809 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3810 is_detected<range_value_t, ConstructibleArrayType>::value&&
3811 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3812 // c.f. https://github.com/nlohmann/json/pull/3073
3813 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3815  detected_t<range_value_t, ConstructibleArrayType >>::value >>
3816 {
3818 
3819  static constexpr bool value =
3820  std::is_same<value_type,
3821  typename BasicJsonType::array_t::value_type>::value ||
3822  has_from_json<BasicJsonType,
3823  value_type>::value ||
3825  BasicJsonType,
3826  value_type >::value;
3827 };
3828 
3829 template<typename BasicJsonType, typename ConstructibleArrayType>
3831  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3832 
3833 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3834  typename = void>
3835 struct is_compatible_integer_type_impl : std::false_type {};
3836 
3837 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3839  RealIntegerType, CompatibleNumberIntegerType,
3840  enable_if_t < std::is_integral<RealIntegerType>::value&&
3841  std::is_integral<CompatibleNumberIntegerType>::value&&
3842  !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3843 {
3844  // is there an assert somewhere on overflows?
3845  using RealLimits = std::numeric_limits<RealIntegerType>;
3846  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3847 
3848  static constexpr auto value =
3849  is_constructible<RealIntegerType,
3850  CompatibleNumberIntegerType>::value &&
3851  CompatibleLimits::is_integer &&
3852  RealLimits::is_signed == CompatibleLimits::is_signed;
3853 };
3854 
3855 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3857  : is_compatible_integer_type_impl<RealIntegerType,
3858  CompatibleNumberIntegerType> {};
3859 
3860 template<typename BasicJsonType, typename CompatibleType, typename = void>
3861 struct is_compatible_type_impl: std::false_type {};
3862 
3863 template<typename BasicJsonType, typename CompatibleType>
3865  BasicJsonType, CompatibleType,
3866  enable_if_t<is_complete_type<CompatibleType>::value >>
3867 {
3868  static constexpr bool value =
3870 };
3871 
3872 template<typename BasicJsonType, typename CompatibleType>
3874  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3875 
3876 template<typename T1, typename T2>
3877 struct is_constructible_tuple : std::false_type {};
3878 
3879 template<typename T1, typename... Args>
3880 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3881 
3882 template<typename BasicJsonType, typename T>
3883 struct is_json_iterator_of : std::false_type {};
3884 
3885 template<typename BasicJsonType>
3886 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3887 
3888 template<typename BasicJsonType>
3889 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3890 {};
3891 
3892 // checks if a given type T is a template specialization of Primary
3893 template<template <typename...> class Primary, typename T>
3894 struct is_specialization_of : std::false_type {};
3895 
3896 template<template <typename...> class Primary, typename... Args>
3897 struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3898 
3899 template<typename T>
3901 
3902 // checks if A and B are comparable using Compare functor
3903 template<typename Compare, typename A, typename B, typename = void>
3904 struct is_comparable : std::false_type {};
3905 
3906 template<typename Compare, typename A, typename B>
3907 struct is_comparable<Compare, A, B, void_t<
3908 decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3909 decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3910 >> : std::true_type {};
3911 
3912 template<typename T>
3914 
3915 // type trait to check if KeyType can be used as object key (without a BasicJsonType)
3916 // see is_usable_as_basic_json_key_type below
3917 template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3918  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3919 using is_usable_as_key_type = typename std::conditional <
3921  && !(ExcludeObjectKeyType && std::is_same<KeyType,
3922  ObjectKeyType>::value)
3923  && (!RequireTransparentComparator
3926  std::true_type,
3927  std::false_type >::type;
3928 
3929 // type trait to check if KeyType can be used as object key
3930 // true if:
3931 // - KeyType is comparable with BasicJsonType::object_t::key_type
3932 // - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
3933 // - the comparator is transparent or RequireTransparentComparator is false
3934 // - KeyType is not a JSON iterator or json_pointer
3935 template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3936  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3937 using is_usable_as_basic_json_key_type = typename std::conditional <
3938  is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
3939  typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
3940  RequireTransparentComparator, ExcludeObjectKeyType>::value
3942  std::true_type,
3943  std::false_type >::type;
3944 
3945 template<typename ObjectType, typename KeyType>
3946 using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
3947 
3948 // type trait to check if object_t has an erase() member functions accepting KeyType
3949 template<typename BasicJsonType, typename KeyType>
3950 using has_erase_with_key_type = typename std::conditional <
3951  is_detected <
3953  typename BasicJsonType::object_t, KeyType >::value,
3954  std::true_type,
3955  std::false_type >::type;
3956 
3957 // a naive helper to check if a type is an ordered_map (exploits the fact that
3958 // ordered_map inherits capacity() from std::vector)
3959 template <typename T>
3961 {
3962  using one = char;
3963 
3964  struct two
3965  {
3966  char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3967  };
3968 
3969  template <typename C> static one test( decltype(&C::capacity) ) ;
3970  template <typename C> static two test(...);
3971 
3972  enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3973 };
3974 
3975 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3976 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3978 {
3979  return static_cast<T>(value);
3980 }
3981 
3982 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3983 T conditional_static_cast(U value)
3984 {
3985  return value;
3986 }
3987 
3988 template<typename... Types>
3990 
3991 template<typename... Types>
3993 
3994 template<typename... Types>
3996 
3997 // there's a disjunction trait in another PR; replace when merged
3998 template<typename... Types>
3999 using same_sign = std::integral_constant < bool,
4000  all_signed<Types...>::value || all_unsigned<Types...>::value >;
4001 
4002 template<typename OfType, typename T>
4003 using never_out_of_range = std::integral_constant < bool,
4004  (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
4005  || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
4006 
4007 template<typename OfType, typename T,
4008  bool OfTypeSigned = std::is_signed<OfType>::value,
4009  bool TSigned = std::is_signed<T>::value>
4011 
4012 template<typename OfType, typename T>
4013 struct value_in_range_of_impl2<OfType, T, false, false>
4014 {
4015  static constexpr bool test(T val)
4016  {
4017  using CommonType = typename std::common_type<OfType, T>::type;
4018  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4019  }
4020 };
4021 
4022 template<typename OfType, typename T>
4023 struct value_in_range_of_impl2<OfType, T, true, false>
4024 {
4025  static constexpr bool test(T val)
4026  {
4027  using CommonType = typename std::common_type<OfType, T>::type;
4028  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4029  }
4030 };
4031 
4032 template<typename OfType, typename T>
4033 struct value_in_range_of_impl2<OfType, T, false, true>
4034 {
4035  static constexpr bool test(T val)
4036  {
4037  using CommonType = typename std::common_type<OfType, T>::type;
4038  return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4039  }
4040 };
4041 
4042 
4043 template<typename OfType, typename T>
4044 struct value_in_range_of_impl2<OfType, T, true, true>
4045 {
4046  static constexpr bool test(T val)
4047  {
4048  using CommonType = typename std::common_type<OfType, T>::type;
4049  return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
4050  && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4051  }
4052 };
4053 
4054 template<typename OfType, typename T,
4055  bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
4058 
4059 template<typename OfType, typename T>
4060 struct value_in_range_of_impl1<OfType, T, false>
4061 {
4062  static constexpr bool test(T val)
4063  {
4065  }
4066 };
4067 
4068 template<typename OfType, typename T>
4069 struct value_in_range_of_impl1<OfType, T, true>
4070 {
4071  static constexpr bool test(T /*val*/)
4072  {
4073  return true;
4074  }
4075 };
4076 
4077 template<typename OfType, typename T>
4078 inline constexpr bool value_in_range_of(T val)
4079 {
4081 }
4082 
4083 template<bool Value>
4084 using bool_constant = std::integral_constant<bool, Value>;
4085 
4087 // is_c_string
4089 
4090 namespace impl
4091 {
4092 
4093 template<typename T>
4094 inline constexpr bool is_c_string()
4095 {
4096  using TUnExt = typename std::remove_extent<T>::type;
4097  using TUnCVExt = typename std::remove_cv<TUnExt>::type;
4098  using TUnPtr = typename std::remove_pointer<T>::type;
4099  using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
4100  return
4101  (std::is_array<T>::value && std::is_same<TUnCVExt, char>::value)
4102  || (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
4103 }
4104 
4105 } // namespace impl
4106 
4107 // checks whether T is a [cv] char */[cv] char[] C string
4108 template<typename T>
4109 struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
4110 
4111 template<typename T>
4113 
4115 // is_transparent
4117 
4118 namespace impl
4119 {
4120 
4121 template<typename T>
4122 inline constexpr bool is_transparent()
4123 {
4125 }
4126 
4127 } // namespace impl
4128 
4129 // checks whether T has a member named is_transparent
4130 template<typename T>
4131 struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
4132 
4134 
4135 } // namespace detail
4137 
4138 // #include <nlohmann/detail/string_concat.hpp>
4139 // __ _____ _____ _____
4140 // __| | __| | | | JSON for Modern C++
4141 // | | |__ | | | | | | version 3.11.2
4142 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4143 //
4144 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4145 // SPDX-License-Identifier: MIT
4146 
4147 
4148 
4149 #include <cstring> // strlen
4150 #include <string> // string
4151 #include <utility> // forward
4152 
4153 // #include <nlohmann/detail/meta/cpp_future.hpp>
4154 
4155 // #include <nlohmann/detail/meta/detected.hpp>
4156 
4157 
4159 namespace detail
4160 {
4161 
4162 inline std::size_t concat_length()
4163 {
4164  return 0;
4165 }
4166 
4167 template<typename... Args>
4168 inline std::size_t concat_length(const char* cstr, Args&& ... rest);
4169 
4170 template<typename StringType, typename... Args>
4171 inline std::size_t concat_length(const StringType& str, Args&& ... rest);
4172 
4173 template<typename... Args>
4174 inline std::size_t concat_length(const char /*c*/, Args&& ... rest)
4175 {
4176  return 1 + concat_length(std::forward<Args>(rest)...);
4177 }
4178 
4179 template<typename... Args>
4180 inline std::size_t concat_length(const char* cstr, Args&& ... rest)
4181 {
4182  // cppcheck-suppress ignoredReturnValue
4183  return ::strlen(cstr) + concat_length(std::forward<Args>(rest)...);
4184 }
4185 
4186 template<typename StringType, typename... Args>
4187 inline std::size_t concat_length(const StringType& str, Args&& ... rest)
4188 {
4189  return str.size() + concat_length(std::forward<Args>(rest)...);
4190 }
4191 
4192 template<typename OutStringType>
4193 inline void concat_into(OutStringType& /*out*/)
4194 {}
4195 
4196 template<typename StringType, typename Arg>
4197 using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
4198 
4199 template<typename StringType, typename Arg>
4201 
4202 template<typename StringType, typename Arg>
4203 using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
4204 
4205 template<typename StringType, typename Arg>
4207 
4208 template<typename StringType, typename Arg>
4209 using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
4210 
4211 template<typename StringType, typename Arg>
4213 
4214 template<typename StringType, typename Arg>
4215 using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
4216 
4217 template<typename StringType, typename Arg>
4219 
4220 template < typename OutStringType, typename Arg, typename... Args,
4223 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
4224 
4225 template < typename OutStringType, typename Arg, typename... Args,
4229 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4230 
4231 template < typename OutStringType, typename Arg, typename... Args,
4236 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4237 
4238 template<typename OutStringType, typename Arg, typename... Args,
4240 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
4241 {
4242  out.append(std::forward<Arg>(arg));
4243  concat_into(out, std::forward<Args>(rest)...);
4244 }
4245 
4246 template < typename OutStringType, typename Arg, typename... Args,
4247  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4248  && detect_string_can_append_op<OutStringType, Arg>::value, int > >
4249 inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
4250 {
4251  out += std::forward<Arg>(arg);
4252  concat_into(out, std::forward<Args>(rest)...);
4253 }
4254 
4255 template < typename OutStringType, typename Arg, typename... Args,
4256  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4257  && !detect_string_can_append_op<OutStringType, Arg>::value
4258  && detect_string_can_append_iter<OutStringType, Arg>::value, int > >
4259 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4260 {
4261  out.append(arg.begin(), arg.end());
4262  concat_into(out, std::forward<Args>(rest)...);
4263 }
4264 
4265 template < typename OutStringType, typename Arg, typename... Args,
4266  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4267  && !detect_string_can_append_op<OutStringType, Arg>::value
4268  && !detect_string_can_append_iter<OutStringType, Arg>::value
4269  && detect_string_can_append_data<OutStringType, Arg>::value, int > >
4270 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4271 {
4272  out.append(arg.data(), arg.size());
4273  concat_into(out, std::forward<Args>(rest)...);
4274 }
4275 
4276 template<typename OutStringType = std::string, typename... Args>
4277 inline OutStringType concat(Args && ... args)
4278 {
4279  OutStringType str;
4280  str.reserve(concat_length(std::forward<Args>(args)...));
4281  concat_into(str, std::forward<Args>(args)...);
4282  return str;
4283 }
4284 
4285 } // namespace detail
4287 
4288 
4289 
4291 namespace detail
4292 {
4293 
4295 // exceptions //
4297 
4300 class exception : public std::exception
4301 {
4302  public:
4304  const char* what() const noexcept override
4305  {
4306  return m.what();
4307  }
4308 
4310  const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4311 
4312  protected:
4314  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
4315 
4316  static std::string name(const std::string& ename, int id_)
4317  {
4318  return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
4319  }
4320 
4321  static std::string diagnostics(std::nullptr_t /*leaf_element*/)
4322  {
4323  return "";
4324  }
4325 
4326  template<typename BasicJsonType>
4327  static std::string diagnostics(const BasicJsonType* leaf_element)
4328  {
4329 #if JSON_DIAGNOSTICS
4330  std::vector<std::string> tokens;
4331  for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
4332  {
4333  switch (current->m_parent->type())
4334  {
4335  case value_t::array:
4336  {
4337  for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
4338  {
4339  if (&current->m_parent->m_value.array->operator[](i) == current)
4340  {
4341  tokens.emplace_back(std::to_string(i));
4342  break;
4343  }
4344  }
4345  break;
4346  }
4347 
4348  case value_t::object:
4349  {
4350  for (const auto& element : *current->m_parent->m_value.object)
4351  {
4352  if (&element.second == current)
4353  {
4354  tokens.emplace_back(element.first.c_str());
4355  break;
4356  }
4357  }
4358  break;
4359  }
4360 
4361  case value_t::null: // LCOV_EXCL_LINE
4362  case value_t::string: // LCOV_EXCL_LINE
4363  case value_t::boolean: // LCOV_EXCL_LINE
4364  case value_t::number_integer: // LCOV_EXCL_LINE
4365  case value_t::number_unsigned: // LCOV_EXCL_LINE
4366  case value_t::number_float: // LCOV_EXCL_LINE
4367  case value_t::binary: // LCOV_EXCL_LINE
4368  case value_t::discarded: // LCOV_EXCL_LINE
4369  default: // LCOV_EXCL_LINE
4370  break; // LCOV_EXCL_LINE
4371  }
4372  }
4373 
4374  if (tokens.empty())
4375  {
4376  return "";
4377  }
4378 
4379  auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4380  [](const std::string & a, const std::string & b)
4381  {
4382  return concat(a, '/', detail::escape(b));
4383  });
4384  return concat('(', str, ") ");
4385 #else
4386  static_cast<void>(leaf_element);
4387  return "";
4388 #endif
4389  }
4390 
4391  private:
4393  std::runtime_error m;
4394 };
4395 
4398 class parse_error : public exception
4399 {
4400  public:
4410  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4411  static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4412  {
4413  std::string w = concat(exception::name("parse_error", id_), "parse error",
4414  position_string(pos), ": ", exception::diagnostics(context), what_arg);
4415  return {id_, pos.chars_read_total, w.c_str()};
4416  }
4417 
4418  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4419  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4420  {
4421  std::string w = concat(exception::name("parse_error", id_), "parse error",
4422  (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4423  ": ", exception::diagnostics(context), what_arg);
4424  return {id_, byte_, w.c_str()};
4425  }
4426 
4436  const std::size_t byte;
4437 
4438  private:
4439  parse_error(int id_, std::size_t byte_, const char* what_arg)
4440  : exception(id_, what_arg), byte(byte_) {}
4441 
4442  static std::string position_string(const position_t& pos)
4443  {
4444  return concat(" at line ", std::to_string(pos.lines_read + 1),
4445  ", column ", std::to_string(pos.chars_read_current_line));
4446  }
4447 };
4448 
4452 {
4453  public:
4454  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4455  static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4456  {
4457  std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4458  return {id_, w.c_str()};
4459  }
4460 
4461  private:
4463  invalid_iterator(int id_, const char* what_arg)
4464  : exception(id_, what_arg) {}
4465 };
4466 
4469 class type_error : public exception
4470 {
4471  public:
4472  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4473  static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4474  {
4475  std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4476  return {id_, w.c_str()};
4477  }
4478 
4479  private:
4481  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4482 };
4483 
4486 class out_of_range : public exception
4487 {
4488  public:
4489  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4490  static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4491  {
4492  std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4493  return {id_, w.c_str()};
4494  }
4495 
4496  private:
4498  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4499 };
4500 
4503 class other_error : public exception
4504 {
4505  public:
4506  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4507  static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4508  {
4509  std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4510  return {id_, w.c_str()};
4511  }
4512 
4513  private:
4515  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4516 };
4517 
4518 } // namespace detail
4520 
4521 // #include <nlohmann/detail/macro_scope.hpp>
4522 
4523 // #include <nlohmann/detail/meta/cpp_future.hpp>
4524 
4525 // #include <nlohmann/detail/meta/identity_tag.hpp>
4526 // __ _____ _____ _____
4527 // __| | __| | | | JSON for Modern C++
4528 // | | |__ | | | | | | version 3.11.2
4529 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4530 //
4531 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4532 // SPDX-License-Identifier: MIT
4533 
4534 
4535 
4536 // #include <nlohmann/detail/abi_macros.hpp>
4537 
4538 
4540 namespace detail
4541 {
4542 
4543 // dispatching helper struct
4544 template <class T> struct identity_tag {};
4545 
4546 } // namespace detail
4548 
4549 // #include <nlohmann/detail/meta/std_fs.hpp>
4550 // __ _____ _____ _____
4551 // __| | __| | | | JSON for Modern C++
4552 // | | |__ | | | | | | version 3.11.2
4553 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4554 //
4555 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4556 // SPDX-License-Identifier: MIT
4557 
4558 
4559 
4560 // #include <nlohmann/detail/macro_scope.hpp>
4561 
4562 
4563 #if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4564 #include <experimental/filesystem>
4566 namespace detail
4567 {
4568 namespace std_fs = std::experimental::filesystem;
4569 } // namespace detail
4571 #elif JSON_HAS_FILESYSTEM
4572 #include <filesystem>
4574 namespace detail
4575 {
4576 namespace std_fs = std::filesystem;
4577 } // namespace detail
4579 #endif
4580 
4581 // #include <nlohmann/detail/meta/type_traits.hpp>
4582 
4583 // #include <nlohmann/detail/string_concat.hpp>
4584 
4585 // #include <nlohmann/detail/value_t.hpp>
4586 
4587 
4589 namespace detail
4590 {
4591 
4592 template<typename BasicJsonType>
4593 inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4594 {
4595  if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4596  {
4597  JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4598  }
4599  n = nullptr;
4600 }
4601 
4602 // overloads for basic_json template parameters
4603 template < typename BasicJsonType, typename ArithmeticType,
4604  enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
4605  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4606  int > = 0 >
4607 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4608 {
4609  switch (static_cast<value_t>(j))
4610  {
4612  {
4613  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4614  break;
4615  }
4617  {
4618  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4619  break;
4620  }
4621  case value_t::number_float:
4622  {
4623  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4624  break;
4625  }
4626 
4627  case value_t::null:
4628  case value_t::object:
4629  case value_t::array:
4630  case value_t::string:
4631  case value_t::boolean:
4632  case value_t::binary:
4633  case value_t::discarded:
4634  default:
4635  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4636  }
4637 }
4638 
4639 template<typename BasicJsonType>
4640 inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4641 {
4642  if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4643  {
4644  JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4645  }
4646  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4647 }
4648 
4649 template<typename BasicJsonType>
4650 inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4651 {
4652  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4653  {
4654  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4655  }
4656  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4657 }
4658 
4659 template <
4660  typename BasicJsonType, typename StringType,
4661  enable_if_t <
4662  std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4663  && is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value
4664  && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4665  && !is_json_ref<StringType>::value, int > = 0 >
4666 inline void from_json(const BasicJsonType& j, StringType& s)
4667 {
4668  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4669  {
4670  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4671  }
4672 
4673  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4674 }
4675 
4676 template<typename BasicJsonType>
4677 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4678 {
4679  get_arithmetic_value(j, val);
4680 }
4681 
4682 template<typename BasicJsonType>
4683 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4684 {
4685  get_arithmetic_value(j, val);
4686 }
4687 
4688 template<typename BasicJsonType>
4689 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4690 {
4691  get_arithmetic_value(j, val);
4692 }
4693 
4694 #if !JSON_DISABLE_ENUM_SERIALIZATION
4695 template<typename BasicJsonType, typename EnumType,
4696  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4697 inline void from_json(const BasicJsonType& j, EnumType& e)
4698 {
4700  get_arithmetic_value(j, val);
4701  e = static_cast<EnumType>(val);
4702 }
4703 #endif // JSON_DISABLE_ENUM_SERIALIZATION
4704 
4705 // forward_list doesn't have an insert method
4706 template<typename BasicJsonType, typename T, typename Allocator,
4707  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4708 inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4709 {
4710  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4711  {
4712  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4713  }
4714  l.clear();
4715  std::transform(j.rbegin(), j.rend(),
4716  std::front_inserter(l), [](const BasicJsonType & i)
4717  {
4718  return i.template get<T>();
4719  });
4720 }
4721 
4722 // valarray doesn't have an insert method
4723 template<typename BasicJsonType, typename T,
4724  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4725 inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
4726 {
4727  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4728  {
4729  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4730  }
4731  l.resize(j.size());
4732  std::transform(j.begin(), j.end(), std::begin(l),
4733  [](const BasicJsonType & elem)
4734  {
4735  return elem.template get<T>();
4736  });
4737 }
4738 
4739 template<typename BasicJsonType, typename T, std::size_t N>
4740 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4741 -> decltype(j.template get<T>(), void())
4742 {
4743  for (std::size_t i = 0; i < N; ++i)
4744  {
4745  arr[i] = j.at(i).template get<T>();
4746  }
4747 }
4748 
4749 template<typename BasicJsonType>
4750 inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4751 {
4752  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4753 }
4754 
4755 template<typename BasicJsonType, typename T, std::size_t N>
4756 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4757  priority_tag<2> /*unused*/)
4758 -> decltype(j.template get<T>(), void())
4759 {
4760  for (std::size_t i = 0; i < N; ++i)
4761  {
4762  arr[i] = j.at(i).template get<T>();
4763  }
4764 }
4765 
4766 template<typename BasicJsonType, typename ConstructibleArrayType,
4767  enable_if_t<
4768  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4769  int> = 0>
4770 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4771 -> decltype(
4772  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4773  j.template get<typename ConstructibleArrayType::value_type>(),
4774  void())
4775 {
4776  using std::end;
4777 
4778  ConstructibleArrayType ret;
4779  ret.reserve(j.size());
4780  std::transform(j.begin(), j.end(),
4781  std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4782  {
4783  // get<BasicJsonType>() returns *this, this won't call a from_json
4784  // method when value_type is BasicJsonType
4785  return i.template get<typename ConstructibleArrayType::value_type>();
4786  });
4787  arr = std::move(ret);
4788 }
4789 
4790 template<typename BasicJsonType, typename ConstructibleArrayType,
4791  enable_if_t<
4792  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4793  int> = 0>
4794 inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4795  priority_tag<0> /*unused*/)
4796 {
4797  using std::end;
4798 
4799  ConstructibleArrayType ret;
4800  std::transform(
4801  j.begin(), j.end(), std::inserter(ret, end(ret)),
4802  [](const BasicJsonType & i)
4803  {
4804  // get<BasicJsonType>() returns *this, this won't call a from_json
4805  // method when value_type is BasicJsonType
4806  return i.template get<typename ConstructibleArrayType::value_type>();
4807  });
4808  arr = std::move(ret);
4809 }
4810 
4811 template < typename BasicJsonType, typename ConstructibleArrayType,
4812  enable_if_t <
4813  is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4814  !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4816  !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4817  !is_basic_json<ConstructibleArrayType>::value,
4818  int > = 0 >
4819 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4820 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4821 j.template get<typename ConstructibleArrayType::value_type>(),
4822 void())
4823 {
4824  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4825  {
4826  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4827  }
4828 
4830 }
4831 
4832 template < typename BasicJsonType, typename T, std::size_t... Idx >
4833 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4834  identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4835 {
4836  return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4837 }
4838 
4839 template < typename BasicJsonType, typename T, std::size_t N >
4840 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4841 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4842 {
4843  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4844  {
4845  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4846  }
4847 
4848  return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4849 }
4850 
4851 template<typename BasicJsonType>
4852 inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4853 {
4854  if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4855  {
4856  JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4857  }
4858 
4859  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4860 }
4861 
4862 template<typename BasicJsonType, typename ConstructibleObjectType,
4863  enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4864 inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4865 {
4866  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4867  {
4868  JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4869  }
4870 
4871  ConstructibleObjectType ret;
4872  const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4873  using value_type = typename ConstructibleObjectType::value_type;
4874  std::transform(
4875  inner_object->begin(), inner_object->end(),
4876  std::inserter(ret, ret.begin()),
4877  [](typename BasicJsonType::object_t::value_type const & p)
4878  {
4879  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4880  });
4881  obj = std::move(ret);
4882 }
4883 
4884 // overload for arithmetic types, not chosen for basic_json template arguments
4885 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4886 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4887 // an arithmetic type?
4888 template < typename BasicJsonType, typename ArithmeticType,
4889  enable_if_t <
4890  std::is_arithmetic<ArithmeticType>::value&&
4891  !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4892  !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4893  !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4894  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4895  int > = 0 >
4896 inline void from_json(const BasicJsonType& j, ArithmeticType& val)
4897 {
4898  switch (static_cast<value_t>(j))
4899  {
4901  {
4902  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4903  break;
4904  }
4906  {
4907  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4908  break;
4909  }
4910  case value_t::number_float:
4911  {
4912  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4913  break;
4914  }
4915  case value_t::boolean:
4916  {
4917  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4918  break;
4919  }
4920 
4921  case value_t::null:
4922  case value_t::object:
4923  case value_t::array:
4924  case value_t::string:
4925  case value_t::binary:
4926  case value_t::discarded:
4927  default:
4928  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4929  }
4930 }
4931 
4932 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4933 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4934 {
4935  return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4936 }
4937 
4938 template < typename BasicJsonType, class A1, class A2 >
4939 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4940 {
4941  return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4942  std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4943 }
4944 
4945 template<typename BasicJsonType, typename A1, typename A2>
4946 inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4947 {
4948  p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4949 }
4950 
4951 template<typename BasicJsonType, typename... Args>
4952 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4953 {
4954  return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4955 }
4956 
4957 template<typename BasicJsonType, typename... Args>
4958 inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4959 {
4960  t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4961 }
4962 
4963 template<typename BasicJsonType, typename TupleRelated>
4964 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4965 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4966 {
4967  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4968  {
4969  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4970  }
4971 
4972  return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4973 }
4974 
4975 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4976  typename = enable_if_t < !std::is_constructible <
4977  typename BasicJsonType::string_t, Key >::value >>
4978 inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4979 {
4980  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4981  {
4982  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4983  }
4984  m.clear();
4985  for (const auto& p : j)
4986  {
4987  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4988  {
4989  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4990  }
4991  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4992  }
4993 }
4994 
4995 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4996  typename = enable_if_t < !std::is_constructible <
4997  typename BasicJsonType::string_t, Key >::value >>
4998 inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4999 {
5000  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5001  {
5002  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5003  }
5004  m.clear();
5005  for (const auto& p : j)
5006  {
5007  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5008  {
5009  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5010  }
5011  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5012  }
5013 }
5014 
5015 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5016 template<typename BasicJsonType>
5017 inline void from_json(const BasicJsonType& j, std_fs::path& p)
5018 {
5019  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
5020  {
5021  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
5022  }
5023  p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
5024 }
5025 #endif
5026 
5028 {
5029  template<typename BasicJsonType, typename T>
5030  auto operator()(const BasicJsonType& j, T&& val) const
5031  noexcept(noexcept(from_json(j, std::forward<T>(val))))
5032  -> decltype(from_json(j, std::forward<T>(val)))
5033  {
5034  return from_json(j, std::forward<T>(val));
5035  }
5036 };
5037 
5038 } // namespace detail
5039 
5040 #ifndef JSON_HAS_CPP_17
5041 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5045 {
5046 #endif
5047 JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
5049 #ifndef JSON_HAS_CPP_17
5050 } // namespace
5051 #endif
5052 
5054 
5055 // #include <nlohmann/detail/conversions/to_json.hpp>
5056 // __ _____ _____ _____
5057 // __| | __| | | | JSON for Modern C++
5058 // | | |__ | | | | | | version 3.11.2
5059 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5060 //
5061 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5062 // SPDX-License-Identifier: MIT
5063 
5064 
5065 
5066 #include <algorithm> // copy
5067 #include <iterator> // begin, end
5068 #include <string> // string
5069 #include <tuple> // tuple, get
5070 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
5071 #include <utility> // move, forward, declval, pair
5072 #include <valarray> // valarray
5073 #include <vector> // vector
5074 
5075 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5076 // __ _____ _____ _____
5077 // __| | __| | | | JSON for Modern C++
5078 // | | |__ | | | | | | version 3.11.2
5079 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5080 //
5081 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5082 // SPDX-License-Identifier: MIT
5083 
5084 
5085 
5086 #include <cstddef> // size_t
5087 #include <iterator> // input_iterator_tag
5088 #include <string> // string, to_string
5089 #include <tuple> // tuple_size, get, tuple_element
5090 #include <utility> // move
5091 
5092 #if JSON_HAS_RANGES
5093  #include <ranges> // enable_borrowed_range
5094 #endif
5095 
5096 // #include <nlohmann/detail/abi_macros.hpp>
5097 
5098 // #include <nlohmann/detail/meta/type_traits.hpp>
5099 
5100 // #include <nlohmann/detail/value_t.hpp>
5101 
5102 
5104 namespace detail
5105 {
5106 
5107 template<typename string_type>
5108 void int_to_string( string_type& target, std::size_t value )
5109 {
5110  // For ADL
5111  using std::to_string;
5112  target = to_string(value);
5113 }
5114 template<typename IteratorType> class iteration_proxy_value
5115 {
5116  public:
5117  using difference_type = std::ptrdiff_t;
5119  using pointer = value_type *;
5121  using iterator_category = std::input_iterator_tag;
5122  using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
5123 
5124  private:
5126  IteratorType anchor{};
5128  std::size_t array_index = 0;
5130  mutable std::size_t array_index_last = 0;
5132  mutable string_type array_index_str = "0";
5134  string_type empty_str{};
5135 
5136  public:
5137  explicit iteration_proxy_value() = default;
5138  explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
5139  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5140  && std::is_nothrow_default_constructible<string_type>::value)
5141  : anchor(std::move(it))
5142  , array_index(array_index_)
5143  {}
5144 
5145  iteration_proxy_value(iteration_proxy_value const&) = default;
5147  // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
5149  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5150  && std::is_nothrow_move_constructible<string_type>::value) = default;
5152  noexcept(std::is_nothrow_move_assignable<IteratorType>::value
5153  && std::is_nothrow_move_assignable<string_type>::value) = default;
5154  ~iteration_proxy_value() = default;
5155 
5157  const iteration_proxy_value& operator*() const
5158  {
5159  return *this;
5160  }
5161 
5164  {
5165  ++anchor;
5166  ++array_index;
5167 
5168  return *this;
5169  }
5170 
5171  iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
5172  {
5173  auto tmp = iteration_proxy_value(anchor, array_index);
5174  ++anchor;
5175  ++array_index;
5176  return tmp;
5177  }
5178 
5180  bool operator==(const iteration_proxy_value& o) const
5181  {
5182  return anchor == o.anchor;
5183  }
5184 
5186  bool operator!=(const iteration_proxy_value& o) const
5187  {
5188  return anchor != o.anchor;
5189  }
5190 
5192  const string_type& key() const
5193  {
5194  JSON_ASSERT(anchor.m_object != nullptr);
5195 
5196  switch (anchor.m_object->type())
5197  {
5198  // use integer array index as key
5199  case value_t::array:
5200  {
5201  if (array_index != array_index_last)
5202  {
5203  int_to_string( array_index_str, array_index );
5204  array_index_last = array_index;
5205  }
5206  return array_index_str;
5207  }
5208 
5209  // use key from the object
5210  case value_t::object:
5211  return anchor.key();
5212 
5213  // use an empty key for all primitive types
5214  case value_t::null:
5215  case value_t::string:
5216  case value_t::boolean:
5219  case value_t::number_float:
5220  case value_t::binary:
5221  case value_t::discarded:
5222  default:
5223  return empty_str;
5224  }
5225  }
5226 
5228  typename IteratorType::reference value() const
5229  {
5230  return anchor.value();
5231  }
5232 };
5233 
5235 template<typename IteratorType> class iteration_proxy
5236 {
5237  private:
5239  typename IteratorType::pointer container = nullptr;
5240 
5241  public:
5242  explicit iteration_proxy() = default;
5243 
5245  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
5246  : container(&cont) {}
5247 
5248  iteration_proxy(iteration_proxy const&) = default;
5249  iteration_proxy& operator=(iteration_proxy const&) = default;
5250  iteration_proxy(iteration_proxy&&) noexcept = default;
5251  iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
5252  ~iteration_proxy() = default;
5253 
5255  iteration_proxy_value<IteratorType> begin() const noexcept
5256  {
5257  return iteration_proxy_value<IteratorType>(container->begin());
5258  }
5259 
5262  {
5263  return iteration_proxy_value<IteratorType>(container->end());
5264  }
5265 };
5266 
5267 // Structured Bindings Support
5268 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5269 // And see https://github.com/nlohmann/json/pull/1391
5270 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
5271 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
5272 {
5273  return i.key();
5274 }
5275 // Structured Bindings Support
5276 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5277 // And see https://github.com/nlohmann/json/pull/1391
5278 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
5279 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
5280 {
5281  return i.value();
5282 }
5283 
5284 } // namespace detail
5286 
5287 // The Addition to the STD Namespace is required to add
5288 // Structured Bindings Support to the iteration_proxy_value class
5289 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5290 // And see https://github.com/nlohmann/json/pull/1391
5291 namespace std
5292 {
5293 
5294 #if defined(__clang__)
5295  // Fix: https://github.com/nlohmann/json/issues/1401
5296  #pragma clang diagnostic push
5297  #pragma clang diagnostic ignored "-Wmismatched-tags"
5298 #endif
5299 template<typename IteratorType>
5300 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
5301  : public std::integral_constant<std::size_t, 2> {};
5302 
5303 template<std::size_t N, typename IteratorType>
5304 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
5305 {
5306  public:
5307  using type = decltype(
5308  get<N>(std::declval <
5309  ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
5310 };
5311 #if defined(__clang__)
5312  #pragma clang diagnostic pop
5313 #endif
5314 
5315 } // namespace std
5316 
5317 #if JSON_HAS_RANGES
5318  template <typename IteratorType>
5319  inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
5320 #endif
5321 
5322 // #include <nlohmann/detail/macro_scope.hpp>
5323 
5324 // #include <nlohmann/detail/meta/cpp_future.hpp>
5325 
5326 // #include <nlohmann/detail/meta/std_fs.hpp>
5327 
5328 // #include <nlohmann/detail/meta/type_traits.hpp>
5329 
5330 // #include <nlohmann/detail/value_t.hpp>
5331 
5332 
5334 namespace detail
5335 {
5336 
5338 // constructors //
5340 
5341 /*
5342  * Note all external_constructor<>::construct functions need to call
5343  * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
5344  * allocated value (e.g., a string). See bug issue
5345  * https://github.com/nlohmann/json/issues/2865 for more information.
5346  */
5347 
5348 template<value_t> struct external_constructor;
5349 
5350 template<>
5352 {
5353  template<typename BasicJsonType>
5354  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
5355  {
5356  j.m_value.destroy(j.m_type);
5357  j.m_type = value_t::boolean;
5358  j.m_value = b;
5359  j.assert_invariant();
5360  }
5361 };
5362 
5363 template<>
5365 {
5366  template<typename BasicJsonType>
5367  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
5368  {
5369  j.m_value.destroy(j.m_type);
5370  j.m_type = value_t::string;
5371  j.m_value = s;
5372  j.assert_invariant();
5373  }
5374 
5375  template<typename BasicJsonType>
5376  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5377  {
5378  j.m_value.destroy(j.m_type);
5379  j.m_type = value_t::string;
5380  j.m_value = std::move(s);
5381  j.assert_invariant();
5382  }
5383 
5384  template < typename BasicJsonType, typename CompatibleStringType,
5386  int > = 0 >
5387  static void construct(BasicJsonType& j, const CompatibleStringType& str)
5388  {
5389  j.m_value.destroy(j.m_type);
5390  j.m_type = value_t::string;
5391  j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
5392  j.assert_invariant();
5393  }
5394 };
5395 
5396 template<>
5398 {
5399  template<typename BasicJsonType>
5400  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
5401  {
5402  j.m_value.destroy(j.m_type);
5403  j.m_type = value_t::binary;
5404  j.m_value = typename BasicJsonType::binary_t(b);
5405  j.assert_invariant();
5406  }
5407 
5408  template<typename BasicJsonType>
5409  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
5410  {
5411  j.m_value.destroy(j.m_type);
5412  j.m_type = value_t::binary;
5413  j.m_value = typename BasicJsonType::binary_t(std::move(b));
5414  j.assert_invariant();
5415  }
5416 };
5417 
5418 template<>
5420 {
5421  template<typename BasicJsonType>
5422  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5423  {
5424  j.m_value.destroy(j.m_type);
5425  j.m_type = value_t::number_float;
5426  j.m_value = val;
5427  j.assert_invariant();
5428  }
5429 };
5430 
5431 template<>
5433 {
5434  template<typename BasicJsonType>
5435  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5436  {
5437  j.m_value.destroy(j.m_type);
5438  j.m_type = value_t::number_unsigned;
5439  j.m_value = val;
5440  j.assert_invariant();
5441  }
5442 };
5443 
5444 template<>
5446 {
5447  template<typename BasicJsonType>
5448  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5449  {
5450  j.m_value.destroy(j.m_type);
5451  j.m_type = value_t::number_integer;
5452  j.m_value = val;
5453  j.assert_invariant();
5454  }
5455 };
5456 
5457 template<>
5459 {
5460  template<typename BasicJsonType>
5461  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5462  {
5463  j.m_value.destroy(j.m_type);
5464  j.m_type = value_t::array;
5465  j.m_value = arr;
5466  j.set_parents();
5467  j.assert_invariant();
5468  }
5469 
5470  template<typename BasicJsonType>
5471  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5472  {
5473  j.m_value.destroy(j.m_type);
5474  j.m_type = value_t::array;
5475  j.m_value = std::move(arr);
5476  j.set_parents();
5477  j.assert_invariant();
5478  }
5479 
5480  template < typename BasicJsonType, typename CompatibleArrayType,
5482  int > = 0 >
5483  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5484  {
5485  using std::begin;
5486  using std::end;
5487 
5488  j.m_value.destroy(j.m_type);
5489  j.m_type = value_t::array;
5490  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5491  j.set_parents();
5492  j.assert_invariant();
5493  }
5494 
5495  template<typename BasicJsonType>
5496  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5497  {
5498  j.m_value.destroy(j.m_type);
5499  j.m_type = value_t::array;
5500  j.m_value = value_t::array;
5501  j.m_value.array->reserve(arr.size());
5502  for (const bool x : arr)
5503  {
5504  j.m_value.array->push_back(x);
5505  j.set_parent(j.m_value.array->back());
5506  }
5507  j.assert_invariant();
5508  }
5509 
5510  template<typename BasicJsonType, typename T,
5512  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5513  {
5514  j.m_value.destroy(j.m_type);
5515  j.m_type = value_t::array;
5516  j.m_value = value_t::array;
5517  j.m_value.array->resize(arr.size());
5518  if (arr.size() > 0)
5519  {
5520  std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
5521  }
5522  j.set_parents();
5523  j.assert_invariant();
5524  }
5525 };
5526 
5527 template<>
5529 {
5530  template<typename BasicJsonType>
5531  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5532  {
5533  j.m_value.destroy(j.m_type);
5534  j.m_type = value_t::object;
5535  j.m_value = obj;
5536  j.set_parents();
5537  j.assert_invariant();
5538  }
5539 
5540  template<typename BasicJsonType>
5541  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5542  {
5543  j.m_value.destroy(j.m_type);
5544  j.m_type = value_t::object;
5545  j.m_value = std::move(obj);
5546  j.set_parents();
5547  j.assert_invariant();
5548  }
5549 
5550  template < typename BasicJsonType, typename CompatibleObjectType,
5552  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5553  {
5554  using std::begin;
5555  using std::end;
5556 
5557  j.m_value.destroy(j.m_type);
5558  j.m_type = value_t::object;
5559  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5560  j.set_parents();
5561  j.assert_invariant();
5562  }
5563 };
5564 
5566 // to_json //
5568 
5569 template<typename BasicJsonType, typename T,
5570  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5571 inline void to_json(BasicJsonType& j, T b) noexcept
5572 {
5574 }
5575 
5576 template < typename BasicJsonType, typename BoolRef,
5577  enable_if_t <
5578  ((std::is_same<std::vector<bool>::reference, BoolRef>::value
5579  && !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
5580  || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
5581  && !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
5582  typename BasicJsonType::boolean_t >::value))
5583  && std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 >
5584 inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
5585 {
5586  external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
5587 }
5588 
5589 template<typename BasicJsonType, typename CompatibleString,
5590  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5591 inline void to_json(BasicJsonType& j, const CompatibleString& s)
5592 {
5594 }
5595 
5596 template<typename BasicJsonType>
5597 inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5598 {
5600 }
5601 
5602 template<typename BasicJsonType, typename FloatType,
5603  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5604 inline void to_json(BasicJsonType& j, FloatType val) noexcept
5605 {
5606  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5607 }
5608 
5609 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5610  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5611 inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5612 {
5613  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5614 }
5615 
5616 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5617  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5618 inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5619 {
5620  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5621 }
5622 
5623 #if !JSON_DISABLE_ENUM_SERIALIZATION
5624 template<typename BasicJsonType, typename EnumType,
5625  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5626 inline void to_json(BasicJsonType& j, EnumType e) noexcept
5627 {
5628  using underlying_type = typename std::underlying_type<EnumType>::type;
5629  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5630 }
5631 #endif // JSON_DISABLE_ENUM_SERIALIZATION
5632 
5633 template<typename BasicJsonType>
5634 inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
5635 {
5637 }
5638 
5639 template < typename BasicJsonType, typename CompatibleArrayType,
5640  enable_if_t < is_compatible_array_type<BasicJsonType,
5641  CompatibleArrayType>::value&&
5642  !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
5644  !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
5645  !is_basic_json<CompatibleArrayType>::value,
5646  int > = 0 >
5647 inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5648 {
5650 }
5651 
5652 template<typename BasicJsonType>
5653 inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5654 {
5656 }
5657 
5658 template<typename BasicJsonType, typename T,
5659  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
5660 inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5661 {
5663 }
5664 
5665 template<typename BasicJsonType>
5666 inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5667 {
5669 }
5670 
5671 template < typename BasicJsonType, typename CompatibleObjectType,
5672  enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
5673 inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5674 {
5676 }
5677 
5678 template<typename BasicJsonType>
5679 inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5680 {
5682 }
5683 
5684 template <
5685  typename BasicJsonType, typename T, std::size_t N,
5686  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5687  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5688  int > = 0 >
5689 inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5690 {
5692 }
5693 
5694 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
5695 inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5696 {
5697  j = { p.first, p.second };
5698 }
5699 
5700 // for https://github.com/nlohmann/json/pull/1134
5701 template<typename BasicJsonType, typename T,
5702  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
5703 inline void to_json(BasicJsonType& j, const T& b)
5704 {
5705  j = { {b.key(), b.value()} };
5706 }
5707 
5708 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5709 inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5710 {
5711  j = { std::get<Idx>(t)... };
5712 }
5713 
5714 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5715 inline void to_json(BasicJsonType& j, const T& t)
5716 {
5717  to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5718 }
5719 
5720 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5721 template<typename BasicJsonType>
5722 inline void to_json(BasicJsonType& j, const std_fs::path& p)
5723 {
5724  j = p.string();
5725 }
5726 #endif
5727 
5729 {
5730  template<typename BasicJsonType, typename T>
5731  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5732  -> decltype(to_json(j, std::forward<T>(val)), void())
5733  {
5734  return to_json(j, std::forward<T>(val));
5735  }
5736 };
5737 } // namespace detail
5738 
5739 #ifndef JSON_HAS_CPP_17
5740 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5744 {
5745 #endif
5746 JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
5748 #ifndef JSON_HAS_CPP_17
5749 } // namespace
5750 #endif
5751 
5753 
5754 // #include <nlohmann/detail/meta/identity_tag.hpp>
5755 
5756 
5758 
5760 template<typename ValueType, typename>
5761 struct adl_serializer
5762 {
5765  template<typename BasicJsonType, typename TargetType = ValueType>
5766  static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5767  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5768  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5769  {
5770  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5771  }
5772 
5775  template<typename BasicJsonType, typename TargetType = ValueType>
5776  static auto from_json(BasicJsonType && j) noexcept(
5777  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5778  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5779  {
5780  return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5781  }
5782 
5785  template<typename BasicJsonType, typename TargetType = ValueType>
5786  static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5787  noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5788  -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5789  {
5790  ::nlohmann::to_json(j, std::forward<TargetType>(val));
5791  }
5792 };
5793 
5795 
5796 // #include <nlohmann/byte_container_with_subtype.hpp>
5797 // __ _____ _____ _____
5798 // __| | __| | | | JSON for Modern C++
5799 // | | |__ | | | | | | version 3.11.2
5800 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5801 //
5802 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5803 // SPDX-License-Identifier: MIT
5804 
5805 
5806 
5807 #include <cstdint> // uint8_t, uint64_t
5808 #include <tuple> // tie
5809 #include <utility> // move
5810 
5811 // #include <nlohmann/detail/abi_macros.hpp>
5812 
5813 
5815 
5818 template<typename BinaryType>
5820 {
5821  public:
5823  using subtype_type = std::uint64_t;
5824 
5827  : container_type()
5828  {}
5829 
5832  : container_type(b)
5833  {}
5834 
5836  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5837  : container_type(std::move(b))
5838  {}
5839 
5841  byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5842  : container_type(b)
5843  , m_subtype(subtype_)
5844  , m_has_subtype(true)
5845  {}
5846 
5848  byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5849  : container_type(std::move(b))
5850  , m_subtype(subtype_)
5851  , m_has_subtype(true)
5852  {}
5853 
5855  {
5856  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5857  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5858  }
5859 
5861  {
5862  return !(rhs == *this);
5863  }
5864 
5867  void set_subtype(subtype_type subtype_) noexcept
5868  {
5869  m_subtype = subtype_;
5870  m_has_subtype = true;
5871  }
5872 
5875  constexpr subtype_type subtype() const noexcept
5876  {
5877  return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5878  }
5879 
5882  constexpr bool has_subtype() const noexcept
5883  {
5884  return m_has_subtype;
5885  }
5886 
5889  void clear_subtype() noexcept
5890  {
5891  m_subtype = 0;
5892  m_has_subtype = false;
5893  }
5894 
5895  private:
5896  subtype_type m_subtype = 0;
5897  bool m_has_subtype = false;
5898 };
5899 
5901 
5902 // #include <nlohmann/detail/conversions/from_json.hpp>
5903 
5904 // #include <nlohmann/detail/conversions/to_json.hpp>
5905 
5906 // #include <nlohmann/detail/exceptions.hpp>
5907 
5908 // #include <nlohmann/detail/hash.hpp>
5909 // __ _____ _____ _____
5910 // __| | __| | | | JSON for Modern C++
5911 // | | |__ | | | | | | version 3.11.2
5912 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5913 //
5914 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5915 // SPDX-License-Identifier: MIT
5916 
5917 
5918 
5919 #include <cstdint> // uint8_t
5920 #include <cstddef> // size_t
5921 #include <functional> // hash
5922 
5923 // #include <nlohmann/detail/abi_macros.hpp>
5924 
5925 // #include <nlohmann/detail/value_t.hpp>
5926 
5927 
5929 namespace detail
5930 {
5931 
5932 // boost::hash_combine
5933 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5934 {
5935  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5936  return seed;
5937 }
5938 
5950 template<typename BasicJsonType>
5951 std::size_t hash(const BasicJsonType& j)
5952 {
5953  using string_t = typename BasicJsonType::string_t;
5954  using number_integer_t = typename BasicJsonType::number_integer_t;
5955  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5956  using number_float_t = typename BasicJsonType::number_float_t;
5957 
5958  const auto type = static_cast<std::size_t>(j.type());
5959  switch (j.type())
5960  {
5961  case BasicJsonType::value_t::null:
5962  case BasicJsonType::value_t::discarded:
5963  {
5964  return combine(type, 0);
5965  }
5966 
5967  case BasicJsonType::value_t::object:
5968  {
5969  auto seed = combine(type, j.size());
5970  for (const auto& element : j.items())
5971  {
5972  const auto h = std::hash<string_t> {}(element.key());
5973  seed = combine(seed, h);
5974  seed = combine(seed, hash(element.value()));
5975  }
5976  return seed;
5977  }
5978 
5979  case BasicJsonType::value_t::array:
5980  {
5981  auto seed = combine(type, j.size());
5982  for (const auto& element : j)
5983  {
5984  seed = combine(seed, hash(element));
5985  }
5986  return seed;
5987  }
5988 
5989  case BasicJsonType::value_t::string:
5990  {
5991  const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5992  return combine(type, h);
5993  }
5994 
5995  case BasicJsonType::value_t::boolean:
5996  {
5997  const auto h = std::hash<bool> {}(j.template get<bool>());
5998  return combine(type, h);
5999  }
6000 
6001  case BasicJsonType::value_t::number_integer:
6002  {
6003  const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
6004  return combine(type, h);
6005  }
6006 
6007  case BasicJsonType::value_t::number_unsigned:
6008  {
6009  const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
6010  return combine(type, h);
6011  }
6012 
6013  case BasicJsonType::value_t::number_float:
6014  {
6015  const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
6016  return combine(type, h);
6017  }
6018 
6019  case BasicJsonType::value_t::binary:
6020  {
6021  auto seed = combine(type, j.get_binary().size());
6022  const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
6023  seed = combine(seed, h);
6024  seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
6025  for (const auto byte : j.get_binary())
6026  {
6027  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
6028  }
6029  return seed;
6030  }
6031 
6032  default: // LCOV_EXCL_LINE
6033  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
6034  return 0; // LCOV_EXCL_LINE
6035  }
6036 }
6037 
6038 } // namespace detail
6040 
6041 // #include <nlohmann/detail/input/binary_reader.hpp>
6042 // __ _____ _____ _____
6043 // __| | __| | | | JSON for Modern C++
6044 // | | |__ | | | | | | version 3.11.2
6045 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6046 //
6047 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6048 // SPDX-License-Identifier: MIT
6049 
6050 
6051 
6052 #include <algorithm> // generate_n
6053 #include <array> // array
6054 #include <cmath> // ldexp
6055 #include <cstddef> // size_t
6056 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6057 #include <cstdio> // snprintf
6058 #include <cstring> // memcpy
6059 #include <iterator> // back_inserter
6060 #include <limits> // numeric_limits
6061 #include <string> // char_traits, string
6062 #include <utility> // make_pair, move
6063 #include <vector> // vector
6064 
6065 // #include <nlohmann/detail/exceptions.hpp>
6066 
6067 // #include <nlohmann/detail/input/input_adapters.hpp>
6068 // __ _____ _____ _____
6069 // __| | __| | | | JSON for Modern C++
6070 // | | |__ | | | | | | version 3.11.2
6071 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6072 //
6073 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6074 // SPDX-License-Identifier: MIT
6075 
6076 
6077 
6078 #include <array> // array
6079 #include <cstddef> // size_t
6080 #include <cstring> // strlen
6081 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
6082 #include <memory> // shared_ptr, make_shared, addressof
6083 #include <numeric> // accumulate
6084 #include <string> // string, char_traits
6085 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
6086 #include <utility> // pair, declval
6087 
6088 #ifndef JSON_NO_IO
6089  #include <cstdio> // FILE *
6090  #include <istream> // istream
6091 #endif // JSON_NO_IO
6092 
6093 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
6094 
6095 // #include <nlohmann/detail/macro_scope.hpp>
6096 
6097 
6099 namespace detail
6100 {
6101 
6104 
6106 // input adapters //
6108 
6109 #ifndef JSON_NO_IO
6110 
6115 {
6116  public:
6117  using char_type = char;
6118 
6120  explicit file_input_adapter(std::FILE* f) noexcept
6121  : m_file(f)
6122  {
6123  JSON_ASSERT(m_file != nullptr);
6124  }
6125 
6126  // make class move-only
6127  file_input_adapter(const file_input_adapter&) = delete;
6128  file_input_adapter(file_input_adapter&&) noexcept = default;
6129  file_input_adapter& operator=(const file_input_adapter&) = delete;
6130  file_input_adapter& operator=(file_input_adapter&&) = delete;
6131  ~file_input_adapter() = default;
6132 
6133  std::char_traits<char>::int_type get_character() noexcept
6134  {
6135  return std::fgetc(m_file);
6136  }
6137 
6138  private:
6140  std::FILE* m_file;
6141 };
6142 
6143 
6154 {
6155  public:
6156  using char_type = char;
6157 
6159  {
6160  // clear stream flags; we use underlying streambuf I/O, do not
6161  // maintain ifstream flags, except eof
6162  if (is != nullptr)
6163  {
6164  is->clear(is->rdstate() & std::ios::eofbit);
6165  }
6166  }
6167 
6168  explicit input_stream_adapter(std::istream& i)
6169  : is(&i), sb(i.rdbuf())
6170  {}
6171 
6172  // delete because of pointer members
6173  input_stream_adapter(const input_stream_adapter&) = delete;
6176 
6178  : is(rhs.is), sb(rhs.sb)
6179  {
6180  rhs.is = nullptr;
6181  rhs.sb = nullptr;
6182  }
6183 
6184  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
6185  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
6186  // end up as the same value, e.g. 0xFFFFFFFF.
6187  std::char_traits<char>::int_type get_character()
6188  {
6189  auto res = sb->sbumpc();
6190  // set eof manually, as we don't use the istream interface.
6191  if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
6192  {
6193  is->clear(is->rdstate() | std::ios::eofbit);
6194  }
6195  return res;
6196  }
6197 
6198  private:
6200  std::istream* is = nullptr;
6201  std::streambuf* sb = nullptr;
6202 };
6203 #endif // JSON_NO_IO
6204 
6205 // General-purpose iterator-based adapter. It might not be as fast as
6206 // theoretically possible for some containers, but it is extremely versatile.
6207 template<typename IteratorType>
6209 {
6210  public:
6211  using char_type = typename std::iterator_traits<IteratorType>::value_type;
6212 
6213  iterator_input_adapter(IteratorType first, IteratorType last)
6214  : current(std::move(first)), end(std::move(last))
6215  {}
6216 
6217  typename std::char_traits<char_type>::int_type get_character()
6218  {
6219  if (JSON_HEDLEY_LIKELY(current != end))
6220  {
6221  auto result = std::char_traits<char_type>::to_int_type(*current);
6222  std::advance(current, 1);
6223  return result;
6224  }
6225 
6226  return std::char_traits<char_type>::eof();
6227  }
6228 
6229  private:
6230  IteratorType current;
6231  IteratorType end;
6232 
6233  template<typename BaseInputAdapter, size_t T>
6235 
6236  bool empty() const
6237  {
6238  return current == end;
6239  }
6240 };
6241 
6242 
6243 template<typename BaseInputAdapter, size_t T>
6245 
6246 template<typename BaseInputAdapter>
6247 struct wide_string_input_helper<BaseInputAdapter, 4>
6248 {
6249  // UTF-32
6250  static void fill_buffer(BaseInputAdapter& input,
6251  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6252  size_t& utf8_bytes_index,
6253  size_t& utf8_bytes_filled)
6254  {
6255  utf8_bytes_index = 0;
6256 
6257  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6258  {
6259  utf8_bytes[0] = std::char_traits<char>::eof();
6260  utf8_bytes_filled = 1;
6261  }
6262  else
6263  {
6264  // get the current character
6265  const auto wc = input.get_character();
6266 
6267  // UTF-32 to UTF-8 encoding
6268  if (wc < 0x80)
6269  {
6270  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6271  utf8_bytes_filled = 1;
6272  }
6273  else if (wc <= 0x7FF)
6274  {
6275  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
6276  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6277  utf8_bytes_filled = 2;
6278  }
6279  else if (wc <= 0xFFFF)
6280  {
6281  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
6282  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6283  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6284  utf8_bytes_filled = 3;
6285  }
6286  else if (wc <= 0x10FFFF)
6287  {
6288  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
6289  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
6290  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6291  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6292  utf8_bytes_filled = 4;
6293  }
6294  else
6295  {
6296  // unknown character
6297  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6298  utf8_bytes_filled = 1;
6299  }
6300  }
6301  }
6302 };
6303 
6304 template<typename BaseInputAdapter>
6305 struct wide_string_input_helper<BaseInputAdapter, 2>
6306 {
6307  // UTF-16
6308  static void fill_buffer(BaseInputAdapter& input,
6309  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6310  size_t& utf8_bytes_index,
6311  size_t& utf8_bytes_filled)
6312  {
6313  utf8_bytes_index = 0;
6314 
6315  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6316  {
6317  utf8_bytes[0] = std::char_traits<char>::eof();
6318  utf8_bytes_filled = 1;
6319  }
6320  else
6321  {
6322  // get the current character
6323  const auto wc = input.get_character();
6324 
6325  // UTF-16 to UTF-8 encoding
6326  if (wc < 0x80)
6327  {
6328  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6329  utf8_bytes_filled = 1;
6330  }
6331  else if (wc <= 0x7FF)
6332  {
6333  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
6334  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6335  utf8_bytes_filled = 2;
6336  }
6337  else if (0xD800 > wc || wc >= 0xE000)
6338  {
6339  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
6340  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6341  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6342  utf8_bytes_filled = 3;
6343  }
6344  else
6345  {
6346  if (JSON_HEDLEY_UNLIKELY(!input.empty()))
6347  {
6348  const auto wc2 = static_cast<unsigned int>(input.get_character());
6349  const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
6350  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
6351  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
6352  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
6353  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
6354  utf8_bytes_filled = 4;
6355  }
6356  else
6357  {
6358  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6359  utf8_bytes_filled = 1;
6360  }
6361  }
6362  }
6363  }
6364 };
6365 
6366 // Wraps another input apdater to convert wide character types into individual bytes.
6367 template<typename BaseInputAdapter, typename WideCharType>
6369 {
6370  public:
6371  using char_type = char;
6372 
6373  wide_string_input_adapter(BaseInputAdapter base)
6374  : base_adapter(base) {}
6375 
6376  typename std::char_traits<char>::int_type get_character() noexcept
6377  {
6378  // check if buffer needs to be filled
6379  if (utf8_bytes_index == utf8_bytes_filled)
6380  {
6381  fill_buffer<sizeof(WideCharType)>();
6382 
6383  JSON_ASSERT(utf8_bytes_filled > 0);
6384  JSON_ASSERT(utf8_bytes_index == 0);
6385  }
6386 
6387  // use buffer
6388  JSON_ASSERT(utf8_bytes_filled > 0);
6389  JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
6390  return utf8_bytes[utf8_bytes_index++];
6391  }
6392 
6393  private:
6394  BaseInputAdapter base_adapter;
6395 
6396  template<size_t T>
6397  void fill_buffer()
6398  {
6399  wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
6400  }
6401 
6403  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
6404 
6406  std::size_t utf8_bytes_index = 0;
6408  std::size_t utf8_bytes_filled = 0;
6409 };
6410 
6411 
6412 template<typename IteratorType, typename Enable = void>
6414 {
6415  using iterator_type = IteratorType;
6416  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6418 
6419  static adapter_type create(IteratorType first, IteratorType last)
6420  {
6421  return adapter_type(std::move(first), std::move(last));
6422  }
6423 };
6424 
6425 template<typename T>
6427 {
6428  using value_type = typename std::iterator_traits<T>::value_type;
6429  enum
6430  {
6431  value = sizeof(value_type) > 1
6432  };
6433 };
6434 
6435 template<typename IteratorType>
6437 {
6438  using iterator_type = IteratorType;
6439  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6442 
6443  static adapter_type create(IteratorType first, IteratorType last)
6444  {
6445  return adapter_type(base_adapter_type(std::move(first), std::move(last)));
6446  }
6447 };
6448 
6449 // General purpose iterator-based input
6450 template<typename IteratorType>
6451 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
6452 {
6453  using factory_type = iterator_input_adapter_factory<IteratorType>;
6454  return factory_type::create(first, last);
6455 }
6456 
6457 // Convenience shorthand from container to iterator
6458 // Enables ADL on begin(container) and end(container)
6459 // Encloses the using declarations in namespace for not to leak them to outside scope
6460 
6461 namespace container_input_adapter_factory_impl
6462 {
6463 
6464 using std::begin;
6465 using std::end;
6466 
6467 template<typename ContainerType, typename Enable = void>
6469 
6470 template<typename ContainerType>
6471 struct container_input_adapter_factory< ContainerType,
6472  void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6473  {
6474  using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6475 
6476  static adapter_type create(const ContainerType& container)
6477 {
6478  return input_adapter(begin(container), end(container));
6479 }
6480  };
6481 
6482 } // namespace container_input_adapter_factory_impl
6483 
6484 template<typename ContainerType>
6486 {
6488 }
6489 
6490 #ifndef JSON_NO_IO
6491 // Special cases with fast paths
6492 inline file_input_adapter input_adapter(std::FILE* file)
6493 {
6494  return file_input_adapter(file);
6495 }
6496 
6497 inline input_stream_adapter input_adapter(std::istream& stream)
6498 {
6499  return input_stream_adapter(stream);
6500 }
6501 
6502 inline input_stream_adapter input_adapter(std::istream&& stream)
6503 {
6504  return input_stream_adapter(stream);
6505 }
6506 #endif // JSON_NO_IO
6507 
6508 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6509 
6510 // Null-delimited strings, and the like.
6511 template < typename CharT,
6512  typename std::enable_if <
6513  std::is_pointer<CharT>::value&&
6514  !std::is_array<CharT>::value&&
6516  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6517  int >::type = 0 >
6519 {
6520  auto length = std::strlen(reinterpret_cast<const char*>(b));
6521  const auto* ptr = reinterpret_cast<const char*>(b);
6522  return input_adapter(ptr, ptr + length);
6523 }
6524 
6525 template<typename T, std::size_t N>
6526 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)
6527 {
6528  return input_adapter(array, array + N);
6529 }
6530 
6531 // This class only handles inputs of input_buffer_adapter type.
6532 // It's required so that expressions like {ptr, len} can be implicitly cast
6533 // to the correct adapter.
6535 {
6536  public:
6537  template < typename CharT,
6538  typename std::enable_if <
6539  std::is_pointer<CharT>::value&&
6541  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6542  int >::type = 0 >
6543  span_input_adapter(CharT b, std::size_t l)
6544  : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
6545 
6546  template<class IteratorType,
6547  typename std::enable_if<
6548  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
6549  int>::type = 0>
6550  span_input_adapter(IteratorType first, IteratorType last)
6551  : ia(input_adapter(first, last)) {}
6552 
6554  {
6555  return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6556  }
6557 
6558  private:
6560 };
6561 
6562 } // namespace detail
6564 
6565 // #include <nlohmann/detail/input/json_sax.hpp>
6566 // __ _____ _____ _____
6567 // __| | __| | | | JSON for Modern C++
6568 // | | |__ | | | | | | version 3.11.2
6569 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6570 //
6571 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6572 // SPDX-License-Identifier: MIT
6573 
6574 
6575 
6576 #include <cstddef>
6577 #include <string> // string
6578 #include <utility> // move
6579 #include <vector> // vector
6580 
6581 // #include <nlohmann/detail/exceptions.hpp>
6582 
6583 // #include <nlohmann/detail/macro_scope.hpp>
6584 
6585 // #include <nlohmann/detail/string_concat.hpp>
6586 
6587 
6589 
6598 template<typename BasicJsonType>
6599 struct json_sax
6600 {
6601  using number_integer_t = typename BasicJsonType::number_integer_t;
6602  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6603  using number_float_t = typename BasicJsonType::number_float_t;
6604  using string_t = typename BasicJsonType::string_t;
6605  using binary_t = typename BasicJsonType::binary_t;
6606 
6611  virtual bool null() = 0;
6612 
6618  virtual bool boolean(bool val) = 0;
6619 
6625  virtual bool number_integer(number_integer_t val) = 0;
6626 
6632  virtual bool number_unsigned(number_unsigned_t val) = 0;
6633 
6640  virtual bool number_float(number_float_t val, const string_t& s) = 0;
6641 
6648  virtual bool string(string_t& val) = 0;
6649 
6656  virtual bool binary(binary_t& val) = 0;
6657 
6664  virtual bool start_object(std::size_t elements) = 0;
6665 
6672  virtual bool key(string_t& val) = 0;
6673 
6678  virtual bool end_object() = 0;
6679 
6686  virtual bool start_array(std::size_t elements) = 0;
6687 
6692  virtual bool end_array() = 0;
6693 
6701  virtual bool parse_error(std::size_t position,
6702  const std::string& last_token,
6703  const detail::exception& ex) = 0;
6704 
6705  json_sax() = default;
6706  json_sax(const json_sax&) = default;
6707  json_sax(json_sax&&) noexcept = default;
6708  json_sax& operator=(const json_sax&) = default;
6709  json_sax& operator=(json_sax&&) noexcept = default;
6710  virtual ~json_sax() = default;
6711 };
6712 
6713 
6714 namespace detail
6715 {
6729 template<typename BasicJsonType>
6731 {
6732  public:
6733  using number_integer_t = typename BasicJsonType::number_integer_t;
6734  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6735  using number_float_t = typename BasicJsonType::number_float_t;
6736  using string_t = typename BasicJsonType::string_t;
6737  using binary_t = typename BasicJsonType::binary_t;
6738 
6744  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6745  : root(r), allow_exceptions(allow_exceptions_)
6746  {}
6747 
6748  // make class move-only
6749  json_sax_dom_parser(const json_sax_dom_parser&) = delete;
6750  json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6752  json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6753  ~json_sax_dom_parser() = default;
6754 
6755  bool null()
6756  {
6757  handle_value(nullptr);
6758  return true;
6759  }
6760 
6761  bool boolean(bool val)
6762  {
6763  handle_value(val);
6764  return true;
6765  }
6766 
6768  {
6769  handle_value(val);
6770  return true;
6771  }
6772 
6774  {
6775  handle_value(val);
6776  return true;
6777  }
6778 
6779  bool number_float(number_float_t val, const string_t& /*unused*/)
6780  {
6781  handle_value(val);
6782  return true;
6783  }
6784 
6785  bool string(string_t& val)
6786  {
6787  handle_value(val);
6788  return true;
6789  }
6790 
6791  bool binary(binary_t& val)
6792  {
6793  handle_value(std::move(val));
6794  return true;
6795  }
6796 
6797  bool start_object(std::size_t len)
6798  {
6799  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6800 
6801  if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6802  {
6803  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6804  }
6805 
6806  return true;
6807  }
6808 
6809  bool key(string_t& val)
6810  {
6811  JSON_ASSERT(!ref_stack.empty());
6812  JSON_ASSERT(ref_stack.back()->is_object());
6813 
6814  // add null at given key and store the reference for later
6815  object_element = &(ref_stack.back()->m_value.object->operator[](val));
6816  return true;
6817  }
6818 
6819  bool end_object()
6820  {
6821  JSON_ASSERT(!ref_stack.empty());
6822  JSON_ASSERT(ref_stack.back()->is_object());
6823 
6824  ref_stack.back()->set_parents();
6825  ref_stack.pop_back();
6826  return true;
6827  }
6828 
6829  bool start_array(std::size_t len)
6830  {
6831  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6832 
6833  if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6834  {
6835  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6836  }
6837 
6838  return true;
6839  }
6840 
6841  bool end_array()
6842  {
6843  JSON_ASSERT(!ref_stack.empty());
6844  JSON_ASSERT(ref_stack.back()->is_array());
6845 
6846  ref_stack.back()->set_parents();
6847  ref_stack.pop_back();
6848  return true;
6849  }
6850 
6851  template<class Exception>
6852  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6853  const Exception& ex)
6854  {
6855  errored = true;
6856  static_cast<void>(ex);
6857  if (allow_exceptions)
6858  {
6859  JSON_THROW(ex);
6860  }
6861  return false;
6862  }
6863 
6864  constexpr bool is_errored() const
6865  {
6866  return errored;
6867  }
6868 
6869  private:
6876  template<typename Value>
6878  BasicJsonType* handle_value(Value&& v)
6879  {
6880  if (ref_stack.empty())
6881  {
6882  root = BasicJsonType(std::forward<Value>(v));
6883  return &root;
6884  }
6885 
6886  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6887 
6888  if (ref_stack.back()->is_array())
6889  {
6890  ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6891  return &(ref_stack.back()->m_value.array->back());
6892  }
6893 
6894  JSON_ASSERT(ref_stack.back()->is_object());
6895  JSON_ASSERT(object_element);
6896  *object_element = BasicJsonType(std::forward<Value>(v));
6897  return object_element;
6898  }
6899 
6901  BasicJsonType& root;
6903  std::vector<BasicJsonType*> ref_stack {};
6905  BasicJsonType* object_element = nullptr;
6907  bool errored = false;
6909  const bool allow_exceptions = true;
6910 };
6911 
6912 template<typename BasicJsonType>
6914 {
6915  public:
6916  using number_integer_t = typename BasicJsonType::number_integer_t;
6917  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6918  using number_float_t = typename BasicJsonType::number_float_t;
6919  using string_t = typename BasicJsonType::string_t;
6920  using binary_t = typename BasicJsonType::binary_t;
6923 
6925  const parser_callback_t cb,
6926  const bool allow_exceptions_ = true)
6927  : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6928  {
6929  keep_stack.push_back(true);
6930  }
6931 
6932  // make class move-only
6934  json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6936  json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6937  ~json_sax_dom_callback_parser() = default;
6938 
6939  bool null()
6940  {
6941  handle_value(nullptr);
6942  return true;
6943  }
6944 
6945  bool boolean(bool val)
6946  {
6947  handle_value(val);
6948  return true;
6949  }
6950 
6952  {
6953  handle_value(val);
6954  return true;
6955  }
6956 
6958  {
6959  handle_value(val);
6960  return true;
6961  }
6962 
6963  bool number_float(number_float_t val, const string_t& /*unused*/)
6964  {
6965  handle_value(val);
6966  return true;
6967  }
6968 
6969  bool string(string_t& val)
6970  {
6971  handle_value(val);
6972  return true;
6973  }
6974 
6975  bool binary(binary_t& val)
6976  {
6977  handle_value(std::move(val));
6978  return true;
6979  }
6980 
6981  bool start_object(std::size_t len)
6982  {
6983  // check callback for object start
6984  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6985  keep_stack.push_back(keep);
6986 
6987  auto val = handle_value(BasicJsonType::value_t::object, true);
6988  ref_stack.push_back(val.second);
6989 
6990  // check object limit
6991  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6992  {
6993  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6994  }
6995 
6996  return true;
6997  }
6998 
6999  bool key(string_t& val)
7000  {
7001  BasicJsonType k = BasicJsonType(val);
7002 
7003  // check callback for key
7004  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
7005  key_keep_stack.push_back(keep);
7006 
7007  // add discarded value at given key and store the reference for later
7008  if (keep && ref_stack.back())
7009  {
7010  object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
7011  }
7012 
7013  return true;
7014  }
7015 
7016  bool end_object()
7017  {
7018  if (ref_stack.back())
7019  {
7020  if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
7021  {
7022  // discard object
7023  *ref_stack.back() = discarded;
7024  }
7025  else
7026  {
7027  ref_stack.back()->set_parents();
7028  }
7029  }
7030 
7031  JSON_ASSERT(!ref_stack.empty());
7032  JSON_ASSERT(!keep_stack.empty());
7033  ref_stack.pop_back();
7034  keep_stack.pop_back();
7035 
7036  if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
7037  {
7038  // remove discarded value
7039  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
7040  {
7041  if (it->is_discarded())
7042  {
7043  ref_stack.back()->erase(it);
7044  break;
7045  }
7046  }
7047  }
7048 
7049  return true;
7050  }
7051 
7052  bool start_array(std::size_t len)
7053  {
7054  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
7055  keep_stack.push_back(keep);
7056 
7057  auto val = handle_value(BasicJsonType::value_t::array, true);
7058  ref_stack.push_back(val.second);
7059 
7060  // check array limit
7061  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
7062  {
7063  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
7064  }
7065 
7066  return true;
7067  }
7068 
7069  bool end_array()
7070  {
7071  bool keep = true;
7072 
7073  if (ref_stack.back())
7074  {
7075  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
7076  if (keep)
7077  {
7078  ref_stack.back()->set_parents();
7079  }
7080  else
7081  {
7082  // discard array
7083  *ref_stack.back() = discarded;
7084  }
7085  }
7086 
7087  JSON_ASSERT(!ref_stack.empty());
7088  JSON_ASSERT(!keep_stack.empty());
7089  ref_stack.pop_back();
7090  keep_stack.pop_back();
7091 
7092  // remove discarded value
7093  if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
7094  {
7095  ref_stack.back()->m_value.array->pop_back();
7096  }
7097 
7098  return true;
7099  }
7100 
7101  template<class Exception>
7102  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
7103  const Exception& ex)
7104  {
7105  errored = true;
7106  static_cast<void>(ex);
7107  if (allow_exceptions)
7108  {
7109  JSON_THROW(ex);
7110  }
7111  return false;
7112  }
7113 
7114  constexpr bool is_errored() const
7115  {
7116  return errored;
7117  }
7118 
7119  private:
7135  template<typename Value>
7136  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
7137  {
7138  JSON_ASSERT(!keep_stack.empty());
7139 
7140  // do not handle this value if we know it would be added to a discarded
7141  // container
7142  if (!keep_stack.back())
7143  {
7144  return {false, nullptr};
7145  }
7146 
7147  // create value
7148  auto value = BasicJsonType(std::forward<Value>(v));
7149 
7150  // check callback
7151  const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
7152 
7153  // do not handle this value if we just learnt it shall be discarded
7154  if (!keep)
7155  {
7156  return {false, nullptr};
7157  }
7158 
7159  if (ref_stack.empty())
7160  {
7161  root = std::move(value);
7162  return {true, &root};
7163  }
7164 
7165  // skip this value if we already decided to skip the parent
7166  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
7167  if (!ref_stack.back())
7168  {
7169  return {false, nullptr};
7170  }
7171 
7172  // we now only expect arrays and objects
7173  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
7174 
7175  // array
7176  if (ref_stack.back()->is_array())
7177  {
7178  ref_stack.back()->m_value.array->emplace_back(std::move(value));
7179  return {true, &(ref_stack.back()->m_value.array->back())};
7180  }
7181 
7182  // object
7183  JSON_ASSERT(ref_stack.back()->is_object());
7184  // check if we should store an element for the current key
7185  JSON_ASSERT(!key_keep_stack.empty());
7186  const bool store_element = key_keep_stack.back();
7187  key_keep_stack.pop_back();
7188 
7189  if (!store_element)
7190  {
7191  return {false, nullptr};
7192  }
7193 
7194  JSON_ASSERT(object_element);
7195  *object_element = std::move(value);
7196  return {true, object_element};
7197  }
7198 
7200  BasicJsonType& root;
7202  std::vector<BasicJsonType*> ref_stack {};
7204  std::vector<bool> keep_stack {};
7206  std::vector<bool> key_keep_stack {};
7208  BasicJsonType* object_element = nullptr;
7210  bool errored = false;
7212  const parser_callback_t callback = nullptr;
7214  const bool allow_exceptions = true;
7216  BasicJsonType discarded = BasicJsonType::value_t::discarded;
7217 };
7218 
7219 template<typename BasicJsonType>
7221 {
7222  public:
7223  using number_integer_t = typename BasicJsonType::number_integer_t;
7224  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7225  using number_float_t = typename BasicJsonType::number_float_t;
7226  using string_t = typename BasicJsonType::string_t;
7227  using binary_t = typename BasicJsonType::binary_t;
7228 
7229  bool null()
7230  {
7231  return true;
7232  }
7233 
7234  bool boolean(bool /*unused*/)
7235  {
7236  return true;
7237  }
7238 
7240  {
7241  return true;
7242  }
7243 
7245  {
7246  return true;
7247  }
7248 
7249  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
7250  {
7251  return true;
7252  }
7253 
7254  bool string(string_t& /*unused*/)
7255  {
7256  return true;
7257  }
7258 
7259  bool binary(binary_t& /*unused*/)
7260  {
7261  return true;
7262  }
7263 
7264  bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7265  {
7266  return true;
7267  }
7268 
7269  bool key(string_t& /*unused*/)
7270  {
7271  return true;
7272  }
7273 
7274  bool end_object()
7275  {
7276  return true;
7277  }
7278 
7279  bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7280  {
7281  return true;
7282  }
7283 
7284  bool end_array()
7285  {
7286  return true;
7287  }
7288 
7289  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
7290  {
7291  return false;
7292  }
7293 };
7294 
7295 } // namespace detail
7297 
7298 // #include <nlohmann/detail/input/lexer.hpp>
7299 // __ _____ _____ _____
7300 // __| | __| | | | JSON for Modern C++
7301 // | | |__ | | | | | | version 3.11.2
7302 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
7303 //
7304 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7305 // SPDX-License-Identifier: MIT
7306 
7307 
7308 
7309 #include <array> // array
7310 #include <clocale> // localeconv
7311 #include <cstddef> // size_t
7312 #include <cstdio> // snprintf
7313 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7314 #include <initializer_list> // initializer_list
7315 #include <string> // char_traits, string
7316 #include <utility> // move
7317 #include <vector> // vector
7318 
7319 // #include <nlohmann/detail/input/input_adapters.hpp>
7320 
7321 // #include <nlohmann/detail/input/position_t.hpp>
7322 
7323 // #include <nlohmann/detail/macro_scope.hpp>
7324 
7325 
7327 namespace detail
7328 {
7329 
7331 // lexer //
7333 
7334 template<typename BasicJsonType>
7336 {
7337  public:
7339  enum class token_type
7340  {
7341  uninitialized,
7342  literal_true,
7343  literal_false,
7344  literal_null,
7345  value_string,
7346  value_unsigned,
7347  value_integer,
7348  value_float,
7349  begin_array,
7350  begin_object,
7351  end_array,
7352  end_object,
7353  name_separator,
7354  value_separator,
7355  parse_error,
7356  end_of_input,
7357  literal_or_value
7358  };
7359 
7363  static const char* token_type_name(const token_type t) noexcept
7364  {
7365  switch (t)
7366  {
7367  case token_type::uninitialized:
7368  return "<uninitialized>";
7369  case token_type::literal_true:
7370  return "true literal";
7371  case token_type::literal_false:
7372  return "false literal";
7373  case token_type::literal_null:
7374  return "null literal";
7375  case token_type::value_string:
7376  return "string literal";
7377  case token_type::value_unsigned:
7378  case token_type::value_integer:
7379  case token_type::value_float:
7380  return "number literal";
7381  case token_type::begin_array:
7382  return "'['";
7383  case token_type::begin_object:
7384  return "'{'";
7385  case token_type::end_array:
7386  return "']'";
7387  case token_type::end_object:
7388  return "'}'";
7389  case token_type::name_separator:
7390  return "':'";
7391  case token_type::value_separator:
7392  return "','";
7393  case token_type::parse_error:
7394  return "<parse error>";
7395  case token_type::end_of_input:
7396  return "end of input";
7397  case token_type::literal_or_value:
7398  return "'[', '{', or a literal";
7399  // LCOV_EXCL_START
7400  default: // catch non-enum values
7401  return "unknown token";
7402  // LCOV_EXCL_STOP
7403  }
7404  }
7405 };
7411 template<typename BasicJsonType, typename InputAdapterType>
7412 class lexer : public lexer_base<BasicJsonType>
7413 {
7414  using number_integer_t = typename BasicJsonType::number_integer_t;
7415  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7416  using number_float_t = typename BasicJsonType::number_float_t;
7417  using string_t = typename BasicJsonType::string_t;
7418  using char_type = typename InputAdapterType::char_type;
7419  using char_int_type = typename std::char_traits<char_type>::int_type;
7420 
7421  public:
7423 
7424  explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
7425  : ia(std::move(adapter))
7426  , ignore_comments(ignore_comments_)
7427  , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
7428  {}
7429 
7430  // delete because of pointer members
7431  lexer(const lexer&) = delete;
7432  lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7433  lexer& operator=(lexer&) = delete;
7434  lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7435  ~lexer() = default;
7436 
7437  private:
7439  // locales
7441 
7444  static char get_decimal_point() noexcept
7445  {
7446  const auto* loc = localeconv();
7447  JSON_ASSERT(loc != nullptr);
7448  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7449  }
7450 
7452  // scan functions
7454 
7470  int get_codepoint()
7471  {
7472  // this function only makes sense after reading `\u`
7473  JSON_ASSERT(current == 'u');
7474  int codepoint = 0;
7475 
7476  const auto factors = { 12u, 8u, 4u, 0u };
7477  for (const auto factor : factors)
7478  {
7479  get();
7480 
7481  if (current >= '0' && current <= '9')
7482  {
7483  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7484  }
7485  else if (current >= 'A' && current <= 'F')
7486  {
7487  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7488  }
7489  else if (current >= 'a' && current <= 'f')
7490  {
7491  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7492  }
7493  else
7494  {
7495  return -1;
7496  }
7497  }
7498 
7499  JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7500  return codepoint;
7501  }
7502 
7518  bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7519  {
7520  JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7521  add(current);
7522 
7523  for (auto range = ranges.begin(); range != ranges.end(); ++range)
7524  {
7525  get();
7526  if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
7527  {
7528  add(current);
7529  }
7530  else
7531  {
7532  error_message = "invalid string: ill-formed UTF-8 byte";
7533  return false;
7534  }
7535  }
7536 
7537  return true;
7538  }
7539 
7555  token_type scan_string()
7556  {
7557  // reset token_buffer (ignore opening quote)
7558  reset();
7559 
7560  // we entered the function by reading an open quote
7561  JSON_ASSERT(current == '\"');
7562 
7563  while (true)
7564  {
7565  // get next character
7566  switch (get())
7567  {
7568  // end of file while parsing string
7569  case std::char_traits<char_type>::eof():
7570  {
7571  error_message = "invalid string: missing closing quote";
7572  return token_type::parse_error;
7573  }
7574 
7575  // closing quote
7576  case '\"':
7577  {
7578  return token_type::value_string;
7579  }
7580 
7581  // escapes
7582  case '\\':
7583  {
7584  switch (get())
7585  {
7586  // quotation mark
7587  case '\"':
7588  add('\"');
7589  break;
7590  // reverse solidus
7591  case '\\':
7592  add('\\');
7593  break;
7594  // solidus
7595  case '/':
7596  add('/');
7597  break;
7598  // backspace
7599  case 'b':
7600  add('\b');
7601  break;
7602  // form feed
7603  case 'f':
7604  add('\f');
7605  break;
7606  // line feed
7607  case 'n':
7608  add('\n');
7609  break;
7610  // carriage return
7611  case 'r':
7612  add('\r');
7613  break;
7614  // tab
7615  case 't':
7616  add('\t');
7617  break;
7618 
7619  // unicode escapes
7620  case 'u':
7621  {
7622  const int codepoint1 = get_codepoint();
7623  int codepoint = codepoint1; // start with codepoint1
7624 
7625  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7626  {
7627  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7628  return token_type::parse_error;
7629  }
7630 
7631  // check if code point is a high surrogate
7632  if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7633  {
7634  // expect next \uxxxx entry
7635  if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7636  {
7637  const int codepoint2 = get_codepoint();
7638 
7639  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7640  {
7641  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7642  return token_type::parse_error;
7643  }
7644 
7645  // check if codepoint2 is a low surrogate
7646  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7647  {
7648  // overwrite codepoint
7649  codepoint = static_cast<int>(
7650  // high surrogate occupies the most significant 22 bits
7651  (static_cast<unsigned int>(codepoint1) << 10u)
7652  // low surrogate occupies the least significant 15 bits
7653  + static_cast<unsigned int>(codepoint2)
7654  // there is still the 0xD800, 0xDC00 and 0x10000 noise
7655  // in the result, so we have to subtract with:
7656  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7657  - 0x35FDC00u);
7658  }
7659  else
7660  {
7661  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7662  return token_type::parse_error;
7663  }
7664  }
7665  else
7666  {
7667  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7668  return token_type::parse_error;
7669  }
7670  }
7671  else
7672  {
7673  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7674  {
7675  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7676  return token_type::parse_error;
7677  }
7678  }
7679 
7680  // result of the above calculation yields a proper codepoint
7681  JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7682 
7683  // translate codepoint into bytes
7684  if (codepoint < 0x80)
7685  {
7686  // 1-byte characters: 0xxxxxxx (ASCII)
7687  add(static_cast<char_int_type>(codepoint));
7688  }
7689  else if (codepoint <= 0x7FF)
7690  {
7691  // 2-byte characters: 110xxxxx 10xxxxxx
7692  add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7693  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7694  }
7695  else if (codepoint <= 0xFFFF)
7696  {
7697  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7698  add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7699  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7700  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7701  }
7702  else
7703  {
7704  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7705  add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7706  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7707  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7708  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7709  }
7710 
7711  break;
7712  }
7713 
7714  // other characters after escape
7715  default:
7716  error_message = "invalid string: forbidden character after backslash";
7717  return token_type::parse_error;
7718  }
7719 
7720  break;
7721  }
7722 
7723  // invalid control characters
7724  case 0x00:
7725  {
7726  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7727  return token_type::parse_error;
7728  }
7729 
7730  case 0x01:
7731  {
7732  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7733  return token_type::parse_error;
7734  }
7735 
7736  case 0x02:
7737  {
7738  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7739  return token_type::parse_error;
7740  }
7741 
7742  case 0x03:
7743  {
7744  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7745  return token_type::parse_error;
7746  }
7747 
7748  case 0x04:
7749  {
7750  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7751  return token_type::parse_error;
7752  }
7753 
7754  case 0x05:
7755  {
7756  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7757  return token_type::parse_error;
7758  }
7759 
7760  case 0x06:
7761  {
7762  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7763  return token_type::parse_error;
7764  }
7765 
7766  case 0x07:
7767  {
7768  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7769  return token_type::parse_error;
7770  }
7771 
7772  case 0x08:
7773  {
7774  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7775  return token_type::parse_error;
7776  }
7777 
7778  case 0x09:
7779  {
7780  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7781  return token_type::parse_error;
7782  }
7783 
7784  case 0x0A:
7785  {
7786  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7787  return token_type::parse_error;
7788  }
7789 
7790  case 0x0B:
7791  {
7792  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7793  return token_type::parse_error;
7794  }
7795 
7796  case 0x0C:
7797  {
7798  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7799  return token_type::parse_error;
7800  }
7801 
7802  case 0x0D:
7803  {
7804  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7805  return token_type::parse_error;
7806  }
7807 
7808  case 0x0E:
7809  {
7810  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7811  return token_type::parse_error;
7812  }
7813 
7814  case 0x0F:
7815  {
7816  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7817  return token_type::parse_error;
7818  }
7819 
7820  case 0x10:
7821  {
7822  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7823  return token_type::parse_error;
7824  }
7825 
7826  case 0x11:
7827  {
7828  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7829  return token_type::parse_error;
7830  }
7831 
7832  case 0x12:
7833  {
7834  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7835  return token_type::parse_error;
7836  }
7837 
7838  case 0x13:
7839  {
7840  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7841  return token_type::parse_error;
7842  }
7843 
7844  case 0x14:
7845  {
7846  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7847  return token_type::parse_error;
7848  }
7849 
7850  case 0x15:
7851  {
7852  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7853  return token_type::parse_error;
7854  }
7855 
7856  case 0x16:
7857  {
7858  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7859  return token_type::parse_error;
7860  }
7861 
7862  case 0x17:
7863  {
7864  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7865  return token_type::parse_error;
7866  }
7867 
7868  case 0x18:
7869  {
7870  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7871  return token_type::parse_error;
7872  }
7873 
7874  case 0x19:
7875  {
7876  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7877  return token_type::parse_error;
7878  }
7879 
7880  case 0x1A:
7881  {
7882  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7883  return token_type::parse_error;
7884  }
7885 
7886  case 0x1B:
7887  {
7888  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7889  return token_type::parse_error;
7890  }
7891 
7892  case 0x1C:
7893  {
7894  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7895  return token_type::parse_error;
7896  }
7897 
7898  case 0x1D:
7899  {
7900  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7901  return token_type::parse_error;
7902  }
7903 
7904  case 0x1E:
7905  {
7906  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7907  return token_type::parse_error;
7908  }
7909 
7910  case 0x1F:
7911  {
7912  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7913  return token_type::parse_error;
7914  }
7915 
7916  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7917  case 0x20:
7918  case 0x21:
7919  case 0x23:
7920  case 0x24:
7921  case 0x25:
7922  case 0x26:
7923  case 0x27:
7924  case 0x28:
7925  case 0x29:
7926  case 0x2A:
7927  case 0x2B:
7928  case 0x2C:
7929  case 0x2D:
7930  case 0x2E:
7931  case 0x2F:
7932  case 0x30:
7933  case 0x31:
7934  case 0x32:
7935  case 0x33:
7936  case 0x34:
7937  case 0x35:
7938  case 0x36:
7939  case 0x37:
7940  case 0x38:
7941  case 0x39:
7942  case 0x3A:
7943  case 0x3B:
7944  case 0x3C:
7945  case 0x3D:
7946  case 0x3E:
7947  case 0x3F:
7948  case 0x40:
7949  case 0x41:
7950  case 0x42:
7951  case 0x43:
7952  case 0x44:
7953  case 0x45:
7954  case 0x46:
7955  case 0x47:
7956  case 0x48:
7957  case 0x49:
7958  case 0x4A:
7959  case 0x4B:
7960  case 0x4C:
7961  case 0x4D:
7962  case 0x4E:
7963  case 0x4F:
7964  case 0x50:
7965  case 0x51:
7966  case 0x52:
7967  case 0x53:
7968  case 0x54:
7969  case 0x55:
7970  case 0x56:
7971  case 0x57:
7972  case 0x58:
7973  case 0x59:
7974  case 0x5A:
7975  case 0x5B:
7976  case 0x5D:
7977  case 0x5E:
7978  case 0x5F:
7979  case 0x60:
7980  case 0x61:
7981  case 0x62:
7982  case 0x63:
7983  case 0x64:
7984  case 0x65:
7985  case 0x66:
7986  case 0x67:
7987  case 0x68:
7988  case 0x69:
7989  case 0x6A:
7990  case 0x6B:
7991  case 0x6C:
7992  case 0x6D:
7993  case 0x6E:
7994  case 0x6F:
7995  case 0x70:
7996  case 0x71:
7997  case 0x72:
7998  case 0x73:
7999  case 0x74:
8000  case 0x75:
8001  case 0x76:
8002  case 0x77:
8003  case 0x78:
8004  case 0x79:
8005  case 0x7A:
8006  case 0x7B:
8007  case 0x7C:
8008  case 0x7D:
8009  case 0x7E:
8010  case 0x7F:
8011  {
8012  add(current);
8013  break;
8014  }
8015 
8016  // U+0080..U+07FF: bytes C2..DF 80..BF
8017  case 0xC2:
8018  case 0xC3:
8019  case 0xC4:
8020  case 0xC5:
8021  case 0xC6:
8022  case 0xC7:
8023  case 0xC8:
8024  case 0xC9:
8025  case 0xCA:
8026  case 0xCB:
8027  case 0xCC:
8028  case 0xCD:
8029  case 0xCE:
8030  case 0xCF:
8031  case 0xD0:
8032  case 0xD1:
8033  case 0xD2:
8034  case 0xD3:
8035  case 0xD4:
8036  case 0xD5:
8037  case 0xD6:
8038  case 0xD7:
8039  case 0xD8:
8040  case 0xD9:
8041  case 0xDA:
8042  case 0xDB:
8043  case 0xDC:
8044  case 0xDD:
8045  case 0xDE:
8046  case 0xDF:
8047  {
8048  if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
8049  {
8050  return token_type::parse_error;
8051  }
8052  break;
8053  }
8054 
8055  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
8056  case 0xE0:
8057  {
8058  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
8059  {
8060  return token_type::parse_error;
8061  }
8062  break;
8063  }
8064 
8065  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
8066  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
8067  case 0xE1:
8068  case 0xE2:
8069  case 0xE3:
8070  case 0xE4:
8071  case 0xE5:
8072  case 0xE6:
8073  case 0xE7:
8074  case 0xE8:
8075  case 0xE9:
8076  case 0xEA:
8077  case 0xEB:
8078  case 0xEC:
8079  case 0xEE:
8080  case 0xEF:
8081  {
8082  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
8083  {
8084  return token_type::parse_error;
8085  }
8086  break;
8087  }
8088 
8089  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
8090  case 0xED:
8091  {
8092  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
8093  {
8094  return token_type::parse_error;
8095  }
8096  break;
8097  }
8098 
8099  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
8100  case 0xF0:
8101  {
8102  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8103  {
8104  return token_type::parse_error;
8105  }
8106  break;
8107  }
8108 
8109  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
8110  case 0xF1:
8111  case 0xF2:
8112  case 0xF3:
8113  {
8114  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8115  {
8116  return token_type::parse_error;
8117  }
8118  break;
8119  }
8120 
8121  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
8122  case 0xF4:
8123  {
8124  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
8125  {
8126  return token_type::parse_error;
8127  }
8128  break;
8129  }
8130 
8131  // remaining bytes (80..C1 and F5..FF) are ill-formed
8132  default:
8133  {
8134  error_message = "invalid string: ill-formed UTF-8 byte";
8135  return token_type::parse_error;
8136  }
8137  }
8138  }
8139  }
8140 
8145  bool scan_comment()
8146  {
8147  switch (get())
8148  {
8149  // single-line comments skip input until a newline or EOF is read
8150  case '/':
8151  {
8152  while (true)
8153  {
8154  switch (get())
8155  {
8156  case '\n':
8157  case '\r':
8158  case std::char_traits<char_type>::eof():
8159  case '\0':
8160  return true;
8161 
8162  default:
8163  break;
8164  }
8165  }
8166  }
8167 
8168  // multi-line comments skip input until */ is read
8169  case '*':
8170  {
8171  while (true)
8172  {
8173  switch (get())
8174  {
8175  case std::char_traits<char_type>::eof():
8176  case '\0':
8177  {
8178  error_message = "invalid comment; missing closing '*/'";
8179  return false;
8180  }
8181 
8182  case '*':
8183  {
8184  switch (get())
8185  {
8186  case '/':
8187  return true;
8188 
8189  default:
8190  {
8191  unget();
8192  continue;
8193  }
8194  }
8195  }
8196 
8197  default:
8198  continue;
8199  }
8200  }
8201  }
8202 
8203  // unexpected character after reading '/'
8204  default:
8205  {
8206  error_message = "invalid comment; expecting '/' or '*' after '/'";
8207  return false;
8208  }
8209  }
8210  }
8211 
8213  static void strtof(float& f, const char* str, char** endptr) noexcept
8214  {
8215  f = std::strtof(str, endptr);
8216  }
8217 
8219  static void strtof(double& f, const char* str, char** endptr) noexcept
8220  {
8221  f = std::strtod(str, endptr);
8222  }
8223 
8225  static void strtof(long double& f, const char* str, char** endptr) noexcept
8226  {
8227  f = std::strtold(str, endptr);
8228  }
8229 
8270  token_type scan_number() // lgtm [cpp/use-of-goto]
8271  {
8272  // reset token_buffer to store the number's bytes
8273  reset();
8274 
8275  // the type of the parsed number; initially set to unsigned; will be
8276  // changed if minus sign, decimal point or exponent is read
8277  token_type number_type = token_type::value_unsigned;
8278 
8279  // state (init): we just found out we need to scan a number
8280  switch (current)
8281  {
8282  case '-':
8283  {
8284  add(current);
8285  goto scan_number_minus;
8286  }
8287 
8288  case '0':
8289  {
8290  add(current);
8291  goto scan_number_zero;
8292  }
8293 
8294  case '1':
8295  case '2':
8296  case '3':
8297  case '4':
8298  case '5':
8299  case '6':
8300  case '7':
8301  case '8':
8302  case '9':
8303  {
8304  add(current);
8305  goto scan_number_any1;
8306  }
8307 
8308  // all other characters are rejected outside scan_number()
8309  default: // LCOV_EXCL_LINE
8310  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8311  }
8312 
8313 scan_number_minus:
8314  // state: we just parsed a leading minus sign
8315  number_type = token_type::value_integer;
8316  switch (get())
8317  {
8318  case '0':
8319  {
8320  add(current);
8321  goto scan_number_zero;
8322  }
8323 
8324  case '1':
8325  case '2':
8326  case '3':
8327  case '4':
8328  case '5':
8329  case '6':
8330  case '7':
8331  case '8':
8332  case '9':
8333  {
8334  add(current);
8335  goto scan_number_any1;
8336  }
8337 
8338  default:
8339  {
8340  error_message = "invalid number; expected digit after '-'";
8341  return token_type::parse_error;
8342  }
8343  }
8344 
8345 scan_number_zero:
8346  // state: we just parse a zero (maybe with a leading minus sign)
8347  switch (get())
8348  {
8349  case '.':
8350  {
8351  add(decimal_point_char);
8352  goto scan_number_decimal1;
8353  }
8354 
8355  case 'e':
8356  case 'E':
8357  {
8358  add(current);
8359  goto scan_number_exponent;
8360  }
8361 
8362  default:
8363  goto scan_number_done;
8364  }
8365 
8366 scan_number_any1:
8367  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8368  switch (get())
8369  {
8370  case '0':
8371  case '1':
8372  case '2':
8373  case '3':
8374  case '4':
8375  case '5':
8376  case '6':
8377  case '7':
8378  case '8':
8379  case '9':
8380  {
8381  add(current);
8382  goto scan_number_any1;
8383  }
8384 
8385  case '.':
8386  {
8387  add(decimal_point_char);
8388  goto scan_number_decimal1;
8389  }
8390 
8391  case 'e':
8392  case 'E':
8393  {
8394  add(current);
8395  goto scan_number_exponent;
8396  }
8397 
8398  default:
8399  goto scan_number_done;
8400  }
8401 
8402 scan_number_decimal1:
8403  // state: we just parsed a decimal point
8404  number_type = token_type::value_float;
8405  switch (get())
8406  {
8407  case '0':
8408  case '1':
8409  case '2':
8410  case '3':
8411  case '4':
8412  case '5':
8413  case '6':
8414  case '7':
8415  case '8':
8416  case '9':
8417  {
8418  add(current);
8419  goto scan_number_decimal2;
8420  }
8421 
8422  default:
8423  {
8424  error_message = "invalid number; expected digit after '.'";
8425  return token_type::parse_error;
8426  }
8427  }
8428 
8429 scan_number_decimal2:
8430  // we just parsed at least one number after a decimal point
8431  switch (get())
8432  {
8433  case '0':
8434  case '1':
8435  case '2':
8436  case '3':
8437  case '4':
8438  case '5':
8439  case '6':
8440  case '7':
8441  case '8':
8442  case '9':
8443  {
8444  add(current);
8445  goto scan_number_decimal2;
8446  }
8447 
8448  case 'e':
8449  case 'E':
8450  {
8451  add(current);
8452  goto scan_number_exponent;
8453  }
8454 
8455  default:
8456  goto scan_number_done;
8457  }
8458 
8459 scan_number_exponent:
8460  // we just parsed an exponent
8461  number_type = token_type::value_float;
8462  switch (get())
8463  {
8464  case '+':
8465  case '-':
8466  {
8467  add(current);
8468  goto scan_number_sign;
8469  }
8470 
8471  case '0':
8472  case '1':
8473  case '2':
8474  case '3':
8475  case '4':
8476  case '5':
8477  case '6':
8478  case '7':
8479  case '8':
8480  case '9':
8481  {
8482  add(current);
8483  goto scan_number_any2;
8484  }
8485 
8486  default:
8487  {
8488  error_message =
8489  "invalid number; expected '+', '-', or digit after exponent";
8490  return token_type::parse_error;
8491  }
8492  }
8493 
8494 scan_number_sign:
8495  // we just parsed an exponent sign
8496  switch (get())
8497  {
8498  case '0':
8499  case '1':
8500  case '2':
8501  case '3':
8502  case '4':
8503  case '5':
8504  case '6':
8505  case '7':
8506  case '8':
8507  case '9':
8508  {
8509  add(current);
8510  goto scan_number_any2;
8511  }
8512 
8513  default:
8514  {
8515  error_message = "invalid number; expected digit after exponent sign";
8516  return token_type::parse_error;
8517  }
8518  }
8519 
8520 scan_number_any2:
8521  // we just parsed a number after the exponent or exponent sign
8522  switch (get())
8523  {
8524  case '0':
8525  case '1':
8526  case '2':
8527  case '3':
8528  case '4':
8529  case '5':
8530  case '6':
8531  case '7':
8532  case '8':
8533  case '9':
8534  {
8535  add(current);
8536  goto scan_number_any2;
8537  }
8538 
8539  default:
8540  goto scan_number_done;
8541  }
8542 
8543 scan_number_done:
8544  // unget the character after the number (we only read it to know that
8545  // we are done scanning a number)
8546  unget();
8547 
8548  char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8549  errno = 0;
8550 
8551  // try to parse integers first and fall back to floats
8552  if (number_type == token_type::value_unsigned)
8553  {
8554  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8555 
8556  // we checked the number format before
8557  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8558 
8559  if (errno == 0)
8560  {
8561  value_unsigned = static_cast<number_unsigned_t>(x);
8562  if (value_unsigned == x)
8563  {
8564  return token_type::value_unsigned;
8565  }
8566  }
8567  }
8568  else if (number_type == token_type::value_integer)
8569  {
8570  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8571 
8572  // we checked the number format before
8573  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8574 
8575  if (errno == 0)
8576  {
8577  value_integer = static_cast<number_integer_t>(x);
8578  if (value_integer == x)
8579  {
8580  return token_type::value_integer;
8581  }
8582  }
8583  }
8584 
8585  // this code is reached if we parse a floating-point number or if an
8586  // integer conversion above failed
8587  strtof(value_float, token_buffer.data(), &endptr);
8588 
8589  // we checked the number format before
8590  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8591 
8592  return token_type::value_float;
8593  }
8594 
8601  token_type scan_literal(const char_type* literal_text, const std::size_t length,
8602  token_type return_type)
8603  {
8604  JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
8605  for (std::size_t i = 1; i < length; ++i)
8606  {
8607  if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
8608  {
8609  error_message = "invalid literal";
8610  return token_type::parse_error;
8611  }
8612  }
8613  return return_type;
8614  }
8615 
8617  // input management
8619 
8621  void reset() noexcept
8622  {
8623  token_buffer.clear();
8624  token_string.clear();
8625  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8626  }
8627 
8628  /*
8629  @brief get next character from the input
8630 
8631  This function provides the interface to the used input adapter. It does
8632  not throw in case the input reached EOF, but returns a
8633  `std::char_traits<char>::eof()` in that case. Stores the scanned characters
8634  for use in error messages.
8635 
8636  @return character read from the input
8637  */
8638  char_int_type get()
8639  {
8640  ++position.chars_read_total;
8641  ++position.chars_read_current_line;
8642 
8643  if (next_unget)
8644  {
8645  // just reset the next_unget variable and work with current
8646  next_unget = false;
8647  }
8648  else
8649  {
8650  current = ia.get_character();
8651  }
8652 
8653  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8654  {
8655  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8656  }
8657 
8658  if (current == '\n')
8659  {
8660  ++position.lines_read;
8661  position.chars_read_current_line = 0;
8662  }
8663 
8664  return current;
8665  }
8666 
8675  void unget()
8676  {
8677  next_unget = true;
8678 
8679  --position.chars_read_total;
8680 
8681  // in case we "unget" a newline, we have to also decrement the lines_read
8682  if (position.chars_read_current_line == 0)
8683  {
8684  if (position.lines_read > 0)
8685  {
8686  --position.lines_read;
8687  }
8688  }
8689  else
8690  {
8691  --position.chars_read_current_line;
8692  }
8693 
8694  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8695  {
8696  JSON_ASSERT(!token_string.empty());
8697  token_string.pop_back();
8698  }
8699  }
8700 
8702  void add(char_int_type c)
8703  {
8704  token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8705  }
8706 
8707  public:
8709  // value getters
8711 
8713  constexpr number_integer_t get_number_integer() const noexcept
8714  {
8715  return value_integer;
8716  }
8717 
8719  constexpr number_unsigned_t get_number_unsigned() const noexcept
8720  {
8721  return value_unsigned;
8722  }
8723 
8725  constexpr number_float_t get_number_float() const noexcept
8726  {
8727  return value_float;
8728  }
8729 
8731  string_t& get_string()
8732  {
8733  return token_buffer;
8734  }
8735 
8737  // diagnostics
8739 
8741  constexpr position_t get_position() const noexcept
8742  {
8743  return position;
8744  }
8745 
8749  std::string get_token_string() const
8750  {
8751  // escape control characters
8752  std::string result;
8753  for (const auto c : token_string)
8754  {
8755  if (static_cast<unsigned char>(c) <= '\x1F')
8756  {
8757  // escape control characters
8758  std::array<char, 9> cs{{}};
8759  static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8760  result += cs.data();
8761  }
8762  else
8763  {
8764  // add character as is
8765  result.push_back(static_cast<std::string::value_type>(c));
8766  }
8767  }
8768 
8769  return result;
8770  }
8771 
8774  constexpr const char* get_error_message() const noexcept
8775  {
8776  return error_message;
8777  }
8778 
8780  // actual scanner
8782 
8787  bool skip_bom()
8788  {
8789  if (get() == 0xEF)
8790  {
8791  // check if we completely parse the BOM
8792  return get() == 0xBB && get() == 0xBF;
8793  }
8794 
8795  // the first character is not the beginning of the BOM; unget it to
8796  // process is later
8797  unget();
8798  return true;
8799  }
8800 
8802  {
8803  do
8804  {
8805  get();
8806  }
8807  while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8808  }
8809 
8811  {
8812  // initially, skip the BOM
8813  if (position.chars_read_total == 0 && !skip_bom())
8814  {
8815  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8816  return token_type::parse_error;
8817  }
8818 
8819  // read next character and ignore whitespace
8820  skip_whitespace();
8821 
8822  // ignore comments
8823  while (ignore_comments && current == '/')
8824  {
8825  if (!scan_comment())
8826  {
8827  return token_type::parse_error;
8828  }
8829 
8830  // skip following whitespace
8831  skip_whitespace();
8832  }
8833 
8834  switch (current)
8835  {
8836  // structural characters
8837  case '[':
8838  return token_type::begin_array;
8839  case ']':
8840  return token_type::end_array;
8841  case '{':
8842  return token_type::begin_object;
8843  case '}':
8844  return token_type::end_object;
8845  case ':':
8846  return token_type::name_separator;
8847  case ',':
8848  return token_type::value_separator;
8849 
8850  // literals
8851  case 't':
8852  {
8853  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')}};
8854  return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8855  }
8856  case 'f':
8857  {
8858  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')}};
8859  return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8860  }
8861  case 'n':
8862  {
8863  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')}};
8864  return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8865  }
8866 
8867  // string
8868  case '\"':
8869  return scan_string();
8870 
8871  // number
8872  case '-':
8873  case '0':
8874  case '1':
8875  case '2':
8876  case '3':
8877  case '4':
8878  case '5':
8879  case '6':
8880  case '7':
8881  case '8':
8882  case '9':
8883  return scan_number();
8884 
8885  // end of input (the null byte is needed when parsing from
8886  // string literals)
8887  case '\0':
8888  case std::char_traits<char_type>::eof():
8889  return token_type::end_of_input;
8890 
8891  // error
8892  default:
8893  error_message = "invalid literal";
8894  return token_type::parse_error;
8895  }
8896  }
8897 
8898  private:
8900  InputAdapterType ia;
8901 
8903  const bool ignore_comments = false;
8904 
8906  char_int_type current = std::char_traits<char_type>::eof();
8907 
8909  bool next_unget = false;
8910 
8912  position_t position {};
8913 
8915  std::vector<char_type> token_string {};
8916 
8918  string_t token_buffer {};
8919 
8921  const char* error_message = "";
8922 
8923  // number values
8924  number_integer_t value_integer = 0;
8925  number_unsigned_t value_unsigned = 0;
8926  number_float_t value_float = 0;
8927 
8929  const char_int_type decimal_point_char = '.';
8930 };
8931 
8932 } // namespace detail
8934 
8935 // #include <nlohmann/detail/macro_scope.hpp>
8936 
8937 // #include <nlohmann/detail/meta/is_sax.hpp>
8938 // __ _____ _____ _____
8939 // __| | __| | | | JSON for Modern C++
8940 // | | |__ | | | | | | version 3.11.2
8941 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
8942 //
8943 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
8944 // SPDX-License-Identifier: MIT
8945 
8946 
8947 
8948 #include <cstdint> // size_t
8949 #include <utility> // declval
8950 #include <string> // string
8951 
8952 // #include <nlohmann/detail/abi_macros.hpp>
8953 
8954 // #include <nlohmann/detail/meta/detected.hpp>
8955 
8956 // #include <nlohmann/detail/meta/type_traits.hpp>
8957 
8958 
8960 namespace detail
8961 {
8962 
8963 template<typename T>
8964 using null_function_t = decltype(std::declval<T&>().null());
8965 
8966 template<typename T>
8967 using boolean_function_t =
8968  decltype(std::declval<T&>().boolean(std::declval<bool>()));
8969 
8970 template<typename T, typename Integer>
8972  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8973 
8974 template<typename T, typename Unsigned>
8976  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8977 
8978 template<typename T, typename Float, typename String>
8979 using number_float_function_t = decltype(std::declval<T&>().number_float(
8980  std::declval<Float>(), std::declval<const String&>()));
8981 
8982 template<typename T, typename String>
8983 using string_function_t =
8984  decltype(std::declval<T&>().string(std::declval<String&>()));
8985 
8986 template<typename T, typename Binary>
8987 using binary_function_t =
8988  decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8989 
8990 template<typename T>
8992  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8993 
8994 template<typename T, typename String>
8995 using key_function_t =
8996  decltype(std::declval<T&>().key(std::declval<String&>()));
8997 
8998 template<typename T>
8999 using end_object_function_t = decltype(std::declval<T&>().end_object());
9000 
9001 template<typename T>
9002 using start_array_function_t =
9003  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
9004 
9005 template<typename T>
9006 using end_array_function_t = decltype(std::declval<T&>().end_array());
9007 
9008 template<typename T, typename Exception>
9009 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
9010  std::declval<std::size_t>(), std::declval<const std::string&>(),
9011  std::declval<const Exception&>()));
9012 
9013 template<typename SAX, typename BasicJsonType>
9014 struct is_sax
9015 {
9016  private:
9018  "BasicJsonType must be of type basic_json<...>");
9019 
9020  using number_integer_t = typename BasicJsonType::number_integer_t;
9021  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9022  using number_float_t = typename BasicJsonType::number_float_t;
9023  using string_t = typename BasicJsonType::string_t;
9024  using binary_t = typename BasicJsonType::binary_t;
9025  using exception_t = typename BasicJsonType::exception;
9026 
9027  public:
9028  static constexpr bool value =
9042 };
9043 
9044 template<typename SAX, typename BasicJsonType>
9046 {
9047  private:
9049  "BasicJsonType must be of type basic_json<...>");
9050 
9051  using number_integer_t = typename BasicJsonType::number_integer_t;
9052  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9053  using number_float_t = typename BasicJsonType::number_float_t;
9054  using string_t = typename BasicJsonType::string_t;
9055  using binary_t = typename BasicJsonType::binary_t;
9056  using exception_t = typename BasicJsonType::exception;
9057 
9058  public:
9060  "Missing/invalid function: bool null()");
9062  "Missing/invalid function: bool boolean(bool)");
9064  "Missing/invalid function: bool boolean(bool)");
9065  static_assert(
9067  number_integer_t>::value,
9068  "Missing/invalid function: bool number_integer(number_integer_t)");
9069  static_assert(
9071  number_unsigned_t>::value,
9072  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
9073  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
9074  number_float_t, string_t>::value,
9075  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
9076  static_assert(
9078  "Missing/invalid function: bool string(string_t&)");
9079  static_assert(
9081  "Missing/invalid function: bool binary(binary_t&)");
9083  "Missing/invalid function: bool start_object(std::size_t)");
9085  "Missing/invalid function: bool key(string_t&)");
9087  "Missing/invalid function: bool end_object()");
9089  "Missing/invalid function: bool start_array(std::size_t)");
9091  "Missing/invalid function: bool end_array()");
9092  static_assert(
9094  "Missing/invalid function: bool parse_error(std::size_t, const "
9095  "std::string&, const exception&)");
9096 };
9097 
9098 } // namespace detail
9100 
9101 // #include <nlohmann/detail/meta/type_traits.hpp>
9102 
9103 // #include <nlohmann/detail/string_concat.hpp>
9104 
9105 // #include <nlohmann/detail/value_t.hpp>
9106 
9107 
9109 namespace detail
9110 {
9111 
9114 {
9115  error,
9116  ignore,
9117  store
9118 };
9119 
9127 static inline bool little_endianness(int num = 1) noexcept
9128 {
9129  return *reinterpret_cast<char*>(&num) == 1;
9130 }
9131 
9132 
9134 // binary reader //
9136 
9140 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
9142 {
9143  using number_integer_t = typename BasicJsonType::number_integer_t;
9144  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9145  using number_float_t = typename BasicJsonType::number_float_t;
9146  using string_t = typename BasicJsonType::string_t;
9147  using binary_t = typename BasicJsonType::binary_t;
9148  using json_sax_t = SAX;
9149  using char_type = typename InputAdapterType::char_type;
9150  using char_int_type = typename std::char_traits<char_type>::int_type;
9151 
9152  public:
9158  explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
9159  {
9161  }
9162 
9163  // make class move-only
9164  binary_reader(const binary_reader&) = delete;
9165  binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9166  binary_reader& operator=(const binary_reader&) = delete;
9167  binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9168  ~binary_reader() = default;
9169 
9180  json_sax_t* sax_,
9181  const bool strict = true,
9182  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
9183  {
9184  sax = sax_;
9185  bool result = false;
9186 
9187  switch (format)
9188  {
9189  case input_format_t::bson:
9190  result = parse_bson_internal();
9191  break;
9192 
9193  case input_format_t::cbor:
9194  result = parse_cbor_internal(true, tag_handler);
9195  break;
9196 
9198  result = parse_msgpack_internal();
9199  break;
9200 
9203  result = parse_ubjson_internal();
9204  break;
9205 
9206  case input_format_t::json: // LCOV_EXCL_LINE
9207  default: // LCOV_EXCL_LINE
9208  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9209  }
9210 
9211  // strict mode: next byte must be EOF
9212  if (result && strict)
9213  {
9214  if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
9215  {
9216  get_ignore_noop();
9217  }
9218  else
9219  {
9220  get();
9221  }
9222 
9223  if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
9224  {
9225  return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
9226  exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
9227  }
9228  }
9229 
9230  return result;
9231  }
9232 
9233  private:
9235  // BSON //
9237 
9242  bool parse_bson_internal()
9243  {
9244  std::int32_t document_size{};
9245  get_number<std::int32_t, true>(input_format_t::bson, document_size);
9246 
9247  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
9248  {
9249  return false;
9250  }
9251 
9252  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
9253  {
9254  return false;
9255  }
9256 
9257  return sax->end_object();
9258  }
9259 
9267  bool get_bson_cstr(string_t& result)
9268  {
9269  auto out = std::back_inserter(result);
9270  while (true)
9271  {
9272  get();
9273  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
9274  {
9275  return false;
9276  }
9277  if (current == 0x00)
9278  {
9279  return true;
9280  }
9281  *out++ = static_cast<typename string_t::value_type>(current);
9282  }
9283  }
9284 
9296  template<typename NumberType>
9297  bool get_bson_string(const NumberType len, string_t& result)
9298  {
9299  if (JSON_HEDLEY_UNLIKELY(len < 1))
9300  {
9301  auto last_token = get_token_string();
9302  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9303  exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
9304  }
9305 
9306  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
9307  }
9308 
9318  template<typename NumberType>
9319  bool get_bson_binary(const NumberType len, binary_t& result)
9320  {
9321  if (JSON_HEDLEY_UNLIKELY(len < 0))
9322  {
9323  auto last_token = get_token_string();
9324  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9325  exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
9326  }
9327 
9328  // All BSON binary values have a subtype
9329  std::uint8_t subtype{};
9330  get_number<std::uint8_t>(input_format_t::bson, subtype);
9331  result.set_subtype(subtype);
9332 
9333  return get_binary(input_format_t::bson, len, result);
9334  }
9335 
9346  bool parse_bson_element_internal(const char_int_type element_type,
9347  const std::size_t element_type_parse_position)
9348  {
9349  switch (element_type)
9350  {
9351  case 0x01: // double
9352  {
9353  double number{};
9354  return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9355  }
9356 
9357  case 0x02: // string
9358  {
9359  std::int32_t len{};
9360  string_t value;
9361  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
9362  }
9363 
9364  case 0x03: // object
9365  {
9366  return parse_bson_internal();
9367  }
9368 
9369  case 0x04: // array
9370  {
9371  return parse_bson_array();
9372  }
9373 
9374  case 0x05: // binary
9375  {
9376  std::int32_t len{};
9377  binary_t value;
9378  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
9379  }
9380 
9381  case 0x08: // boolean
9382  {
9383  return sax->boolean(get() != 0);
9384  }
9385 
9386  case 0x0A: // null
9387  {
9388  return sax->null();
9389  }
9390 
9391  case 0x10: // int32
9392  {
9393  std::int32_t value{};
9394  return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9395  }
9396 
9397  case 0x12: // int64
9398  {
9399  std::int64_t value{};
9400  return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9401  }
9402 
9403  default: // anything else not supported (yet)
9404  {
9405  std::array<char, 3> cr{{}};
9406  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
9407  std::string cr_str{cr.data()};
9408  return sax->parse_error(element_type_parse_position, cr_str,
9409  parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
9410  }
9411  }
9412  }
9413 
9426  bool parse_bson_element_list(const bool is_array)
9427  {
9428  string_t key;
9429 
9430  while (auto element_type = get())
9431  {
9432  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
9433  {
9434  return false;
9435  }
9436 
9437  const std::size_t element_type_parse_position = chars_read;
9438  if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
9439  {
9440  return false;
9441  }
9442 
9443  if (!is_array && !sax->key(key))
9444  {
9445  return false;
9446  }
9447 
9448  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
9449  {
9450  return false;
9451  }
9452 
9453  // get_bson_cstr only appends
9454  key.clear();
9455  }
9456 
9457  return true;
9458  }
9459 
9464  bool parse_bson_array()
9465  {
9466  std::int32_t document_size{};
9467  get_number<std::int32_t, true>(input_format_t::bson, document_size);
9468 
9469  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
9470  {
9471  return false;
9472  }
9473 
9474  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
9475  {
9476  return false;
9477  }
9478 
9479  return sax->end_array();
9480  }
9481 
9483  // CBOR //
9485 
9494  bool parse_cbor_internal(const bool get_char,
9495  const cbor_tag_handler_t tag_handler)
9496  {
9497  switch (get_char ? get() : current)
9498  {
9499  // EOF
9500  case std::char_traits<char_type>::eof():
9501  return unexpect_eof(input_format_t::cbor, "value");
9502 
9503  // Integer 0x00..0x17 (0..23)
9504  case 0x00:
9505  case 0x01:
9506  case 0x02:
9507  case 0x03:
9508  case 0x04:
9509  case 0x05:
9510  case 0x06:
9511  case 0x07:
9512  case 0x08:
9513  case 0x09:
9514  case 0x0A:
9515  case 0x0B:
9516  case 0x0C:
9517  case 0x0D:
9518  case 0x0E:
9519  case 0x0F:
9520  case 0x10:
9521  case 0x11:
9522  case 0x12:
9523  case 0x13:
9524  case 0x14:
9525  case 0x15:
9526  case 0x16:
9527  case 0x17:
9528  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9529 
9530  case 0x18: // Unsigned integer (one-byte uint8_t follows)
9531  {
9532  std::uint8_t number{};
9533  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9534  }
9535 
9536  case 0x19: // Unsigned integer (two-byte uint16_t follows)
9537  {
9538  std::uint16_t number{};
9539  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9540  }
9541 
9542  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
9543  {
9544  std::uint32_t number{};
9545  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9546  }
9547 
9548  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
9549  {
9550  std::uint64_t number{};
9551  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9552  }
9553 
9554  // Negative integer -1-0x00..-1-0x17 (-1..-24)
9555  case 0x20:
9556  case 0x21:
9557  case 0x22:
9558  case 0x23:
9559  case 0x24:
9560  case 0x25:
9561  case 0x26:
9562  case 0x27:
9563  case 0x28:
9564  case 0x29:
9565  case 0x2A:
9566  case 0x2B:
9567  case 0x2C:
9568  case 0x2D:
9569  case 0x2E:
9570  case 0x2F:
9571  case 0x30:
9572  case 0x31:
9573  case 0x32:
9574  case 0x33:
9575  case 0x34:
9576  case 0x35:
9577  case 0x36:
9578  case 0x37:
9579  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
9580 
9581  case 0x38: // Negative integer (one-byte uint8_t follows)
9582  {
9583  std::uint8_t number{};
9584  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9585  }
9586 
9587  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
9588  {
9589  std::uint16_t number{};
9590  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9591  }
9592 
9593  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
9594  {
9595  std::uint32_t number{};
9596  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9597  }
9598 
9599  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
9600  {
9601  std::uint64_t number{};
9602  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
9603  - static_cast<number_integer_t>(number));
9604  }
9605 
9606  // Binary data (0x00..0x17 bytes follow)
9607  case 0x40:
9608  case 0x41:
9609  case 0x42:
9610  case 0x43:
9611  case 0x44:
9612  case 0x45:
9613  case 0x46:
9614  case 0x47:
9615  case 0x48:
9616  case 0x49:
9617  case 0x4A:
9618  case 0x4B:
9619  case 0x4C:
9620  case 0x4D:
9621  case 0x4E:
9622  case 0x4F:
9623  case 0x50:
9624  case 0x51:
9625  case 0x52:
9626  case 0x53:
9627  case 0x54:
9628  case 0x55:
9629  case 0x56:
9630  case 0x57:
9631  case 0x58: // Binary data (one-byte uint8_t for n follows)
9632  case 0x59: // Binary data (two-byte uint16_t for n follow)
9633  case 0x5A: // Binary data (four-byte uint32_t for n follow)
9634  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9635  case 0x5F: // Binary data (indefinite length)
9636  {
9637  binary_t b;
9638  return get_cbor_binary(b) && sax->binary(b);
9639  }
9640 
9641  // UTF-8 string (0x00..0x17 bytes follow)
9642  case 0x60:
9643  case 0x61:
9644  case 0x62:
9645  case 0x63:
9646  case 0x64:
9647  case 0x65:
9648  case 0x66:
9649  case 0x67:
9650  case 0x68:
9651  case 0x69:
9652  case 0x6A:
9653  case 0x6B:
9654  case 0x6C:
9655  case 0x6D:
9656  case 0x6E:
9657  case 0x6F:
9658  case 0x70:
9659  case 0x71:
9660  case 0x72:
9661  case 0x73:
9662  case 0x74:
9663  case 0x75:
9664  case 0x76:
9665  case 0x77:
9666  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9667  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9668  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9669  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9670  case 0x7F: // UTF-8 string (indefinite length)
9671  {
9672  string_t s;
9673  return get_cbor_string(s) && sax->string(s);
9674  }
9675 
9676  // array (0x00..0x17 data items follow)
9677  case 0x80:
9678  case 0x81:
9679  case 0x82:
9680  case 0x83:
9681  case 0x84:
9682  case 0x85:
9683  case 0x86:
9684  case 0x87:
9685  case 0x88:
9686  case 0x89:
9687  case 0x8A:
9688  case 0x8B:
9689  case 0x8C:
9690  case 0x8D:
9691  case 0x8E:
9692  case 0x8F:
9693  case 0x90:
9694  case 0x91:
9695  case 0x92:
9696  case 0x93:
9697  case 0x94:
9698  case 0x95:
9699  case 0x96:
9700  case 0x97:
9701  return get_cbor_array(
9702  conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9703 
9704  case 0x98: // array (one-byte uint8_t for n follows)
9705  {
9706  std::uint8_t len{};
9707  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9708  }
9709 
9710  case 0x99: // array (two-byte uint16_t for n follow)
9711  {
9712  std::uint16_t len{};
9713  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9714  }
9715 
9716  case 0x9A: // array (four-byte uint32_t for n follow)
9717  {
9718  std::uint32_t len{};
9719  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9720  }
9721 
9722  case 0x9B: // array (eight-byte uint64_t for n follow)
9723  {
9724  std::uint64_t len{};
9725  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9726  }
9727 
9728  case 0x9F: // array (indefinite length)
9729  return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9730 
9731  // map (0x00..0x17 pairs of data items follow)
9732  case 0xA0:
9733  case 0xA1:
9734  case 0xA2:
9735  case 0xA3:
9736  case 0xA4:
9737  case 0xA5:
9738  case 0xA6:
9739  case 0xA7:
9740  case 0xA8:
9741  case 0xA9:
9742  case 0xAA:
9743  case 0xAB:
9744  case 0xAC:
9745  case 0xAD:
9746  case 0xAE:
9747  case 0xAF:
9748  case 0xB0:
9749  case 0xB1:
9750  case 0xB2:
9751  case 0xB3:
9752  case 0xB4:
9753  case 0xB5:
9754  case 0xB6:
9755  case 0xB7:
9756  return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9757 
9758  case 0xB8: // map (one-byte uint8_t for n follows)
9759  {
9760  std::uint8_t len{};
9761  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9762  }
9763 
9764  case 0xB9: // map (two-byte uint16_t for n follow)
9765  {
9766  std::uint16_t len{};
9767  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9768  }
9769 
9770  case 0xBA: // map (four-byte uint32_t for n follow)
9771  {
9772  std::uint32_t len{};
9773  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9774  }
9775 
9776  case 0xBB: // map (eight-byte uint64_t for n follow)
9777  {
9778  std::uint64_t len{};
9779  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9780  }
9781 
9782  case 0xBF: // map (indefinite length)
9783  return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9784 
9785  case 0xC6: // tagged item
9786  case 0xC7:
9787  case 0xC8:
9788  case 0xC9:
9789  case 0xCA:
9790  case 0xCB:
9791  case 0xCC:
9792  case 0xCD:
9793  case 0xCE:
9794  case 0xCF:
9795  case 0xD0:
9796  case 0xD1:
9797  case 0xD2:
9798  case 0xD3:
9799  case 0xD4:
9800  case 0xD8: // tagged item (1 bytes follow)
9801  case 0xD9: // tagged item (2 bytes follow)
9802  case 0xDA: // tagged item (4 bytes follow)
9803  case 0xDB: // tagged item (8 bytes follow)
9804  {
9805  switch (tag_handler)
9806  {
9808  {
9809  auto last_token = get_token_string();
9810  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9811  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9812  }
9813 
9815  {
9816  // ignore binary subtype
9817  switch (current)
9818  {
9819  case 0xD8:
9820  {
9821  std::uint8_t subtype_to_ignore{};
9822  get_number(input_format_t::cbor, subtype_to_ignore);
9823  break;
9824  }
9825  case 0xD9:
9826  {
9827  std::uint16_t subtype_to_ignore{};
9828  get_number(input_format_t::cbor, subtype_to_ignore);
9829  break;
9830  }
9831  case 0xDA:
9832  {
9833  std::uint32_t subtype_to_ignore{};
9834  get_number(input_format_t::cbor, subtype_to_ignore);
9835  break;
9836  }
9837  case 0xDB:
9838  {
9839  std::uint64_t subtype_to_ignore{};
9840  get_number(input_format_t::cbor, subtype_to_ignore);
9841  break;
9842  }
9843  default:
9844  break;
9845  }
9846  return parse_cbor_internal(true, tag_handler);
9847  }
9848 
9850  {
9851  binary_t b;
9852  // use binary subtype and store in binary container
9853  switch (current)
9854  {
9855  case 0xD8:
9856  {
9857  std::uint8_t subtype{};
9858  get_number(input_format_t::cbor, subtype);
9859  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9860  break;
9861  }
9862  case 0xD9:
9863  {
9864  std::uint16_t subtype{};
9865  get_number(input_format_t::cbor, subtype);
9866  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9867  break;
9868  }
9869  case 0xDA:
9870  {
9871  std::uint32_t subtype{};
9872  get_number(input_format_t::cbor, subtype);
9873  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9874  break;
9875  }
9876  case 0xDB:
9877  {
9878  std::uint64_t subtype{};
9879  get_number(input_format_t::cbor, subtype);
9880  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9881  break;
9882  }
9883  default:
9884  return parse_cbor_internal(true, tag_handler);
9885  }
9886  get();
9887  return get_cbor_binary(b) && sax->binary(b);
9888  }
9889 
9890  default: // LCOV_EXCL_LINE
9891  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9892  return false; // LCOV_EXCL_LINE
9893  }
9894  }
9895 
9896  case 0xF4: // false
9897  return sax->boolean(false);
9898 
9899  case 0xF5: // true
9900  return sax->boolean(true);
9901 
9902  case 0xF6: // null
9903  return sax->null();
9904 
9905  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9906  {
9907  const auto byte1_raw = get();
9908  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9909  {
9910  return false;
9911  }
9912  const auto byte2_raw = get();
9913  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9914  {
9915  return false;
9916  }
9917 
9918  const auto byte1 = static_cast<unsigned char>(byte1_raw);
9919  const auto byte2 = static_cast<unsigned char>(byte2_raw);
9920 
9921  // code from RFC 7049, Appendix D, Figure 3:
9922  // As half-precision floating-point numbers were only added
9923  // to IEEE 754 in 2008, today's programming platforms often
9924  // still only have limited support for them. It is very
9925  // easy to include at least decoding support for them even
9926  // without such support. An example of a small decoder for
9927  // half-precision floating-point numbers in the C language
9928  // is shown in Fig. 3.
9929  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9930  const double val = [&half]
9931  {
9932  const int exp = (half >> 10u) & 0x1Fu;
9933  const unsigned int mant = half & 0x3FFu;
9934  JSON_ASSERT(0 <= exp&& exp <= 32);
9935  JSON_ASSERT(mant <= 1024);
9936  switch (exp)
9937  {
9938  case 0:
9939  return std::ldexp(mant, -24);
9940  case 31:
9941  return (mant == 0)
9942  ? std::numeric_limits<double>::infinity()
9943  : std::numeric_limits<double>::quiet_NaN();
9944  default:
9945  return std::ldexp(mant + 1024, exp - 25);
9946  }
9947  }();
9948  return sax->number_float((half & 0x8000u) != 0
9949  ? static_cast<number_float_t>(-val)
9950  : static_cast<number_float_t>(val), "");
9951  }
9952 
9953  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9954  {
9955  float number{};
9956  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9957  }
9958 
9959  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9960  {
9961  double number{};
9962  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9963  }
9964 
9965  default: // anything else (0xFF is handled inside the other types)
9966  {
9967  auto last_token = get_token_string();
9968  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9969  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9970  }
9971  }
9972  }
9973 
9985  bool get_cbor_string(string_t& result)
9986  {
9987  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9988  {
9989  return false;
9990  }
9991 
9992  switch (current)
9993  {
9994  // UTF-8 string (0x00..0x17 bytes follow)
9995  case 0x60:
9996  case 0x61:
9997  case 0x62:
9998  case 0x63:
9999  case 0x64:
10000  case 0x65:
10001  case 0x66:
10002  case 0x67:
10003  case 0x68:
10004  case 0x69:
10005  case 0x6A:
10006  case 0x6B:
10007  case 0x6C:
10008  case 0x6D:
10009  case 0x6E:
10010  case 0x6F:
10011  case 0x70:
10012  case 0x71:
10013  case 0x72:
10014  case 0x73:
10015  case 0x74:
10016  case 0x75:
10017  case 0x76:
10018  case 0x77:
10019  {
10020  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10021  }
10022 
10023  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
10024  {
10025  std::uint8_t len{};
10026  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10027  }
10028 
10029  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
10030  {
10031  std::uint16_t len{};
10032  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10033  }
10034 
10035  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
10036  {
10037  std::uint32_t len{};
10038  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10039  }
10040 
10041  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
10042  {
10043  std::uint64_t len{};
10044  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10045  }
10046 
10047  case 0x7F: // UTF-8 string (indefinite length)
10048  {
10049  while (get() != 0xFF)
10050  {
10051  string_t chunk;
10052  if (!get_cbor_string(chunk))
10053  {
10054  return false;
10055  }
10056  result.append(chunk);
10057  }
10058  return true;
10059  }
10060 
10061  default:
10062  {
10063  auto last_token = get_token_string();
10064  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10065  exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
10066  }
10067  }
10068  }
10069 
10081  bool get_cbor_binary(binary_t& result)
10082  {
10083  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
10084  {
10085  return false;
10086  }
10087 
10088  switch (current)
10089  {
10090  // Binary data (0x00..0x17 bytes follow)
10091  case 0x40:
10092  case 0x41:
10093  case 0x42:
10094  case 0x43:
10095  case 0x44:
10096  case 0x45:
10097  case 0x46:
10098  case 0x47:
10099  case 0x48:
10100  case 0x49:
10101  case 0x4A:
10102  case 0x4B:
10103  case 0x4C:
10104  case 0x4D:
10105  case 0x4E:
10106  case 0x4F:
10107  case 0x50:
10108  case 0x51:
10109  case 0x52:
10110  case 0x53:
10111  case 0x54:
10112  case 0x55:
10113  case 0x56:
10114  case 0x57:
10115  {
10116  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10117  }
10118 
10119  case 0x58: // Binary data (one-byte uint8_t for n follows)
10120  {
10121  std::uint8_t len{};
10122  return get_number(input_format_t::cbor, len) &&
10123  get_binary(input_format_t::cbor, len, result);
10124  }
10125 
10126  case 0x59: // Binary data (two-byte uint16_t for n follow)
10127  {
10128  std::uint16_t len{};
10129  return get_number(input_format_t::cbor, len) &&
10130  get_binary(input_format_t::cbor, len, result);
10131  }
10132 
10133  case 0x5A: // Binary data (four-byte uint32_t for n follow)
10134  {
10135  std::uint32_t len{};
10136  return get_number(input_format_t::cbor, len) &&
10137  get_binary(input_format_t::cbor, len, result);
10138  }
10139 
10140  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10141  {
10142  std::uint64_t len{};
10143  return get_number(input_format_t::cbor, len) &&
10144  get_binary(input_format_t::cbor, len, result);
10145  }
10146 
10147  case 0x5F: // Binary data (indefinite length)
10148  {
10149  while (get() != 0xFF)
10150  {
10151  binary_t chunk;
10152  if (!get_cbor_binary(chunk))
10153  {
10154  return false;
10155  }
10156  result.insert(result.end(), chunk.begin(), chunk.end());
10157  }
10158  return true;
10159  }
10160 
10161  default:
10162  {
10163  auto last_token = get_token_string();
10164  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10165  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));
10166  }
10167  }
10168  }
10169 
10176  bool get_cbor_array(const std::size_t len,
10177  const cbor_tag_handler_t tag_handler)
10178  {
10179  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10180  {
10181  return false;
10182  }
10183 
10184  if (len != static_cast<std::size_t>(-1))
10185  {
10186  for (std::size_t i = 0; i < len; ++i)
10187  {
10188  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10189  {
10190  return false;
10191  }
10192  }
10193  }
10194  else
10195  {
10196  while (get() != 0xFF)
10197  {
10198  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
10199  {
10200  return false;
10201  }
10202  }
10203  }
10204 
10205  return sax->end_array();
10206  }
10207 
10214  bool get_cbor_object(const std::size_t len,
10215  const cbor_tag_handler_t tag_handler)
10216  {
10217  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10218  {
10219  return false;
10220  }
10221 
10222  if (len != 0)
10223  {
10224  string_t key;
10225  if (len != static_cast<std::size_t>(-1))
10226  {
10227  for (std::size_t i = 0; i < len; ++i)
10228  {
10229  get();
10230  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10231  {
10232  return false;
10233  }
10234 
10235  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10236  {
10237  return false;
10238  }
10239  key.clear();
10240  }
10241  }
10242  else
10243  {
10244  while (get() != 0xFF)
10245  {
10246  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10247  {
10248  return false;
10249  }
10250 
10251  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10252  {
10253  return false;
10254  }
10255  key.clear();
10256  }
10257  }
10258  }
10259 
10260  return sax->end_object();
10261  }
10262 
10264  // MsgPack //
10266 
10270  bool parse_msgpack_internal()
10271  {
10272  switch (get())
10273  {
10274  // EOF
10275  case std::char_traits<char_type>::eof():
10276  return unexpect_eof(input_format_t::msgpack, "value");
10277 
10278  // positive fixint
10279  case 0x00:
10280  case 0x01:
10281  case 0x02:
10282  case 0x03:
10283  case 0x04:
10284  case 0x05:
10285  case 0x06:
10286  case 0x07:
10287  case 0x08:
10288  case 0x09:
10289  case 0x0A:
10290  case 0x0B:
10291  case 0x0C:
10292  case 0x0D:
10293  case 0x0E:
10294  case 0x0F:
10295  case 0x10:
10296  case 0x11:
10297  case 0x12:
10298  case 0x13:
10299  case 0x14:
10300  case 0x15:
10301  case 0x16:
10302  case 0x17:
10303  case 0x18:
10304  case 0x19:
10305  case 0x1A:
10306  case 0x1B:
10307  case 0x1C:
10308  case 0x1D:
10309  case 0x1E:
10310  case 0x1F:
10311  case 0x20:
10312  case 0x21:
10313  case 0x22:
10314  case 0x23:
10315  case 0x24:
10316  case 0x25:
10317  case 0x26:
10318  case 0x27:
10319  case 0x28:
10320  case 0x29:
10321  case 0x2A:
10322  case 0x2B:
10323  case 0x2C:
10324  case 0x2D:
10325  case 0x2E:
10326  case 0x2F:
10327  case 0x30:
10328  case 0x31:
10329  case 0x32:
10330  case 0x33:
10331  case 0x34:
10332  case 0x35:
10333  case 0x36:
10334  case 0x37:
10335  case 0x38:
10336  case 0x39:
10337  case 0x3A:
10338  case 0x3B:
10339  case 0x3C:
10340  case 0x3D:
10341  case 0x3E:
10342  case 0x3F:
10343  case 0x40:
10344  case 0x41:
10345  case 0x42:
10346  case 0x43:
10347  case 0x44:
10348  case 0x45:
10349  case 0x46:
10350  case 0x47:
10351  case 0x48:
10352  case 0x49:
10353  case 0x4A:
10354  case 0x4B:
10355  case 0x4C:
10356  case 0x4D:
10357  case 0x4E:
10358  case 0x4F:
10359  case 0x50:
10360  case 0x51:
10361  case 0x52:
10362  case 0x53:
10363  case 0x54:
10364  case 0x55:
10365  case 0x56:
10366  case 0x57:
10367  case 0x58:
10368  case 0x59:
10369  case 0x5A:
10370  case 0x5B:
10371  case 0x5C:
10372  case 0x5D:
10373  case 0x5E:
10374  case 0x5F:
10375  case 0x60:
10376  case 0x61:
10377  case 0x62:
10378  case 0x63:
10379  case 0x64:
10380  case 0x65:
10381  case 0x66:
10382  case 0x67:
10383  case 0x68:
10384  case 0x69:
10385  case 0x6A:
10386  case 0x6B:
10387  case 0x6C:
10388  case 0x6D:
10389  case 0x6E:
10390  case 0x6F:
10391  case 0x70:
10392  case 0x71:
10393  case 0x72:
10394  case 0x73:
10395  case 0x74:
10396  case 0x75:
10397  case 0x76:
10398  case 0x77:
10399  case 0x78:
10400  case 0x79:
10401  case 0x7A:
10402  case 0x7B:
10403  case 0x7C:
10404  case 0x7D:
10405  case 0x7E:
10406  case 0x7F:
10407  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
10408 
10409  // fixmap
10410  case 0x80:
10411  case 0x81:
10412  case 0x82:
10413  case 0x83:
10414  case 0x84:
10415  case 0x85:
10416  case 0x86:
10417  case 0x87:
10418  case 0x88:
10419  case 0x89:
10420  case 0x8A:
10421  case 0x8B:
10422  case 0x8C:
10423  case 0x8D:
10424  case 0x8E:
10425  case 0x8F:
10426  return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10427 
10428  // fixarray
10429  case 0x90:
10430  case 0x91:
10431  case 0x92:
10432  case 0x93:
10433  case 0x94:
10434  case 0x95:
10435  case 0x96:
10436  case 0x97:
10437  case 0x98:
10438  case 0x99:
10439  case 0x9A:
10440  case 0x9B:
10441  case 0x9C:
10442  case 0x9D:
10443  case 0x9E:
10444  case 0x9F:
10445  return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10446 
10447  // fixstr
10448  case 0xA0:
10449  case 0xA1:
10450  case 0xA2:
10451  case 0xA3:
10452  case 0xA4:
10453  case 0xA5:
10454  case 0xA6:
10455  case 0xA7:
10456  case 0xA8:
10457  case 0xA9:
10458  case 0xAA:
10459  case 0xAB:
10460  case 0xAC:
10461  case 0xAD:
10462  case 0xAE:
10463  case 0xAF:
10464  case 0xB0:
10465  case 0xB1:
10466  case 0xB2:
10467  case 0xB3:
10468  case 0xB4:
10469  case 0xB5:
10470  case 0xB6:
10471  case 0xB7:
10472  case 0xB8:
10473  case 0xB9:
10474  case 0xBA:
10475  case 0xBB:
10476  case 0xBC:
10477  case 0xBD:
10478  case 0xBE:
10479  case 0xBF:
10480  case 0xD9: // str 8
10481  case 0xDA: // str 16
10482  case 0xDB: // str 32
10483  {
10484  string_t s;
10485  return get_msgpack_string(s) && sax->string(s);
10486  }
10487 
10488  case 0xC0: // nil
10489  return sax->null();
10490 
10491  case 0xC2: // false
10492  return sax->boolean(false);
10493 
10494  case 0xC3: // true
10495  return sax->boolean(true);
10496 
10497  case 0xC4: // bin 8
10498  case 0xC5: // bin 16
10499  case 0xC6: // bin 32
10500  case 0xC7: // ext 8
10501  case 0xC8: // ext 16
10502  case 0xC9: // ext 32
10503  case 0xD4: // fixext 1
10504  case 0xD5: // fixext 2
10505  case 0xD6: // fixext 4
10506  case 0xD7: // fixext 8
10507  case 0xD8: // fixext 16
10508  {
10509  binary_t b;
10510  return get_msgpack_binary(b) && sax->binary(b);
10511  }
10512 
10513  case 0xCA: // float 32
10514  {
10515  float number{};
10516  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10517  }
10518 
10519  case 0xCB: // float 64
10520  {
10521  double number{};
10522  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10523  }
10524 
10525  case 0xCC: // uint 8
10526  {
10527  std::uint8_t number{};
10528  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10529  }
10530 
10531  case 0xCD: // uint 16
10532  {
10533  std::uint16_t number{};
10534  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10535  }
10536 
10537  case 0xCE: // uint 32
10538  {
10539  std::uint32_t number{};
10540  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10541  }
10542 
10543  case 0xCF: // uint 64
10544  {
10545  std::uint64_t number{};
10546  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10547  }
10548 
10549  case 0xD0: // int 8
10550  {
10551  std::int8_t number{};
10552  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10553  }
10554 
10555  case 0xD1: // int 16
10556  {
10557  std::int16_t number{};
10558  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10559  }
10560 
10561  case 0xD2: // int 32
10562  {
10563  std::int32_t number{};
10564  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10565  }
10566 
10567  case 0xD3: // int 64
10568  {
10569  std::int64_t number{};
10570  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10571  }
10572 
10573  case 0xDC: // array 16
10574  {
10575  std::uint16_t len{};
10576  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
10577  }
10578 
10579  case 0xDD: // array 32
10580  {
10581  std::uint32_t len{};
10582  return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));
10583  }
10584 
10585  case 0xDE: // map 16
10586  {
10587  std::uint16_t len{};
10588  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
10589  }
10590 
10591  case 0xDF: // map 32
10592  {
10593  std::uint32_t len{};
10594  return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));
10595  }
10596 
10597  // negative fixint
10598  case 0xE0:
10599  case 0xE1:
10600  case 0xE2:
10601  case 0xE3:
10602  case 0xE4:
10603  case 0xE5:
10604  case 0xE6:
10605  case 0xE7:
10606  case 0xE8:
10607  case 0xE9:
10608  case 0xEA:
10609  case 0xEB:
10610  case 0xEC:
10611  case 0xED:
10612  case 0xEE:
10613  case 0xEF:
10614  case 0xF0:
10615  case 0xF1:
10616  case 0xF2:
10617  case 0xF3:
10618  case 0xF4:
10619  case 0xF5:
10620  case 0xF6:
10621  case 0xF7:
10622  case 0xF8:
10623  case 0xF9:
10624  case 0xFA:
10625  case 0xFB:
10626  case 0xFC:
10627  case 0xFD:
10628  case 0xFE:
10629  case 0xFF:
10630  return sax->number_integer(static_cast<std::int8_t>(current));
10631 
10632  default: // anything else
10633  {
10634  auto last_token = get_token_string();
10635  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10636  exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10637  }
10638  }
10639  }
10640 
10651  bool get_msgpack_string(string_t& result)
10652  {
10653  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
10654  {
10655  return false;
10656  }
10657 
10658  switch (current)
10659  {
10660  // fixstr
10661  case 0xA0:
10662  case 0xA1:
10663  case 0xA2:
10664  case 0xA3:
10665  case 0xA4:
10666  case 0xA5:
10667  case 0xA6:
10668  case 0xA7:
10669  case 0xA8:
10670  case 0xA9:
10671  case 0xAA:
10672  case 0xAB:
10673  case 0xAC:
10674  case 0xAD:
10675  case 0xAE:
10676  case 0xAF:
10677  case 0xB0:
10678  case 0xB1:
10679  case 0xB2:
10680  case 0xB3:
10681  case 0xB4:
10682  case 0xB5:
10683  case 0xB6:
10684  case 0xB7:
10685  case 0xB8:
10686  case 0xB9:
10687  case 0xBA:
10688  case 0xBB:
10689  case 0xBC:
10690  case 0xBD:
10691  case 0xBE:
10692  case 0xBF:
10693  {
10694  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10695  }
10696 
10697  case 0xD9: // str 8
10698  {
10699  std::uint8_t len{};
10700  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10701  }
10702 
10703  case 0xDA: // str 16
10704  {
10705  std::uint16_t len{};
10706  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10707  }
10708 
10709  case 0xDB: // str 32
10710  {
10711  std::uint32_t len{};
10712  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10713  }
10714 
10715  default:
10716  {
10717  auto last_token = get_token_string();
10718  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10719  exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10720  }
10721  }
10722  }
10723 
10734  bool get_msgpack_binary(binary_t& result)
10735  {
10736  // helper function to set the subtype
10737  auto assign_and_return_true = [&result](std::int8_t subtype)
10738  {
10739  result.set_subtype(static_cast<std::uint8_t>(subtype));
10740  return true;
10741  };
10742 
10743  switch (current)
10744  {
10745  case 0xC4: // bin 8
10746  {
10747  std::uint8_t len{};
10748  return get_number(input_format_t::msgpack, len) &&
10749  get_binary(input_format_t::msgpack, len, result);
10750  }
10751 
10752  case 0xC5: // bin 16
10753  {
10754  std::uint16_t len{};
10755  return get_number(input_format_t::msgpack, len) &&
10756  get_binary(input_format_t::msgpack, len, result);
10757  }
10758 
10759  case 0xC6: // bin 32
10760  {
10761  std::uint32_t len{};
10762  return get_number(input_format_t::msgpack, len) &&
10763  get_binary(input_format_t::msgpack, len, result);
10764  }
10765 
10766  case 0xC7: // ext 8
10767  {
10768  std::uint8_t len{};
10769  std::int8_t subtype{};
10770  return get_number(input_format_t::msgpack, len) &&
10771  get_number(input_format_t::msgpack, subtype) &&
10772  get_binary(input_format_t::msgpack, len, result) &&
10773  assign_and_return_true(subtype);
10774  }
10775 
10776  case 0xC8: // ext 16
10777  {
10778  std::uint16_t len{};
10779  std::int8_t subtype{};
10780  return get_number(input_format_t::msgpack, len) &&
10781  get_number(input_format_t::msgpack, subtype) &&
10782  get_binary(input_format_t::msgpack, len, result) &&
10783  assign_and_return_true(subtype);
10784  }
10785 
10786  case 0xC9: // ext 32
10787  {
10788  std::uint32_t len{};
10789  std::int8_t subtype{};
10790  return get_number(input_format_t::msgpack, len) &&
10791  get_number(input_format_t::msgpack, subtype) &&
10792  get_binary(input_format_t::msgpack, len, result) &&
10793  assign_and_return_true(subtype);
10794  }
10795 
10796  case 0xD4: // fixext 1
10797  {
10798  std::int8_t subtype{};
10799  return get_number(input_format_t::msgpack, subtype) &&
10800  get_binary(input_format_t::msgpack, 1, result) &&
10801  assign_and_return_true(subtype);
10802  }
10803 
10804  case 0xD5: // fixext 2
10805  {
10806  std::int8_t subtype{};
10807  return get_number(input_format_t::msgpack, subtype) &&
10808  get_binary(input_format_t::msgpack, 2, result) &&
10809  assign_and_return_true(subtype);
10810  }
10811 
10812  case 0xD6: // fixext 4
10813  {
10814  std::int8_t subtype{};
10815  return get_number(input_format_t::msgpack, subtype) &&
10816  get_binary(input_format_t::msgpack, 4, result) &&
10817  assign_and_return_true(subtype);
10818  }
10819 
10820  case 0xD7: // fixext 8
10821  {
10822  std::int8_t subtype{};
10823  return get_number(input_format_t::msgpack, subtype) &&
10824  get_binary(input_format_t::msgpack, 8, result) &&
10825  assign_and_return_true(subtype);
10826  }
10827 
10828  case 0xD8: // fixext 16
10829  {
10830  std::int8_t subtype{};
10831  return get_number(input_format_t::msgpack, subtype) &&
10832  get_binary(input_format_t::msgpack, 16, result) &&
10833  assign_and_return_true(subtype);
10834  }
10835 
10836  default: // LCOV_EXCL_LINE
10837  return false; // LCOV_EXCL_LINE
10838  }
10839  }
10840 
10845  bool get_msgpack_array(const std::size_t len)
10846  {
10847  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10848  {
10849  return false;
10850  }
10851 
10852  for (std::size_t i = 0; i < len; ++i)
10853  {
10854  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10855  {
10856  return false;
10857  }
10858  }
10859 
10860  return sax->end_array();
10861  }
10862 
10867  bool get_msgpack_object(const std::size_t len)
10868  {
10869  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10870  {
10871  return false;
10872  }
10873 
10874  string_t key;
10875  for (std::size_t i = 0; i < len; ++i)
10876  {
10877  get();
10878  if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10879  {
10880  return false;
10881  }
10882 
10883  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10884  {
10885  return false;
10886  }
10887  key.clear();
10888  }
10889 
10890  return sax->end_object();
10891  }
10892 
10894  // UBJSON //
10896 
10904  bool parse_ubjson_internal(const bool get_char = true)
10905  {
10906  return get_ubjson_value(get_char ? get_ignore_noop() : current);
10907  }
10908 
10923  bool get_ubjson_string(string_t& result, const bool get_char = true)
10924  {
10925  if (get_char)
10926  {
10927  get(); // TODO(niels): may we ignore N here?
10928  }
10929 
10930  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10931  {
10932  return false;
10933  }
10934 
10935  switch (current)
10936  {
10937  case 'U':
10938  {
10939  std::uint8_t len{};
10940  return get_number(input_format, len) && get_string(input_format, len, result);
10941  }
10942 
10943  case 'i':
10944  {
10945  std::int8_t len{};
10946  return get_number(input_format, len) && get_string(input_format, len, result);
10947  }
10948 
10949  case 'I':
10950  {
10951  std::int16_t len{};
10952  return get_number(input_format, len) && get_string(input_format, len, result);
10953  }
10954 
10955  case 'l':
10956  {
10957  std::int32_t len{};
10958  return get_number(input_format, len) && get_string(input_format, len, result);
10959  }
10960 
10961  case 'L':
10962  {
10963  std::int64_t len{};
10964  return get_number(input_format, len) && get_string(input_format, len, result);
10965  }
10966 
10967  case 'u':
10968  {
10969  if (input_format != input_format_t::bjdata)
10970  {
10971  break;
10972  }
10973  std::uint16_t len{};
10974  return get_number(input_format, len) && get_string(input_format, len, result);
10975  }
10976 
10977  case 'm':
10978  {
10979  if (input_format != input_format_t::bjdata)
10980  {
10981  break;
10982  }
10983  std::uint32_t len{};
10984  return get_number(input_format, len) && get_string(input_format, len, result);
10985  }
10986 
10987  case 'M':
10988  {
10989  if (input_format != input_format_t::bjdata)
10990  {
10991  break;
10992  }
10993  std::uint64_t len{};
10994  return get_number(input_format, len) && get_string(input_format, len, result);
10995  }
10996 
10997  default:
10998  break;
10999  }
11000  auto last_token = get_token_string();
11001  std::string message;
11002 
11003  if (input_format != input_format_t::bjdata)
11004  {
11005  message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
11006  }
11007  else
11008  {
11009  message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
11010  }
11011  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
11012  }
11013 
11018  bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
11019  {
11020  std::pair<std::size_t, char_int_type> size_and_type;
11021  size_t dimlen = 0;
11022  bool no_ndarray = true;
11023 
11024  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
11025  {
11026  return false;
11027  }
11028 
11029  if (size_and_type.first != npos)
11030  {
11031  if (size_and_type.second != 0)
11032  {
11033  if (size_and_type.second != 'N')
11034  {
11035  for (std::size_t i = 0; i < size_and_type.first; ++i)
11036  {
11037  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
11038  {
11039  return false;
11040  }
11041  dim.push_back(dimlen);
11042  }
11043  }
11044  }
11045  else
11046  {
11047  for (std::size_t i = 0; i < size_and_type.first; ++i)
11048  {
11049  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
11050  {
11051  return false;
11052  }
11053  dim.push_back(dimlen);
11054  }
11055  }
11056  }
11057  else
11058  {
11059  while (current != ']')
11060  {
11061  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
11062  {
11063  return false;
11064  }
11065  dim.push_back(dimlen);
11066  get_ignore_noop();
11067  }
11068  }
11069  return true;
11070  }
11071 
11083  bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
11084  {
11085  if (prefix == 0)
11086  {
11087  prefix = get_ignore_noop();
11088  }
11089 
11090  switch (prefix)
11091  {
11092  case 'U':
11093  {
11094  std::uint8_t number{};
11095  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11096  {
11097  return false;
11098  }
11099  result = static_cast<std::size_t>(number);
11100  return true;
11101  }
11102 
11103  case 'i':
11104  {
11105  std::int8_t number{};
11106  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11107  {
11108  return false;
11109  }
11110  if (number < 0)
11111  {
11112  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11113  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11114  }
11115  result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
11116  return true;
11117  }
11118 
11119  case 'I':
11120  {
11121  std::int16_t number{};
11122  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11123  {
11124  return false;
11125  }
11126  if (number < 0)
11127  {
11128  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11129  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11130  }
11131  result = static_cast<std::size_t>(number);
11132  return true;
11133  }
11134 
11135  case 'l':
11136  {
11137  std::int32_t number{};
11138  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11139  {
11140  return false;
11141  }
11142  if (number < 0)
11143  {
11144  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11145  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11146  }
11147  result = static_cast<std::size_t>(number);
11148  return true;
11149  }
11150 
11151  case 'L':
11152  {
11153  std::int64_t number{};
11154  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11155  {
11156  return false;
11157  }
11158  if (number < 0)
11159  {
11160  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11161  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11162  }
11163  if (!value_in_range_of<std::size_t>(number))
11164  {
11165  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11166  exception_message(input_format, "integer value overflow", "size"), nullptr));
11167  }
11168  result = static_cast<std::size_t>(number);
11169  return true;
11170  }
11171 
11172  case 'u':
11173  {
11174  if (input_format != input_format_t::bjdata)
11175  {
11176  break;
11177  }
11178  std::uint16_t number{};
11179  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11180  {
11181  return false;
11182  }
11183  result = static_cast<std::size_t>(number);
11184  return true;
11185  }
11186 
11187  case 'm':
11188  {
11189  if (input_format != input_format_t::bjdata)
11190  {
11191  break;
11192  }
11193  std::uint32_t number{};
11194  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11195  {
11196  return false;
11197  }
11198  result = conditional_static_cast<std::size_t>(number);
11199  return true;
11200  }
11201 
11202  case 'M':
11203  {
11204  if (input_format != input_format_t::bjdata)
11205  {
11206  break;
11207  }
11208  std::uint64_t number{};
11209  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11210  {
11211  return false;
11212  }
11213  if (!value_in_range_of<std::size_t>(number))
11214  {
11215  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11216  exception_message(input_format, "integer value overflow", "size"), nullptr));
11217  }
11218  result = detail::conditional_static_cast<std::size_t>(number);
11219  return true;
11220  }
11221 
11222  case '[':
11223  {
11224  if (input_format != input_format_t::bjdata)
11225  {
11226  break;
11227  }
11228  if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
11229  {
11230  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimentional vector is not allowed", "size"), nullptr));
11231  }
11232  std::vector<size_t> dim;
11233  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
11234  {
11235  return false;
11236  }
11237  if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
11238  {
11239  result = dim.at(dim.size() - 1);
11240  return true;
11241  }
11242  if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
11243  {
11244  for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
11245  {
11246  if ( i == 0 )
11247  {
11248  result = 0;
11249  return true;
11250  }
11251  }
11252 
11253  string_t key = "_ArraySize_";
11254  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
11255  {
11256  return false;
11257  }
11258  result = 1;
11259  for (auto i : dim)
11260  {
11261  result *= i;
11262  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()
11263  {
11264  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));
11265  }
11266  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
11267  {
11268  return false;
11269  }
11270  }
11271  is_ndarray = true;
11272  return sax->end_array();
11273  }
11274  result = 0;
11275  return true;
11276  }
11277 
11278  default:
11279  break;
11280  }
11281  auto last_token = get_token_string();
11282  std::string message;
11283 
11284  if (input_format != input_format_t::bjdata)
11285  {
11286  message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
11287  }
11288  else
11289  {
11290  message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
11291  }
11292  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
11293  }
11294 
11306  bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
11307  {
11308  result.first = npos; // size
11309  result.second = 0; // type
11310  bool is_ndarray = false;
11311 
11312  get_ignore_noop();
11313 
11314  if (current == '$')
11315  {
11316  result.second = get(); // must not ignore 'N', because 'N' maybe the type
11317  if (input_format == input_format_t::bjdata
11318  && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
11319  {
11320  auto last_token = get_token_string();
11321  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11322  exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
11323  }
11324 
11325  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
11326  {
11327  return false;
11328  }
11329 
11330  get_ignore_noop();
11331  if (JSON_HEDLEY_UNLIKELY(current != '#'))
11332  {
11333  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
11334  {
11335  return false;
11336  }
11337  auto last_token = get_token_string();
11338  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11339  exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
11340  }
11341 
11342  bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11343  if (input_format == input_format_t::bjdata && is_ndarray)
11344  {
11345  if (inside_ndarray)
11346  {
11347  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11348  exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
11349  }
11350  result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
11351  }
11352  return is_error;
11353  }
11354 
11355  if (current == '#')
11356  {
11357  bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11358  if (input_format == input_format_t::bjdata && is_ndarray)
11359  {
11360  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11361  exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
11362  }
11363  return is_error;
11364  }
11365 
11366  return true;
11367  }
11368 
11373  bool get_ubjson_value(const char_int_type prefix)
11374  {
11375  switch (prefix)
11376  {
11377  case std::char_traits<char_type>::eof(): // EOF
11378  return unexpect_eof(input_format, "value");
11379 
11380  case 'T': // true
11381  return sax->boolean(true);
11382  case 'F': // false
11383  return sax->boolean(false);
11384 
11385  case 'Z': // null
11386  return sax->null();
11387 
11388  case 'U':
11389  {
11390  std::uint8_t number{};
11391  return get_number(input_format, number) && sax->number_unsigned(number);
11392  }
11393 
11394  case 'i':
11395  {
11396  std::int8_t number{};
11397  return get_number(input_format, number) && sax->number_integer(number);
11398  }
11399 
11400  case 'I':
11401  {
11402  std::int16_t number{};
11403  return get_number(input_format, number) && sax->number_integer(number);
11404  }
11405 
11406  case 'l':
11407  {
11408  std::int32_t number{};
11409  return get_number(input_format, number) && sax->number_integer(number);
11410  }
11411 
11412  case 'L':
11413  {
11414  std::int64_t number{};
11415  return get_number(input_format, number) && sax->number_integer(number);
11416  }
11417 
11418  case 'u':
11419  {
11420  if (input_format != input_format_t::bjdata)
11421  {
11422  break;
11423  }
11424  std::uint16_t number{};
11425  return get_number(input_format, number) && sax->number_unsigned(number);
11426  }
11427 
11428  case 'm':
11429  {
11430  if (input_format != input_format_t::bjdata)
11431  {
11432  break;
11433  }
11434  std::uint32_t number{};
11435  return get_number(input_format, number) && sax->number_unsigned(number);
11436  }
11437 
11438  case 'M':
11439  {
11440  if (input_format != input_format_t::bjdata)
11441  {
11442  break;
11443  }
11444  std::uint64_t number{};
11445  return get_number(input_format, number) && sax->number_unsigned(number);
11446  }
11447 
11448  case 'h':
11449  {
11450  if (input_format != input_format_t::bjdata)
11451  {
11452  break;
11453  }
11454  const auto byte1_raw = get();
11455  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11456  {
11457  return false;
11458  }
11459  const auto byte2_raw = get();
11460  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11461  {
11462  return false;
11463  }
11464 
11465  const auto byte1 = static_cast<unsigned char>(byte1_raw);
11466  const auto byte2 = static_cast<unsigned char>(byte2_raw);
11467 
11468  // code from RFC 7049, Appendix D, Figure 3:
11469  // As half-precision floating-point numbers were only added
11470  // to IEEE 754 in 2008, today's programming platforms often
11471  // still only have limited support for them. It is very
11472  // easy to include at least decoding support for them even
11473  // without such support. An example of a small decoder for
11474  // half-precision floating-point numbers in the C language
11475  // is shown in Fig. 3.
11476  const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
11477  const double val = [&half]
11478  {
11479  const int exp = (half >> 10u) & 0x1Fu;
11480  const unsigned int mant = half & 0x3FFu;
11481  JSON_ASSERT(0 <= exp&& exp <= 32);
11482  JSON_ASSERT(mant <= 1024);
11483  switch (exp)
11484  {
11485  case 0:
11486  return std::ldexp(mant, -24);
11487  case 31:
11488  return (mant == 0)
11489  ? std::numeric_limits<double>::infinity()
11490  : std::numeric_limits<double>::quiet_NaN();
11491  default:
11492  return std::ldexp(mant + 1024, exp - 25);
11493  }
11494  }();
11495  return sax->number_float((half & 0x8000u) != 0
11496  ? static_cast<number_float_t>(-val)
11497  : static_cast<number_float_t>(val), "");
11498  }
11499 
11500  case 'd':
11501  {
11502  float number{};
11503  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11504  }
11505 
11506  case 'D':
11507  {
11508  double number{};
11509  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11510  }
11511 
11512  case 'H':
11513  {
11514  return get_ubjson_high_precision_number();
11515  }
11516 
11517  case 'C': // char
11518  {
11519  get();
11520  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
11521  {
11522  return false;
11523  }
11524  if (JSON_HEDLEY_UNLIKELY(current > 127))
11525  {
11526  auto last_token = get_token_string();
11527  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11528  exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
11529  }
11530  string_t s(1, static_cast<typename string_t::value_type>(current));
11531  return sax->string(s);
11532  }
11533 
11534  case 'S': // string
11535  {
11536  string_t s;
11537  return get_ubjson_string(s) && sax->string(s);
11538  }
11539 
11540  case '[': // array
11541  return get_ubjson_array();
11542 
11543  case '{': // object
11544  return get_ubjson_object();
11545 
11546  default: // anything else
11547  break;
11548  }
11549  auto last_token = get_token_string();
11550  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));
11551  }
11552 
11556  bool get_ubjson_array()
11557  {
11558  std::pair<std::size_t, char_int_type> size_and_type;
11559  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11560  {
11561  return false;
11562  }
11563 
11564  // 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):
11565  // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
11566 
11567  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11568  {
11569  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
11570  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)
11571  {
11572  return p.first < t;
11573  });
11574  string_t key = "_ArrayType_";
11575  if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
11576  {
11577  auto last_token = get_token_string();
11578  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11579  exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
11580  }
11581 
11582  string_t type = it->second; // sax->string() takes a reference
11583  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type)))
11584  {
11585  return false;
11586  }
11587 
11588  if (size_and_type.second == 'C')
11589  {
11590  size_and_type.second = 'U';
11591  }
11592 
11593  key = "_ArrayData_";
11594  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) ))
11595  {
11596  return false;
11597  }
11598 
11599  for (std::size_t i = 0; i < size_and_type.first; ++i)
11600  {
11601  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11602  {
11603  return false;
11604  }
11605  }
11606 
11607  return (sax->end_array() && sax->end_object());
11608  }
11609 
11610  if (size_and_type.first != npos)
11611  {
11612  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
11613  {
11614  return false;
11615  }
11616 
11617  if (size_and_type.second != 0)
11618  {
11619  if (size_and_type.second != 'N')
11620  {
11621  for (std::size_t i = 0; i < size_and_type.first; ++i)
11622  {
11623  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11624  {
11625  return false;
11626  }
11627  }
11628  }
11629  }
11630  else
11631  {
11632  for (std::size_t i = 0; i < size_and_type.first; ++i)
11633  {
11634  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11635  {
11636  return false;
11637  }
11638  }
11639  }
11640  }
11641  else
11642  {
11643  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11644  {
11645  return false;
11646  }
11647 
11648  while (current != ']')
11649  {
11650  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
11651  {
11652  return false;
11653  }
11654  get_ignore_noop();
11655  }
11656  }
11657 
11658  return sax->end_array();
11659  }
11660 
11664  bool get_ubjson_object()
11665  {
11666  std::pair<std::size_t, char_int_type> size_and_type;
11667  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11668  {
11669  return false;
11670  }
11671 
11672  // do not accept ND-array size in objects in BJData
11673  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11674  {
11675  auto last_token = get_token_string();
11676  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11677  exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
11678  }
11679 
11680  string_t key;
11681  if (size_and_type.first != npos)
11682  {
11683  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
11684  {
11685  return false;
11686  }
11687 
11688  if (size_and_type.second != 0)
11689  {
11690  for (std::size_t i = 0; i < size_and_type.first; ++i)
11691  {
11692  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11693  {
11694  return false;
11695  }
11696  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11697  {
11698  return false;
11699  }
11700  key.clear();
11701  }
11702  }
11703  else
11704  {
11705  for (std::size_t i = 0; i < size_and_type.first; ++i)
11706  {
11707  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11708  {
11709  return false;
11710  }
11711  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11712  {
11713  return false;
11714  }
11715  key.clear();
11716  }
11717  }
11718  }
11719  else
11720  {
11721  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11722  {
11723  return false;
11724  }
11725 
11726  while (current != '}')
11727  {
11728  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11729  {
11730  return false;
11731  }
11732  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11733  {
11734  return false;
11735  }
11736  get_ignore_noop();
11737  key.clear();
11738  }
11739  }
11740 
11741  return sax->end_object();
11742  }
11743 
11744  // Note, no reader for UBJSON binary types is implemented because they do
11745  // not exist
11746 
11747  bool get_ubjson_high_precision_number()
11748  {
11749  // get size of following number string
11750  std::size_t size{};
11751  bool no_ndarray = true;
11752  auto res = get_ubjson_size_value(size, no_ndarray);
11753  if (JSON_HEDLEY_UNLIKELY(!res))
11754  {
11755  return res;
11756  }
11757 
11758  // get number string
11759  std::vector<char> number_vector;
11760  for (std::size_t i = 0; i < size; ++i)
11761  {
11762  get();
11763  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11764  {
11765  return false;
11766  }
11767  number_vector.push_back(static_cast<char>(current));
11768  }
11769 
11770  // parse number string
11771  using ia_type = decltype(detail::input_adapter(number_vector));
11772  auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11773  const auto result_number = number_lexer.scan();
11774  const auto number_string = number_lexer.get_token_string();
11775  const auto result_remainder = number_lexer.scan();
11776 
11777  using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11778 
11779  if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11780  {
11781  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11782  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11783  }
11784 
11785  switch (result_number)
11786  {
11787  case token_type::value_integer:
11788  return sax->number_integer(number_lexer.get_number_integer());
11789  case token_type::value_unsigned:
11790  return sax->number_unsigned(number_lexer.get_number_unsigned());
11791  case token_type::value_float:
11792  return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11793  case token_type::uninitialized:
11794  case token_type::literal_true:
11795  case token_type::literal_false:
11796  case token_type::literal_null:
11797  case token_type::value_string:
11798  case token_type::begin_array:
11799  case token_type::begin_object:
11800  case token_type::end_array:
11801  case token_type::end_object:
11802  case token_type::name_separator:
11803  case token_type::value_separator:
11804  case token_type::parse_error:
11805  case token_type::end_of_input:
11806  case token_type::literal_or_value:
11807  default:
11808  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11809  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11810  }
11811  }
11812 
11814  // Utility functions //
11816 
11826  char_int_type get()
11827  {
11828  ++chars_read;
11829  return current = ia.get_character();
11830  }
11831 
11835  char_int_type get_ignore_noop()
11836  {
11837  do
11838  {
11839  get();
11840  }
11841  while (current == 'N');
11842 
11843  return current;
11844  }
11845 
11846  /*
11847  @brief read a number from the input
11848 
11849  @tparam NumberType the type of the number
11850  @param[in] format the current format (for diagnostics)
11851  @param[out] result number of type @a NumberType
11852 
11853  @return whether conversion completed
11854 
11855  @note This function needs to respect the system's endianness, because
11856  bytes in CBOR, MessagePack, and UBJSON are stored in network order
11857  (big endian) and therefore need reordering on little endian systems.
11858  On the other hand, BSON and BJData use little endian and should reorder
11859  on big endian systems.
11860  */
11861  template<typename NumberType, bool InputIsLittleEndian = false>
11862  bool get_number(const input_format_t format, NumberType& result)
11863  {
11864  // step 1: read input into array with system's byte order
11865  std::array<std::uint8_t, sizeof(NumberType)> vec{};
11866  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11867  {
11868  get();
11869  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11870  {
11871  return false;
11872  }
11873 
11874  // reverse byte order prior to conversion if necessary
11875  if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11876  {
11877  vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11878  }
11879  else
11880  {
11881  vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11882  }
11883  }
11884 
11885  // step 2: convert array into number of type T and return
11886  std::memcpy(&result, vec.data(), sizeof(NumberType));
11887  return true;
11888  }
11889 
11904  template<typename NumberType>
11905  bool get_string(const input_format_t format,
11906  const NumberType len,
11907  string_t& result)
11908  {
11909  bool success = true;
11910  for (NumberType i = 0; i < len; i++)
11911  {
11912  get();
11913  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11914  {
11915  success = false;
11916  break;
11917  }
11918  result.push_back(static_cast<typename string_t::value_type>(current));
11919  }
11920  return success;
11921  }
11922 
11937  template<typename NumberType>
11938  bool get_binary(const input_format_t format,
11939  const NumberType len,
11940  binary_t& result)
11941  {
11942  bool success = true;
11943  for (NumberType i = 0; i < len; i++)
11944  {
11945  get();
11946  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
11947  {
11948  success = false;
11949  break;
11950  }
11951  result.push_back(static_cast<std::uint8_t>(current));
11952  }
11953  return success;
11954  }
11955 
11962  bool unexpect_eof(const input_format_t format, const char* context) const
11963  {
11964  if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
11965  {
11966  return sax->parse_error(chars_read, "<end of file>",
11967  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
11968  }
11969  return true;
11970  }
11971 
11975  std::string get_token_string() const
11976  {
11977  std::array<char, 3> cr{{}};
11978  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
11979  return std::string{cr.data()};
11980  }
11981 
11988  std::string exception_message(const input_format_t format,
11989  const std::string& detail,
11990  const std::string& context) const
11991  {
11992  std::string error_msg = "syntax error while parsing ";
11993 
11994  switch (format)
11995  {
11996  case input_format_t::cbor:
11997  error_msg += "CBOR";
11998  break;
11999 
12001  error_msg += "MessagePack";
12002  break;
12003 
12005  error_msg += "UBJSON";
12006  break;
12007 
12008  case input_format_t::bson:
12009  error_msg += "BSON";
12010  break;
12011 
12013  error_msg += "BJData";
12014  break;
12015 
12016  case input_format_t::json: // LCOV_EXCL_LINE
12017  default: // LCOV_EXCL_LINE
12018  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
12019  }
12020 
12021  return concat(error_msg, ' ', context, ": ", detail);
12022  }
12023 
12024  private:
12025  static JSON_INLINE_VARIABLE constexpr std::size_t npos = static_cast<std::size_t>(-1);
12026 
12028  InputAdapterType ia;
12029 
12031  char_int_type current = std::char_traits<char_type>::eof();
12032 
12034  std::size_t chars_read = 0;
12035 
12037  const bool is_little_endian = little_endianness();
12038 
12040  const input_format_t input_format = input_format_t::json;
12041 
12043  json_sax_t* sax = nullptr;
12044 
12045  // excluded markers in bjdata optimized type
12046 #define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \
12047  make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
12048 
12049 #define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
12050  make_array<bjd_type>( \
12051  bjd_type{'C', "char"}, \
12052  bjd_type{'D', "double"}, \
12053  bjd_type{'I', "int16"}, \
12054  bjd_type{'L', "int64"}, \
12055  bjd_type{'M', "uint64"}, \
12056  bjd_type{'U', "uint8"}, \
12057  bjd_type{'d', "single"}, \
12058  bjd_type{'i', "int8"}, \
12059  bjd_type{'l', "int32"}, \
12060  bjd_type{'m', "uint32"}, \
12061  bjd_type{'u', "uint16"})
12062 
12064  // lookup tables
12065  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12066  const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =
12068 
12069  using bjd_type = std::pair<char_int_type, string_t>;
12070  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12071  const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map =
12073 
12074 #undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
12075 #undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
12076 };
12077 
12078 #ifndef JSON_HAS_CPP_17
12079  template<typename BasicJsonType, typename InputAdapterType, typename SAX>
12080  constexpr std::size_t binary_reader<BasicJsonType, InputAdapterType, SAX>::npos;
12081 #endif
12082 
12083 } // namespace detail
12085 
12086 // #include <nlohmann/detail/input/input_adapters.hpp>
12087 
12088 // #include <nlohmann/detail/input/lexer.hpp>
12089 
12090 // #include <nlohmann/detail/input/parser.hpp>
12091 // __ _____ _____ _____
12092 // __| | __| | | | JSON for Modern C++
12093 // | | |__ | | | | | | version 3.11.2
12094 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12095 //
12096 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12097 // SPDX-License-Identifier: MIT
12098 
12099 
12100 
12101 #include <cmath> // isfinite
12102 #include <cstdint> // uint8_t
12103 #include <functional> // function
12104 #include <string> // string
12105 #include <utility> // move
12106 #include <vector> // vector
12107 
12108 // #include <nlohmann/detail/exceptions.hpp>
12109 
12110 // #include <nlohmann/detail/input/input_adapters.hpp>
12111 
12112 // #include <nlohmann/detail/input/json_sax.hpp>
12113 
12114 // #include <nlohmann/detail/input/lexer.hpp>
12115 
12116 // #include <nlohmann/detail/macro_scope.hpp>
12117 
12118 // #include <nlohmann/detail/meta/is_sax.hpp>
12119 
12120 // #include <nlohmann/detail/string_concat.hpp>
12121 
12122 // #include <nlohmann/detail/value_t.hpp>
12123 
12124 
12126 namespace detail
12127 {
12129 // parser //
12131 
12132 enum class parse_event_t : std::uint8_t
12133 {
12135  object_start,
12137  object_end,
12139  array_start,
12141  array_end,
12143  key,
12145  value
12146 };
12147 
12148 template<typename BasicJsonType>
12149 using parser_callback_t =
12150  std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
12151 
12157 template<typename BasicJsonType, typename InputAdapterType>
12158 class parser
12159 {
12160  using number_integer_t = typename BasicJsonType::number_integer_t;
12161  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12162  using number_float_t = typename BasicJsonType::number_float_t;
12163  using string_t = typename BasicJsonType::string_t;
12165  using token_type = typename lexer_t::token_type;
12166 
12167  public:
12169  explicit parser(InputAdapterType&& adapter,
12170  const parser_callback_t<BasicJsonType> cb = nullptr,
12171  const bool allow_exceptions_ = true,
12172  const bool skip_comments = false)
12173  : callback(cb)
12174  , m_lexer(std::move(adapter), skip_comments)
12175  , allow_exceptions(allow_exceptions_)
12176  {
12177  // read first token
12178  get_token();
12179  }
12180 
12191  void parse(const bool strict, BasicJsonType& result)
12192  {
12193  if (callback)
12194  {
12195  json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
12196  sax_parse_internal(&sdp);
12197 
12198  // in strict mode, input must be completely read
12199  if (strict && (get_token() != token_type::end_of_input))
12200  {
12201  sdp.parse_error(m_lexer.get_position(),
12202  m_lexer.get_token_string(),
12203  parse_error::create(101, m_lexer.get_position(),
12204  exception_message(token_type::end_of_input, "value"), nullptr));
12205  }
12206 
12207  // in case of an error, return discarded value
12208  if (sdp.is_errored())
12209  {
12210  result = value_t::discarded;
12211  return;
12212  }
12213 
12214  // set top-level value to null if it was discarded by the callback
12215  // function
12216  if (result.is_discarded())
12217  {
12218  result = nullptr;
12219  }
12220  }
12221  else
12222  {
12223  json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
12224  sax_parse_internal(&sdp);
12225 
12226  // in strict mode, input must be completely read
12227  if (strict && (get_token() != token_type::end_of_input))
12228  {
12229  sdp.parse_error(m_lexer.get_position(),
12230  m_lexer.get_token_string(),
12231  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12232  }
12233 
12234  // in case of an error, return discarded value
12235  if (sdp.is_errored())
12236  {
12237  result = value_t::discarded;
12238  return;
12239  }
12240  }
12241 
12242  result.assert_invariant();
12243  }
12244 
12251  bool accept(const bool strict = true)
12252  {
12253  json_sax_acceptor<BasicJsonType> sax_acceptor;
12254  return sax_parse(&sax_acceptor, strict);
12255  }
12256 
12257  template<typename SAX>
12259  bool sax_parse(SAX* sax, const bool strict = true)
12260  {
12262  const bool result = sax_parse_internal(sax);
12263 
12264  // strict mode: next byte must be EOF
12265  if (result && strict && (get_token() != token_type::end_of_input))
12266  {
12267  return sax->parse_error(m_lexer.get_position(),
12268  m_lexer.get_token_string(),
12269  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12270  }
12271 
12272  return result;
12273  }
12274 
12275  private:
12276  template<typename SAX>
12278  bool sax_parse_internal(SAX* sax)
12279  {
12280  // stack to remember the hierarchy of structured values we are parsing
12281  // true = array; false = object
12282  std::vector<bool> states;
12283  // value to avoid a goto (see comment where set to true)
12284  bool skip_to_state_evaluation = false;
12285 
12286  while (true)
12287  {
12288  if (!skip_to_state_evaluation)
12289  {
12290  // invariant: get_token() was called before each iteration
12291  switch (last_token)
12292  {
12293  case token_type::begin_object:
12294  {
12295  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
12296  {
12297  return false;
12298  }
12299 
12300  // closing } -> we are done
12301  if (get_token() == token_type::end_object)
12302  {
12303  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12304  {
12305  return false;
12306  }
12307  break;
12308  }
12309 
12310  // parse key
12311  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
12312  {
12313  return sax->parse_error(m_lexer.get_position(),
12314  m_lexer.get_token_string(),
12315  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12316  }
12317  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12318  {
12319  return false;
12320  }
12321 
12322  // parse separator (:)
12323  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12324  {
12325  return sax->parse_error(m_lexer.get_position(),
12326  m_lexer.get_token_string(),
12327  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12328  }
12329 
12330  // remember we are now inside an object
12331  states.push_back(false);
12332 
12333  // parse values
12334  get_token();
12335  continue;
12336  }
12337 
12338  case token_type::begin_array:
12339  {
12340  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
12341  {
12342  return false;
12343  }
12344 
12345  // closing ] -> we are done
12346  if (get_token() == token_type::end_array)
12347  {
12348  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12349  {
12350  return false;
12351  }
12352  break;
12353  }
12354 
12355  // remember we are now inside an array
12356  states.push_back(true);
12357 
12358  // parse values (no need to call get_token)
12359  continue;
12360  }
12361 
12362  case token_type::value_float:
12363  {
12364  const auto res = m_lexer.get_number_float();
12365 
12366  if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
12367  {
12368  return sax->parse_error(m_lexer.get_position(),
12369  m_lexer.get_token_string(),
12370  out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
12371  }
12372 
12373  if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
12374  {
12375  return false;
12376  }
12377 
12378  break;
12379  }
12380 
12381  case token_type::literal_false:
12382  {
12383  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
12384  {
12385  return false;
12386  }
12387  break;
12388  }
12389 
12390  case token_type::literal_null:
12391  {
12392  if (JSON_HEDLEY_UNLIKELY(!sax->null()))
12393  {
12394  return false;
12395  }
12396  break;
12397  }
12398 
12399  case token_type::literal_true:
12400  {
12401  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
12402  {
12403  return false;
12404  }
12405  break;
12406  }
12407 
12408  case token_type::value_integer:
12409  {
12410  if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
12411  {
12412  return false;
12413  }
12414  break;
12415  }
12416 
12417  case token_type::value_string:
12418  {
12419  if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
12420  {
12421  return false;
12422  }
12423  break;
12424  }
12425 
12426  case token_type::value_unsigned:
12427  {
12428  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
12429  {
12430  return false;
12431  }
12432  break;
12433  }
12434 
12435  case token_type::parse_error:
12436  {
12437  // using "uninitialized" to avoid "expected" message
12438  return sax->parse_error(m_lexer.get_position(),
12439  m_lexer.get_token_string(),
12440  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
12441  }
12442 
12443  case token_type::uninitialized:
12444  case token_type::end_array:
12445  case token_type::end_object:
12446  case token_type::name_separator:
12447  case token_type::value_separator:
12448  case token_type::end_of_input:
12449  case token_type::literal_or_value:
12450  default: // the last token was unexpected
12451  {
12452  return sax->parse_error(m_lexer.get_position(),
12453  m_lexer.get_token_string(),
12454  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12455  }
12456  }
12457  }
12458  else
12459  {
12460  skip_to_state_evaluation = false;
12461  }
12462 
12463  // we reached this line after we successfully parsed a value
12464  if (states.empty())
12465  {
12466  // empty stack: we reached the end of the hierarchy: done
12467  return true;
12468  }
12469 
12470  if (states.back()) // array
12471  {
12472  // comma -> next value
12473  if (get_token() == token_type::value_separator)
12474  {
12475  // parse a new value
12476  get_token();
12477  continue;
12478  }
12479 
12480  // closing ]
12481  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
12482  {
12483  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12484  {
12485  return false;
12486  }
12487 
12488  // We are done with this array. Before we can parse a
12489  // new value, we need to evaluate the new state first.
12490  // By setting skip_to_state_evaluation to false, we
12491  // are effectively jumping to the beginning of this if.
12492  JSON_ASSERT(!states.empty());
12493  states.pop_back();
12494  skip_to_state_evaluation = true;
12495  continue;
12496  }
12497 
12498  return sax->parse_error(m_lexer.get_position(),
12499  m_lexer.get_token_string(),
12500  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
12501  }
12502 
12503  // states.back() is false -> object
12504 
12505  // comma -> next value
12506  if (get_token() == token_type::value_separator)
12507  {
12508  // parse key
12509  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
12510  {
12511  return sax->parse_error(m_lexer.get_position(),
12512  m_lexer.get_token_string(),
12513  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12514  }
12515 
12516  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12517  {
12518  return false;
12519  }
12520 
12521  // parse separator (:)
12522  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12523  {
12524  return sax->parse_error(m_lexer.get_position(),
12525  m_lexer.get_token_string(),
12526  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12527  }
12528 
12529  // parse values
12530  get_token();
12531  continue;
12532  }
12533 
12534  // closing }
12535  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
12536  {
12537  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12538  {
12539  return false;
12540  }
12541 
12542  // We are done with this object. Before we can parse a
12543  // new value, we need to evaluate the new state first.
12544  // By setting skip_to_state_evaluation to false, we
12545  // are effectively jumping to the beginning of this if.
12546  JSON_ASSERT(!states.empty());
12547  states.pop_back();
12548  skip_to_state_evaluation = true;
12549  continue;
12550  }
12551 
12552  return sax->parse_error(m_lexer.get_position(),
12553  m_lexer.get_token_string(),
12554  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
12555  }
12556  }
12557 
12559  token_type get_token()
12560  {
12561  return last_token = m_lexer.scan();
12562  }
12563 
12564  std::string exception_message(const token_type expected, const std::string& context)
12565  {
12566  std::string error_msg = "syntax error ";
12567 
12568  if (!context.empty())
12569  {
12570  error_msg += concat("while parsing ", context, ' ');
12571  }
12572 
12573  error_msg += "- ";
12574 
12575  if (last_token == token_type::parse_error)
12576  {
12577  error_msg += concat(m_lexer.get_error_message(), "; last read: '",
12578  m_lexer.get_token_string(), '\'');
12579  }
12580  else
12581  {
12582  error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
12583  }
12584 
12585  if (expected != token_type::uninitialized)
12586  {
12587  error_msg += concat("; expected ", lexer_t::token_type_name(expected));
12588  }
12589 
12590  return error_msg;
12591  }
12592 
12593  private:
12595  const parser_callback_t<BasicJsonType> callback = nullptr;
12597  token_type last_token = token_type::uninitialized;
12599  lexer_t m_lexer;
12601  const bool allow_exceptions = true;
12602 };
12603 
12604 } // namespace detail
12606 
12607 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
12608 // __ _____ _____ _____
12609 // __| | __| | | | JSON for Modern C++
12610 // | | |__ | | | | | | version 3.11.2
12611 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12612 //
12613 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12614 // SPDX-License-Identifier: MIT
12615 
12616 
12617 
12618 // #include <nlohmann/detail/abi_macros.hpp>
12619 
12620 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12621 // __ _____ _____ _____
12622 // __| | __| | | | JSON for Modern C++
12623 // | | |__ | | | | | | version 3.11.2
12624 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12625 //
12626 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12627 // SPDX-License-Identifier: MIT
12628 
12629 
12630 
12631 #include <cstddef> // ptrdiff_t
12632 #include <limits> // numeric_limits
12633 
12634 // #include <nlohmann/detail/macro_scope.hpp>
12635 
12636 
12638 namespace detail
12639 {
12640 
12641 /*
12642 @brief an iterator for primitive JSON types
12643 
12644 This class models an iterator for primitive JSON types (boolean, number,
12645 string). It's only purpose is to allow the iterator/const_iterator classes
12646 to "iterate" over primitive values. Internally, the iterator is modeled by
12647 a `difference_type` variable. Value begin_value (`0`) models the begin,
12648 end_value (`1`) models past the end.
12649 */
12651 {
12652  private:
12653  using difference_type = std::ptrdiff_t;
12654  static constexpr difference_type begin_value = 0;
12655  static constexpr difference_type end_value = begin_value + 1;
12656 
12659  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
12660 
12661  public:
12662  constexpr difference_type get_value() const noexcept
12663  {
12664  return m_it;
12665  }
12666 
12668  void set_begin() noexcept
12669  {
12670  m_it = begin_value;
12671  }
12672 
12674  void set_end() noexcept
12675  {
12676  m_it = end_value;
12677  }
12678 
12680  constexpr bool is_begin() const noexcept
12681  {
12682  return m_it == begin_value;
12683  }
12684 
12686  constexpr bool is_end() const noexcept
12687  {
12688  return m_it == end_value;
12689  }
12690 
12691  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12692  {
12693  return lhs.m_it == rhs.m_it;
12694  }
12695 
12696  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12697  {
12698  return lhs.m_it < rhs.m_it;
12699  }
12700 
12701  primitive_iterator_t operator+(difference_type n) noexcept
12702  {
12703  auto result = *this;
12704  result += n;
12705  return result;
12706  }
12707 
12708  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12709  {
12710  return lhs.m_it - rhs.m_it;
12711  }
12712 
12714  {
12715  ++m_it;
12716  return *this;
12717  }
12718 
12719  primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
12720  {
12721  auto result = *this;
12722  ++m_it;
12723  return result;
12724  }
12725 
12727  {
12728  --m_it;
12729  return *this;
12730  }
12731 
12732  primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
12733  {
12734  auto result = *this;
12735  --m_it;
12736  return result;
12737  }
12738 
12739  primitive_iterator_t& operator+=(difference_type n) noexcept
12740  {
12741  m_it += n;
12742  return *this;
12743  }
12744 
12745  primitive_iterator_t& operator-=(difference_type n) noexcept
12746  {
12747  m_it -= n;
12748  return *this;
12749  }
12750 };
12751 
12752 } // namespace detail
12754 
12755 
12757 namespace detail
12758 {
12759 
12766 template<typename BasicJsonType> struct internal_iterator
12767 {
12769  typename BasicJsonType::object_t::iterator object_iterator {};
12771  typename BasicJsonType::array_t::iterator array_iterator {};
12774 };
12775 
12776 } // namespace detail
12778 
12779 // #include <nlohmann/detail/iterators/iter_impl.hpp>
12780 // __ _____ _____ _____
12781 // __| | __| | | | JSON for Modern C++
12782 // | | |__ | | | | | | version 3.11.2
12783 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12784 //
12785 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12786 // SPDX-License-Identifier: MIT
12787 
12788 
12789 
12790 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12791 #include <type_traits> // conditional, is_const, remove_const
12792 
12793 // #include <nlohmann/detail/exceptions.hpp>
12794 
12795 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
12796 
12797 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12798 
12799 // #include <nlohmann/detail/macro_scope.hpp>
12800 
12801 // #include <nlohmann/detail/meta/cpp_future.hpp>
12802 
12803 // #include <nlohmann/detail/meta/type_traits.hpp>
12804 
12805 // #include <nlohmann/detail/value_t.hpp>
12806 
12807 
12809 namespace detail
12810 {
12811 
12812 // forward declare, to be able to friend it later on
12813 template<typename IteratorType> class iteration_proxy;
12814 template<typename IteratorType> class iteration_proxy_value;
12815 
12832 template<typename BasicJsonType>
12833 class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12834 {
12838  friend other_iter_impl;
12839  friend BasicJsonType;
12842 
12843  using object_t = typename BasicJsonType::object_t;
12844  using array_t = typename BasicJsonType::array_t;
12845  // make sure BasicJsonType is basic_json or const basic_json
12847  "iter_impl only accepts (const) basic_json");
12848  // superficial check for the LegacyBidirectionalIterator named requirement
12849  static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
12850  && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
12851  "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
12852 
12853  public:
12859  using iterator_category = std::bidirectional_iterator_tag;
12860 
12862  using value_type = typename BasicJsonType::value_type;
12864  using difference_type = typename BasicJsonType::difference_type;
12866  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12867  typename BasicJsonType::const_pointer,
12868  typename BasicJsonType::pointer>::type;
12870  using reference =
12871  typename std::conditional<std::is_const<BasicJsonType>::value,
12872  typename BasicJsonType::const_reference,
12873  typename BasicJsonType::reference>::type;
12874 
12875  iter_impl() = default;
12876  ~iter_impl() = default;
12877  iter_impl(iter_impl&&) noexcept = default;
12878  iter_impl& operator=(iter_impl&&) noexcept = default;
12879 
12886  explicit iter_impl(pointer object) noexcept : m_object(object)
12887  {
12888  JSON_ASSERT(m_object != nullptr);
12889 
12890  switch (m_object->m_type)
12891  {
12892  case value_t::object:
12893  {
12894  m_it.object_iterator = typename object_t::iterator();
12895  break;
12896  }
12897 
12898  case value_t::array:
12899  {
12900  m_it.array_iterator = typename array_t::iterator();
12901  break;
12902  }
12903 
12904  case value_t::null:
12905  case value_t::string:
12906  case value_t::boolean:
12909  case value_t::number_float:
12910  case value_t::binary:
12911  case value_t::discarded:
12912  default:
12913  {
12915  break;
12916  }
12917  }
12918  }
12919 
12937  : m_object(other.m_object), m_it(other.m_it)
12938  {}
12939 
12947  {
12948  if (&other != this)
12949  {
12950  m_object = other.m_object;
12951  m_it = other.m_it;
12952  }
12953  return *this;
12954  }
12955 
12962  : m_object(other.m_object), m_it(other.m_it)
12963  {}
12964 
12971  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
12972  {
12973  m_object = other.m_object;
12974  m_it = other.m_it;
12975  return *this;
12976  }
12977 
12983  void set_begin() noexcept
12984  {
12985  JSON_ASSERT(m_object != nullptr);
12986 
12987  switch (m_object->m_type)
12988  {
12989  case value_t::object:
12990  {
12991  m_it.object_iterator = m_object->m_value.object->begin();
12992  break;
12993  }
12994 
12995  case value_t::array:
12996  {
12997  m_it.array_iterator = m_object->m_value.array->begin();
12998  break;
12999  }
13000 
13001  case value_t::null:
13002  {
13003  // set to end so begin()==end() is true: null is empty
13005  break;
13006  }
13007 
13008  case value_t::string:
13009  case value_t::boolean:
13012  case value_t::number_float:
13013  case value_t::binary:
13014  case value_t::discarded:
13015  default:
13016  {
13018  break;
13019  }
13020  }
13021  }
13022 
13027  void set_end() noexcept
13028  {
13029  JSON_ASSERT(m_object != nullptr);
13030 
13031  switch (m_object->m_type)
13032  {
13033  case value_t::object:
13034  {
13035  m_it.object_iterator = m_object->m_value.object->end();
13036  break;
13037  }
13038 
13039  case value_t::array:
13040  {
13041  m_it.array_iterator = m_object->m_value.array->end();
13042  break;
13043  }
13044 
13045  case value_t::null:
13046  case value_t::string:
13047  case value_t::boolean:
13050  case value_t::number_float:
13051  case value_t::binary:
13052  case value_t::discarded:
13053  default:
13054  {
13056  break;
13057  }
13058  }
13059  }
13060 
13061  public:
13067  {
13068  JSON_ASSERT(m_object != nullptr);
13069 
13070  switch (m_object->m_type)
13071  {
13072  case value_t::object:
13073  {
13074  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
13075  return m_it.object_iterator->second;
13076  }
13077 
13078  case value_t::array:
13079  {
13080  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
13081  return *m_it.array_iterator;
13082  }
13083 
13084  case value_t::null:
13085  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13086 
13087  case value_t::string:
13088  case value_t::boolean:
13091  case value_t::number_float:
13092  case value_t::binary:
13093  case value_t::discarded:
13094  default:
13095  {
13097  {
13098  return *m_object;
13099  }
13100 
13101  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13102  }
13103  }
13104  }
13105 
13111  {
13112  JSON_ASSERT(m_object != nullptr);
13113 
13114  switch (m_object->m_type)
13115  {
13116  case value_t::object:
13117  {
13118  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
13119  return &(m_it.object_iterator->second);
13120  }
13121 
13122  case value_t::array:
13123  {
13124  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
13125  return &*m_it.array_iterator;
13126  }
13127 
13128  case value_t::null:
13129  case value_t::string:
13130  case value_t::boolean:
13133  case value_t::number_float:
13134  case value_t::binary:
13135  case value_t::discarded:
13136  default:
13137  {
13139  {
13140  return m_object;
13141  }
13142 
13143  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13144  }
13145  }
13146  }
13147 
13152  iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
13153  {
13154  auto result = *this;
13155  ++(*this);
13156  return result;
13157  }
13158 
13164  {
13165  JSON_ASSERT(m_object != nullptr);
13166 
13167  switch (m_object->m_type)
13168  {
13169  case value_t::object:
13170  {
13171  std::advance(m_it.object_iterator, 1);
13172  break;
13173  }
13174 
13175  case value_t::array:
13176  {
13177  std::advance(m_it.array_iterator, 1);
13178  break;
13179  }
13180 
13181  case value_t::null:
13182  case value_t::string:
13183  case value_t::boolean:
13186  case value_t::number_float:
13187  case value_t::binary:
13188  case value_t::discarded:
13189  default:
13190  {
13192  break;
13193  }
13194  }
13195 
13196  return *this;
13197  }
13198 
13203  iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
13204  {
13205  auto result = *this;
13206  --(*this);
13207  return result;
13208  }
13209 
13215  {
13216  JSON_ASSERT(m_object != nullptr);
13217 
13218  switch (m_object->m_type)
13219  {
13220  case value_t::object:
13221  {
13222  std::advance(m_it.object_iterator, -1);
13223  break;
13224  }
13225 
13226  case value_t::array:
13227  {
13228  std::advance(m_it.array_iterator, -1);
13229  break;
13230  }
13231 
13232  case value_t::null:
13233  case value_t::string:
13234  case value_t::boolean:
13237  case value_t::number_float:
13238  case value_t::binary:
13239  case value_t::discarded:
13240  default:
13241  {
13243  break;
13244  }
13245  }
13246 
13247  return *this;
13248  }
13249 
13254  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 >
13255  bool operator==(const IterImpl& other) const
13256  {
13257  // if objects are not the same, the comparison is undefined
13258  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13259  {
13260  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13261  }
13262 
13263  JSON_ASSERT(m_object != nullptr);
13264 
13265  switch (m_object->m_type)
13266  {
13267  case value_t::object:
13268  return (m_it.object_iterator == other.m_it.object_iterator);
13269 
13270  case value_t::array:
13271  return (m_it.array_iterator == other.m_it.array_iterator);
13272 
13273  case value_t::null:
13274  case value_t::string:
13275  case value_t::boolean:
13278  case value_t::number_float:
13279  case value_t::binary:
13280  case value_t::discarded:
13281  default:
13282  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
13283  }
13284  }
13285 
13290  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 >
13291  bool operator!=(const IterImpl& other) const
13292  {
13293  return !operator==(other);
13294  }
13295 
13300  bool operator<(const iter_impl& other) const
13301  {
13302  // if objects are not the same, the comparison is undefined
13303  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13304  {
13305  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13306  }
13307 
13308  JSON_ASSERT(m_object != nullptr);
13309 
13310  switch (m_object->m_type)
13311  {
13312  case value_t::object:
13313  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
13314 
13315  case value_t::array:
13316  return (m_it.array_iterator < other.m_it.array_iterator);
13317 
13318  case value_t::null:
13319  case value_t::string:
13320  case value_t::boolean:
13323  case value_t::number_float:
13324  case value_t::binary:
13325  case value_t::discarded:
13326  default:
13328  }
13329  }
13330 
13335  bool operator<=(const iter_impl& other) const
13336  {
13337  return !other.operator < (*this);
13338  }
13339 
13344  bool operator>(const iter_impl& other) const
13345  {
13346  return !operator<=(other);
13347  }
13348 
13353  bool operator>=(const iter_impl& other) const
13354  {
13355  return !operator<(other);
13356  }
13357 
13363  {
13364  JSON_ASSERT(m_object != nullptr);
13365 
13366  switch (m_object->m_type)
13367  {
13368  case value_t::object:
13369  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13370 
13371  case value_t::array:
13372  {
13373  std::advance(m_it.array_iterator, i);
13374  break;
13375  }
13376 
13377  case value_t::null:
13378  case value_t::string:
13379  case value_t::boolean:
13382  case value_t::number_float:
13383  case value_t::binary:
13384  case value_t::discarded:
13385  default:
13386  {
13387  m_it.primitive_iterator += i;
13388  break;
13389  }
13390  }
13391 
13392  return *this;
13393  }
13394 
13400  {
13401  return operator+=(-i);
13402  }
13403 
13409  {
13410  auto result = *this;
13411  result += i;
13412  return result;
13413  }
13414 
13420  {
13421  auto result = it;
13422  result += i;
13423  return result;
13424  }
13425 
13431  {
13432  auto result = *this;
13433  result -= i;
13434  return result;
13435  }
13436 
13442  {
13443  JSON_ASSERT(m_object != nullptr);
13444 
13445  switch (m_object->m_type)
13446  {
13447  case value_t::object:
13448  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13449 
13450  case value_t::array:
13451  return m_it.array_iterator - other.m_it.array_iterator;
13452 
13453  case value_t::null:
13454  case value_t::string:
13455  case value_t::boolean:
13458  case value_t::number_float:
13459  case value_t::binary:
13460  case value_t::discarded:
13461  default:
13463  }
13464  }
13465 
13471  {
13472  JSON_ASSERT(m_object != nullptr);
13473 
13474  switch (m_object->m_type)
13475  {
13476  case value_t::object:
13477  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
13478 
13479  case value_t::array:
13480  return *std::next(m_it.array_iterator, n);
13481 
13482  case value_t::null:
13483  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13484 
13485  case value_t::string:
13486  case value_t::boolean:
13489  case value_t::number_float:
13490  case value_t::binary:
13491  case value_t::discarded:
13492  default:
13493  {
13495  {
13496  return *m_object;
13497  }
13498 
13499  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13500  }
13501  }
13502  }
13503 
13508  const typename object_t::key_type& key() const
13509  {
13510  JSON_ASSERT(m_object != nullptr);
13511 
13512  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
13513  {
13514  return m_it.object_iterator->first;
13515  }
13516 
13517  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
13518  }
13519 
13525  {
13526  return operator*();
13527  }
13528 
13531  pointer m_object = nullptr;
13534 };
13535 
13536 } // namespace detail
13538 
13539 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
13540 
13541 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
13542 // __ _____ _____ _____
13543 // __| | __| | | | JSON for Modern C++
13544 // | | |__ | | | | | | version 3.11.2
13545 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13546 //
13547 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
13548 // SPDX-License-Identifier: MIT
13549 
13550 
13551 
13552 #include <cstddef> // ptrdiff_t
13553 #include <iterator> // reverse_iterator
13554 #include <utility> // declval
13555 
13556 // #include <nlohmann/detail/abi_macros.hpp>
13557 
13558 
13560 namespace detail
13561 {
13562 
13564 // reverse_iterator //
13566 
13585 template<typename Base>
13586 class json_reverse_iterator : public std::reverse_iterator<Base>
13587 {
13588  public:
13589  using difference_type = std::ptrdiff_t;
13591  using base_iterator = std::reverse_iterator<Base>;
13593  using reference = typename Base::reference;
13594 
13596  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
13597  : base_iterator(it) {}
13598 
13600  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
13601 
13603  json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
13604  {
13605  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
13606  }
13607 
13610  {
13611  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
13612  }
13613 
13615  json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
13616  {
13617  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
13618  }
13619 
13622  {
13623  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
13624  }
13625 
13628  {
13629  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
13630  }
13631 
13634  {
13635  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
13636  }
13637 
13640  {
13641  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
13642  }
13643 
13646  {
13647  return base_iterator(*this) - base_iterator(other);
13648  }
13649 
13652  {
13653  return *(this->operator+(n));
13654  }
13655 
13657  auto key() const -> decltype(std::declval<Base>().key())
13658  {
13659  auto it = --this->base();
13660  return it.key();
13661  }
13662 
13665  {
13666  auto it = --this->base();
13667  return it.operator * ();
13668  }
13669 };
13670 
13671 } // namespace detail
13673 
13674 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13675 
13676 // #include <nlohmann/detail/json_pointer.hpp>
13677 // __ _____ _____ _____
13678 // __| | __| | | | JSON for Modern C++
13679 // | | |__ | | | | | | version 3.11.2
13680 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13681 //
13682 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
13683 // SPDX-License-Identifier: MIT
13684 
13685 
13686 
13687 #include <algorithm> // all_of
13688 #include <cctype> // isdigit
13689 #include <cerrno> // errno, ERANGE
13690 #include <cstdlib> // strtoull
13691 #ifndef JSON_NO_IO
13692  #include <iosfwd> // ostream
13693 #endif // JSON_NO_IO
13694 #include <limits> // max
13695 #include <numeric> // accumulate
13696 #include <string> // string
13697 #include <utility> // move
13698 #include <vector> // vector
13699 
13700 // #include <nlohmann/detail/exceptions.hpp>
13701 
13702 // #include <nlohmann/detail/macro_scope.hpp>
13703 
13704 // #include <nlohmann/detail/string_concat.hpp>
13705 
13706 // #include <nlohmann/detail/string_escape.hpp>
13707 
13708 // #include <nlohmann/detail/value_t.hpp>
13709 
13710 
13712 
13715 template<typename RefStringType>
13716 class json_pointer
13717 {
13718  // allow basic_json to access private members
13720  friend class basic_json;
13721 
13722  template<typename>
13723  friend class json_pointer;
13724 
13725  template<typename T>
13726  struct string_t_helper
13727  {
13728  using type = T;
13729  };
13730 
13732  struct string_t_helper<NLOHMANN_BASIC_JSON_TPL>
13733  {
13734  using type = StringType;
13735  };
13736 
13737  public:
13738  // for backwards compatibility accept BasicJsonType
13739  using string_t = typename string_t_helper<RefStringType>::type;
13740 
13743  explicit json_pointer(const string_t& s = "")
13744  : reference_tokens(split(s))
13745  {}
13746 
13750  {
13751  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
13752  string_t{},
13753  [](const string_t& a, const string_t& b)
13754  {
13755  return detail::concat(a, '/', detail::escape(b));
13756  });
13757  }
13758 
13762  operator string_t() const
13763  {
13764  return to_string();
13765  }
13766 
13767 #ifndef JSON_NO_IO
13768  friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
13771  {
13772  o << ptr.to_string();
13773  return o;
13774  }
13775 #endif
13776 
13780  {
13781  reference_tokens.insert(reference_tokens.end(),
13782  ptr.reference_tokens.begin(),
13783  ptr.reference_tokens.end());
13784  return *this;
13785  }
13786 
13790  {
13791  push_back(std::move(token));
13792  return *this;
13793  }
13794 
13797  json_pointer& operator/=(std::size_t array_idx)
13798  {
13799  return *this /= std::to_string(array_idx);
13800  }
13801 
13805  const json_pointer& rhs)
13806  {
13807  return json_pointer(lhs) /= rhs;
13808  }
13809 
13812  friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
13813  {
13814  return json_pointer(lhs) /= std::move(token);
13815  }
13816 
13819  friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13820  {
13821  return json_pointer(lhs) /= array_idx;
13822  }
13823 
13827  {
13828  if (empty())
13829  {
13830  return *this;
13831  }
13832 
13833  json_pointer res = *this;
13834  res.pop_back();
13835  return res;
13836  }
13837 
13840  void pop_back()
13841  {
13842  if (JSON_HEDLEY_UNLIKELY(empty()))
13843  {
13844  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13845  }
13846 
13847  reference_tokens.pop_back();
13848  }
13849 
13852  const string_t& back() const
13853  {
13854  if (JSON_HEDLEY_UNLIKELY(empty()))
13855  {
13856  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13857  }
13858 
13859  return reference_tokens.back();
13860  }
13861 
13864  void push_back(const string_t& token)
13865  {
13866  reference_tokens.push_back(token);
13867  }
13868 
13871  void push_back(string_t&& token)
13872  {
13873  reference_tokens.push_back(std::move(token));
13874  }
13875 
13878  bool empty() const noexcept
13879  {
13880  return reference_tokens.empty();
13881  }
13882 
13883  private:
13894  template<typename BasicJsonType>
13895  static typename BasicJsonType::size_type array_index(const string_t& s)
13896  {
13897  using size_type = typename BasicJsonType::size_type;
13898 
13899  // error condition (cf. RFC 6901, Sect. 4)
13900  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
13901  {
13902  JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
13903  }
13904 
13905  // error condition (cf. RFC 6901, Sect. 4)
13906  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
13907  {
13908  JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
13909  }
13910 
13911  const char* p = s.c_str();
13912  char* p_end = nullptr;
13913  errno = 0; // strtoull doesn't reset errno
13914  unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
13915  if (p == p_end // invalid input or empty string
13916  || errno == ERANGE // out of range
13917  || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
13918  {
13919  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
13920  }
13921 
13922  // only triggered on special platforms (like 32bit), see also
13923  // https://github.com/nlohmann/json/pull/2203
13924  if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
13925  {
13926  JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
13927  }
13928 
13929  return static_cast<size_type>(res);
13930  }
13931 
13933  json_pointer top() const
13934  {
13935  if (JSON_HEDLEY_UNLIKELY(empty()))
13936  {
13937  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13938  }
13939 
13940  json_pointer result = *this;
13941  result.reference_tokens = {reference_tokens[0]};
13942  return result;
13943  }
13944 
13945  private:
13954  template<typename BasicJsonType>
13955  BasicJsonType& get_and_create(BasicJsonType& j) const
13956  {
13957  auto* result = &j;
13958 
13959  // in case no reference tokens exist, return a reference to the JSON value
13960  // j which will be overwritten by a primitive value
13961  for (const auto& reference_token : reference_tokens)
13962  {
13963  switch (result->type())
13964  {
13965  case detail::value_t::null:
13966  {
13967  if (reference_token == "0")
13968  {
13969  // start a new array if reference token is 0
13970  result = &result->operator[](0);
13971  }
13972  else
13973  {
13974  // start a new object otherwise
13975  result = &result->operator[](reference_token);
13976  }
13977  break;
13978  }
13979 
13981  {
13982  // create an entry in the object
13983  result = &result->operator[](reference_token);
13984  break;
13985  }
13986 
13988  {
13989  // create an entry in the array
13990  result = &result->operator[](array_index<BasicJsonType>(reference_token));
13991  break;
13992  }
13993 
13994  /*
13995  The following code is only reached if there exists a reference
13996  token _and_ the current value is primitive. In this case, we have
13997  an error situation, because primitive values may only occur as
13998  single value; that is, with an empty list of reference tokens.
13999  */
14007  default:
14008  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
14009  }
14010  }
14011 
14012  return *result;
14013  }
14014 
14034  template<typename BasicJsonType>
14035  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
14036  {
14037  for (const auto& reference_token : reference_tokens)
14038  {
14039  // convert null values to arrays or objects before continuing
14040  if (ptr->is_null())
14041  {
14042  // check if reference token is a number
14043  const bool nums =
14044  std::all_of(reference_token.begin(), reference_token.end(),
14045  [](const unsigned char x)
14046  {
14047  return std::isdigit(x);
14048  });
14049 
14050  // change value to array for numbers or "-" or to object otherwise
14051  *ptr = (nums || reference_token == "-")
14054  }
14055 
14056  switch (ptr->type())
14057  {
14059  {
14060  // use unchecked object access
14061  ptr = &ptr->operator[](reference_token);
14062  break;
14063  }
14064 
14066  {
14067  if (reference_token == "-")
14068  {
14069  // explicitly treat "-" as index beyond the end
14070  ptr = &ptr->operator[](ptr->m_value.array->size());
14071  }
14072  else
14073  {
14074  // convert array index to number; unchecked access
14075  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14076  }
14077  break;
14078  }
14079 
14080  case detail::value_t::null:
14088  default:
14089  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14090  }
14091  }
14092 
14093  return *ptr;
14094  }
14095 
14102  template<typename BasicJsonType>
14103  BasicJsonType& get_checked(BasicJsonType* ptr) const
14104  {
14105  for (const auto& reference_token : reference_tokens)
14106  {
14107  switch (ptr->type())
14108  {
14110  {
14111  // note: at performs range check
14112  ptr = &ptr->at(reference_token);
14113  break;
14114  }
14115 
14117  {
14118  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14119  {
14120  // "-" always fails the range check
14122  "array index '-' (", std::to_string(ptr->m_value.array->size()),
14123  ") is out of range"), ptr));
14124  }
14125 
14126  // note: at performs range check
14127  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14128  break;
14129  }
14130 
14131  case detail::value_t::null:
14139  default:
14140  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14141  }
14142  }
14143 
14144  return *ptr;
14145  }
14146 
14160  template<typename BasicJsonType>
14161  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
14162  {
14163  for (const auto& reference_token : reference_tokens)
14164  {
14165  switch (ptr->type())
14166  {
14168  {
14169  // use unchecked object access
14170  ptr = &ptr->operator[](reference_token);
14171  break;
14172  }
14173 
14175  {
14176  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14177  {
14178  // "-" cannot be used for const access
14179  JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_value.array->size()), ") is out of range"), ptr));
14180  }
14181 
14182  // use unchecked array access
14183  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14184  break;
14185  }
14186 
14187  case detail::value_t::null:
14195  default:
14196  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14197  }
14198  }
14199 
14200  return *ptr;
14201  }
14202 
14209  template<typename BasicJsonType>
14210  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
14211  {
14212  for (const auto& reference_token : reference_tokens)
14213  {
14214  switch (ptr->type())
14215  {
14217  {
14218  // note: at performs range check
14219  ptr = &ptr->at(reference_token);
14220  break;
14221  }
14222 
14224  {
14225  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14226  {
14227  // "-" always fails the range check
14229  "array index '-' (", std::to_string(ptr->m_value.array->size()),
14230  ") is out of range"), ptr));
14231  }
14232 
14233  // note: at performs range check
14234  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14235  break;
14236  }
14237 
14238  case detail::value_t::null:
14246  default:
14247  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14248  }
14249  }
14250 
14251  return *ptr;
14252  }
14253 
14258  template<typename BasicJsonType>
14259  bool contains(const BasicJsonType* ptr) const
14260  {
14261  for (const auto& reference_token : reference_tokens)
14262  {
14263  switch (ptr->type())
14264  {
14266  {
14267  if (!ptr->contains(reference_token))
14268  {
14269  // we did not find the key in the object
14270  return false;
14271  }
14272 
14273  ptr = &ptr->operator[](reference_token);
14274  break;
14275  }
14276 
14278  {
14279  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14280  {
14281  // "-" always fails the range check
14282  return false;
14283  }
14284  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
14285  {
14286  // invalid char
14287  return false;
14288  }
14289  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
14290  {
14291  if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
14292  {
14293  // first char should be between '1' and '9'
14294  return false;
14295  }
14296  for (std::size_t i = 1; i < reference_token.size(); i++)
14297  {
14298  if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
14299  {
14300  // other char should be between '0' and '9'
14301  return false;
14302  }
14303  }
14304  }
14305 
14306  const auto idx = array_index<BasicJsonType>(reference_token);
14307  if (idx >= ptr->size())
14308  {
14309  // index out of range
14310  return false;
14311  }
14312 
14313  ptr = &ptr->operator[](idx);
14314  break;
14315  }
14316 
14317  case detail::value_t::null:
14325  default:
14326  {
14327  // we do not expect primitive values if there is still a
14328  // reference token to process
14329  return false;
14330  }
14331  }
14332  }
14333 
14334  // no reference token left means we found a primitive value
14335  return true;
14336  }
14337 
14347  static std::vector<string_t> split(const string_t& reference_string)
14348  {
14349  std::vector<string_t> result;
14350 
14351  // special case: empty reference string -> no reference tokens
14352  if (reference_string.empty())
14353  {
14354  return result;
14355  }
14356 
14357  // check if nonempty reference string begins with slash
14358  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
14359  {
14360  JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
14361  }
14362 
14363  // extract the reference tokens:
14364  // - slash: position of the last read slash (or end of string)
14365  // - start: position after the previous slash
14366  for (
14367  // search for the first slash after the first character
14368  std::size_t slash = reference_string.find_first_of('/', 1),
14369  // set the beginning of the first reference token
14370  start = 1;
14371  // we can stop if start == 0 (if slash == string_t::npos)
14372  start != 0;
14373  // set the beginning of the next reference token
14374  // (will eventually be 0 if slash == string_t::npos)
14375  start = (slash == string_t::npos) ? 0 : slash + 1,
14376  // find next slash
14377  slash = reference_string.find_first_of('/', start))
14378  {
14379  // use the text between the beginning of the reference token
14380  // (start) and the last slash (slash).
14381  auto reference_token = reference_string.substr(start, slash - start);
14382 
14383  // check reference tokens are properly escaped
14384  for (std::size_t pos = reference_token.find_first_of('~');
14385  pos != string_t::npos;
14386  pos = reference_token.find_first_of('~', pos + 1))
14387  {
14388  JSON_ASSERT(reference_token[pos] == '~');
14389 
14390  // ~ must be followed by 0 or 1
14391  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
14392  (reference_token[pos + 1] != '0' &&
14393  reference_token[pos + 1] != '1')))
14394  {
14395  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
14396  }
14397  }
14398 
14399  // finally, store the reference token
14400  detail::unescape(reference_token);
14401  result.push_back(reference_token);
14402  }
14403 
14404  return result;
14405  }
14406 
14407  private:
14415  template<typename BasicJsonType>
14416  static void flatten(const string_t& reference_string,
14417  const BasicJsonType& value,
14418  BasicJsonType& result)
14419  {
14420  switch (value.type())
14421  {
14423  {
14424  if (value.m_value.array->empty())
14425  {
14426  // flatten empty array as null
14427  result[reference_string] = nullptr;
14428  }
14429  else
14430  {
14431  // iterate array and use index as reference string
14432  for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
14433  {
14434  flatten(detail::concat(reference_string, '/', std::to_string(i)),
14435  value.m_value.array->operator[](i), result);
14436  }
14437  }
14438  break;
14439  }
14440 
14442  {
14443  if (value.m_value.object->empty())
14444  {
14445  // flatten empty object as null
14446  result[reference_string] = nullptr;
14447  }
14448  else
14449  {
14450  // iterate object and use keys as reference string
14451  for (const auto& element : *value.m_value.object)
14452  {
14453  flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
14454  }
14455  }
14456  break;
14457  }
14458 
14459  case detail::value_t::null:
14467  default:
14468  {
14469  // add primitive value with its reference string
14470  result[reference_string] = value;
14471  break;
14472  }
14473  }
14474  }
14475 
14486  template<typename BasicJsonType>
14487  static BasicJsonType
14488  unflatten(const BasicJsonType& value)
14489  {
14490  if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
14491  {
14492  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
14493  }
14494 
14495  BasicJsonType result;
14496 
14497  // iterate the JSON object values
14498  for (const auto& element : *value.m_value.object)
14499  {
14500  if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
14501  {
14502  JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
14503  }
14504 
14505  // assign value to reference pointed to by JSON pointer; Note that if
14506  // the JSON pointer is "" (i.e., points to the whole value), function
14507  // get_and_create returns a reference to result itself. An assignment
14508  // will then create a primitive value.
14509  json_pointer(element.first).get_and_create(result) = element.second;
14510  }
14511 
14512  return result;
14513  }
14514 
14515  // can't use conversion operator because of ambiguity
14516  json_pointer<string_t> convert() const&
14517  {
14518  json_pointer<string_t> result;
14519  result.reference_tokens = reference_tokens;
14520  return result;
14521  }
14522 
14523  json_pointer<string_t> convert()&&
14524  {
14525  json_pointer<string_t> result;
14526  result.reference_tokens = std::move(reference_tokens);
14527  return result;
14528  }
14529 
14530  public:
14531 #if JSON_HAS_THREE_WAY_COMPARISON
14532  template<typename RefStringTypeRhs>
14535  bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept
14536  {
14537  return reference_tokens == rhs.reference_tokens;
14538  }
14539 
14542  JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))
14543  bool operator==(const string_t& rhs) const
14544  {
14545  return *this == json_pointer(rhs);
14546  }
14547 
14549  template<typename RefStringTypeRhs>
14550  std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
14551  {
14552  return reference_tokens <=> rhs.reference_tokens; // *NOPAD*
14553  }
14554 #else
14555  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14558  // NOLINTNEXTLINE(readability-redundant-declaration)
14559  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14560  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14561 
14564  template<typename RefStringTypeLhs, typename StringType>
14565  // NOLINTNEXTLINE(readability-redundant-declaration)
14566  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14567  const StringType& rhs);
14568 
14571  template<typename RefStringTypeRhs, typename StringType>
14572  // NOLINTNEXTLINE(readability-redundant-declaration)
14573  friend bool operator==(const StringType& lhs,
14574  const json_pointer<RefStringTypeRhs>& rhs);
14575 
14578  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14579  // NOLINTNEXTLINE(readability-redundant-declaration)
14580  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14581  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14582 
14585  template<typename RefStringTypeLhs, typename StringType>
14586  // NOLINTNEXTLINE(readability-redundant-declaration)
14587  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14588  const StringType& rhs);
14589 
14592  template<typename RefStringTypeRhs, typename StringType>
14593  // NOLINTNEXTLINE(readability-redundant-declaration)
14594  friend bool operator!=(const StringType& lhs,
14595  const json_pointer<RefStringTypeRhs>& rhs);
14596 
14598  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14599  // NOLINTNEXTLINE(readability-redundant-declaration)
14600  friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
14601  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14602 #endif
14603 
14604  private:
14606  std::vector<string_t> reference_tokens;
14607 };
14608 
14609 #if !JSON_HAS_THREE_WAY_COMPARISON
14610 // functions cannot be defined inside class due to ODR violations
14611 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14613  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14614 {
14615  return lhs.reference_tokens == rhs.reference_tokens;
14616 }
14617 
14618 template<typename RefStringTypeLhs,
14619  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14621 inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14622  const StringType& rhs)
14623 {
14624  return lhs == json_pointer<RefStringTypeLhs>(rhs);
14625 }
14626 
14627 template<typename RefStringTypeRhs,
14628  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14630 inline bool operator==(const StringType& lhs,
14631  const json_pointer<RefStringTypeRhs>& rhs)
14632 {
14633  return json_pointer<RefStringTypeRhs>(lhs) == rhs;
14634 }
14635 
14636 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14638  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14639 {
14640  return !(lhs == rhs);
14641 }
14642 
14643 template<typename RefStringTypeLhs,
14644  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14646 inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14647  const StringType& rhs)
14648 {
14649  return !(lhs == rhs);
14650 }
14651 
14652 template<typename RefStringTypeRhs,
14653  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14655 inline bool operator!=(const StringType& lhs,
14656  const json_pointer<RefStringTypeRhs>& rhs)
14657 {
14658  return !(lhs == rhs);
14659 }
14660 
14661 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14663  const json_pointer<RefStringTypeRhs>& rhs) noexcept
14664 {
14665  return lhs.reference_tokens < rhs.reference_tokens;
14666 }
14667 #endif
14668 
14670 
14671 // #include <nlohmann/detail/json_ref.hpp>
14672 // __ _____ _____ _____
14673 // __| | __| | | | JSON for Modern C++
14674 // | | |__ | | | | | | version 3.11.2
14675 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14676 //
14677 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14678 // SPDX-License-Identifier: MIT
14679 
14680 
14681 
14682 #include <initializer_list>
14683 #include <utility>
14684 
14685 // #include <nlohmann/detail/abi_macros.hpp>
14686 
14687 // #include <nlohmann/detail/meta/type_traits.hpp>
14688 
14689 
14691 namespace detail
14692 {
14693 
14694 template<typename BasicJsonType>
14695 class json_ref
14696 {
14697  public:
14698  using value_type = BasicJsonType;
14699 
14701  : owned_value(std::move(value))
14702  {}
14703 
14704  json_ref(const value_type& value)
14705  : value_ref(&value)
14706  {}
14707 
14708  json_ref(std::initializer_list<json_ref> init)
14709  : owned_value(init)
14710  {}
14711 
14712  template <
14713  class... Args,
14714  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
14715  json_ref(Args && ... args)
14716  : owned_value(std::forward<Args>(args)...)
14717  {}
14718 
14719  // class should be movable only
14720  json_ref(json_ref&&) noexcept = default;
14721  json_ref(const json_ref&) = delete;
14722  json_ref& operator=(const json_ref&) = delete;
14723  json_ref& operator=(json_ref&&) = delete;
14724  ~json_ref() = default;
14725 
14727  {
14728  if (value_ref == nullptr)
14729  {
14730  return std::move(owned_value);
14731  }
14732  return *value_ref;
14733  }
14734 
14735  value_type const& operator*() const
14736  {
14737  return value_ref ? *value_ref : owned_value;
14738  }
14739 
14740  value_type const* operator->() const
14741  {
14742  return &** this;
14743  }
14744 
14745  private:
14746  mutable value_type owned_value = nullptr;
14747  value_type const* value_ref = nullptr;
14748 };
14749 
14750 } // namespace detail
14752 
14753 // #include <nlohmann/detail/macro_scope.hpp>
14754 
14755 // #include <nlohmann/detail/string_concat.hpp>
14756 
14757 // #include <nlohmann/detail/string_escape.hpp>
14758 
14759 // #include <nlohmann/detail/meta/cpp_future.hpp>
14760 
14761 // #include <nlohmann/detail/meta/type_traits.hpp>
14762 
14763 // #include <nlohmann/detail/output/binary_writer.hpp>
14764 // __ _____ _____ _____
14765 // __| | __| | | | JSON for Modern C++
14766 // | | |__ | | | | | | version 3.11.2
14767 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14768 //
14769 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14770 // SPDX-License-Identifier: MIT
14771 
14772 
14773 
14774 #include <algorithm> // reverse
14775 #include <array> // array
14776 #include <map> // map
14777 #include <cmath> // isnan, isinf
14778 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
14779 #include <cstring> // memcpy
14780 #include <limits> // numeric_limits
14781 #include <string> // string
14782 #include <utility> // move
14783 #include <vector> // vector
14784 
14785 // #include <nlohmann/detail/input/binary_reader.hpp>
14786 
14787 // #include <nlohmann/detail/macro_scope.hpp>
14788 
14789 // #include <nlohmann/detail/output/output_adapters.hpp>
14790 // __ _____ _____ _____
14791 // __| | __| | | | JSON for Modern C++
14792 // | | |__ | | | | | | version 3.11.2
14793 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14794 //
14795 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14796 // SPDX-License-Identifier: MIT
14797 
14798 
14799 
14800 #include <algorithm> // copy
14801 #include <cstddef> // size_t
14802 #include <iterator> // back_inserter
14803 #include <memory> // shared_ptr, make_shared
14804 #include <string> // basic_string
14805 #include <vector> // vector
14806 
14807 #ifndef JSON_NO_IO
14808  #include <ios> // streamsize
14809  #include <ostream> // basic_ostream
14810 #endif // JSON_NO_IO
14811 
14812 // #include <nlohmann/detail/macro_scope.hpp>
14813 
14814 
14816 namespace detail
14817 {
14818 
14820 template<typename CharType> struct output_adapter_protocol
14821 {
14822  virtual void write_character(CharType c) = 0;
14823  virtual void write_characters(const CharType* s, std::size_t length) = 0;
14824  virtual ~output_adapter_protocol() = default;
14825 
14826  output_adapter_protocol() = default;
14828  output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
14829  output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
14830  output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
14831 };
14832 
14834 template<typename CharType>
14835 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
14836 
14838 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
14840 {
14841  public:
14842  explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
14843  : v(vec)
14844  {}
14845 
14846  void write_character(CharType c) override
14847  {
14848  v.push_back(c);
14849  }
14850 
14852  void write_characters(const CharType* s, std::size_t length) override
14853  {
14854  v.insert(v.end(), s, s + length);
14855  }
14856 
14857  private:
14858  std::vector<CharType, AllocatorType>& v;
14859 };
14860 
14861 #ifndef JSON_NO_IO
14862 template<typename CharType>
14865 {
14866  public:
14867  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
14868  : stream(s)
14869  {}
14870 
14871  void write_character(CharType c) override
14872  {
14873  stream.put(c);
14874  }
14875 
14877  void write_characters(const CharType* s, std::size_t length) override
14878  {
14879  stream.write(s, static_cast<std::streamsize>(length));
14880  }
14881 
14882  private:
14883  std::basic_ostream<CharType>& stream;
14884 };
14885 #endif // JSON_NO_IO
14886 
14888 template<typename CharType, typename StringType = std::basic_string<CharType>>
14890 {
14891  public:
14892  explicit output_string_adapter(StringType& s) noexcept
14893  : str(s)
14894  {}
14895 
14896  void write_character(CharType c) override
14897  {
14898  str.push_back(c);
14899  }
14900 
14902  void write_characters(const CharType* s, std::size_t length) override
14903  {
14904  str.append(s, length);
14905  }
14906 
14907  private:
14908  StringType& str;
14909 };
14910 
14911 template<typename CharType, typename StringType = std::basic_string<CharType>>
14913 {
14914  public:
14915  template<typename AllocatorType = std::allocator<CharType>>
14916  output_adapter(std::vector<CharType, AllocatorType>& vec)
14917  : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
14918 
14919 #ifndef JSON_NO_IO
14920  output_adapter(std::basic_ostream<CharType>& s)
14921  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
14922 #endif // JSON_NO_IO
14923 
14924  output_adapter(StringType& s)
14925  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
14926 
14928  {
14929  return oa;
14930  }
14931 
14932  private:
14933  output_adapter_t<CharType> oa = nullptr;
14934 };
14935 
14936 } // namespace detail
14938 
14939 // #include <nlohmann/detail/string_concat.hpp>
14940 
14941 
14943 namespace detail
14944 {
14945 
14947 // binary writer //
14949 
14953 template<typename BasicJsonType, typename CharType>
14955 {
14956  using string_t = typename BasicJsonType::string_t;
14957  using binary_t = typename BasicJsonType::binary_t;
14958  using number_float_t = typename BasicJsonType::number_float_t;
14959 
14960  public:
14966  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
14967  {
14968  JSON_ASSERT(oa);
14969  }
14970 
14975  void write_bson(const BasicJsonType& j)
14976  {
14977  switch (j.type())
14978  {
14979  case value_t::object:
14980  {
14981  write_bson_object(*j.m_value.object);
14982  break;
14983  }
14984 
14985  case value_t::null:
14986  case value_t::array:
14987  case value_t::string:
14988  case value_t::boolean:
14991  case value_t::number_float:
14992  case value_t::binary:
14993  case value_t::discarded:
14994  default:
14995  {
14996  JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
14997  }
14998  }
14999  }
15000 
15004  void write_cbor(const BasicJsonType& j)
15005  {
15006  switch (j.type())
15007  {
15008  case value_t::null:
15009  {
15010  oa->write_character(to_char_type(0xF6));
15011  break;
15012  }
15013 
15014  case value_t::boolean:
15015  {
15016  oa->write_character(j.m_value.boolean
15017  ? to_char_type(0xF5)
15018  : to_char_type(0xF4));
15019  break;
15020  }
15021 
15023  {
15024  if (j.m_value.number_integer >= 0)
15025  {
15026  // CBOR does not differentiate between positive signed
15027  // integers and unsigned integers. Therefore, we used the
15028  // code from the value_t::number_unsigned case here.
15029  if (j.m_value.number_integer <= 0x17)
15030  {
15031  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15032  }
15033  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15034  {
15035  oa->write_character(to_char_type(0x18));
15036  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15037  }
15038  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
15039  {
15040  oa->write_character(to_char_type(0x19));
15041  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
15042  }
15043  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
15044  {
15045  oa->write_character(to_char_type(0x1A));
15046  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
15047  }
15048  else
15049  {
15050  oa->write_character(to_char_type(0x1B));
15051  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
15052  }
15053  }
15054  else
15055  {
15056  // The conversions below encode the sign in the first
15057  // byte, and the value is converted to a positive number.
15058  const auto positive_number = -1 - j.m_value.number_integer;
15059  if (j.m_value.number_integer >= -24)
15060  {
15061  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
15062  }
15063  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
15064  {
15065  oa->write_character(to_char_type(0x38));
15066  write_number(static_cast<std::uint8_t>(positive_number));
15067  }
15068  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
15069  {
15070  oa->write_character(to_char_type(0x39));
15071  write_number(static_cast<std::uint16_t>(positive_number));
15072  }
15073  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
15074  {
15075  oa->write_character(to_char_type(0x3A));
15076  write_number(static_cast<std::uint32_t>(positive_number));
15077  }
15078  else
15079  {
15080  oa->write_character(to_char_type(0x3B));
15081  write_number(static_cast<std::uint64_t>(positive_number));
15082  }
15083  }
15084  break;
15085  }
15086 
15088  {
15089  if (j.m_value.number_unsigned <= 0x17)
15090  {
15091  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
15092  }
15093  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15094  {
15095  oa->write_character(to_char_type(0x18));
15096  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
15097  }
15098  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15099  {
15100  oa->write_character(to_char_type(0x19));
15101  write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
15102  }
15103  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15104  {
15105  oa->write_character(to_char_type(0x1A));
15106  write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
15107  }
15108  else
15109  {
15110  oa->write_character(to_char_type(0x1B));
15111  write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
15112  }
15113  break;
15114  }
15115 
15116  case value_t::number_float:
15117  {
15118  if (std::isnan(j.m_value.number_float))
15119  {
15120  // NaN is 0xf97e00 in CBOR
15121  oa->write_character(to_char_type(0xF9));
15122  oa->write_character(to_char_type(0x7E));
15123  oa->write_character(to_char_type(0x00));
15124  }
15125  else if (std::isinf(j.m_value.number_float))
15126  {
15127  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
15128  oa->write_character(to_char_type(0xf9));
15129  oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
15130  oa->write_character(to_char_type(0x00));
15131  }
15132  else
15133  {
15134  write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
15135  }
15136  break;
15137  }
15138 
15139  case value_t::string:
15140  {
15141  // step 1: write control byte and the string length
15142  const auto N = j.m_value.string->size();
15143  if (N <= 0x17)
15144  {
15145  write_number(static_cast<std::uint8_t>(0x60 + N));
15146  }
15147  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15148  {
15149  oa->write_character(to_char_type(0x78));
15150  write_number(static_cast<std::uint8_t>(N));
15151  }
15152  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15153  {
15154  oa->write_character(to_char_type(0x79));
15155  write_number(static_cast<std::uint16_t>(N));
15156  }
15157  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15158  {
15159  oa->write_character(to_char_type(0x7A));
15160  write_number(static_cast<std::uint32_t>(N));
15161  }
15162  // LCOV_EXCL_START
15163  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15164  {
15165  oa->write_character(to_char_type(0x7B));
15166  write_number(static_cast<std::uint64_t>(N));
15167  }
15168  // LCOV_EXCL_STOP
15169 
15170  // step 2: write the string
15171  oa->write_characters(
15172  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
15173  j.m_value.string->size());
15174  break;
15175  }
15176 
15177  case value_t::array:
15178  {
15179  // step 1: write control byte and the array size
15180  const auto N = j.m_value.array->size();
15181  if (N <= 0x17)
15182  {
15183  write_number(static_cast<std::uint8_t>(0x80 + N));
15184  }
15185  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15186  {
15187  oa->write_character(to_char_type(0x98));
15188  write_number(static_cast<std::uint8_t>(N));
15189  }
15190  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15191  {
15192  oa->write_character(to_char_type(0x99));
15193  write_number(static_cast<std::uint16_t>(N));
15194  }
15195  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15196  {
15197  oa->write_character(to_char_type(0x9A));
15198  write_number(static_cast<std::uint32_t>(N));
15199  }
15200  // LCOV_EXCL_START
15201  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15202  {
15203  oa->write_character(to_char_type(0x9B));
15204  write_number(static_cast<std::uint64_t>(N));
15205  }
15206  // LCOV_EXCL_STOP
15207 
15208  // step 2: write each element
15209  for (const auto& el : *j.m_value.array)
15210  {
15211  write_cbor(el);
15212  }
15213  break;
15214  }
15215 
15216  case value_t::binary:
15217  {
15218  if (j.m_value.binary->has_subtype())
15219  {
15220  if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
15221  {
15222  write_number(static_cast<std::uint8_t>(0xd8));
15223  write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
15224  }
15225  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
15226  {
15227  write_number(static_cast<std::uint8_t>(0xd9));
15228  write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
15229  }
15230  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
15231  {
15232  write_number(static_cast<std::uint8_t>(0xda));
15233  write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
15234  }
15235  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
15236  {
15237  write_number(static_cast<std::uint8_t>(0xdb));
15238  write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
15239  }
15240  }
15241 
15242  // step 1: write control byte and the binary array size
15243  const auto N = j.m_value.binary->size();
15244  if (N <= 0x17)
15245  {
15246  write_number(static_cast<std::uint8_t>(0x40 + N));
15247  }
15248  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15249  {
15250  oa->write_character(to_char_type(0x58));
15251  write_number(static_cast<std::uint8_t>(N));
15252  }
15253  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15254  {
15255  oa->write_character(to_char_type(0x59));
15256  write_number(static_cast<std::uint16_t>(N));
15257  }
15258  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15259  {
15260  oa->write_character(to_char_type(0x5A));
15261  write_number(static_cast<std::uint32_t>(N));
15262  }
15263  // LCOV_EXCL_START
15264  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15265  {
15266  oa->write_character(to_char_type(0x5B));
15267  write_number(static_cast<std::uint64_t>(N));
15268  }
15269  // LCOV_EXCL_STOP
15270 
15271  // step 2: write each element
15272  oa->write_characters(
15273  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15274  N);
15275 
15276  break;
15277  }
15278 
15279  case value_t::object:
15280  {
15281  // step 1: write control byte and the object size
15282  const auto N = j.m_value.object->size();
15283  if (N <= 0x17)
15284  {
15285  write_number(static_cast<std::uint8_t>(0xA0 + N));
15286  }
15287  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15288  {
15289  oa->write_character(to_char_type(0xB8));
15290  write_number(static_cast<std::uint8_t>(N));
15291  }
15292  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15293  {
15294  oa->write_character(to_char_type(0xB9));
15295  write_number(static_cast<std::uint16_t>(N));
15296  }
15297  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15298  {
15299  oa->write_character(to_char_type(0xBA));
15300  write_number(static_cast<std::uint32_t>(N));
15301  }
15302  // LCOV_EXCL_START
15303  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15304  {
15305  oa->write_character(to_char_type(0xBB));
15306  write_number(static_cast<std::uint64_t>(N));
15307  }
15308  // LCOV_EXCL_STOP
15309 
15310  // step 2: write each element
15311  for (const auto& el : *j.m_value.object)
15312  {
15313  write_cbor(el.first);
15314  write_cbor(el.second);
15315  }
15316  break;
15317  }
15318 
15319  case value_t::discarded:
15320  default:
15321  break;
15322  }
15323  }
15324 
15328  void write_msgpack(const BasicJsonType& j)
15329  {
15330  switch (j.type())
15331  {
15332  case value_t::null: // nil
15333  {
15334  oa->write_character(to_char_type(0xC0));
15335  break;
15336  }
15337 
15338  case value_t::boolean: // true and false
15339  {
15340  oa->write_character(j.m_value.boolean
15341  ? to_char_type(0xC3)
15342  : to_char_type(0xC2));
15343  break;
15344  }
15345 
15347  {
15348  if (j.m_value.number_integer >= 0)
15349  {
15350  // MessagePack does not differentiate between positive
15351  // signed integers and unsigned integers. Therefore, we used
15352  // the code from the value_t::number_unsigned case here.
15353  if (j.m_value.number_unsigned < 128)
15354  {
15355  // positive fixnum
15356  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15357  }
15358  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15359  {
15360  // uint 8
15361  oa->write_character(to_char_type(0xCC));
15362  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15363  }
15364  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15365  {
15366  // uint 16
15367  oa->write_character(to_char_type(0xCD));
15368  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
15369  }
15370  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15371  {
15372  // uint 32
15373  oa->write_character(to_char_type(0xCE));
15374  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
15375  }
15376  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15377  {
15378  // uint 64
15379  oa->write_character(to_char_type(0xCF));
15380  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
15381  }
15382  }
15383  else
15384  {
15385  if (j.m_value.number_integer >= -32)
15386  {
15387  // negative fixnum
15388  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
15389  }
15390  else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
15391  j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15392  {
15393  // int 8
15394  oa->write_character(to_char_type(0xD0));
15395  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
15396  }
15397  else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
15398  j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15399  {
15400  // int 16
15401  oa->write_character(to_char_type(0xD1));
15402  write_number(static_cast<std::int16_t>(j.m_value.number_integer));
15403  }
15404  else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
15405  j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15406  {
15407  // int 32
15408  oa->write_character(to_char_type(0xD2));
15409  write_number(static_cast<std::int32_t>(j.m_value.number_integer));
15410  }
15411  else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
15412  j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15413  {
15414  // int 64
15415  oa->write_character(to_char_type(0xD3));
15416  write_number(static_cast<std::int64_t>(j.m_value.number_integer));
15417  }
15418  }
15419  break;
15420  }
15421 
15423  {
15424  if (j.m_value.number_unsigned < 128)
15425  {
15426  // positive fixnum
15427  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15428  }
15429  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15430  {
15431  // uint 8
15432  oa->write_character(to_char_type(0xCC));
15433  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15434  }
15435  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15436  {
15437  // uint 16
15438  oa->write_character(to_char_type(0xCD));
15439  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
15440  }
15441  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15442  {
15443  // uint 32
15444  oa->write_character(to_char_type(0xCE));
15445  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
15446  }
15447  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15448  {
15449  // uint 64
15450  oa->write_character(to_char_type(0xCF));
15451  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
15452  }
15453  break;
15454  }
15455 
15456  case value_t::number_float:
15457  {
15458  write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
15459  break;
15460  }
15461 
15462  case value_t::string:
15463  {
15464  // step 1: write control byte and the string length
15465  const auto N = j.m_value.string->size();
15466  if (N <= 31)
15467  {
15468  // fixstr
15469  write_number(static_cast<std::uint8_t>(0xA0 | N));
15470  }
15471  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15472  {
15473  // str 8
15474  oa->write_character(to_char_type(0xD9));
15475  write_number(static_cast<std::uint8_t>(N));
15476  }
15477  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15478  {
15479  // str 16
15480  oa->write_character(to_char_type(0xDA));
15481  write_number(static_cast<std::uint16_t>(N));
15482  }
15483  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15484  {
15485  // str 32
15486  oa->write_character(to_char_type(0xDB));
15487  write_number(static_cast<std::uint32_t>(N));
15488  }
15489 
15490  // step 2: write the string
15491  oa->write_characters(
15492  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
15493  j.m_value.string->size());
15494  break;
15495  }
15496 
15497  case value_t::array:
15498  {
15499  // step 1: write control byte and the array size
15500  const auto N = j.m_value.array->size();
15501  if (N <= 15)
15502  {
15503  // fixarray
15504  write_number(static_cast<std::uint8_t>(0x90 | N));
15505  }
15506  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15507  {
15508  // array 16
15509  oa->write_character(to_char_type(0xDC));
15510  write_number(static_cast<std::uint16_t>(N));
15511  }
15512  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15513  {
15514  // array 32
15515  oa->write_character(to_char_type(0xDD));
15516  write_number(static_cast<std::uint32_t>(N));
15517  }
15518 
15519  // step 2: write each element
15520  for (const auto& el : *j.m_value.array)
15521  {
15522  write_msgpack(el);
15523  }
15524  break;
15525  }
15526 
15527  case value_t::binary:
15528  {
15529  // step 0: determine if the binary type has a set subtype to
15530  // determine whether or not to use the ext or fixext types
15531  const bool use_ext = j.m_value.binary->has_subtype();
15532 
15533  // step 1: write control byte and the byte string length
15534  const auto N = j.m_value.binary->size();
15535  if (N <= (std::numeric_limits<std::uint8_t>::max)())
15536  {
15537  std::uint8_t output_type{};
15538  bool fixed = true;
15539  if (use_ext)
15540  {
15541  switch (N)
15542  {
15543  case 1:
15544  output_type = 0xD4; // fixext 1
15545  break;
15546  case 2:
15547  output_type = 0xD5; // fixext 2
15548  break;
15549  case 4:
15550  output_type = 0xD6; // fixext 4
15551  break;
15552  case 8:
15553  output_type = 0xD7; // fixext 8
15554  break;
15555  case 16:
15556  output_type = 0xD8; // fixext 16
15557  break;
15558  default:
15559  output_type = 0xC7; // ext 8
15560  fixed = false;
15561  break;
15562  }
15563 
15564  }
15565  else
15566  {
15567  output_type = 0xC4; // bin 8
15568  fixed = false;
15569  }
15570 
15571  oa->write_character(to_char_type(output_type));
15572  if (!fixed)
15573  {
15574  write_number(static_cast<std::uint8_t>(N));
15575  }
15576  }
15577  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15578  {
15579  std::uint8_t output_type = use_ext
15580  ? 0xC8 // ext 16
15581  : 0xC5; // bin 16
15582 
15583  oa->write_character(to_char_type(output_type));
15584  write_number(static_cast<std::uint16_t>(N));
15585  }
15586  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15587  {
15588  std::uint8_t output_type = use_ext
15589  ? 0xC9 // ext 32
15590  : 0xC6; // bin 32
15591 
15592  oa->write_character(to_char_type(output_type));
15593  write_number(static_cast<std::uint32_t>(N));
15594  }
15595 
15596  // step 1.5: if this is an ext type, write the subtype
15597  if (use_ext)
15598  {
15599  write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
15600  }
15601 
15602  // step 2: write the byte string
15603  oa->write_characters(
15604  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15605  N);
15606 
15607  break;
15608  }
15609 
15610  case value_t::object:
15611  {
15612  // step 1: write control byte and the object size
15613  const auto N = j.m_value.object->size();
15614  if (N <= 15)
15615  {
15616  // fixmap
15617  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
15618  }
15619  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15620  {
15621  // map 16
15622  oa->write_character(to_char_type(0xDE));
15623  write_number(static_cast<std::uint16_t>(N));
15624  }
15625  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15626  {
15627  // map 32
15628  oa->write_character(to_char_type(0xDF));
15629  write_number(static_cast<std::uint32_t>(N));
15630  }
15631 
15632  // step 2: write each element
15633  for (const auto& el : *j.m_value.object)
15634  {
15635  write_msgpack(el.first);
15636  write_msgpack(el.second);
15637  }
15638  break;
15639  }
15640 
15641  case value_t::discarded:
15642  default:
15643  break;
15644  }
15645  }
15646 
15654  void write_ubjson(const BasicJsonType& j, const bool use_count,
15655  const bool use_type, const bool add_prefix = true,
15656  const bool use_bjdata = false)
15657  {
15658  switch (j.type())
15659  {
15660  case value_t::null:
15661  {
15662  if (add_prefix)
15663  {
15664  oa->write_character(to_char_type('Z'));
15665  }
15666  break;
15667  }
15668 
15669  case value_t::boolean:
15670  {
15671  if (add_prefix)
15672  {
15673  oa->write_character(j.m_value.boolean
15674  ? to_char_type('T')
15675  : to_char_type('F'));
15676  }
15677  break;
15678  }
15679 
15681  {
15682  write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata);
15683  break;
15684  }
15685 
15687  {
15688  write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix, use_bjdata);
15689  break;
15690  }
15691 
15692  case value_t::number_float:
15693  {
15694  write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix, use_bjdata);
15695  break;
15696  }
15697 
15698  case value_t::string:
15699  {
15700  if (add_prefix)
15701  {
15702  oa->write_character(to_char_type('S'));
15703  }
15704  write_number_with_ubjson_prefix(j.m_value.string->size(), true, use_bjdata);
15705  oa->write_characters(
15706  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
15707  j.m_value.string->size());
15708  break;
15709  }
15710 
15711  case value_t::array:
15712  {
15713  if (add_prefix)
15714  {
15715  oa->write_character(to_char_type('['));
15716  }
15717 
15718  bool prefix_required = true;
15719  if (use_type && !j.m_value.array->empty())
15720  {
15721  JSON_ASSERT(use_count);
15722  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15723  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
15724  [this, first_prefix, use_bjdata](const BasicJsonType & v)
15725  {
15726  return ubjson_prefix(v, use_bjdata) == first_prefix;
15727  });
15728 
15729  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15730 
15731  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15732  {
15733  prefix_required = false;
15734  oa->write_character(to_char_type('$'));
15735  oa->write_character(first_prefix);
15736  }
15737  }
15738 
15739  if (use_count)
15740  {
15741  oa->write_character(to_char_type('#'));
15742  write_number_with_ubjson_prefix(j.m_value.array->size(), true, use_bjdata);
15743  }
15744 
15745  for (const auto& el : *j.m_value.array)
15746  {
15747  write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
15748  }
15749 
15750  if (!use_count)
15751  {
15752  oa->write_character(to_char_type(']'));
15753  }
15754 
15755  break;
15756  }
15757 
15758  case value_t::binary:
15759  {
15760  if (add_prefix)
15761  {
15762  oa->write_character(to_char_type('['));
15763  }
15764 
15765  if (use_type && !j.m_value.binary->empty())
15766  {
15767  JSON_ASSERT(use_count);
15768  oa->write_character(to_char_type('$'));
15769  oa->write_character('U');
15770  }
15771 
15772  if (use_count)
15773  {
15774  oa->write_character(to_char_type('#'));
15775  write_number_with_ubjson_prefix(j.m_value.binary->size(), true, use_bjdata);
15776  }
15777 
15778  if (use_type)
15779  {
15780  oa->write_characters(
15781  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15782  j.m_value.binary->size());
15783  }
15784  else
15785  {
15786  for (size_t i = 0; i < j.m_value.binary->size(); ++i)
15787  {
15788  oa->write_character(to_char_type('U'));
15789  oa->write_character(j.m_value.binary->data()[i]);
15790  }
15791  }
15792 
15793  if (!use_count)
15794  {
15795  oa->write_character(to_char_type(']'));
15796  }
15797 
15798  break;
15799  }
15800 
15801  case value_t::object:
15802  {
15803  if (use_bjdata && j.m_value.object->size() == 3 && j.m_value.object->find("_ArrayType_") != j.m_value.object->end() && j.m_value.object->find("_ArraySize_") != j.m_value.object->end() && j.m_value.object->find("_ArrayData_") != j.m_value.object->end())
15804  {
15805  if (!write_bjdata_ndarray(*j.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
15806  {
15807  break;
15808  }
15809  }
15810 
15811  if (add_prefix)
15812  {
15813  oa->write_character(to_char_type('{'));
15814  }
15815 
15816  bool prefix_required = true;
15817  if (use_type && !j.m_value.object->empty())
15818  {
15819  JSON_ASSERT(use_count);
15820  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15821  const bool same_prefix = std::all_of(j.begin(), j.end(),
15822  [this, first_prefix, use_bjdata](const BasicJsonType & v)
15823  {
15824  return ubjson_prefix(v, use_bjdata) == first_prefix;
15825  });
15826 
15827  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15828 
15829  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15830  {
15831  prefix_required = false;
15832  oa->write_character(to_char_type('$'));
15833  oa->write_character(first_prefix);
15834  }
15835  }
15836 
15837  if (use_count)
15838  {
15839  oa->write_character(to_char_type('#'));
15840  write_number_with_ubjson_prefix(j.m_value.object->size(), true, use_bjdata);
15841  }
15842 
15843  for (const auto& el : *j.m_value.object)
15844  {
15845  write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
15846  oa->write_characters(
15847  reinterpret_cast<const CharType*>(el.first.c_str()),
15848  el.first.size());
15849  write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
15850  }
15851 
15852  if (!use_count)
15853  {
15854  oa->write_character(to_char_type('}'));
15855  }
15856 
15857  break;
15858  }
15859 
15860  case value_t::discarded:
15861  default:
15862  break;
15863  }
15864  }
15865 
15866  private:
15868  // BSON //
15870 
15875  static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
15876  {
15877  const auto it = name.find(static_cast<typename string_t::value_type>(0));
15878  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
15879  {
15880  JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
15881  static_cast<void>(j);
15882  }
15883 
15884  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
15885  }
15886 
15890  void write_bson_entry_header(const string_t& name,
15891  const std::uint8_t element_type)
15892  {
15893  oa->write_character(to_char_type(element_type)); // boolean
15894  oa->write_characters(
15895  reinterpret_cast<const CharType*>(name.c_str()),
15896  name.size() + 1u);
15897  }
15898 
15902  void write_bson_boolean(const string_t& name,
15903  const bool value)
15904  {
15905  write_bson_entry_header(name, 0x08);
15906  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
15907  }
15908 
15912  void write_bson_double(const string_t& name,
15913  const double value)
15914  {
15915  write_bson_entry_header(name, 0x01);
15916  write_number<double>(value, true);
15917  }
15918 
15922  static std::size_t calc_bson_string_size(const string_t& value)
15923  {
15924  return sizeof(std::int32_t) + value.size() + 1ul;
15925  }
15926 
15930  void write_bson_string(const string_t& name,
15931  const string_t& value)
15932  {
15933  write_bson_entry_header(name, 0x02);
15934 
15935  write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
15936  oa->write_characters(
15937  reinterpret_cast<const CharType*>(value.c_str()),
15938  value.size() + 1);
15939  }
15940 
15944  void write_bson_null(const string_t& name)
15945  {
15946  write_bson_entry_header(name, 0x0A);
15947  }
15948 
15952  static std::size_t calc_bson_integer_size(const std::int64_t value)
15953  {
15954  return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
15955  ? sizeof(std::int32_t)
15956  : sizeof(std::int64_t);
15957  }
15958 
15962  void write_bson_integer(const string_t& name,
15963  const std::int64_t value)
15964  {
15965  if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
15966  {
15967  write_bson_entry_header(name, 0x10); // int32
15968  write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
15969  }
15970  else
15971  {
15972  write_bson_entry_header(name, 0x12); // int64
15973  write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
15974  }
15975  }
15976 
15980  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
15981  {
15982  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15983  ? sizeof(std::int32_t)
15984  : sizeof(std::int64_t);
15985  }
15986 
15990  void write_bson_unsigned(const string_t& name,
15991  const BasicJsonType& j)
15992  {
15993  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15994  {
15995  write_bson_entry_header(name, 0x10 /* int32 */);
15996  write_number<std::int32_t>(static_cast<std::int32_t>(j.m_value.number_unsigned), true);
15997  }
15998  else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15999  {
16000  write_bson_entry_header(name, 0x12 /* int64 */);
16001  write_number<std::int64_t>(static_cast<std::int64_t>(j.m_value.number_unsigned), true);
16002  }
16003  else
16004  {
16005  JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
16006  }
16007  }
16008 
16012  void write_bson_object_entry(const string_t& name,
16013  const typename BasicJsonType::object_t& value)
16014  {
16015  write_bson_entry_header(name, 0x03); // object
16016  write_bson_object(value);
16017  }
16018 
16022  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
16023  {
16024  std::size_t array_index = 0ul;
16025 
16026  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)
16027  {
16028  return result + calc_bson_element_size(std::to_string(array_index++), el);
16029  });
16030 
16031  return sizeof(std::int32_t) + embedded_document_size + 1ul;
16032  }
16033 
16037  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
16038  {
16039  return sizeof(std::int32_t) + value.size() + 1ul;
16040  }
16041 
16045  void write_bson_array(const string_t& name,
16046  const typename BasicJsonType::array_t& value)
16047  {
16048  write_bson_entry_header(name, 0x04); // array
16049  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
16050 
16051  std::size_t array_index = 0ul;
16052 
16053  for (const auto& el : value)
16054  {
16055  write_bson_element(std::to_string(array_index++), el);
16056  }
16057 
16058  oa->write_character(to_char_type(0x00));
16059  }
16060 
16064  void write_bson_binary(const string_t& name,
16065  const binary_t& value)
16066  {
16067  write_bson_entry_header(name, 0x05);
16068 
16069  write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
16070  write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
16071 
16072  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
16073  }
16074 
16079  static std::size_t calc_bson_element_size(const string_t& name,
16080  const BasicJsonType& j)
16081  {
16082  const auto header_size = calc_bson_entry_header_size(name, j);
16083  switch (j.type())
16084  {
16085  case value_t::object:
16086  return header_size + calc_bson_object_size(*j.m_value.object);
16087 
16088  case value_t::array:
16089  return header_size + calc_bson_array_size(*j.m_value.array);
16090 
16091  case value_t::binary:
16092  return header_size + calc_bson_binary_size(*j.m_value.binary);
16093 
16094  case value_t::boolean:
16095  return header_size + 1ul;
16096 
16097  case value_t::number_float:
16098  return header_size + 8ul;
16099 
16101  return header_size + calc_bson_integer_size(j.m_value.number_integer);
16102 
16104  return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
16105 
16106  case value_t::string:
16107  return header_size + calc_bson_string_size(*j.m_value.string);
16108 
16109  case value_t::null:
16110  return header_size + 0ul;
16111 
16112  // LCOV_EXCL_START
16113  case value_t::discarded:
16114  default:
16115  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16116  return 0ul;
16117  // LCOV_EXCL_STOP
16118  }
16119  }
16120 
16127  void write_bson_element(const string_t& name,
16128  const BasicJsonType& j)
16129  {
16130  switch (j.type())
16131  {
16132  case value_t::object:
16133  return write_bson_object_entry(name, *j.m_value.object);
16134 
16135  case value_t::array:
16136  return write_bson_array(name, *j.m_value.array);
16137 
16138  case value_t::binary:
16139  return write_bson_binary(name, *j.m_value.binary);
16140 
16141  case value_t::boolean:
16142  return write_bson_boolean(name, j.m_value.boolean);
16143 
16144  case value_t::number_float:
16145  return write_bson_double(name, j.m_value.number_float);
16146 
16148  return write_bson_integer(name, j.m_value.number_integer);
16149 
16151  return write_bson_unsigned(name, j);
16152 
16153  case value_t::string:
16154  return write_bson_string(name, *j.m_value.string);
16155 
16156  case value_t::null:
16157  return write_bson_null(name);
16158 
16159  // LCOV_EXCL_START
16160  case value_t::discarded:
16161  default:
16162  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16163  return;
16164  // LCOV_EXCL_STOP
16165  }
16166  }
16167 
16174  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
16175  {
16176  std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
16177  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
16178  {
16179  return result += calc_bson_element_size(el.first, el.second);
16180  });
16181 
16182  return sizeof(std::int32_t) + document_size + 1ul;
16183  }
16184 
16189  void write_bson_object(const typename BasicJsonType::object_t& value)
16190  {
16191  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
16192 
16193  for (const auto& el : value)
16194  {
16195  write_bson_element(el.first, el.second);
16196  }
16197 
16198  oa->write_character(to_char_type(0x00));
16199  }
16200 
16202  // CBOR //
16204 
16205  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
16206  {
16207  return to_char_type(0xFA); // Single-Precision Float
16208  }
16209 
16210  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
16211  {
16212  return to_char_type(0xFB); // Double-Precision Float
16213  }
16214 
16216  // MsgPack //
16218 
16219  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
16220  {
16221  return to_char_type(0xCA); // float 32
16222  }
16223 
16224  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
16225  {
16226  return to_char_type(0xCB); // float 64
16227  }
16228 
16230  // UBJSON //
16232 
16233  // UBJSON: write number (floating point)
16234  template<typename NumberType, typename std::enable_if<
16235  std::is_floating_point<NumberType>::value, int>::type = 0>
16236  void write_number_with_ubjson_prefix(const NumberType n,
16237  const bool add_prefix,
16238  const bool use_bjdata)
16239  {
16240  if (add_prefix)
16241  {
16242  oa->write_character(get_ubjson_float_prefix(n));
16243  }
16244  write_number(n, use_bjdata);
16245  }
16246 
16247  // UBJSON: write number (unsigned integer)
16248  template<typename NumberType, typename std::enable_if<
16249  std::is_unsigned<NumberType>::value, int>::type = 0>
16250  void write_number_with_ubjson_prefix(const NumberType n,
16251  const bool add_prefix,
16252  const bool use_bjdata)
16253  {
16254  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16255  {
16256  if (add_prefix)
16257  {
16258  oa->write_character(to_char_type('i')); // int8
16259  }
16260  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16261  }
16262  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
16263  {
16264  if (add_prefix)
16265  {
16266  oa->write_character(to_char_type('U')); // uint8
16267  }
16268  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16269  }
16270  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16271  {
16272  if (add_prefix)
16273  {
16274  oa->write_character(to_char_type('I')); // int16
16275  }
16276  write_number(static_cast<std::int16_t>(n), use_bjdata);
16277  }
16278  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
16279  {
16280  if (add_prefix)
16281  {
16282  oa->write_character(to_char_type('u')); // uint16 - bjdata only
16283  }
16284  write_number(static_cast<std::uint16_t>(n), use_bjdata);
16285  }
16286  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16287  {
16288  if (add_prefix)
16289  {
16290  oa->write_character(to_char_type('l')); // int32
16291  }
16292  write_number(static_cast<std::int32_t>(n), use_bjdata);
16293  }
16294  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
16295  {
16296  if (add_prefix)
16297  {
16298  oa->write_character(to_char_type('m')); // uint32 - bjdata only
16299  }
16300  write_number(static_cast<std::uint32_t>(n), use_bjdata);
16301  }
16302  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16303  {
16304  if (add_prefix)
16305  {
16306  oa->write_character(to_char_type('L')); // int64
16307  }
16308  write_number(static_cast<std::int64_t>(n), use_bjdata);
16309  }
16310  else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
16311  {
16312  if (add_prefix)
16313  {
16314  oa->write_character(to_char_type('M')); // uint64 - bjdata only
16315  }
16316  write_number(static_cast<std::uint64_t>(n), use_bjdata);
16317  }
16318  else
16319  {
16320  if (add_prefix)
16321  {
16322  oa->write_character(to_char_type('H')); // high-precision number
16323  }
16324 
16325  const auto number = BasicJsonType(n).dump();
16326  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16327  for (std::size_t i = 0; i < number.size(); ++i)
16328  {
16329  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16330  }
16331  }
16332  }
16333 
16334  // UBJSON: write number (signed integer)
16335  template < typename NumberType, typename std::enable_if <
16336  std::is_signed<NumberType>::value&&
16337  !std::is_floating_point<NumberType>::value, int >::type = 0 >
16338  void write_number_with_ubjson_prefix(const NumberType n,
16339  const bool add_prefix,
16340  const bool use_bjdata)
16341  {
16342  if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
16343  {
16344  if (add_prefix)
16345  {
16346  oa->write_character(to_char_type('i')); // int8
16347  }
16348  write_number(static_cast<std::int8_t>(n), use_bjdata);
16349  }
16350  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)()))
16351  {
16352  if (add_prefix)
16353  {
16354  oa->write_character(to_char_type('U')); // uint8
16355  }
16356  write_number(static_cast<std::uint8_t>(n), use_bjdata);
16357  }
16358  else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
16359  {
16360  if (add_prefix)
16361  {
16362  oa->write_character(to_char_type('I')); // int16
16363  }
16364  write_number(static_cast<std::int16_t>(n), use_bjdata);
16365  }
16366  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)())))
16367  {
16368  if (add_prefix)
16369  {
16370  oa->write_character(to_char_type('u')); // uint16 - bjdata only
16371  }
16372  write_number(static_cast<uint16_t>(n), use_bjdata);
16373  }
16374  else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
16375  {
16376  if (add_prefix)
16377  {
16378  oa->write_character(to_char_type('l')); // int32
16379  }
16380  write_number(static_cast<std::int32_t>(n), use_bjdata);
16381  }
16382  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)())))
16383  {
16384  if (add_prefix)
16385  {
16386  oa->write_character(to_char_type('m')); // uint32 - bjdata only
16387  }
16388  write_number(static_cast<uint32_t>(n), use_bjdata);
16389  }
16390  else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
16391  {
16392  if (add_prefix)
16393  {
16394  oa->write_character(to_char_type('L')); // int64
16395  }
16396  write_number(static_cast<std::int64_t>(n), use_bjdata);
16397  }
16398  // LCOV_EXCL_START
16399  else
16400  {
16401  if (add_prefix)
16402  {
16403  oa->write_character(to_char_type('H')); // high-precision number
16404  }
16405 
16406  const auto number = BasicJsonType(n).dump();
16407  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16408  for (std::size_t i = 0; i < number.size(); ++i)
16409  {
16410  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16411  }
16412  }
16413  // LCOV_EXCL_STOP
16414  }
16415 
16419  CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
16420  {
16421  switch (j.type())
16422  {
16423  case value_t::null:
16424  return 'Z';
16425 
16426  case value_t::boolean:
16427  return j.m_value.boolean ? 'T' : 'F';
16428 
16430  {
16431  if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
16432  {
16433  return 'i';
16434  }
16435  if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
16436  {
16437  return 'U';
16438  }
16439  if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
16440  {
16441  return 'I';
16442  }
16443  if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
16444  {
16445  return 'u';
16446  }
16447  if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
16448  {
16449  return 'l';
16450  }
16451  if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
16452  {
16453  return 'm';
16454  }
16455  if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
16456  {
16457  return 'L';
16458  }
16459  // anything else is treated as high-precision number
16460  return 'H'; // LCOV_EXCL_LINE
16461  }
16462 
16464  {
16465  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16466  {
16467  return 'i';
16468  }
16469  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
16470  {
16471  return 'U';
16472  }
16473  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16474  {
16475  return 'I';
16476  }
16477  if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
16478  {
16479  return 'u';
16480  }
16481  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16482  {
16483  return 'l';
16484  }
16485  if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
16486  {
16487  return 'm';
16488  }
16489  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16490  {
16491  return 'L';
16492  }
16493  if (use_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16494  {
16495  return 'M';
16496  }
16497  // anything else is treated as high-precision number
16498  return 'H'; // LCOV_EXCL_LINE
16499  }
16500 
16501  case value_t::number_float:
16502  return get_ubjson_float_prefix(j.m_value.number_float);
16503 
16504  case value_t::string:
16505  return 'S';
16506 
16507  case value_t::array: // fallthrough
16508  case value_t::binary:
16509  return '[';
16510 
16511  case value_t::object:
16512  return '{';
16513 
16514  case value_t::discarded:
16515  default: // discarded values
16516  return 'N';
16517  }
16518  }
16519 
16520  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
16521  {
16522  return 'd'; // float 32
16523  }
16524 
16525  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
16526  {
16527  return 'D'; // float 64
16528  }
16529 
16533  bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
16534  {
16535  std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
16536  {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
16537  };
16538 
16539  string_t key = "_ArrayType_";
16540  auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
16541  if (it == bjdtype.end())
16542  {
16543  return true;
16544  }
16545  CharType dtype = it->second;
16546 
16547  key = "_ArraySize_";
16548  std::size_t len = (value.at(key).empty() ? 0 : 1);
16549  for (const auto& el : value.at(key))
16550  {
16551  len *= static_cast<std::size_t>(el.m_value.number_unsigned);
16552  }
16553 
16554  key = "_ArrayData_";
16555  if (value.at(key).size() != len)
16556  {
16557  return true;
16558  }
16559 
16560  oa->write_character('[');
16561  oa->write_character('$');
16562  oa->write_character(dtype);
16563  oa->write_character('#');
16564 
16565  key = "_ArraySize_";
16566  write_ubjson(value.at(key), use_count, use_type, true, true);
16567 
16568  key = "_ArrayData_";
16569  if (dtype == 'U' || dtype == 'C')
16570  {
16571  for (const auto& el : value.at(key))
16572  {
16573  write_number(static_cast<std::uint8_t>(el.m_value.number_unsigned), true);
16574  }
16575  }
16576  else if (dtype == 'i')
16577  {
16578  for (const auto& el : value.at(key))
16579  {
16580  write_number(static_cast<std::int8_t>(el.m_value.number_integer), true);
16581  }
16582  }
16583  else if (dtype == 'u')
16584  {
16585  for (const auto& el : value.at(key))
16586  {
16587  write_number(static_cast<std::uint16_t>(el.m_value.number_unsigned), true);
16588  }
16589  }
16590  else if (dtype == 'I')
16591  {
16592  for (const auto& el : value.at(key))
16593  {
16594  write_number(static_cast<std::int16_t>(el.m_value.number_integer), true);
16595  }
16596  }
16597  else if (dtype == 'm')
16598  {
16599  for (const auto& el : value.at(key))
16600  {
16601  write_number(static_cast<std::uint32_t>(el.m_value.number_unsigned), true);
16602  }
16603  }
16604  else if (dtype == 'l')
16605  {
16606  for (const auto& el : value.at(key))
16607  {
16608  write_number(static_cast<std::int32_t>(el.m_value.number_integer), true);
16609  }
16610  }
16611  else if (dtype == 'M')
16612  {
16613  for (const auto& el : value.at(key))
16614  {
16615  write_number(static_cast<std::uint64_t>(el.m_value.number_unsigned), true);
16616  }
16617  }
16618  else if (dtype == 'L')
16619  {
16620  for (const auto& el : value.at(key))
16621  {
16622  write_number(static_cast<std::int64_t>(el.m_value.number_integer), true);
16623  }
16624  }
16625  else if (dtype == 'd')
16626  {
16627  for (const auto& el : value.at(key))
16628  {
16629  write_number(static_cast<float>(el.m_value.number_float), true);
16630  }
16631  }
16632  else if (dtype == 'D')
16633  {
16634  for (const auto& el : value.at(key))
16635  {
16636  write_number(static_cast<double>(el.m_value.number_float), true);
16637  }
16638  }
16639  return false;
16640  }
16641 
16643  // Utility functions //
16645 
16646  /*
16647  @brief write a number to output input
16648  @param[in] n number of type @a NumberType
16649  @param[in] OutputIsLittleEndian Set to true if output data is
16650  required to be little endian
16651  @tparam NumberType the type of the number
16652 
16653  @note This function needs to respect the system's endianness, because bytes
16654  in CBOR, MessagePack, and UBJSON are stored in network order (big
16655  endian) and therefore need reordering on little endian systems.
16656  On the other hand, BSON and BJData use little endian and should reorder
16657  on big endian systems.
16658  */
16659  template<typename NumberType>
16660  void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
16661  {
16662  // step 1: write number to array of length NumberType
16663  std::array<CharType, sizeof(NumberType)> vec{};
16664  std::memcpy(vec.data(), &n, sizeof(NumberType));
16665 
16666  // step 2: write array to output (with possible reordering)
16667  if (is_little_endian != OutputIsLittleEndian)
16668  {
16669  // reverse byte order prior to conversion if necessary
16670  std::reverse(vec.begin(), vec.end());
16671  }
16672 
16673  oa->write_characters(vec.data(), sizeof(NumberType));
16674  }
16675 
16676  void write_compact_float(const number_float_t n, detail::input_format_t format)
16677  {
16678 #ifdef __GNUC__
16679 #pragma GCC diagnostic push
16680 #pragma GCC diagnostic ignored "-Wfloat-equal"
16681 #endif
16682  if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
16683  static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
16684  static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
16685  {
16686  oa->write_character(format == detail::input_format_t::cbor
16687  ? get_cbor_float_prefix(static_cast<float>(n))
16688  : get_msgpack_float_prefix(static_cast<float>(n)));
16689  write_number(static_cast<float>(n));
16690  }
16691  else
16692  {
16693  oa->write_character(format == detail::input_format_t::cbor
16694  ? get_cbor_float_prefix(n)
16695  : get_msgpack_float_prefix(n));
16696  write_number(n);
16697  }
16698 #ifdef __GNUC__
16699 #pragma GCC diagnostic pop
16700 #endif
16701  }
16702 
16703  public:
16704  // The following to_char_type functions are implement the conversion
16705  // between uint8_t and CharType. In case CharType is not unsigned,
16706  // such a conversion is required to allow values greater than 128.
16707  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
16708  template < typename C = CharType,
16709  enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
16710  static constexpr CharType to_char_type(std::uint8_t x) noexcept
16711  {
16712  return *reinterpret_cast<char*>(&x);
16713  }
16714 
16715  template < typename C = CharType,
16716  enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
16717  static CharType to_char_type(std::uint8_t x) noexcept
16718  {
16719  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
16720  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
16721  CharType result;
16722  std::memcpy(&result, &x, sizeof(x));
16723  return result;
16724  }
16725 
16726  template<typename C = CharType,
16728  static constexpr CharType to_char_type(std::uint8_t x) noexcept
16729  {
16730  return x;
16731  }
16732 
16733  template < typename InputCharType, typename C = CharType,
16734  enable_if_t <
16735  std::is_signed<C>::value &&
16736  std::is_signed<char>::value &&
16738  > * = nullptr >
16739  static constexpr CharType to_char_type(InputCharType x) noexcept
16740  {
16741  return x;
16742  }
16743 
16744  private:
16746  const bool is_little_endian = little_endianness();
16747 
16749  output_adapter_t<CharType> oa = nullptr;
16750 };
16751 
16752 } // namespace detail
16754 
16755 // #include <nlohmann/detail/output/output_adapters.hpp>
16756 
16757 // #include <nlohmann/detail/output/serializer.hpp>
16758 // __ _____ _____ _____
16759 // __| | __| | | | JSON for Modern C++
16760 // | | |__ | | | | | | version 3.11.2
16761 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
16762 //
16763 // SPDX-FileCopyrightText: 2008-2009 Björn Hoehrmann <bjoern@hoehrmann.de>
16764 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
16765 // SPDX-License-Identifier: MIT
16766 
16767 
16768 
16769 #include <algorithm> // reverse, remove, fill, find, none_of
16770 #include <array> // array
16771 #include <clocale> // localeconv, lconv
16772 #include <cmath> // labs, isfinite, isnan, signbit
16773 #include <cstddef> // size_t, ptrdiff_t
16774 #include <cstdint> // uint8_t
16775 #include <cstdio> // snprintf
16776 #include <limits> // numeric_limits
16777 #include <string> // string, char_traits
16778 #include <iomanip> // setfill, setw
16779 #include <type_traits> // is_same
16780 #include <utility> // move
16781 
16782 // #include <nlohmann/detail/conversions/to_chars.hpp>
16783 // __ _____ _____ _____
16784 // __| | __| | | | JSON for Modern C++
16785 // | | |__ | | | | | | version 3.11.2
16786 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
16787 //
16788 // SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>
16789 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
16790 // SPDX-License-Identifier: MIT
16791 
16792 
16793 
16794 #include <array> // array
16795 #include <cmath> // signbit, isfinite
16796 #include <cstdint> // intN_t, uintN_t
16797 #include <cstring> // memcpy, memmove
16798 #include <limits> // numeric_limits
16799 #include <type_traits> // conditional
16800 
16801 // #include <nlohmann/detail/macro_scope.hpp>
16802 
16803 
16805 namespace detail
16806 {
16807 
16827 namespace dtoa_impl
16828 {
16829 
16830 template<typename Target, typename Source>
16831 Target reinterpret_bits(const Source source)
16832 {
16833  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
16834 
16835  Target target;
16836  std::memcpy(&target, &source, sizeof(Source));
16837  return target;
16838 }
16839 
16840 struct diyfp // f * 2^e
16841 {
16842  static constexpr int kPrecision = 64; // = q
16843 
16844  std::uint64_t f = 0;
16845  int e = 0;
16846 
16847  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
16848 
16853  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
16854  {
16855  JSON_ASSERT(x.e == y.e);
16856  JSON_ASSERT(x.f >= y.f);
16857 
16858  return {x.f - y.f, x.e};
16859  }
16860 
16865  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
16866  {
16867  static_assert(kPrecision == 64, "internal error");
16868 
16869  // Computes:
16870  // f = round((x.f * y.f) / 2^q)
16871  // e = x.e + y.e + q
16872 
16873  // Emulate the 64-bit * 64-bit multiplication:
16874  //
16875  // p = u * v
16876  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
16877  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
16878  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
16879  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
16880  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
16881  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
16882  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
16883  //
16884  // (Since Q might be larger than 2^32 - 1)
16885  //
16886  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
16887  //
16888  // (Q_hi + H does not overflow a 64-bit int)
16889  //
16890  // = p_lo + 2^64 p_hi
16891 
16892  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
16893  const std::uint64_t u_hi = x.f >> 32u;
16894  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
16895  const std::uint64_t v_hi = y.f >> 32u;
16896 
16897  const std::uint64_t p0 = u_lo * v_lo;
16898  const std::uint64_t p1 = u_lo * v_hi;
16899  const std::uint64_t p2 = u_hi * v_lo;
16900  const std::uint64_t p3 = u_hi * v_hi;
16901 
16902  const std::uint64_t p0_hi = p0 >> 32u;
16903  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
16904  const std::uint64_t p1_hi = p1 >> 32u;
16905  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
16906  const std::uint64_t p2_hi = p2 >> 32u;
16907 
16908  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
16909 
16910  // The full product might now be computed as
16911  //
16912  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
16913  // p_lo = p0_lo + (Q << 32)
16914  //
16915  // But in this particular case here, the full p_lo is not required.
16916  // Effectively we only need to add the highest bit in p_lo to p_hi (and
16917  // Q_hi + 1 does not overflow).
16918 
16919  Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
16920 
16921  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
16922 
16923  return {h, x.e + y.e + 64};
16924  }
16925 
16930  static diyfp normalize(diyfp x) noexcept
16931  {
16932  JSON_ASSERT(x.f != 0);
16933 
16934  while ((x.f >> 63u) == 0)
16935  {
16936  x.f <<= 1u;
16937  x.e--;
16938  }
16939 
16940  return x;
16941  }
16942 
16947  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
16948  {
16949  const int delta = x.e - target_exponent;
16950 
16951  JSON_ASSERT(delta >= 0);
16952  JSON_ASSERT(((x.f << delta) >> delta) == x.f);
16953 
16954  return {x.f << delta, target_exponent};
16955  }
16956 };
16957 
16959 {
16963 };
16964 
16971 template<typename FloatType>
16973 {
16974  JSON_ASSERT(std::isfinite(value));
16975  JSON_ASSERT(value > 0);
16976 
16977  // Convert the IEEE representation into a diyfp.
16978  //
16979  // If v is denormal:
16980  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
16981  // If v is normalized:
16982  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
16983 
16984  static_assert(std::numeric_limits<FloatType>::is_iec559,
16985  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
16986 
16987  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
16988  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
16989  constexpr int kMinExp = 1 - kBias;
16990  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
16991 
16993 
16994  const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
16995  const std::uint64_t E = bits >> (kPrecision - 1);
16996  const std::uint64_t F = bits & (kHiddenBit - 1);
16997 
16998  const bool is_denormal = E == 0;
16999  const diyfp v = is_denormal
17000  ? diyfp(F, kMinExp)
17001  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
17002 
17003  // Compute the boundaries m- and m+ of the floating-point value
17004  // v = f * 2^e.
17005  //
17006  // Determine v- and v+, the floating-point predecessor and successor if v,
17007  // respectively.
17008  //
17009  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
17010  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
17011  //
17012  // v+ = v + 2^e
17013  //
17014  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
17015  // between m- and m+ round to v, regardless of how the input rounding
17016  // algorithm breaks ties.
17017  //
17018  // ---+-------------+-------------+-------------+-------------+--- (A)
17019  // v- m- v m+ v+
17020  //
17021  // -----------------+------+------+-------------+-------------+--- (B)
17022  // v- m- v m+ v+
17023 
17024  const bool lower_boundary_is_closer = F == 0 && E > 1;
17025  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
17026  const diyfp m_minus = lower_boundary_is_closer
17027  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
17028  : diyfp(2 * v.f - 1, v.e - 1); // (A)
17029 
17030  // Determine the normalized w+ = m+.
17031  const diyfp w_plus = diyfp::normalize(m_plus);
17032 
17033  // Determine w- = m- such that e_(w-) = e_(w+).
17034  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
17035 
17036  return {diyfp::normalize(v), w_minus, w_plus};
17037 }
17038 
17039 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
17040 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
17041 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
17042 //
17043 // alpha <= e = e_c + e_w + q <= gamma
17044 //
17045 // or
17046 //
17047 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
17048 // <= f_c * f_w * 2^gamma
17049 //
17050 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
17051 //
17052 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
17053 //
17054 // or
17055 //
17056 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
17057 //
17058 // The choice of (alpha,gamma) determines the size of the table and the form of
17059 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
17060 // in practice:
17061 //
17062 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
17063 // processed independently: An integral part p1, and a fractional part p2:
17064 //
17065 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
17066 // = (f div 2^-e) + (f mod 2^-e) * 2^e
17067 // = p1 + p2 * 2^e
17068 //
17069 // The conversion of p1 into decimal form requires a series of divisions and
17070 // modulos by (a power of) 10. These operations are faster for 32-bit than for
17071 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
17072 // achieved by choosing
17073 //
17074 // -e >= 32 or e <= -32 := gamma
17075 //
17076 // In order to convert the fractional part
17077 //
17078 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
17079 //
17080 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
17081 // d[-i] are extracted in order:
17082 //
17083 // (10 * p2) div 2^-e = d[-1]
17084 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
17085 //
17086 // The multiplication by 10 must not overflow. It is sufficient to choose
17087 //
17088 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
17089 //
17090 // Since p2 = f mod 2^-e < 2^-e,
17091 //
17092 // -e <= 60 or e >= -60 := alpha
17093 
17094 constexpr int kAlpha = -60;
17095 constexpr int kGamma = -32;
17096 
17097 struct cached_power // c = f * 2^e ~= 10^k
17098 {
17099  std::uint64_t f;
17100  int e;
17101  int k;
17102 };
17103 
17112 {
17113  // Now
17114  //
17115  // alpha <= e_c + e + q <= gamma (1)
17116  // ==> f_c * 2^alpha <= c * 2^e * 2^q
17117  //
17118  // and since the c's are normalized, 2^(q-1) <= f_c,
17119  //
17120  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
17121  // ==> 2^(alpha - e - 1) <= c
17122  //
17123  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
17124  //
17125  // k = ceil( log_10( 2^(alpha - e - 1) ) )
17126  // = ceil( (alpha - e - 1) * log_10(2) )
17127  //
17128  // From the paper:
17129  // "In theory the result of the procedure could be wrong since c is rounded,
17130  // and the computation itself is approximated [...]. In practice, however,
17131  // this simple function is sufficient."
17132  //
17133  // For IEEE double precision floating-point numbers converted into
17134  // normalized diyfp's w = f * 2^e, with q = 64,
17135  //
17136  // e >= -1022 (min IEEE exponent)
17137  // -52 (p - 1)
17138  // -52 (p - 1, possibly normalize denormal IEEE numbers)
17139  // -11 (normalize the diyfp)
17140  // = -1137
17141  //
17142  // and
17143  //
17144  // e <= +1023 (max IEEE exponent)
17145  // -52 (p - 1)
17146  // -11 (normalize the diyfp)
17147  // = 960
17148  //
17149  // This binary exponent range [-1137,960] results in a decimal exponent
17150  // range [-307,324]. One does not need to store a cached power for each
17151  // k in this range. For each such k it suffices to find a cached power
17152  // such that the exponent of the product lies in [alpha,gamma].
17153  // This implies that the difference of the decimal exponents of adjacent
17154  // table entries must be less than or equal to
17155  //
17156  // floor( (gamma - alpha) * log_10(2) ) = 8.
17157  //
17158  // (A smaller distance gamma-alpha would require a larger table.)
17159 
17160  // NB:
17161  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
17162 
17163  constexpr int kCachedPowersMinDecExp = -300;
17164  constexpr int kCachedPowersDecStep = 8;
17165 
17166  static constexpr std::array<cached_power, 79> kCachedPowers =
17167  {
17168  {
17169  { 0xAB70FE17C79AC6CA, -1060, -300 },
17170  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
17171  { 0xBE5691EF416BD60C, -1007, -284 },
17172  { 0x8DD01FAD907FFC3C, -980, -276 },
17173  { 0xD3515C2831559A83, -954, -268 },
17174  { 0x9D71AC8FADA6C9B5, -927, -260 },
17175  { 0xEA9C227723EE8BCB, -901, -252 },
17176  { 0xAECC49914078536D, -874, -244 },
17177  { 0x823C12795DB6CE57, -847, -236 },
17178  { 0xC21094364DFB5637, -821, -228 },
17179  { 0x9096EA6F3848984F, -794, -220 },
17180  { 0xD77485CB25823AC7, -768, -212 },
17181  { 0xA086CFCD97BF97F4, -741, -204 },
17182  { 0xEF340A98172AACE5, -715, -196 },
17183  { 0xB23867FB2A35B28E, -688, -188 },
17184  { 0x84C8D4DFD2C63F3B, -661, -180 },
17185  { 0xC5DD44271AD3CDBA, -635, -172 },
17186  { 0x936B9FCEBB25C996, -608, -164 },
17187  { 0xDBAC6C247D62A584, -582, -156 },
17188  { 0xA3AB66580D5FDAF6, -555, -148 },
17189  { 0xF3E2F893DEC3F126, -529, -140 },
17190  { 0xB5B5ADA8AAFF80B8, -502, -132 },
17191  { 0x87625F056C7C4A8B, -475, -124 },
17192  { 0xC9BCFF6034C13053, -449, -116 },
17193  { 0x964E858C91BA2655, -422, -108 },
17194  { 0xDFF9772470297EBD, -396, -100 },
17195  { 0xA6DFBD9FB8E5B88F, -369, -92 },
17196  { 0xF8A95FCF88747D94, -343, -84 },
17197  { 0xB94470938FA89BCF, -316, -76 },
17198  { 0x8A08F0F8BF0F156B, -289, -68 },
17199  { 0xCDB02555653131B6, -263, -60 },
17200  { 0x993FE2C6D07B7FAC, -236, -52 },
17201  { 0xE45C10C42A2B3B06, -210, -44 },
17202  { 0xAA242499697392D3, -183, -36 },
17203  { 0xFD87B5F28300CA0E, -157, -28 },
17204  { 0xBCE5086492111AEB, -130, -20 },
17205  { 0x8CBCCC096F5088CC, -103, -12 },
17206  { 0xD1B71758E219652C, -77, -4 },
17207  { 0x9C40000000000000, -50, 4 },
17208  { 0xE8D4A51000000000, -24, 12 },
17209  { 0xAD78EBC5AC620000, 3, 20 },
17210  { 0x813F3978F8940984, 30, 28 },
17211  { 0xC097CE7BC90715B3, 56, 36 },
17212  { 0x8F7E32CE7BEA5C70, 83, 44 },
17213  { 0xD5D238A4ABE98068, 109, 52 },
17214  { 0x9F4F2726179A2245, 136, 60 },
17215  { 0xED63A231D4C4FB27, 162, 68 },
17216  { 0xB0DE65388CC8ADA8, 189, 76 },
17217  { 0x83C7088E1AAB65DB, 216, 84 },
17218  { 0xC45D1DF942711D9A, 242, 92 },
17219  { 0x924D692CA61BE758, 269, 100 },
17220  { 0xDA01EE641A708DEA, 295, 108 },
17221  { 0xA26DA3999AEF774A, 322, 116 },
17222  { 0xF209787BB47D6B85, 348, 124 },
17223  { 0xB454E4A179DD1877, 375, 132 },
17224  { 0x865B86925B9BC5C2, 402, 140 },
17225  { 0xC83553C5C8965D3D, 428, 148 },
17226  { 0x952AB45CFA97A0B3, 455, 156 },
17227  { 0xDE469FBD99A05FE3, 481, 164 },
17228  { 0xA59BC234DB398C25, 508, 172 },
17229  { 0xF6C69A72A3989F5C, 534, 180 },
17230  { 0xB7DCBF5354E9BECE, 561, 188 },
17231  { 0x88FCF317F22241E2, 588, 196 },
17232  { 0xCC20CE9BD35C78A5, 614, 204 },
17233  { 0x98165AF37B2153DF, 641, 212 },
17234  { 0xE2A0B5DC971F303A, 667, 220 },
17235  { 0xA8D9D1535CE3B396, 694, 228 },
17236  { 0xFB9B7CD9A4A7443C, 720, 236 },
17237  { 0xBB764C4CA7A44410, 747, 244 },
17238  { 0x8BAB8EEFB6409C1A, 774, 252 },
17239  { 0xD01FEF10A657842C, 800, 260 },
17240  { 0x9B10A4E5E9913129, 827, 268 },
17241  { 0xE7109BFBA19C0C9D, 853, 276 },
17242  { 0xAC2820D9623BF429, 880, 284 },
17243  { 0x80444B5E7AA7CF85, 907, 292 },
17244  { 0xBF21E44003ACDD2D, 933, 300 },
17245  { 0x8E679C2F5E44FF8F, 960, 308 },
17246  { 0xD433179D9C8CB841, 986, 316 },
17247  { 0x9E19DB92B4E31BA9, 1013, 324 },
17248  }
17249  };
17250 
17251  // This computation gives exactly the same results for k as
17252  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
17253  // for |e| <= 1500, but doesn't require floating-point operations.
17254  // NB: log_10(2) ~= 78913 / 2^18
17255  JSON_ASSERT(e >= -1500);
17256  JSON_ASSERT(e <= 1500);
17257  const int f = kAlpha - e - 1;
17258  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
17259 
17260  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
17261  JSON_ASSERT(index >= 0);
17262  JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
17263 
17264  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
17265  JSON_ASSERT(kAlpha <= cached.e + e + 64);
17266  JSON_ASSERT(kGamma >= cached.e + e + 64);
17267 
17268  return cached;
17269 }
17270 
17275 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
17276 {
17277  // LCOV_EXCL_START
17278  if (n >= 1000000000)
17279  {
17280  pow10 = 1000000000;
17281  return 10;
17282  }
17283  // LCOV_EXCL_STOP
17284  if (n >= 100000000)
17285  {
17286  pow10 = 100000000;
17287  return 9;
17288  }
17289  if (n >= 10000000)
17290  {
17291  pow10 = 10000000;
17292  return 8;
17293  }
17294  if (n >= 1000000)
17295  {
17296  pow10 = 1000000;
17297  return 7;
17298  }
17299  if (n >= 100000)
17300  {
17301  pow10 = 100000;
17302  return 6;
17303  }
17304  if (n >= 10000)
17305  {
17306  pow10 = 10000;
17307  return 5;
17308  }
17309  if (n >= 1000)
17310  {
17311  pow10 = 1000;
17312  return 4;
17313  }
17314  if (n >= 100)
17315  {
17316  pow10 = 100;
17317  return 3;
17318  }
17319  if (n >= 10)
17320  {
17321  pow10 = 10;
17322  return 2;
17323  }
17324 
17325  pow10 = 1;
17326  return 1;
17327 }
17328 
17329 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
17330  std::uint64_t rest, std::uint64_t ten_k)
17331 {
17332  JSON_ASSERT(len >= 1);
17333  JSON_ASSERT(dist <= delta);
17334  JSON_ASSERT(rest <= delta);
17335  JSON_ASSERT(ten_k > 0);
17336 
17337  // <--------------------------- delta ---->
17338  // <---- dist --------->
17339  // --------------[------------------+-------------------]--------------
17340  // M- w M+
17341  //
17342  // ten_k
17343  // <------>
17344  // <---- rest ---->
17345  // --------------[------------------+----+--------------]--------------
17346  // w V
17347  // = buf * 10^k
17348  //
17349  // ten_k represents a unit-in-the-last-place in the decimal representation
17350  // stored in buf.
17351  // Decrement buf by ten_k while this takes buf closer to w.
17352 
17353  // The tests are written in this order to avoid overflow in unsigned
17354  // integer arithmetic.
17355 
17356  while (rest < dist
17357  && delta - rest >= ten_k
17358  && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
17359  {
17360  JSON_ASSERT(buf[len - 1] != '0');
17361  buf[len - 1]--;
17362  rest += ten_k;
17363  }
17364 }
17365 
17370 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
17371  diyfp M_minus, diyfp w, diyfp M_plus)
17372 {
17373  static_assert(kAlpha >= -60, "internal error");
17374  static_assert(kGamma <= -32, "internal error");
17375 
17376  // Generates the digits (and the exponent) of a decimal floating-point
17377  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
17378  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
17379  //
17380  // <--------------------------- delta ---->
17381  // <---- dist --------->
17382  // --------------[------------------+-------------------]--------------
17383  // M- w M+
17384  //
17385  // Grisu2 generates the digits of M+ from left to right and stops as soon as
17386  // V is in [M-,M+].
17387 
17388  JSON_ASSERT(M_plus.e >= kAlpha);
17389  JSON_ASSERT(M_plus.e <= kGamma);
17390 
17391  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
17392  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
17393 
17394  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
17395  //
17396  // M+ = f * 2^e
17397  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
17398  // = ((p1 ) * 2^-e + (p2 )) * 2^e
17399  // = p1 + p2 * 2^e
17400 
17401  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
17402 
17403  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.)
17404  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
17405 
17406  // 1)
17407  //
17408  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
17409 
17410  JSON_ASSERT(p1 > 0);
17411 
17412  std::uint32_t pow10{};
17413  const int k = find_largest_pow10(p1, pow10);
17414 
17415  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
17416  //
17417  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
17418  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
17419  //
17420  // M+ = p1 + p2 * 2^e
17421  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
17422  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
17423  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
17424  //
17425  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
17426  //
17427  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
17428  //
17429  // but stop as soon as
17430  //
17431  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
17432 
17433  int n = k;
17434  while (n > 0)
17435  {
17436  // Invariants:
17437  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
17438  // pow10 = 10^(n-1) <= p1 < 10^n
17439  //
17440  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
17441  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
17442  //
17443  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
17444  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
17445  //
17446  JSON_ASSERT(d <= 9);
17447  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17448  //
17449  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
17450  //
17451  p1 = r;
17452  n--;
17453  //
17454  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
17455  // pow10 = 10^n
17456  //
17457 
17458  // Now check if enough digits have been generated.
17459  // Compute
17460  //
17461  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
17462  //
17463  // Note:
17464  // Since rest and delta share the same exponent e, it suffices to
17465  // compare the significands.
17466  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
17467  if (rest <= delta)
17468  {
17469  // V = buffer * 10^n, with M- <= V <= M+.
17470 
17471  decimal_exponent += n;
17472 
17473  // We may now just stop. But instead look if the buffer could be
17474  // decremented to bring V closer to w.
17475  //
17476  // pow10 = 10^n is now 1 ulp in the decimal representation V.
17477  // The rounding procedure works with diyfp's with an implicit
17478  // exponent of e.
17479  //
17480  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
17481  //
17482  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
17483  grisu2_round(buffer, length, dist, delta, rest, ten_n);
17484 
17485  return;
17486  }
17487 
17488  pow10 /= 10;
17489  //
17490  // pow10 = 10^(n-1) <= p1 < 10^n
17491  // Invariants restored.
17492  }
17493 
17494  // 2)
17495  //
17496  // The digits of the integral part have been generated:
17497  //
17498  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
17499  // = buffer + p2 * 2^e
17500  //
17501  // Now generate the digits of the fractional part p2 * 2^e.
17502  //
17503  // Note:
17504  // No decimal point is generated: the exponent is adjusted instead.
17505  //
17506  // p2 actually represents the fraction
17507  //
17508  // p2 * 2^e
17509  // = p2 / 2^-e
17510  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
17511  //
17512  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
17513  //
17514  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
17515  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
17516  //
17517  // using
17518  //
17519  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
17520  // = ( d) * 2^-e + ( r)
17521  //
17522  // or
17523  // 10^m * p2 * 2^e = d + r * 2^e
17524  //
17525  // i.e.
17526  //
17527  // M+ = buffer + p2 * 2^e
17528  // = buffer + 10^-m * (d + r * 2^e)
17529  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
17530  //
17531  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
17532 
17533  JSON_ASSERT(p2 > delta);
17534 
17535  int m = 0;
17536  for (;;)
17537  {
17538  // Invariant:
17539  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
17540  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
17541  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
17542  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
17543  //
17544  JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
17545  p2 *= 10;
17546  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
17547  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
17548  //
17549  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
17550  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
17551  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
17552  //
17553  JSON_ASSERT(d <= 9);
17554  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17555  //
17556  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
17557  //
17558  p2 = r;
17559  m++;
17560  //
17561  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
17562  // Invariant restored.
17563 
17564  // Check if enough digits have been generated.
17565  //
17566  // 10^-m * p2 * 2^e <= delta * 2^e
17567  // p2 * 2^e <= 10^m * delta * 2^e
17568  // p2 <= 10^m * delta
17569  delta *= 10;
17570  dist *= 10;
17571  if (p2 <= delta)
17572  {
17573  break;
17574  }
17575  }
17576 
17577  // V = buffer * 10^-m, with M- <= V <= M+.
17578 
17579  decimal_exponent -= m;
17580 
17581  // 1 ulp in the decimal representation is now 10^-m.
17582  // Since delta and dist are now scaled by 10^m, we need to do the
17583  // same with ulp in order to keep the units in sync.
17584  //
17585  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
17586  //
17587  const std::uint64_t ten_m = one.f;
17588  grisu2_round(buffer, length, dist, delta, p2, ten_m);
17589 
17590  // By construction this algorithm generates the shortest possible decimal
17591  // number (Loitsch, Theorem 6.2) which rounds back to w.
17592  // For an input number of precision p, at least
17593  //
17594  // N = 1 + ceil(p * log_10(2))
17595  //
17596  // decimal digits are sufficient to identify all binary floating-point
17597  // numbers (Matula, "In-and-Out conversions").
17598  // This implies that the algorithm does not produce more than N decimal
17599  // digits.
17600  //
17601  // N = 17 for p = 53 (IEEE double precision)
17602  // N = 9 for p = 24 (IEEE single precision)
17603 }
17604 
17611 inline void grisu2(char* buf, int& len, int& decimal_exponent,
17612  diyfp m_minus, diyfp v, diyfp m_plus)
17613 {
17614  JSON_ASSERT(m_plus.e == m_minus.e);
17615  JSON_ASSERT(m_plus.e == v.e);
17616 
17617  // --------(-----------------------+-----------------------)-------- (A)
17618  // m- v m+
17619  //
17620  // --------------------(-----------+-----------------------)-------- (B)
17621  // m- v m+
17622  //
17623  // First scale v (and m- and m+) such that the exponent is in the range
17624  // [alpha, gamma].
17625 
17626  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
17627 
17628  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
17629 
17630  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
17631  const diyfp w = diyfp::mul(v, c_minus_k);
17632  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
17633  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
17634 
17635  // ----(---+---)---------------(---+---)---------------(---+---)----
17636  // w- w w+
17637  // = c*m- = c*v = c*m+
17638  //
17639  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
17640  // w+ are now off by a small amount.
17641  // In fact:
17642  //
17643  // w - v * 10^k < 1 ulp
17644  //
17645  // To account for this inaccuracy, add resp. subtract 1 ulp.
17646  //
17647  // --------+---[---------------(---+---)---------------]---+--------
17648  // w- M- w M+ w+
17649  //
17650  // Now any number in [M-, M+] (bounds included) will round to w when input,
17651  // regardless of how the input rounding algorithm breaks ties.
17652  //
17653  // And digit_gen generates the shortest possible such number in [M-, M+].
17654  // Note that this does not mean that Grisu2 always generates the shortest
17655  // possible number in the interval (m-, m+).
17656  const diyfp M_minus(w_minus.f + 1, w_minus.e);
17657  const diyfp M_plus (w_plus.f - 1, w_plus.e );
17658 
17659  decimal_exponent = -cached.k; // = -(-k) = k
17660 
17661  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
17662 }
17663 
17669 template<typename FloatType>
17671 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
17672 {
17673  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
17674  "internal error: not enough precision");
17675 
17676  JSON_ASSERT(std::isfinite(value));
17677  JSON_ASSERT(value > 0);
17678 
17679  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
17680  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
17681  // decimal representations are not exactly "short".
17682  //
17683  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
17684  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
17685  // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
17686  // does.
17687  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
17688  // representation using the corresponding std::from_chars function recovers value exactly". That
17689  // indicates that single precision floating-point numbers should be recovered using
17690  // 'std::strtof'.
17691  //
17692  // NB: If the neighbors are computed for single-precision numbers, there is a single float
17693  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
17694  // value is off by 1 ulp.
17695 #if 0
17696  const boundaries w = compute_boundaries(static_cast<double>(value));
17697 #else
17698  const boundaries w = compute_boundaries(value);
17699 #endif
17700 
17701  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
17702 }
17703 
17711 inline char* append_exponent(char* buf, int e)
17712 {
17713  JSON_ASSERT(e > -1000);
17714  JSON_ASSERT(e < 1000);
17715 
17716  if (e < 0)
17717  {
17718  e = -e;
17719  *buf++ = '-';
17720  }
17721  else
17722  {
17723  *buf++ = '+';
17724  }
17725 
17726  auto k = static_cast<std::uint32_t>(e);
17727  if (k < 10)
17728  {
17729  // Always print at least two digits in the exponent.
17730  // This is for compatibility with printf("%g").
17731  *buf++ = '0';
17732  *buf++ = static_cast<char>('0' + k);
17733  }
17734  else if (k < 100)
17735  {
17736  *buf++ = static_cast<char>('0' + k / 10);
17737  k %= 10;
17738  *buf++ = static_cast<char>('0' + k);
17739  }
17740  else
17741  {
17742  *buf++ = static_cast<char>('0' + k / 100);
17743  k %= 100;
17744  *buf++ = static_cast<char>('0' + k / 10);
17745  k %= 10;
17746  *buf++ = static_cast<char>('0' + k);
17747  }
17748 
17749  return buf;
17750 }
17751 
17763 inline char* format_buffer(char* buf, int len, int decimal_exponent,
17764  int min_exp, int max_exp)
17765 {
17766  JSON_ASSERT(min_exp < 0);
17767  JSON_ASSERT(max_exp > 0);
17768 
17769  const int k = len;
17770  const int n = len + decimal_exponent;
17771 
17772  // v = buf * 10^(n-k)
17773  // k is the length of the buffer (number of decimal digits)
17774  // n is the position of the decimal point relative to the start of the buffer.
17775 
17776  if (k <= n && n <= max_exp)
17777  {
17778  // digits[000]
17779  // len <= max_exp + 2
17780 
17781  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
17782  // Make it look like a floating-point number (#362, #378)
17783  buf[n + 0] = '.';
17784  buf[n + 1] = '0';
17785  return buf + (static_cast<size_t>(n) + 2);
17786  }
17787 
17788  if (0 < n && n <= max_exp)
17789  {
17790  // dig.its
17791  // len <= max_digits10 + 1
17792 
17793  JSON_ASSERT(k > n);
17794 
17795  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
17796  buf[n] = '.';
17797  return buf + (static_cast<size_t>(k) + 1U);
17798  }
17799 
17800  if (min_exp < n && n <= 0)
17801  {
17802  // 0.[000]digits
17803  // len <= 2 + (-min_exp - 1) + max_digits10
17804 
17805  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
17806  buf[0] = '0';
17807  buf[1] = '.';
17808  std::memset(buf + 2, '0', static_cast<size_t>(-n));
17809  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
17810  }
17811 
17812  if (k == 1)
17813  {
17814  // dE+123
17815  // len <= 1 + 5
17816 
17817  buf += 1;
17818  }
17819  else
17820  {
17821  // d.igitsE+123
17822  // len <= max_digits10 + 1 + 5
17823 
17824  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
17825  buf[1] = '.';
17826  buf += 1 + static_cast<size_t>(k);
17827  }
17828 
17829  *buf++ = 'e';
17830  return append_exponent(buf, n - 1);
17831 }
17832 
17833 } // namespace dtoa_impl
17834 
17845 template<typename FloatType>
17848 char* to_chars(char* first, const char* last, FloatType value)
17849 {
17850  static_cast<void>(last); // maybe unused - fix warning
17851  JSON_ASSERT(std::isfinite(value));
17852 
17853  // Use signbit(value) instead of (value < 0) since signbit works for -0.
17854  if (std::signbit(value))
17855  {
17856  value = -value;
17857  *first++ = '-';
17858  }
17859 
17860 #ifdef __GNUC__
17861 #pragma GCC diagnostic push
17862 #pragma GCC diagnostic ignored "-Wfloat-equal"
17863 #endif
17864  if (value == 0) // +-0
17865  {
17866  *first++ = '0';
17867  // Make it look like a floating-point number (#362, #378)
17868  *first++ = '.';
17869  *first++ = '0';
17870  return first;
17871  }
17872 #ifdef __GNUC__
17873 #pragma GCC diagnostic pop
17874 #endif
17875 
17876  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
17877 
17878  // Compute v = buffer * 10^decimal_exponent.
17879  // The decimal digits are stored in the buffer, which needs to be interpreted
17880  // as an unsigned decimal integer.
17881  // len is the length of the buffer, i.e. the number of decimal digits.
17882  int len = 0;
17883  int decimal_exponent = 0;
17884  dtoa_impl::grisu2(first, len, decimal_exponent, value);
17885 
17886  JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
17887 
17888  // Format the buffer like printf("%.*g", prec, value)
17889  constexpr int kMinExp = -4;
17890  // Use digits10 here to increase compatibility with version 2.
17891  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
17892 
17893  JSON_ASSERT(last - first >= kMaxExp + 2);
17894  JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
17895  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
17896 
17897  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
17898 }
17899 
17900 } // namespace detail
17902 
17903 // #include <nlohmann/detail/exceptions.hpp>
17904 
17905 // #include <nlohmann/detail/macro_scope.hpp>
17906 
17907 // #include <nlohmann/detail/meta/cpp_future.hpp>
17908 
17909 // #include <nlohmann/detail/output/binary_writer.hpp>
17910 
17911 // #include <nlohmann/detail/output/output_adapters.hpp>
17912 
17913 // #include <nlohmann/detail/string_concat.hpp>
17914 
17915 // #include <nlohmann/detail/value_t.hpp>
17916 
17917 
17919 namespace detail
17920 {
17921 
17923 // serialization //
17925 
17928 {
17929  strict,
17930  replace,
17931  ignore
17932 };
17933 
17934 template<typename BasicJsonType>
17936 {
17937  using string_t = typename BasicJsonType::string_t;
17938  using number_float_t = typename BasicJsonType::number_float_t;
17939  using number_integer_t = typename BasicJsonType::number_integer_t;
17940  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17941  using binary_char_t = typename BasicJsonType::binary_t::value_type;
17942  static constexpr std::uint8_t UTF8_ACCEPT = 0;
17943  static constexpr std::uint8_t UTF8_REJECT = 1;
17944 
17945  public:
17951  serializer(output_adapter_t<char> s, const char ichar,
17952  error_handler_t error_handler_ = error_handler_t::strict)
17953  : o(std::move(s))
17954  , loc(std::localeconv())
17955  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
17956  , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
17957  , indent_char(ichar)
17958  , indent_string(512, indent_char)
17959  , error_handler(error_handler_)
17960  {}
17961 
17962  // delete because of pointer members
17963  serializer(const serializer&) = delete;
17964  serializer& operator=(const serializer&) = delete;
17965  serializer(serializer&&) = delete;
17966  serializer& operator=(serializer&&) = delete;
17967  ~serializer() = default;
17968 
17991  void dump(const BasicJsonType& val,
17992  const bool pretty_print,
17993  const bool ensure_ascii,
17994  const unsigned int indent_step,
17995  const unsigned int current_indent = 0)
17996  {
17997  switch (val.m_type)
17998  {
17999  case value_t::object:
18000  {
18001  if (val.m_value.object->empty())
18002  {
18003  o->write_characters("{}", 2);
18004  return;
18005  }
18006 
18007  if (pretty_print)
18008  {
18009  o->write_characters("{\n", 2);
18010 
18011  // variable to hold indentation for recursive calls
18012  const auto new_indent = current_indent + indent_step;
18013  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18014  {
18015  indent_string.resize(indent_string.size() * 2, ' ');
18016  }
18017 
18018  // first n-1 elements
18019  auto i = val.m_value.object->cbegin();
18020  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
18021  {
18022  o->write_characters(indent_string.c_str(), new_indent);
18023  o->write_character('\"');
18024  dump_escaped(i->first, ensure_ascii);
18025  o->write_characters("\": ", 3);
18026  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18027  o->write_characters(",\n", 2);
18028  }
18029 
18030  // last element
18031  JSON_ASSERT(i != val.m_value.object->cend());
18032  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
18033  o->write_characters(indent_string.c_str(), new_indent);
18034  o->write_character('\"');
18035  dump_escaped(i->first, ensure_ascii);
18036  o->write_characters("\": ", 3);
18037  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18038 
18039  o->write_character('\n');
18040  o->write_characters(indent_string.c_str(), current_indent);
18041  o->write_character('}');
18042  }
18043  else
18044  {
18045  o->write_character('{');
18046 
18047  // first n-1 elements
18048  auto i = val.m_value.object->cbegin();
18049  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
18050  {
18051  o->write_character('\"');
18052  dump_escaped(i->first, ensure_ascii);
18053  o->write_characters("\":", 2);
18054  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18055  o->write_character(',');
18056  }
18057 
18058  // last element
18059  JSON_ASSERT(i != val.m_value.object->cend());
18060  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
18061  o->write_character('\"');
18062  dump_escaped(i->first, ensure_ascii);
18063  o->write_characters("\":", 2);
18064  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18065 
18066  o->write_character('}');
18067  }
18068 
18069  return;
18070  }
18071 
18072  case value_t::array:
18073  {
18074  if (val.m_value.array->empty())
18075  {
18076  o->write_characters("[]", 2);
18077  return;
18078  }
18079 
18080  if (pretty_print)
18081  {
18082  o->write_characters("[\n", 2);
18083 
18084  // variable to hold indentation for recursive calls
18085  const auto new_indent = current_indent + indent_step;
18086  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18087  {
18088  indent_string.resize(indent_string.size() * 2, ' ');
18089  }
18090 
18091  // first n-1 elements
18092  for (auto i = val.m_value.array->cbegin();
18093  i != val.m_value.array->cend() - 1; ++i)
18094  {
18095  o->write_characters(indent_string.c_str(), new_indent);
18096  dump(*i, true, ensure_ascii, indent_step, new_indent);
18097  o->write_characters(",\n", 2);
18098  }
18099 
18100  // last element
18101  JSON_ASSERT(!val.m_value.array->empty());
18102  o->write_characters(indent_string.c_str(), new_indent);
18103  dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
18104 
18105  o->write_character('\n');
18106  o->write_characters(indent_string.c_str(), current_indent);
18107  o->write_character(']');
18108  }
18109  else
18110  {
18111  o->write_character('[');
18112 
18113  // first n-1 elements
18114  for (auto i = val.m_value.array->cbegin();
18115  i != val.m_value.array->cend() - 1; ++i)
18116  {
18117  dump(*i, false, ensure_ascii, indent_step, current_indent);
18118  o->write_character(',');
18119  }
18120 
18121  // last element
18122  JSON_ASSERT(!val.m_value.array->empty());
18123  dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
18124 
18125  o->write_character(']');
18126  }
18127 
18128  return;
18129  }
18130 
18131  case value_t::string:
18132  {
18133  o->write_character('\"');
18134  dump_escaped(*val.m_value.string, ensure_ascii);
18135  o->write_character('\"');
18136  return;
18137  }
18138 
18139  case value_t::binary:
18140  {
18141  if (pretty_print)
18142  {
18143  o->write_characters("{\n", 2);
18144 
18145  // variable to hold indentation for recursive calls
18146  const auto new_indent = current_indent + indent_step;
18147  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18148  {
18149  indent_string.resize(indent_string.size() * 2, ' ');
18150  }
18151 
18152  o->write_characters(indent_string.c_str(), new_indent);
18153 
18154  o->write_characters("\"bytes\": [", 10);
18155 
18156  if (!val.m_value.binary->empty())
18157  {
18158  for (auto i = val.m_value.binary->cbegin();
18159  i != val.m_value.binary->cend() - 1; ++i)
18160  {
18161  dump_integer(*i);
18162  o->write_characters(", ", 2);
18163  }
18164  dump_integer(val.m_value.binary->back());
18165  }
18166 
18167  o->write_characters("],\n", 3);
18168  o->write_characters(indent_string.c_str(), new_indent);
18169 
18170  o->write_characters("\"subtype\": ", 11);
18171  if (val.m_value.binary->has_subtype())
18172  {
18173  dump_integer(val.m_value.binary->subtype());
18174  }
18175  else
18176  {
18177  o->write_characters("null", 4);
18178  }
18179  o->write_character('\n');
18180  o->write_characters(indent_string.c_str(), current_indent);
18181  o->write_character('}');
18182  }
18183  else
18184  {
18185  o->write_characters("{\"bytes\":[", 10);
18186 
18187  if (!val.m_value.binary->empty())
18188  {
18189  for (auto i = val.m_value.binary->cbegin();
18190  i != val.m_value.binary->cend() - 1; ++i)
18191  {
18192  dump_integer(*i);
18193  o->write_character(',');
18194  }
18195  dump_integer(val.m_value.binary->back());
18196  }
18197 
18198  o->write_characters("],\"subtype\":", 12);
18199  if (val.m_value.binary->has_subtype())
18200  {
18201  dump_integer(val.m_value.binary->subtype());
18202  o->write_character('}');
18203  }
18204  else
18205  {
18206  o->write_characters("null}", 5);
18207  }
18208  }
18209  return;
18210  }
18211 
18212  case value_t::boolean:
18213  {
18214  if (val.m_value.boolean)
18215  {
18216  o->write_characters("true", 4);
18217  }
18218  else
18219  {
18220  o->write_characters("false", 5);
18221  }
18222  return;
18223  }
18224 
18226  {
18227  dump_integer(val.m_value.number_integer);
18228  return;
18229  }
18230 
18232  {
18233  dump_integer(val.m_value.number_unsigned);
18234  return;
18235  }
18236 
18237  case value_t::number_float:
18238  {
18239  dump_float(val.m_value.number_float);
18240  return;
18241  }
18242 
18243  case value_t::discarded:
18244  {
18245  o->write_characters("<discarded>", 11);
18246  return;
18247  }
18248 
18249  case value_t::null:
18250  {
18251  o->write_characters("null", 4);
18252  return;
18253  }
18254 
18255  default: // LCOV_EXCL_LINE
18256  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18257  }
18258  }
18259 
18275  void dump_escaped(const string_t& s, const bool ensure_ascii)
18276  {
18277  std::uint32_t codepoint{};
18278  std::uint8_t state = UTF8_ACCEPT;
18279  std::size_t bytes = 0; // number of bytes written to string_buffer
18280 
18281  // number of bytes written at the point of the last valid byte
18282  std::size_t bytes_after_last_accept = 0;
18283  std::size_t undumped_chars = 0;
18284 
18285  for (std::size_t i = 0; i < s.size(); ++i)
18286  {
18287  const auto byte = static_cast<std::uint8_t>(s[i]);
18288 
18289  switch (decode(state, codepoint, byte))
18290  {
18291  case UTF8_ACCEPT: // decode found a new code point
18292  {
18293  switch (codepoint)
18294  {
18295  case 0x08: // backspace
18296  {
18297  string_buffer[bytes++] = '\\';
18298  string_buffer[bytes++] = 'b';
18299  break;
18300  }
18301 
18302  case 0x09: // horizontal tab
18303  {
18304  string_buffer[bytes++] = '\\';
18305  string_buffer[bytes++] = 't';
18306  break;
18307  }
18308 
18309  case 0x0A: // newline
18310  {
18311  string_buffer[bytes++] = '\\';
18312  string_buffer[bytes++] = 'n';
18313  break;
18314  }
18315 
18316  case 0x0C: // formfeed
18317  {
18318  string_buffer[bytes++] = '\\';
18319  string_buffer[bytes++] = 'f';
18320  break;
18321  }
18322 
18323  case 0x0D: // carriage return
18324  {
18325  string_buffer[bytes++] = '\\';
18326  string_buffer[bytes++] = 'r';
18327  break;
18328  }
18329 
18330  case 0x22: // quotation mark
18331  {
18332  string_buffer[bytes++] = '\\';
18333  string_buffer[bytes++] = '\"';
18334  break;
18335  }
18336 
18337  case 0x5C: // reverse solidus
18338  {
18339  string_buffer[bytes++] = '\\';
18340  string_buffer[bytes++] = '\\';
18341  break;
18342  }
18343 
18344  default:
18345  {
18346  // escape control characters (0x00..0x1F) or, if
18347  // ensure_ascii parameter is used, non-ASCII characters
18348  if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
18349  {
18350  if (codepoint <= 0xFFFF)
18351  {
18352  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18353  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
18354  static_cast<std::uint16_t>(codepoint)));
18355  bytes += 6;
18356  }
18357  else
18358  {
18359  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18360  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
18361  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
18362  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
18363  bytes += 12;
18364  }
18365  }
18366  else
18367  {
18368  // copy byte to buffer (all previous bytes
18369  // been copied have in default case above)
18370  string_buffer[bytes++] = s[i];
18371  }
18372  break;
18373  }
18374  }
18375 
18376  // write buffer and reset index; there must be 13 bytes
18377  // left, as this is the maximal number of bytes to be
18378  // written ("\uxxxx\uxxxx\0") for one code point
18379  if (string_buffer.size() - bytes < 13)
18380  {
18381  o->write_characters(string_buffer.data(), bytes);
18382  bytes = 0;
18383  }
18384 
18385  // remember the byte position of this accept
18387  undumped_chars = 0;
18388  break;
18389  }
18390 
18391  case UTF8_REJECT: // decode found invalid UTF-8 byte
18392  {
18393  switch (error_handler)
18394  {
18396  {
18397  JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
18398  }
18399 
18402  {
18403  // in case we saw this character the first time, we
18404  // would like to read it again, because the byte
18405  // may be OK for itself, but just not OK for the
18406  // previous sequence
18407  if (undumped_chars > 0)
18408  {
18409  --i;
18410  }
18411 
18412  // reset length buffer to the last accepted index;
18413  // thus removing/ignoring the invalid characters
18415 
18417  {
18418  // add a replacement character
18419  if (ensure_ascii)
18420  {
18421  string_buffer[bytes++] = '\\';
18422  string_buffer[bytes++] = 'u';
18423  string_buffer[bytes++] = 'f';
18424  string_buffer[bytes++] = 'f';
18425  string_buffer[bytes++] = 'f';
18426  string_buffer[bytes++] = 'd';
18427  }
18428  else
18429  {
18433  }
18434 
18435  // write buffer and reset index; there must be 13 bytes
18436  // left, as this is the maximal number of bytes to be
18437  // written ("\uxxxx\uxxxx\0") for one code point
18438  if (string_buffer.size() - bytes < 13)
18439  {
18440  o->write_characters(string_buffer.data(), bytes);
18441  bytes = 0;
18442  }
18443 
18445  }
18446 
18447  undumped_chars = 0;
18448 
18449  // continue processing the string
18450  state = UTF8_ACCEPT;
18451  break;
18452  }
18453 
18454  default: // LCOV_EXCL_LINE
18455  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18456  }
18457  break;
18458  }
18459 
18460  default: // decode found yet incomplete multi-byte code point
18461  {
18462  if (!ensure_ascii)
18463  {
18464  // code point will not be escaped - copy byte to buffer
18465  string_buffer[bytes++] = s[i];
18466  }
18467  ++undumped_chars;
18468  break;
18469  }
18470  }
18471  }
18472 
18473  // we finished processing the string
18474  if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
18475  {
18476  // write buffer
18477  if (bytes > 0)
18478  {
18479  o->write_characters(string_buffer.data(), bytes);
18480  }
18481  }
18482  else
18483  {
18484  // we finish reading, but do not accept: string was incomplete
18485  switch (error_handler)
18486  {
18488  {
18489  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));
18490  }
18491 
18493  {
18494  // write all accepted bytes
18495  o->write_characters(string_buffer.data(), bytes_after_last_accept);
18496  break;
18497  }
18498 
18500  {
18501  // write all accepted bytes
18502  o->write_characters(string_buffer.data(), bytes_after_last_accept);
18503  // add a replacement character
18504  if (ensure_ascii)
18505  {
18506  o->write_characters("\\ufffd", 6);
18507  }
18508  else
18509  {
18510  o->write_characters("\xEF\xBF\xBD", 3);
18511  }
18512  break;
18513  }
18514 
18515  default: // LCOV_EXCL_LINE
18516  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18517  }
18518  }
18519  }
18520 
18521  private:
18530  inline unsigned int count_digits(number_unsigned_t x) noexcept
18531  {
18532  unsigned int n_digits = 1;
18533  for (;;)
18534  {
18535  if (x < 10)
18536  {
18537  return n_digits;
18538  }
18539  if (x < 100)
18540  {
18541  return n_digits + 1;
18542  }
18543  if (x < 1000)
18544  {
18545  return n_digits + 2;
18546  }
18547  if (x < 10000)
18548  {
18549  return n_digits + 3;
18550  }
18551  x = x / 10000u;
18552  n_digits += 4;
18553  }
18554  }
18555 
18561  static std::string hex_bytes(std::uint8_t byte)
18562  {
18563  std::string result = "FF";
18564  constexpr const char* nibble_to_hex = "0123456789ABCDEF";
18565  result[0] = nibble_to_hex[byte / 16];
18566  result[1] = nibble_to_hex[byte % 16];
18567  return result;
18568  }
18569 
18570  // templates to avoid warnings about useless casts
18571  template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
18572  bool is_negative_number(NumberType x)
18573  {
18574  return x < 0;
18575  }
18576 
18577  template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
18578  bool is_negative_number(NumberType /*unused*/)
18579  {
18580  return false;
18581  }
18582 
18592  template < typename NumberType, detail::enable_if_t <
18593  std::is_integral<NumberType>::value ||
18594  std::is_same<NumberType, number_unsigned_t>::value ||
18595  std::is_same<NumberType, number_integer_t>::value ||
18596  std::is_same<NumberType, binary_char_t>::value,
18597  int > = 0 >
18598  void dump_integer(NumberType x)
18599  {
18600  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
18601  {
18602  {
18603  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
18604  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
18605  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
18606  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
18607  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
18608  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
18609  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
18610  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
18611  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
18612  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
18613  }
18614  };
18615 
18616  // special case for "0"
18617  if (x == 0)
18618  {
18619  o->write_character('0');
18620  return;
18621  }
18622 
18623  // use a pointer to fill the buffer
18624  auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18625 
18626  number_unsigned_t abs_value;
18627 
18628  unsigned int n_chars{};
18629 
18630  if (is_negative_number(x))
18631  {
18632  *buffer_ptr = '-';
18633  abs_value = remove_sign(static_cast<number_integer_t>(x));
18634 
18635  // account one more byte for the minus sign
18636  n_chars = 1 + count_digits(abs_value);
18637  }
18638  else
18639  {
18640  abs_value = static_cast<number_unsigned_t>(x);
18641  n_chars = count_digits(abs_value);
18642  }
18643 
18644  // spare 1 byte for '\0'
18645  JSON_ASSERT(n_chars < number_buffer.size() - 1);
18646 
18647  // jump to the end to generate the string from backward,
18648  // so we later avoid reversing the result
18649  buffer_ptr += n_chars;
18650 
18651  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
18652  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
18653  while (abs_value >= 100)
18654  {
18655  const auto digits_index = static_cast<unsigned>((abs_value % 100));
18656  abs_value /= 100;
18657  *(--buffer_ptr) = digits_to_99[digits_index][1];
18658  *(--buffer_ptr) = digits_to_99[digits_index][0];
18659  }
18660 
18661  if (abs_value >= 10)
18662  {
18663  const auto digits_index = static_cast<unsigned>(abs_value);
18664  *(--buffer_ptr) = digits_to_99[digits_index][1];
18665  *(--buffer_ptr) = digits_to_99[digits_index][0];
18666  }
18667  else
18668  {
18669  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
18670  }
18671 
18672  o->write_characters(number_buffer.data(), n_chars);
18673  }
18674 
18683  void dump_float(number_float_t x)
18684  {
18685  // NaN / inf
18686  if (!std::isfinite(x))
18687  {
18688  o->write_characters("null", 4);
18689  return;
18690  }
18691 
18692  // If number_float_t is an IEEE-754 single or double precision number,
18693  // use the Grisu2 algorithm to produce short numbers which are
18694  // guaranteed to round-trip, using strtof and strtod, resp.
18695  //
18696  // NB: The test below works if <long double> == <double>.
18697  static constexpr bool is_ieee_single_or_double
18698  = (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) ||
18699  (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);
18700 
18701  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
18702  }
18703 
18704  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
18705  {
18706  auto* begin = number_buffer.data();
18707  auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
18708 
18709  o->write_characters(begin, static_cast<size_t>(end - begin));
18710  }
18711 
18712  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
18713  {
18714  // get number of digits for a float -> text -> float round-trip
18715  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
18716 
18717  // the actual conversion
18718  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18719  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
18720 
18721  // negative value indicates an error
18722  JSON_ASSERT(len > 0);
18723  // check if buffer was large enough
18724  JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
18725 
18726  // erase thousands separator
18727  if (thousands_sep != '\0')
18728  {
18729  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
18730  const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
18731  std::fill(end, number_buffer.end(), '\0');
18732  JSON_ASSERT((end - number_buffer.begin()) <= len);
18733  len = (end - number_buffer.begin());
18734  }
18735 
18736  // convert decimal point to '.'
18737  if (decimal_point != '\0' && decimal_point != '.')
18738  {
18739  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
18740  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
18741  if (dec_pos != number_buffer.end())
18742  {
18743  *dec_pos = '.';
18744  }
18745  }
18746 
18747  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
18748 
18749  // determine if we need to append ".0"
18750  const bool value_is_int_like =
18751  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
18752  [](char c)
18753  {
18754  return c == '.' || c == 'e';
18755  });
18756 
18757  if (value_is_int_like)
18758  {
18759  o->write_characters(".0", 2);
18760  }
18761  }
18762 
18784  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
18785  {
18786  static const std::array<std::uint8_t, 400> utf8d =
18787  {
18788  {
18789  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
18790  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
18791  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
18792  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
18793  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
18794  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
18795  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
18796  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
18797  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
18798  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
18799  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
18800  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
18801  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
18802  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
18803  }
18804  };
18805 
18806  JSON_ASSERT(byte < utf8d.size());
18807  const std::uint8_t type = utf8d[byte];
18808 
18809  codep = (state != UTF8_ACCEPT)
18810  ? (byte & 0x3fu) | (codep << 6u)
18811  : (0xFFu >> type) & (byte);
18812 
18813  std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
18814  JSON_ASSERT(index < 400);
18815  state = utf8d[index];
18816  return state;
18817  }
18818 
18819  /*
18820  * Overload to make the compiler happy while it is instantiating
18821  * dump_integer for number_unsigned_t.
18822  * Must never be called.
18823  */
18824  number_unsigned_t remove_sign(number_unsigned_t x)
18825  {
18826  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18827  return x; // LCOV_EXCL_LINE
18828  }
18829 
18830  /*
18831  * Helper function for dump_integer
18832  *
18833  * This function takes a negative signed integer and returns its absolute
18834  * value as unsigned integer. The plus/minus shuffling is necessary as we can
18835  * not directly remove the sign of an arbitrary signed integer as the
18836  * absolute values of INT_MIN and INT_MAX are usually not the same. See
18837  * #1708 for details.
18838  */
18839  inline number_unsigned_t remove_sign(number_integer_t x) noexcept
18840  {
18841  JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
18842  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
18843  }
18844 
18845  private:
18847  output_adapter_t<char> o = nullptr;
18848 
18850  std::array<char, 64> number_buffer{{}};
18851 
18853  const std::lconv* loc = nullptr;
18855  const char thousands_sep = '\0';
18857  const char decimal_point = '\0';
18858 
18860  std::array<char, 512> string_buffer{{}};
18861 
18863  const char indent_char;
18865  string_t indent_string;
18866 
18869 };
18870 
18871 } // namespace detail
18873 
18874 // #include <nlohmann/detail/value_t.hpp>
18875 
18876 // #include <nlohmann/json_fwd.hpp>
18877 
18878 // #include <nlohmann/ordered_map.hpp>
18879 // __ _____ _____ _____
18880 // __| | __| | | | JSON for Modern C++
18881 // | | |__ | | | | | | version 3.11.2
18882 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
18883 //
18884 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
18885 // SPDX-License-Identifier: MIT
18886 
18887 
18888 
18889 #include <functional> // equal_to, less
18890 #include <initializer_list> // initializer_list
18891 #include <iterator> // input_iterator_tag, iterator_traits
18892 #include <memory> // allocator
18893 #include <stdexcept> // for out_of_range
18894 #include <type_traits> // enable_if, is_convertible
18895 #include <utility> // pair
18896 #include <vector> // vector
18897 
18898 // #include <nlohmann/detail/macro_scope.hpp>
18899 
18900 // #include <nlohmann/detail/meta/type_traits.hpp>
18901 
18902 
18904 
18907 template <class Key, class T, class IgnoredLess = std::less<Key>,
18908  class Allocator = std::allocator<std::pair<const Key, T>>>
18909  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
18910 {
18911  using key_type = Key;
18912  using mapped_type = T;
18913  using Container = std::vector<std::pair<const Key, T>, Allocator>;
18914  using iterator = typename Container::iterator;
18915  using const_iterator = typename Container::const_iterator;
18916  using size_type = typename Container::size_type;
18917  using value_type = typename Container::value_type;
18918 #ifdef JSON_HAS_CPP_14
18919  using key_compare = std::equal_to<>;
18920 #else
18921  using key_compare = std::equal_to<Key>;
18922 #endif
18923 
18924  // Explicit constructors instead of `using Container::Container`
18925  // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
18926  ordered_map() noexcept(noexcept(Container())) : Container{} {}
18927  explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
18928  template <class It>
18929  ordered_map(It first, It last, const Allocator& alloc = Allocator())
18930  : Container{first, last, alloc} {}
18931  ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
18932  : Container{init, alloc} {}
18933 
18934  std::pair<iterator, bool> emplace(const key_type& key, T&& t)
18935  {
18936  for (auto it = this->begin(); it != this->end(); ++it)
18937  {
18938  if (m_compare(it->first, key))
18939  {
18940  return {it, false};
18941  }
18942  }
18943  Container::emplace_back(key, std::forward<T>(t));
18944  return {std::prev(this->end()), true};
18945  }
18946 
18947  template<class KeyType, detail::enable_if_t<
18949  std::pair<iterator, bool> emplace(KeyType && key, T && t)
18950  {
18951  for (auto it = this->begin(); it != this->end(); ++it)
18952  {
18953  if (m_compare(it->first, key))
18954  {
18955  return {it, false};
18956  }
18957  }
18958  Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
18959  return {std::prev(this->end()), true};
18960  }
18961 
18962  T& operator[](const key_type& key)
18963  {
18964  return emplace(key, T{}).first->second;
18965  }
18966 
18967  template<class KeyType, detail::enable_if_t<
18969  T & operator[](KeyType && key)
18970  {
18971  return emplace(std::forward<KeyType>(key), T{}).first->second;
18972  }
18973 
18974  const T& operator[](const key_type& key) const
18975  {
18976  return at(key);
18977  }
18978 
18979  template<class KeyType, detail::enable_if_t<
18981  const T & operator[](KeyType && key) const
18982  {
18983  return at(std::forward<KeyType>(key));
18984  }
18985 
18986  T& at(const key_type& key)
18987  {
18988  for (auto it = this->begin(); it != this->end(); ++it)
18989  {
18990  if (m_compare(it->first, key))
18991  {
18992  return it->second;
18993  }
18994  }
18995 
18996  JSON_THROW(std::out_of_range("key not found"));
18997  }
18998 
18999  template<class KeyType, detail::enable_if_t<
19001  T & at(KeyType && key)
19002  {
19003  for (auto it = this->begin(); it != this->end(); ++it)
19004  {
19005  if (m_compare(it->first, key))
19006  {
19007  return it->second;
19008  }
19009  }
19010 
19011  JSON_THROW(std::out_of_range("key not found"));
19012  }
19013 
19014  const T& at(const key_type& key) const
19015  {
19016  for (auto it = this->begin(); it != this->end(); ++it)
19017  {
19018  if (m_compare(it->first, key))
19019  {
19020  return it->second;
19021  }
19022  }
19023 
19024  JSON_THROW(std::out_of_range("key not found"));
19025  }
19026 
19027  template<class KeyType, detail::enable_if_t<
19029  const T & at(KeyType && key) const
19030  {
19031  for (auto it = this->begin(); it != this->end(); ++it)
19032  {
19033  if (m_compare(it->first, key))
19034  {
19035  return it->second;
19036  }
19037  }
19038 
19039  JSON_THROW(std::out_of_range("key not found"));
19040  }
19041 
19043  {
19044  for (auto it = this->begin(); it != this->end(); ++it)
19045  {
19046  if (m_compare(it->first, key))
19047  {
19048  // Since we cannot move const Keys, re-construct them in place
19049  for (auto next = it; ++next != this->end(); ++it)
19050  {
19051  it->~value_type(); // Destroy but keep allocation
19052  new (&*it) value_type{std::move(*next)};
19053  }
19054  Container::pop_back();
19055  return 1;
19056  }
19057  }
19058  return 0;
19059  }
19060 
19061  template<class KeyType, detail::enable_if_t<
19063  size_type erase(KeyType && key)
19064  {
19065  for (auto it = this->begin(); it != this->end(); ++it)
19066  {
19067  if (m_compare(it->first, key))
19068  {
19069  // Since we cannot move const Keys, re-construct them in place
19070  for (auto next = it; ++next != this->end(); ++it)
19071  {
19072  it->~value_type(); // Destroy but keep allocation
19073  new (&*it) value_type{std::move(*next)};
19074  }
19075  Container::pop_back();
19076  return 1;
19077  }
19078  }
19079  return 0;
19080  }
19081 
19083  {
19084  return erase(pos, std::next(pos));
19085  }
19086 
19088  {
19089  if (first == last)
19090  {
19091  return first;
19092  }
19093 
19094  const auto elements_affected = std::distance(first, last);
19095  const auto offset = std::distance(Container::begin(), first);
19096 
19097  // This is the start situation. We need to delete elements_affected
19098  // elements (3 in this example: e, f, g), and need to return an
19099  // iterator past the last deleted element (h in this example).
19100  // Note that offset is the distance from the start of the vector
19101  // to first. We will need this later.
19102 
19103  // [ a, b, c, d, e, f, g, h, i, j ]
19104  // ^ ^
19105  // first last
19106 
19107  // Since we cannot move const Keys, we re-construct them in place.
19108  // We start at first and re-construct (viz. copy) the elements from
19109  // the back of the vector. Example for first iteration:
19110 
19111  // ,--------.
19112  // v | destroy e and re-construct with h
19113  // [ a, b, c, d, e, f, g, h, i, j ]
19114  // ^ ^
19115  // it it + elements_affected
19116 
19117  for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
19118  {
19119  it->~value_type(); // destroy but keep allocation
19120  new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
19121  }
19122 
19123  // [ a, b, c, d, h, i, j, h, i, j ]
19124  // ^ ^
19125  // first last
19126 
19127  // remove the unneeded elements at the end of the vector
19128  Container::resize(this->size() - static_cast<size_type>(elements_affected));
19129 
19130  // [ a, b, c, d, h, i, j ]
19131  // ^ ^
19132  // first last
19133 
19134  // first is now pointing past the last deleted element, but we cannot
19135  // use this iterator, because it may have been invalidated by the
19136  // resize call. Instead, we can return begin() + offset.
19137  return Container::begin() + offset;
19138  }
19139 
19140  size_type count(const key_type& key) const
19141  {
19142  for (auto it = this->begin(); it != this->end(); ++it)
19143  {
19144  if (m_compare(it->first, key))
19145  {
19146  return 1;
19147  }
19148  }
19149  return 0;
19150  }
19151 
19152  template<class KeyType, detail::enable_if_t<
19154  size_type count(KeyType && key) const
19155  {
19156  for (auto it = this->begin(); it != this->end(); ++it)
19157  {
19158  if (m_compare(it->first, key))
19159  {
19160  return 1;
19161  }
19162  }
19163  return 0;
19164  }
19165 
19166  iterator find(const key_type& key)
19167  {
19168  for (auto it = this->begin(); it != this->end(); ++it)
19169  {
19170  if (m_compare(it->first, key))
19171  {
19172  return it;
19173  }
19174  }
19175  return Container::end();
19176  }
19177 
19178  template<class KeyType, detail::enable_if_t<
19180  iterator find(KeyType && key)
19181  {
19182  for (auto it = this->begin(); it != this->end(); ++it)
19183  {
19184  if (m_compare(it->first, key))
19185  {
19186  return it;
19187  }
19188  }
19189  return Container::end();
19190  }
19191 
19192  const_iterator find(const key_type& key) const
19193  {
19194  for (auto it = this->begin(); it != this->end(); ++it)
19195  {
19196  if (m_compare(it->first, key))
19197  {
19198  return it;
19199  }
19200  }
19201  return Container::end();
19202  }
19203 
19204  std::pair<iterator, bool> insert( value_type&& value )
19205  {
19206  return emplace(value.first, std::move(value.second));
19207  }
19208 
19209  std::pair<iterator, bool> insert( const value_type& value )
19210  {
19211  for (auto it = this->begin(); it != this->end(); ++it)
19212  {
19213  if (m_compare(it->first, value.first))
19214  {
19215  return {it, false};
19216  }
19217  }
19218  Container::push_back(value);
19219  return {--this->end(), true};
19220  }
19221 
19222  template<typename InputIt>
19223  using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
19224  std::input_iterator_tag>::value>::type;
19225 
19226  template<typename InputIt, typename = require_input_iter<InputIt>>
19227  void insert(InputIt first, InputIt last)
19228  {
19229  for (auto it = first; it != last; ++it)
19230  {
19231  insert(*it);
19232  }
19233  }
19234 
19235 private:
19237 };
19238 
19240 
19241 
19242 #if defined(JSON_HAS_CPP_17)
19243  #include <any>
19244  #include <string_view>
19245 #endif
19246 
19253 
19273 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
19274 {
19275  private:
19276  template<detail::value_t> friend struct detail::external_constructor;
19277 
19278  template<typename>
19279  friend class ::nlohmann::json_pointer;
19280  // can be restored when json_pointer backwards compatibility is removed
19281  // friend ::nlohmann::json_pointer<StringType>;
19282 
19283  template<typename BasicJsonType, typename InputType>
19284  friend class ::nlohmann::detail::parser;
19285  friend ::nlohmann::detail::serializer<basic_json>;
19286  template<typename BasicJsonType>
19287  friend class ::nlohmann::detail::iter_impl;
19288  template<typename BasicJsonType, typename CharType>
19289  friend class ::nlohmann::detail::binary_writer;
19290  template<typename BasicJsonType, typename InputType, typename SAX>
19291  friend class ::nlohmann::detail::binary_reader;
19292  template<typename BasicJsonType>
19293  friend class ::nlohmann::detail::json_sax_dom_parser;
19294  template<typename BasicJsonType>
19295  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
19296  friend class ::nlohmann::detail::exception;
19297 
19299  using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
19300 
19302  // convenience aliases for types residing in namespace detail;
19303  using lexer = ::nlohmann::detail::lexer_base<basic_json>;
19304 
19305  template<typename InputAdapterType>
19306  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
19307  InputAdapterType adapter,
19309  const bool allow_exceptions = true,
19310  const bool ignore_comments = false
19311  )
19312  {
19313  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
19314  std::move(cb), allow_exceptions, ignore_comments);
19315  }
19316 
19317  private:
19318  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
19319  template<typename BasicJsonType>
19320  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
19321  template<typename BasicJsonType>
19322  using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
19323  template<typename Iterator>
19324  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
19325  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
19326 
19327  template<typename CharType>
19328  using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
19329 
19330  template<typename InputType>
19331  using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
19332  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
19333 
19335  using serializer = ::nlohmann::detail::serializer<basic_json>;
19336 
19337  public:
19340  using json_pointer = ::nlohmann::json_pointer<StringType>;
19341  template<typename T, typename SFINAE>
19342  using json_serializer = JSONSerializer<T, SFINAE>;
19348  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
19349 
19353 
19355  // exceptions //
19357 
19361 
19368 
19370 
19371 
19373  // container types //
19375 
19380 
19383 
19387  using const_reference = const value_type&;
19388 
19390  using difference_type = std::ptrdiff_t;
19392  using size_type = std::size_t;
19393 
19395  using allocator_type = AllocatorType<basic_json>;
19396 
19398  using pointer = typename std::allocator_traits<allocator_type>::pointer;
19400  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
19401 
19403  using iterator = iter_impl<basic_json>;
19405  using const_iterator = iter_impl<const basic_json>;
19407  using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
19409  using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
19410 
19412 
19413 
19417  {
19418  return allocator_type();
19419  }
19420 
19424  static basic_json meta()
19425  {
19426  basic_json result;
19427 
19428  result["copyright"] = "(C) 2013-2022 Niels Lohmann";
19429  result["name"] = "JSON for Modern C++";
19430  result["url"] = "https://github.com/nlohmann/json";
19431  result["version"]["string"] =
19435  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
19436  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
19437  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
19438 
19439 #ifdef _WIN32
19440  result["platform"] = "win32";
19441 #elif defined __linux__
19442  result["platform"] = "linux";
19443 #elif defined __APPLE__
19444  result["platform"] = "apple";
19445 #elif defined __unix__
19446  result["platform"] = "unix";
19447 #else
19448  result["platform"] = "unknown";
19449 #endif
19450 
19451 #if defined(__ICC) || defined(__INTEL_COMPILER)
19452  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
19453 #elif defined(__clang__)
19454  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
19455 #elif defined(__GNUC__) || defined(__GNUG__)
19456  result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
19457  std::to_string(__GNUC__), '.',
19458  std::to_string(__GNUC_MINOR__), '.',
19459  std::to_string(__GNUC_PATCHLEVEL__))
19460  }
19461  };
19462 #elif defined(__HP_cc) || defined(__HP_aCC)
19463  result["compiler"] = "hp"
19464 #elif defined(__IBMCPP__)
19465  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
19466 #elif defined(_MSC_VER)
19467  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
19468 #elif defined(__PGI)
19469  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
19470 #elif defined(__SUNPRO_CC)
19471  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
19472 #else
19473  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
19474 #endif
19475 
19476 
19477 #if defined(_MSVC_LANG)
19478  result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
19479 #elif defined(__cplusplus)
19480  result["compiler"]["c++"] = std::to_string(__cplusplus);
19481 #else
19482  result["compiler"]["c++"] = "unknown";
19483 #endif
19484  return result;
19485  }
19486 
19487 
19489  // JSON value data types //
19491 
19496 
19501 #if defined(JSON_HAS_CPP_14)
19502  // use of transparent comparator avoids unnecessary repeated construction of temporaries
19503  // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
19504  using default_object_comparator_t = std::less<>;
19505 #else
19506  using default_object_comparator_t = std::less<StringType>;
19507 #endif
19508 
19511  using object_t = ObjectType<StringType,
19512  basic_json,
19514  AllocatorType<std::pair<const StringType,
19516 
19519  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
19520 
19523  using string_t = StringType;
19524 
19527  using boolean_t = BooleanType;
19528 
19531  using number_integer_t = NumberIntegerType;
19532 
19535  using number_unsigned_t = NumberUnsignedType;
19536 
19539  using number_float_t = NumberFloatType;
19540 
19543  using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
19544 
19548 
19550 
19551  private:
19552 
19554  template<typename T, typename... Args>
19556  static T* create(Args&& ... args)
19557  {
19558  AllocatorType<T> alloc;
19559  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
19560 
19561  auto deleter = [&](T * obj)
19562  {
19563  AllocatorTraits::deallocate(alloc, obj, 1);
19564  };
19565  std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
19566  AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
19567  JSON_ASSERT(obj != nullptr);
19568  return obj.release();
19569  }
19570 
19572  // JSON value storage //
19574 
19601  union json_value
19602  {
19604  object_t* object;
19606  array_t* array;
19608  string_t* string;
19610  binary_t* binary;
19612  boolean_t boolean;
19614  number_integer_t number_integer;
19616  number_unsigned_t number_unsigned;
19618  number_float_t number_float;
19619 
19621  json_value() = default;
19623  json_value(boolean_t v) noexcept : boolean(v) {}
19625  json_value(number_integer_t v) noexcept : number_integer(v) {}
19627  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
19629  json_value(number_float_t v) noexcept : number_float(v) {}
19631  json_value(value_t t)
19632  {
19633  switch (t)
19634  {
19635  case value_t::object:
19636  {
19637  object = create<object_t>();
19638  break;
19639  }
19640 
19641  case value_t::array:
19642  {
19643  array = create<array_t>();
19644  break;
19645  }
19646 
19647  case value_t::string:
19648  {
19649  string = create<string_t>("");
19650  break;
19651  }
19652 
19653  case value_t::binary:
19654  {
19655  binary = create<binary_t>();
19656  break;
19657  }
19658 
19659  case value_t::boolean:
19660  {
19661  boolean = static_cast<boolean_t>(false);
19662  break;
19663  }
19664 
19666  {
19667  number_integer = static_cast<number_integer_t>(0);
19668  break;
19669  }
19670 
19672  {
19673  number_unsigned = static_cast<number_unsigned_t>(0);
19674  break;
19675  }
19676 
19677  case value_t::number_float:
19678  {
19679  number_float = static_cast<number_float_t>(0.0);
19680  break;
19681  }
19682 
19683  case value_t::null:
19684  {
19685  object = nullptr; // silence warning, see #821
19686  break;
19687  }
19688 
19689  case value_t::discarded:
19690  default:
19691  {
19692  object = nullptr; // silence warning, see #821
19694  {
19695  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.2", nullptr)); // LCOV_EXCL_LINE
19696  }
19697  break;
19698  }
19699  }
19700  }
19701 
19703  json_value(const string_t& value) : string(create<string_t>(value)) {}
19704 
19706  json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
19707 
19709  json_value(const object_t& value) : object(create<object_t>(value)) {}
19710 
19712  json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
19713 
19715  json_value(const array_t& value) : array(create<array_t>(value)) {}
19716 
19718  json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
19719 
19721  json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
19722 
19724  json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
19725 
19727  json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
19728 
19730  json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
19731 
19732  void destroy(value_t t)
19733  {
19734  if (t == value_t::array || t == value_t::object)
19735  {
19736  // flatten the current json_value to a heap-allocated stack
19737  std::vector<basic_json> stack;
19738 
19739  // move the top-level items to stack
19740  if (t == value_t::array)
19741  {
19742  stack.reserve(array->size());
19743  std::move(array->begin(), array->end(), std::back_inserter(stack));
19744  }
19745  else
19746  {
19747  stack.reserve(object->size());
19748  for (auto&& it : *object)
19749  {
19750  stack.push_back(std::move(it.second));
19751  }
19752  }
19753 
19754  while (!stack.empty())
19755  {
19756  // move the last item to local variable to be processed
19757  basic_json current_item(std::move(stack.back()));
19758  stack.pop_back();
19759 
19760  // if current_item is array/object, move
19761  // its children to the stack to be processed later
19762  if (current_item.is_array())
19763  {
19764  std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
19765 
19766  current_item.m_value.array->clear();
19767  }
19768  else if (current_item.is_object())
19769  {
19770  for (auto&& it : *current_item.m_value.object)
19771  {
19772  stack.push_back(std::move(it.second));
19773  }
19774 
19775  current_item.m_value.object->clear();
19776  }
19777 
19778  // it's now safe that current_item get destructed
19779  // since it doesn't have any children
19780  }
19781  }
19782 
19783  switch (t)
19784  {
19785  case value_t::object:
19786  {
19787  AllocatorType<object_t> alloc;
19788  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
19789  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
19790  break;
19791  }
19792 
19793  case value_t::array:
19794  {
19795  AllocatorType<array_t> alloc;
19796  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
19797  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
19798  break;
19799  }
19800 
19801  case value_t::string:
19802  {
19803  AllocatorType<string_t> alloc;
19804  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
19805  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
19806  break;
19807  }
19808 
19809  case value_t::binary:
19810  {
19811  AllocatorType<binary_t> alloc;
19812  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
19813  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
19814  break;
19815  }
19816 
19817  case value_t::null:
19818  case value_t::boolean:
19821  case value_t::number_float:
19822  case value_t::discarded:
19823  default:
19824  {
19825  break;
19826  }
19827  }
19828  }
19829  };
19830 
19831  private:
19850  void assert_invariant(bool check_parents = true) const noexcept
19851  {
19852  JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
19853  JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
19854  JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
19855  JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
19856 
19857 #if JSON_DIAGNOSTICS
19858  JSON_TRY
19859  {
19860  // cppcheck-suppress assertWithSideEffect
19861  JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
19862  {
19863  return j.m_parent == this;
19864  }));
19865  }
19866  JSON_CATCH(...) {} // LCOV_EXCL_LINE
19867 #endif
19868  static_cast<void>(check_parents);
19869  }
19870 
19871  void set_parents()
19872  {
19873 #if JSON_DIAGNOSTICS
19874  switch (m_type)
19875  {
19876  case value_t::array:
19877  {
19878  for (auto& element : *m_value.array)
19879  {
19880  element.m_parent = this;
19881  }
19882  break;
19883  }
19884 
19885  case value_t::object:
19886  {
19887  for (auto& element : *m_value.object)
19888  {
19889  element.second.m_parent = this;
19890  }
19891  break;
19892  }
19893 
19894  case value_t::null:
19895  case value_t::string:
19896  case value_t::boolean:
19899  case value_t::number_float:
19900  case value_t::binary:
19901  case value_t::discarded:
19902  default:
19903  break;
19904  }
19905 #endif
19906  }
19907 
19908  iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
19909  {
19910 #if JSON_DIAGNOSTICS
19911  for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
19912  {
19913  (it + i)->m_parent = this;
19914  }
19915 #else
19916  static_cast<void>(count_set_parents);
19917 #endif
19918  return it;
19919  }
19920 
19921  reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
19922  {
19923 #if JSON_DIAGNOSTICS
19924  if (old_capacity != static_cast<std::size_t>(-1))
19925  {
19926  // see https://github.com/nlohmann/json/issues/2838
19928  if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
19929  {
19930  // capacity has changed: update all parents
19931  set_parents();
19932  return j;
19933  }
19934  }
19935 
19936  // ordered_json uses a vector internally, so pointers could have
19937  // been invalidated; see https://github.com/nlohmann/json/issues/2962
19938 #ifdef JSON_HEDLEY_MSVC_VERSION
19939 #pragma warning(push )
19940 #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
19941 #endif
19943  {
19944  set_parents();
19945  return j;
19946  }
19947 #ifdef JSON_HEDLEY_MSVC_VERSION
19948 #pragma warning( pop )
19949 #endif
19950 
19951  j.m_parent = this;
19952 #else
19953  static_cast<void>(j);
19954  static_cast<void>(old_capacity);
19955 #endif
19956  return j;
19957  }
19958 
19959  public:
19961  // JSON parser callback //
19963 
19967 
19971 
19973  // constructors //
19975 
19980 
19984  : m_type(v), m_value(v)
19985  {
19986  assert_invariant();
19987  }
19988 
19991  basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
19992  : basic_json(value_t::null)
19993  {
19994  assert_invariant();
19995  }
19996 
19999  template < typename CompatibleType,
20000  typename U = detail::uncvref_t<CompatibleType>,
20003  basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
20004  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
20005  std::forward<CompatibleType>(val))))
20006  {
20007  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
20008  set_parents();
20009  assert_invariant();
20010  }
20011 
20014  template < typename BasicJsonType,
20016  detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
20017  basic_json(const BasicJsonType& val)
20018  {
20019  using other_boolean_t = typename BasicJsonType::boolean_t;
20020  using other_number_float_t = typename BasicJsonType::number_float_t;
20021  using other_number_integer_t = typename BasicJsonType::number_integer_t;
20022  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
20023  using other_string_t = typename BasicJsonType::string_t;
20024  using other_object_t = typename BasicJsonType::object_t;
20025  using other_array_t = typename BasicJsonType::array_t;
20026  using other_binary_t = typename BasicJsonType::binary_t;
20027 
20028  switch (val.type())
20029  {
20030  case value_t::boolean:
20031  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
20032  break;
20033  case value_t::number_float:
20034  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
20035  break;
20037  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
20038  break;
20040  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
20041  break;
20042  case value_t::string:
20043  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
20044  break;
20045  case value_t::object:
20046  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
20047  break;
20048  case value_t::array:
20049  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
20050  break;
20051  case value_t::binary:
20052  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
20053  break;
20054  case value_t::null:
20055  *this = nullptr;
20056  break;
20057  case value_t::discarded:
20058  m_type = value_t::discarded;
20059  break;
20060  default: // LCOV_EXCL_LINE
20061  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
20062  }
20063  JSON_ASSERT(m_type == val.type());
20064  set_parents();
20065  assert_invariant();
20066  }
20067 
20071  bool type_deduction = true,
20072  value_t manual_type = value_t::array)
20073  {
20074  // check if each element is an array with two elements whose first
20075  // element is a string
20076  bool is_an_object = std::all_of(init.begin(), init.end(),
20077  [](const detail::json_ref<basic_json>& element_ref)
20078  {
20079  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
20080  });
20081 
20082  // adjust type if type deduction is not wanted
20083  if (!type_deduction)
20084  {
20085  // if array is wanted, do not create an object though possible
20086  if (manual_type == value_t::array)
20087  {
20088  is_an_object = false;
20089  }
20090 
20091  // if object is wanted but impossible, throw an exception
20092  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
20093  {
20094  JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
20095  }
20096  }
20097 
20098  if (is_an_object)
20099  {
20100  // the initializer list is a list of pairs -> create object
20101  m_type = value_t::object;
20103 
20104  for (auto& element_ref : init)
20105  {
20106  auto element = element_ref.moved_or_copied();
20107  m_value.object->emplace(
20108  std::move(*((*element.m_value.array)[0].m_value.string)),
20109  std::move((*element.m_value.array)[1]));
20110  }
20111  }
20112  else
20113  {
20114  // the initializer list describes an array -> create array
20115  m_type = value_t::array;
20116  m_value.array = create<array_t>(init.begin(), init.end());
20117  }
20118 
20119  set_parents();
20120  assert_invariant();
20121  }
20122 
20126  static basic_json binary(const typename binary_t::container_type& init)
20127  {
20128  auto res = basic_json();
20129  res.m_type = value_t::binary;
20130  res.m_value = init;
20131  return res;
20132  }
20133 
20137  static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
20138  {
20139  auto res = basic_json();
20140  res.m_type = value_t::binary;
20141  res.m_value = binary_t(init, subtype);
20142  return res;
20143  }
20144 
20148  static basic_json binary(typename binary_t::container_type&& init)
20149  {
20150  auto res = basic_json();
20151  res.m_type = value_t::binary;
20152  res.m_value = std::move(init);
20153  return res;
20154  }
20155 
20159  static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
20160  {
20161  auto res = basic_json();
20162  res.m_type = value_t::binary;
20163  res.m_value = binary_t(std::move(init), subtype);
20164  return res;
20165  }
20166 
20171  {
20172  return basic_json(init, false, value_t::array);
20173  }
20174 
20179  {
20180  return basic_json(init, false, value_t::object);
20181  }
20182 
20186  : m_type(value_t::array)
20187  {
20188  m_value.array = create<array_t>(cnt, val);
20189  set_parents();
20190  assert_invariant();
20191  }
20192 
20195  template < class InputIT, typename std::enable_if <
20196  std::is_same<InputIT, typename basic_json_t::iterator>::value ||
20197  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
20198  basic_json(InputIT first, InputIT last)
20199  {
20200  JSON_ASSERT(first.m_object != nullptr);
20201  JSON_ASSERT(last.m_object != nullptr);
20202 
20203  // make sure iterator fits the current value
20204  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20205  {
20206  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
20207  }
20208 
20209  // copy type from first iterator
20210  m_type = first.m_object->m_type;
20211 
20212  // check if iterator range is complete for primitive values
20213  switch (m_type)
20214  {
20215  case value_t::boolean:
20216  case value_t::number_float:
20219  case value_t::string:
20220  {
20221  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
20222  || !last.m_it.primitive_iterator.is_end()))
20223  {
20224  JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
20225  }
20226  break;
20227  }
20228 
20229  case value_t::null:
20230  case value_t::object:
20231  case value_t::array:
20232  case value_t::binary:
20233  case value_t::discarded:
20234  default:
20235  break;
20236  }
20237 
20238  switch (m_type)
20239  {
20241  {
20242  m_value.number_integer = first.m_object->m_value.number_integer;
20243  break;
20244  }
20245 
20247  {
20248  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
20249  break;
20250  }
20251 
20252  case value_t::number_float:
20253  {
20254  m_value.number_float = first.m_object->m_value.number_float;
20255  break;
20256  }
20257 
20258  case value_t::boolean:
20259  {
20260  m_value.boolean = first.m_object->m_value.boolean;
20261  break;
20262  }
20263 
20264  case value_t::string:
20265  {
20266  m_value = *first.m_object->m_value.string;
20267  break;
20268  }
20269 
20270  case value_t::object:
20271  {
20272  m_value.object = create<object_t>(first.m_it.object_iterator,
20273  last.m_it.object_iterator);
20274  break;
20275  }
20276 
20277  case value_t::array:
20278  {
20279  m_value.array = create<array_t>(first.m_it.array_iterator,
20280  last.m_it.array_iterator);
20281  break;
20282  }
20283 
20284  case value_t::binary:
20285  {
20286  m_value = *first.m_object->m_value.binary;
20287  break;
20288  }
20289 
20290  case value_t::null:
20291  case value_t::discarded:
20292  default:
20293  JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
20294  }
20295 
20296  set_parents();
20297  assert_invariant();
20298  }
20299 
20300 
20302  // other constructors and destructor //
20304 
20305  template<typename JsonRef,
20307  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
20308  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
20309 
20312  basic_json(const basic_json& other)
20313  : m_type(other.m_type)
20314  {
20315  // check of passed value is valid
20316  other.assert_invariant();
20317 
20318  switch (m_type)
20319  {
20320  case value_t::object:
20321  {
20322  m_value = *other.m_value.object;
20323  break;
20324  }
20325 
20326  case value_t::array:
20327  {
20328  m_value = *other.m_value.array;
20329  break;
20330  }
20331 
20332  case value_t::string:
20333  {
20334  m_value = *other.m_value.string;
20335  break;
20336  }
20337 
20338  case value_t::boolean:
20339  {
20340  m_value = other.m_value.boolean;
20341  break;
20342  }
20343 
20345  {
20346  m_value = other.m_value.number_integer;
20347  break;
20348  }
20349 
20351  {
20352  m_value = other.m_value.number_unsigned;
20353  break;
20354  }
20355 
20356  case value_t::number_float:
20357  {
20358  m_value = other.m_value.number_float;
20359  break;
20360  }
20361 
20362  case value_t::binary:
20363  {
20364  m_value = *other.m_value.binary;
20365  break;
20366  }
20367 
20368  case value_t::null:
20369  case value_t::discarded:
20370  default:
20371  break;
20372  }
20373 
20374  set_parents();
20375  assert_invariant();
20376  }
20377 
20380  basic_json(basic_json&& other) noexcept
20381  : m_type(std::move(other.m_type)),
20382  m_value(std::move(other.m_value))
20383  {
20384  // check that passed value is valid
20385  other.assert_invariant(false);
20386 
20387  // invalidate payload
20388  other.m_type = value_t::null;
20389  other.m_value = {};
20390 
20391  set_parents();
20392  assert_invariant();
20393  }
20394 
20397  basic_json& operator=(basic_json other) noexcept (
20398  std::is_nothrow_move_constructible<value_t>::value&&
20399  std::is_nothrow_move_assignable<value_t>::value&&
20400  std::is_nothrow_move_constructible<json_value>::value&&
20401  std::is_nothrow_move_assignable<json_value>::value
20402  )
20403  {
20404  // check that passed value is valid
20405  other.assert_invariant();
20406 
20407  using std::swap;
20408  swap(m_type, other.m_type);
20409  swap(m_value, other.m_value);
20410 
20411  set_parents();
20412  assert_invariant();
20413  return *this;
20414  }
20415 
20418  ~basic_json() noexcept
20419  {
20420  assert_invariant(false);
20421  m_value.destroy(m_type);
20422  }
20423 
20425 
20426  public:
20428  // object inspection //
20430 
20434 
20437  string_t dump(const int indent = -1,
20438  const char indent_char = ' ',
20439  const bool ensure_ascii = false,
20440  const error_handler_t error_handler = error_handler_t::strict) const
20441  {
20442  string_t result;
20443  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
20444 
20445  if (indent >= 0)
20446  {
20447  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
20448  }
20449  else
20450  {
20451  s.dump(*this, false, ensure_ascii, 0);
20452  }
20453 
20454  return result;
20455  }
20456 
20459  constexpr value_t type() const noexcept
20460  {
20461  return m_type;
20462  }
20463 
20466  constexpr bool is_primitive() const noexcept
20467  {
20468  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20469  }
20470 
20473  constexpr bool is_structured() const noexcept
20474  {
20475  return is_array() || is_object();
20476  }
20477 
20480  constexpr bool is_null() const noexcept
20481  {
20482  return m_type == value_t::null;
20483  }
20484 
20487  constexpr bool is_boolean() const noexcept
20488  {
20489  return m_type == value_t::boolean;
20490  }
20491 
20494  constexpr bool is_number() const noexcept
20495  {
20496  return is_number_integer() || is_number_float();
20497  }
20498 
20501  constexpr bool is_number_integer() const noexcept
20502  {
20503  return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20504  }
20505 
20508  constexpr bool is_number_unsigned() const noexcept
20509  {
20510  return m_type == value_t::number_unsigned;
20511  }
20512 
20515  constexpr bool is_number_float() const noexcept
20516  {
20517  return m_type == value_t::number_float;
20518  }
20519 
20522  constexpr bool is_object() const noexcept
20523  {
20524  return m_type == value_t::object;
20525  }
20526 
20529  constexpr bool is_array() const noexcept
20530  {
20531  return m_type == value_t::array;
20532  }
20533 
20536  constexpr bool is_string() const noexcept
20537  {
20538  return m_type == value_t::string;
20539  }
20540 
20543  constexpr bool is_binary() const noexcept
20544  {
20545  return m_type == value_t::binary;
20546  }
20547 
20550  constexpr bool is_discarded() const noexcept
20551  {
20552  return m_type == value_t::discarded;
20553  }
20554 
20557  constexpr operator value_t() const noexcept
20558  {
20559  return m_type;
20560  }
20561 
20563 
20564  private:
20566  // value access //
20568 
20570  boolean_t get_impl(boolean_t* /*unused*/) const
20571  {
20573  {
20574  return m_value.boolean;
20575  }
20576 
20577  JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
20578  }
20579 
20581  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20582  {
20583  return is_object() ? m_value.object : nullptr;
20584  }
20585 
20587  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20588  {
20589  return is_object() ? m_value.object : nullptr;
20590  }
20591 
20593  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20594  {
20595  return is_array() ? m_value.array : nullptr;
20596  }
20597 
20599  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20600  {
20601  return is_array() ? m_value.array : nullptr;
20602  }
20603 
20605  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20606  {
20607  return is_string() ? m_value.string : nullptr;
20608  }
20609 
20611  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20612  {
20613  return is_string() ? m_value.string : nullptr;
20614  }
20615 
20617  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20618  {
20619  return is_boolean() ? &m_value.boolean : nullptr;
20620  }
20621 
20623  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20624  {
20625  return is_boolean() ? &m_value.boolean : nullptr;
20626  }
20627 
20629  number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20630  {
20631  return is_number_integer() ? &m_value.number_integer : nullptr;
20632  }
20633 
20635  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20636  {
20637  return is_number_integer() ? &m_value.number_integer : nullptr;
20638  }
20639 
20641  number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20642  {
20643  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20644  }
20645 
20647  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20648  {
20649  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20650  }
20651 
20653  number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20654  {
20655  return is_number_float() ? &m_value.number_float : nullptr;
20656  }
20657 
20659  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20660  {
20661  return is_number_float() ? &m_value.number_float : nullptr;
20662  }
20663 
20665  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20666  {
20667  return is_binary() ? m_value.binary : nullptr;
20668  }
20669 
20671  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20672  {
20673  return is_binary() ? m_value.binary : nullptr;
20674  }
20675 
20687  template<typename ReferenceType, typename ThisType>
20688  static ReferenceType get_ref_impl(ThisType& obj)
20689  {
20690  // delegate the call to get_ptr<>()
20691  auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20692 
20693  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20694  {
20695  return *ptr;
20696  }
20697 
20698  JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
20699  }
20700 
20701  public:
20705 
20708  template<typename PointerType, typename std::enable_if<
20709  std::is_pointer<PointerType>::value, int>::type = 0>
20710  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20711  {
20712  // delegate the call to get_impl_ptr<>()
20713  return get_impl_ptr(static_cast<PointerType>(nullptr));
20714  }
20715 
20718  template < typename PointerType, typename std::enable_if <
20719  std::is_pointer<PointerType>::value&&
20721  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20722  {
20723  // delegate the call to get_impl_ptr<>() const
20724  return get_impl_ptr(static_cast<PointerType>(nullptr));
20725  }
20726 
20727  private:
20766  template < typename ValueType,
20770  int > = 0 >
20771  ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20772  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20773  {
20774  auto ret = ValueType();
20776  return ret;
20777  }
20778 
20809  template < typename ValueType,
20812  int > = 0 >
20813  ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20814  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20815  {
20817  }
20818 
20834  template < typename BasicJsonType,
20837  int > = 0 >
20838  BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20839  {
20840  return *this;
20841  }
20842 
20857  template<typename BasicJsonType,
20859  std::is_same<BasicJsonType, basic_json_t>::value,
20860  int> = 0>
20861  basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20862  {
20863  return *this;
20864  }
20865 
20870  template<typename PointerType,
20872  std::is_pointer<PointerType>::value,
20873  int> = 0>
20874  constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20875  -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20876  {
20877  // delegate the call to get_ptr
20878  return get_ptr<PointerType>();
20879  }
20880 
20881  public:
20905  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20906 #if defined(JSON_HAS_CPP_14)
20907  constexpr
20908 #endif
20909  auto get() const noexcept(
20910  noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20911  -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20912  {
20913  // we cannot static_assert on ValueTypeCV being non-const, because
20914  // there is support for get<const basic_json_t>(), which is why we
20915  // still need the uncvref
20916  static_assert(!std::is_reference<ValueTypeCV>::value,
20917  "get() cannot be used with reference types, you might want to use get_ref()");
20918  return get_impl<ValueType>(detail::priority_tag<4> {});
20919  }
20920 
20948  template<typename PointerType, typename std::enable_if<
20949  std::is_pointer<PointerType>::value, int>::type = 0>
20950  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20951  {
20952  // delegate the call to get_ptr
20953  return get_ptr<PointerType>();
20954  }
20955 
20958  template < typename ValueType,
20962  int > = 0 >
20963  ValueType & get_to(ValueType& v) const noexcept(noexcept(
20964  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20965  {
20967  return v;
20968  }
20969 
20970  // specialization to allow calling get_to with a basic_json value
20971  // see https://github.com/nlohmann/json/issues/2175
20972  template<typename ValueType,
20975  int> = 0>
20976  ValueType & get_to(ValueType& v) const
20977  {
20978  v = *this;
20979  return v;
20980  }
20981 
20982  template <
20983  typename T, std::size_t N,
20984  typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20987  Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20988  noexcept(noexcept(JSONSerializer<Array>::from_json(
20989  std::declval<const basic_json_t&>(), v)))
20990  {
20992  return v;
20993  }
20994 
20997  template<typename ReferenceType, typename std::enable_if<
20998  std::is_reference<ReferenceType>::value, int>::type = 0>
20999  ReferenceType get_ref()
21000  {
21001  // delegate call to get_ref_impl
21002  return get_ref_impl<ReferenceType>(*this);
21003  }
21004 
21007  template < typename ReferenceType, typename std::enable_if <
21008  std::is_reference<ReferenceType>::value&&
21010  ReferenceType get_ref() const
21011  {
21012  // delegate call to get_ref_impl
21013  return get_ref_impl<ReferenceType>(*this);
21014  }
21015 
21045  template < typename ValueType, typename std::enable_if <
21053 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
21055 #endif
21056 #if defined(JSON_HAS_CPP_17)
21058 #endif
21060  >::value, int >::type = 0 >
21061  JSON_EXPLICIT operator ValueType() const
21062  {
21063  // delegate the call to get<>() const
21064  return get<ValueType>();
21065  }
21066 
21070  {
21071  if (!is_binary())
21072  {
21073  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21074  }
21075 
21076  return *get_ptr<binary_t*>();
21077  }
21078 
21081  const binary_t& get_binary() const
21082  {
21083  if (!is_binary())
21084  {
21085  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21086  }
21087 
21088  return *get_ptr<const binary_t*>();
21089  }
21090 
21092 
21093 
21095  // element access //
21097 
21101 
21105  {
21106  // at only works for arrays
21108  {
21109  JSON_TRY
21110  {
21111  return set_parent(m_value.array->at(idx));
21112  }
21113  JSON_CATCH (std::out_of_range&)
21114  {
21115  // create better exception explanation
21116  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21117  }
21118  }
21119  else
21120  {
21121  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21122  }
21123  }
21124 
21128  {
21129  // at only works for arrays
21131  {
21132  JSON_TRY
21133  {
21134  return m_value.array->at(idx);
21135  }
21136  JSON_CATCH (std::out_of_range&)
21137  {
21138  // create better exception explanation
21139  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21140  }
21141  }
21142  else
21143  {
21144  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21145  }
21146  }
21147 
21150  reference at(const typename object_t::key_type& key)
21151  {
21152  // at only works for objects
21154  {
21155  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21156  }
21157 
21158  auto it = m_value.object->find(key);
21159  if (it == m_value.object->end())
21160  {
21161  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21162  }
21163  return set_parent(it->second);
21164  }
21165 
21168  template<class KeyType, detail::enable_if_t<
21170  reference at(KeyType && key)
21171  {
21172  // at only works for objects
21174  {
21175  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21176  }
21177 
21178  auto it = m_value.object->find(std::forward<KeyType>(key));
21179  if (it == m_value.object->end())
21180  {
21181  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21182  }
21183  return set_parent(it->second);
21184  }
21185 
21188  const_reference at(const typename object_t::key_type& key) const
21189  {
21190  // at only works for objects
21192  {
21193  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21194  }
21195 
21196  auto it = m_value.object->find(key);
21197  if (it == m_value.object->end())
21198  {
21199  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21200  }
21201  return it->second;
21202  }
21203 
21206  template<class KeyType, detail::enable_if_t<
21208  const_reference at(KeyType && key) const
21209  {
21210  // at only works for objects
21212  {
21213  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21214  }
21215 
21216  auto it = m_value.object->find(std::forward<KeyType>(key));
21217  if (it == m_value.object->end())
21218  {
21219  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21220  }
21221  return it->second;
21222  }
21223 
21227  {
21228  // implicitly convert null value to an empty array
21229  if (is_null())
21230  {
21231  m_type = value_t::array;
21232  m_value.array = create<array_t>();
21233  assert_invariant();
21234  }
21235 
21236  // operator[] only works for arrays
21238  {
21239  // fill up array with null values if given idx is outside range
21240  if (idx >= m_value.array->size())
21241  {
21242 #if JSON_DIAGNOSTICS
21243  // remember array size & capacity before resizing
21244  const auto old_size = m_value.array->size();
21245  const auto old_capacity = m_value.array->capacity();
21246 #endif
21247  m_value.array->resize(idx + 1);
21248 
21249 #if JSON_DIAGNOSTICS
21250  if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
21251  {
21252  // capacity has changed: update all parents
21253  set_parents();
21254  }
21255  else
21256  {
21257  // set parent for values added above
21258  set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21259  }
21260 #endif
21261  assert_invariant();
21262  }
21263 
21264  return m_value.array->operator[](idx);
21265  }
21266 
21267  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21268  }
21269 
21273  {
21274  // const operator[] only works for arrays
21276  {
21277  return m_value.array->operator[](idx);
21278  }
21279 
21280  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21281  }
21282 
21285  reference operator[](typename object_t::key_type key)
21286  {
21287  // implicitly convert null value to an empty object
21288  if (is_null())
21289  {
21290  m_type = value_t::object;
21291  m_value.object = create<object_t>();
21292  assert_invariant();
21293  }
21294 
21295  // operator[] only works for objects
21297  {
21298  auto result = m_value.object->emplace(std::move(key), nullptr);
21299  return set_parent(result.first->second);
21300  }
21301 
21302  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21303  }
21304 
21307  const_reference operator[](const typename object_t::key_type& key) const
21308  {
21309  // const operator[] only works for objects
21311  {
21312  auto it = m_value.object->find(key);
21313  JSON_ASSERT(it != m_value.object->end());
21314  return it->second;
21315  }
21316 
21317  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21318  }
21319 
21320  // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
21321  // (they seemingly cannot be constrained to resolve the ambiguity)
21322  template<typename T>
21324  {
21325  return operator[](typename object_t::key_type(key));
21326  }
21327 
21328  template<typename T>
21330  {
21331  return operator[](typename object_t::key_type(key));
21332  }
21333 
21336  template<class KeyType, detail::enable_if_t<
21338  reference operator[](KeyType && key)
21339  {
21340  // implicitly convert null value to an empty object
21341  if (is_null())
21342  {
21343  m_type = value_t::object;
21344  m_value.object = create<object_t>();
21345  assert_invariant();
21346  }
21347 
21348  // operator[] only works for objects
21350  {
21351  auto result = m_value.object->emplace(std::forward<KeyType>(key), nullptr);
21352  return set_parent(result.first->second);
21353  }
21354 
21355  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21356  }
21357 
21360  template<class KeyType, detail::enable_if_t<
21362  const_reference operator[](KeyType && key) const
21363  {
21364  // const operator[] only works for objects
21366  {
21367  auto it = m_value.object->find(std::forward<KeyType>(key));
21368  JSON_ASSERT(it != m_value.object->end());
21369  return it->second;
21370  }
21371 
21372  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21373  }
21374 
21375  private:
21376  template<typename KeyType>
21377  using is_comparable_with_object_key = detail::is_comparable <
21378  object_comparator_t, const typename object_t::key_type&, KeyType >;
21379 
21380  template<typename ValueType>
21381  using value_return_type = std::conditional <
21384 
21385  public:
21388  template < class ValueType, detail::enable_if_t <
21391  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21392  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21393  {
21394  // value only works for objects
21396  {
21397  // if key is found, return value and given default value otherwise
21398  const auto it = find(key);
21399  if (it != end())
21400  {
21401  return it->template get<ValueType>();
21402  }
21403 
21404  return default_value;
21405  }
21406 
21407  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21408  }
21409 
21416  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21417  ReturnType value(const typename object_t::key_type& key, ValueType && default_value) const
21418  {
21419  // value only works for objects
21421  {
21422  // if key is found, return value and given default value otherwise
21423  const auto it = find(key);
21424  if (it != end())
21425  {
21426  return it->template get<ReturnType>();
21427  }
21428 
21429  return std::forward<ValueType>(default_value);
21430  }
21431 
21432  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21433  }
21434 
21437  template < class ValueType, class KeyType, detail::enable_if_t <
21440  && is_comparable_with_object_key<KeyType>::value
21442  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21443  ValueType value(KeyType && key, const ValueType& default_value) const
21444  {
21445  // value only works for objects
21447  {
21448  // if key is found, return value and given default value otherwise
21449  const auto it = find(std::forward<KeyType>(key));
21450  if (it != end())
21451  {
21452  return it->template get<ValueType>();
21453  }
21454 
21455  return default_value;
21456  }
21457 
21458  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21459  }
21460 
21467  && is_comparable_with_object_key<KeyType>::value
21469  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21470  ReturnType value(KeyType && key, ValueType && default_value) const
21471  {
21472  // value only works for objects
21474  {
21475  // if key is found, return value and given default value otherwise
21476  const auto it = find(std::forward<KeyType>(key));
21477  if (it != end())
21478  {
21479  return it->template get<ReturnType>();
21480  }
21481 
21482  return std::forward<ValueType>(default_value);
21483  }
21484 
21485  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21486  }
21487 
21490  template < class ValueType, detail::enable_if_t <
21492  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21493  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21494  {
21495  // value only works for objects
21497  {
21498  // if pointer resolves a value, return it or use default value
21499  JSON_TRY
21500  {
21501  return ptr.get_checked(this).template get<ValueType>();
21502  }
21504  {
21505  return default_value;
21506  }
21507  }
21508 
21509  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21510  }
21511 
21517  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21518  ReturnType value(const json_pointer& ptr, ValueType && default_value) const
21519  {
21520  // value only works for objects
21522  {
21523  // if pointer resolves a value, return it or use default value
21524  JSON_TRY
21525  {
21526  return ptr.get_checked(this).template get<ReturnType>();
21527  }
21529  {
21530  return std::forward<ValueType>(default_value);
21531  }
21532  }
21533 
21534  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21535  }
21536 
21537  template < class ValueType, class BasicJsonType, detail::enable_if_t <
21540  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21541  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21542  ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
21543  {
21544  return value(ptr.convert(), default_value);
21545  }
21546 
21551  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21552  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21553  ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const
21554  {
21555  return value(ptr.convert(), std::forward<ValueType>(default_value));
21556  }
21557 
21560  reference front()
21561  {
21562  return *begin();
21563  }
21564 
21568  {
21569  return *cbegin();
21570  }
21571 
21575  {
21576  auto tmp = end();
21577  --tmp;
21578  return *tmp;
21579  }
21580 
21584  {
21585  auto tmp = cend();
21586  --tmp;
21587  return *tmp;
21588  }
21589 
21592  template < class IteratorType, detail::enable_if_t <
21593  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21594  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21595  IteratorType erase(IteratorType pos)
21596  {
21597  // make sure iterator fits the current value
21598  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21599  {
21600  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21601  }
21602 
21603  IteratorType result = end();
21604 
21605  switch (m_type)
21606  {
21607  case value_t::boolean:
21608  case value_t::number_float:
21611  case value_t::string:
21612  case value_t::binary:
21613  {
21614  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21615  {
21616  JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
21617  }
21618 
21619  if (is_string())
21620  {
21621  AllocatorType<string_t> alloc;
21622  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21623  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21624  m_value.string = nullptr;
21625  }
21626  else if (is_binary())
21627  {
21628  AllocatorType<binary_t> alloc;
21629  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21630  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21631  m_value.binary = nullptr;
21632  }
21633 
21634  m_type = value_t::null;
21635  assert_invariant();
21636  break;
21637  }
21638 
21639  case value_t::object:
21640  {
21641  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21642  break;
21643  }
21644 
21645  case value_t::array:
21646  {
21647  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21648  break;
21649  }
21650 
21651  case value_t::null:
21652  case value_t::discarded:
21653  default:
21654  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21655  }
21656 
21657  return result;
21658  }
21659 
21662  template < class IteratorType, detail::enable_if_t <
21663  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21664  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21665  IteratorType erase(IteratorType first, IteratorType last)
21666  {
21667  // make sure iterator fits the current value
21668  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21669  {
21670  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
21671  }
21672 
21673  IteratorType result = end();
21674 
21675  switch (m_type)
21676  {
21677  case value_t::boolean:
21678  case value_t::number_float:
21681  case value_t::string:
21682  case value_t::binary:
21683  {
21684  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21685  || !last.m_it.primitive_iterator.is_end()))
21686  {
21687  JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
21688  }
21689 
21690  if (is_string())
21691  {
21692  AllocatorType<string_t> alloc;
21693  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21694  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21695  m_value.string = nullptr;
21696  }
21697  else if (is_binary())
21698  {
21699  AllocatorType<binary_t> alloc;
21700  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21701  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21702  m_value.binary = nullptr;
21703  }
21704 
21705  m_type = value_t::null;
21706  assert_invariant();
21707  break;
21708  }
21709 
21710  case value_t::object:
21711  {
21712  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21713  last.m_it.object_iterator);
21714  break;
21715  }
21716 
21717  case value_t::array:
21718  {
21719  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21720  last.m_it.array_iterator);
21721  break;
21722  }
21723 
21724  case value_t::null:
21725  case value_t::discarded:
21726  default:
21727  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21728  }
21729 
21730  return result;
21731  }
21732 
21733  private:
21734  template < typename KeyType, detail::enable_if_t <
21736  size_type erase_internal(KeyType && key)
21737  {
21738  // this erase only works for objects
21740  {
21741  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21742  }
21743 
21744  return m_value.object->erase(std::forward<KeyType>(key));
21745  }
21746 
21747  template < typename KeyType, detail::enable_if_t <
21749  size_type erase_internal(KeyType && key)
21750  {
21751  // this erase only works for objects
21753  {
21754  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21755  }
21756 
21757  const auto it = m_value.object->find(std::forward<KeyType>(key));
21758  if (it != m_value.object->end())
21759  {
21760  m_value.object->erase(it);
21761  return 1;
21762  }
21763  return 0;
21764  }
21765 
21766  public:
21767 
21770  size_type erase(const typename object_t::key_type& key)
21771  {
21772  // the indirection via erase_internal() is added to avoid making this
21773  // function a template and thus de-rank it during overload resolution
21774  return erase_internal(key);
21775  }
21776 
21779  template<class KeyType, detail::enable_if_t<
21781  size_type erase(KeyType && key)
21782  {
21783  return erase_internal(std::forward<KeyType>(key));
21784  }
21785 
21788  void erase(const size_type idx)
21789  {
21790  // this erase only works for arrays
21792  {
21793  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21794  {
21795  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21796  }
21797 
21798  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21799  }
21800  else
21801  {
21802  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21803  }
21804  }
21805 
21807 
21808 
21810  // lookup //
21812 
21815 
21818  iterator find(const typename object_t::key_type& key)
21819  {
21820  auto result = end();
21821 
21822  if (is_object())
21823  {
21824  result.m_it.object_iterator = m_value.object->find(key);
21825  }
21826 
21827  return result;
21828  }
21829 
21832  const_iterator find(const typename object_t::key_type& key) const
21833  {
21834  auto result = cend();
21835 
21836  if (is_object())
21837  {
21838  result.m_it.object_iterator = m_value.object->find(key);
21839  }
21840 
21841  return result;
21842  }
21843 
21846  template<class KeyType, detail::enable_if_t<
21848  iterator find(KeyType && key)
21849  {
21850  auto result = end();
21851 
21852  if (is_object())
21853  {
21854  result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
21855  }
21856 
21857  return result;
21858  }
21859 
21862  template<class KeyType, detail::enable_if_t<
21864  const_iterator find(KeyType && key) const
21865  {
21866  auto result = cend();
21867 
21868  if (is_object())
21869  {
21870  result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
21871  }
21872 
21873  return result;
21874  }
21875 
21878  size_type count(const typename object_t::key_type& key) const
21879  {
21880  // return 0 for all nonobject types
21881  return is_object() ? m_value.object->count(key) : 0;
21882  }
21883 
21886  template<class KeyType, detail::enable_if_t<
21888  size_type count(KeyType && key) const
21889  {
21890  // return 0 for all nonobject types
21891  return is_object() ? m_value.object->count(std::forward<KeyType>(key)) : 0;
21892  }
21893 
21896  bool contains(const typename object_t::key_type& key) const
21897  {
21898  return is_object() && m_value.object->find(key) != m_value.object->end();
21899  }
21900 
21903  template<class KeyType, detail::enable_if_t<
21905  bool contains(KeyType && key) const
21906  {
21907  return is_object() && m_value.object->find(std::forward<KeyType>(key)) != m_value.object->end();
21908  }
21909 
21912  bool contains(const json_pointer& ptr) const
21913  {
21914  return ptr.contains(this);
21915  }
21916 
21917  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
21918  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21919  bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
21920  {
21921  return ptr.contains(this);
21922  }
21923 
21925 
21926 
21928  // iterators //
21930 
21933 
21936  iterator begin() noexcept
21937  {
21938  iterator result(this);
21939  result.set_begin();
21940  return result;
21941  }
21942 
21945  const_iterator begin() const noexcept
21946  {
21947  return cbegin();
21948  }
21949 
21952  const_iterator cbegin() const noexcept
21953  {
21954  const_iterator result(this);
21955  result.set_begin();
21956  return result;
21957  }
21958 
21961  iterator end() noexcept
21962  {
21963  iterator result(this);
21964  result.set_end();
21965  return result;
21966  }
21967 
21970  const_iterator end() const noexcept
21971  {
21972  return cend();
21973  }
21974 
21977  const_iterator cend() const noexcept
21978  {
21979  const_iterator result(this);
21980  result.set_end();
21981  return result;
21982  }
21983 
21986  reverse_iterator rbegin() noexcept
21987  {
21988  return reverse_iterator(end());
21989  }
21990 
21993  const_reverse_iterator rbegin() const noexcept
21994  {
21995  return crbegin();
21996  }
21997 
22000  reverse_iterator rend() noexcept
22001  {
22002  return reverse_iterator(begin());
22003  }
22004 
22007  const_reverse_iterator rend() const noexcept
22008  {
22009  return crend();
22010  }
22011 
22014  const_reverse_iterator crbegin() const noexcept
22015  {
22016  return const_reverse_iterator(cend());
22017  }
22018 
22021  const_reverse_iterator crend() const noexcept
22022  {
22023  return const_reverse_iterator(cbegin());
22024  }
22025 
22026  public:
22032  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22033  static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22034  {
22035  return ref.items();
22036  }
22037 
22043  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22044  static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22045  {
22046  return ref.items();
22047  }
22048 
22051  iteration_proxy<iterator> items() noexcept
22052  {
22053  return iteration_proxy<iterator>(*this);
22054  }
22055 
22058  iteration_proxy<const_iterator> items() const noexcept
22059  {
22060  return iteration_proxy<const_iterator>(*this);
22061  }
22062 
22064 
22065 
22067  // capacity //
22069 
22072 
22075  bool empty() const noexcept
22076  {
22077  switch (m_type)
22078  {
22079  case value_t::null:
22080  {
22081  // null values are empty
22082  return true;
22083  }
22084 
22085  case value_t::array:
22086  {
22087  // delegate call to array_t::empty()
22088  return m_value.array->empty();
22089  }
22090 
22091  case value_t::object:
22092  {
22093  // delegate call to object_t::empty()
22094  return m_value.object->empty();
22095  }
22096 
22097  case value_t::string:
22098  case value_t::boolean:
22101  case value_t::number_float:
22102  case value_t::binary:
22103  case value_t::discarded:
22104  default:
22105  {
22106  // all other types are nonempty
22107  return false;
22108  }
22109  }
22110  }
22111 
22114  size_type size() const noexcept
22115  {
22116  switch (m_type)
22117  {
22118  case value_t::null:
22119  {
22120  // null values are empty
22121  return 0;
22122  }
22123 
22124  case value_t::array:
22125  {
22126  // delegate call to array_t::size()
22127  return m_value.array->size();
22128  }
22129 
22130  case value_t::object:
22131  {
22132  // delegate call to object_t::size()
22133  return m_value.object->size();
22134  }
22135 
22136  case value_t::string:
22137  case value_t::boolean:
22140  case value_t::number_float:
22141  case value_t::binary:
22142  case value_t::discarded:
22143  default:
22144  {
22145  // all other types have size 1
22146  return 1;
22147  }
22148  }
22149  }
22150 
22153  size_type max_size() const noexcept
22154  {
22155  switch (m_type)
22156  {
22157  case value_t::array:
22158  {
22159  // delegate call to array_t::max_size()
22160  return m_value.array->max_size();
22161  }
22162 
22163  case value_t::object:
22164  {
22165  // delegate call to object_t::max_size()
22166  return m_value.object->max_size();
22167  }
22168 
22169  case value_t::null:
22170  case value_t::string:
22171  case value_t::boolean:
22174  case value_t::number_float:
22175  case value_t::binary:
22176  case value_t::discarded:
22177  default:
22178  {
22179  // all other types have max_size() == size()
22180  return size();
22181  }
22182  }
22183  }
22184 
22186 
22187 
22189  // modifiers //
22191 
22194 
22197  void clear() noexcept
22198  {
22199  switch (m_type)
22200  {
22202  {
22203  m_value.number_integer = 0;
22204  break;
22205  }
22206 
22208  {
22209  m_value.number_unsigned = 0;
22210  break;
22211  }
22212 
22213  case value_t::number_float:
22214  {
22215  m_value.number_float = 0.0;
22216  break;
22217  }
22218 
22219  case value_t::boolean:
22220  {
22221  m_value.boolean = false;
22222  break;
22223  }
22224 
22225  case value_t::string:
22226  {
22227  m_value.string->clear();
22228  break;
22229  }
22230 
22231  case value_t::binary:
22232  {
22233  m_value.binary->clear();
22234  break;
22235  }
22236 
22237  case value_t::array:
22238  {
22239  m_value.array->clear();
22240  break;
22241  }
22242 
22243  case value_t::object:
22244  {
22245  m_value.object->clear();
22246  break;
22247  }
22248 
22249  case value_t::null:
22250  case value_t::discarded:
22251  default:
22252  break;
22253  }
22254  }
22255 
22258  void push_back(basic_json&& val)
22259  {
22260  // push_back only works for null objects or arrays
22261  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22262  {
22263  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22264  }
22265 
22266  // transform null object into an array
22267  if (is_null())
22268  {
22269  m_type = value_t::array;
22271  assert_invariant();
22272  }
22273 
22274  // add element to array (move semantics)
22275  const auto old_capacity = m_value.array->capacity();
22276  m_value.array->push_back(std::move(val));
22277  set_parent(m_value.array->back(), old_capacity);
22278  // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
22279  }
22280 
22284  {
22285  push_back(std::move(val));
22286  return *this;
22287  }
22288 
22291  void push_back(const basic_json& val)
22292  {
22293  // push_back only works for null objects or arrays
22294  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22295  {
22296  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22297  }
22298 
22299  // transform null object into an array
22300  if (is_null())
22301  {
22302  m_type = value_t::array;
22304  assert_invariant();
22305  }
22306 
22307  // add element to array
22308  const auto old_capacity = m_value.array->capacity();
22309  m_value.array->push_back(val);
22310  set_parent(m_value.array->back(), old_capacity);
22311  }
22312 
22316  {
22317  push_back(val);
22318  return *this;
22319  }
22320 
22323  void push_back(const typename object_t::value_type& val)
22324  {
22325  // push_back only works for null objects or objects
22326  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22327  {
22328  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22329  }
22330 
22331  // transform null object into an object
22332  if (is_null())
22333  {
22334  m_type = value_t::object;
22336  assert_invariant();
22337  }
22338 
22339  // add element to object
22340  auto res = m_value.object->insert(val);
22341  set_parent(res.first->second);
22342  }
22343 
22346  reference operator+=(const typename object_t::value_type& val)
22347  {
22348  push_back(val);
22349  return *this;
22350  }
22351 
22355  {
22356  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22357  {
22358  basic_json&& key = init.begin()->moved_or_copied();
22359  push_back(typename object_t::value_type(
22360  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22361  }
22362  else
22363  {
22364  push_back(basic_json(init));
22365  }
22366  }
22367 
22371  {
22372  push_back(init);
22373  return *this;
22374  }
22375 
22378  template<class... Args>
22379  reference emplace_back(Args&& ... args)
22380  {
22381  // emplace_back only works for null objects or arrays
22382  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22383  {
22384  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
22385  }
22386 
22387  // transform null object into an array
22388  if (is_null())
22389  {
22390  m_type = value_t::array;
22392  assert_invariant();
22393  }
22394 
22395  // add element to array (perfect forwarding)
22396  const auto old_capacity = m_value.array->capacity();
22397  m_value.array->emplace_back(std::forward<Args>(args)...);
22398  return set_parent(m_value.array->back(), old_capacity);
22399  }
22400 
22403  template<class... Args>
22404  std::pair<iterator, bool> emplace(Args&& ... args)
22405  {
22406  // emplace only works for null objects or arrays
22407  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22408  {
22409  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
22410  }
22411 
22412  // transform null object into an object
22413  if (is_null())
22414  {
22415  m_type = value_t::object;
22417  assert_invariant();
22418  }
22419 
22420  // add element to array (perfect forwarding)
22421  auto res = m_value.object->emplace(std::forward<Args>(args)...);
22422  set_parent(res.first->second);
22423 
22424  // create result iterator and set iterator to the result of emplace
22425  auto it = begin();
22426  it.m_it.object_iterator = res.first;
22427 
22428  // return pair of iterator and boolean
22429  return {it, res.second};
22430  }
22431 
22435  template<typename... Args>
22437  {
22438  iterator result(this);
22439  JSON_ASSERT(m_value.array != nullptr);
22440 
22441  auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
22442  m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22443  result.m_it.array_iterator = m_value.array->begin() + insert_pos;
22444 
22445  // This could have been written as:
22446  // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22447  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22448 
22449  set_parents();
22450  return result;
22451  }
22452 
22456  {
22457  // insert only works for arrays
22459  {
22460  // check if iterator pos fits to this JSON value
22461  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22462  {
22463  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22464  }
22465 
22466  // insert to array and return iterator
22467  return insert_iterator(pos, val);
22468  }
22469 
22470  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22471  }
22472 
22476  {
22477  return insert(pos, val);
22478  }
22479 
22483  {
22484  // insert only works for arrays
22486  {
22487  // check if iterator pos fits to this JSON value
22488  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22489  {
22490  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22491  }
22492 
22493  // insert to array and return iterator
22494  return insert_iterator(pos, cnt, val);
22495  }
22496 
22497  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22498  }
22499 
22503  {
22504  // insert only works for arrays
22506  {
22507  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22508  }
22509 
22510  // check if iterator pos fits to this JSON value
22511  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22512  {
22513  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22514  }
22515 
22516  // check if range iterators belong to the same JSON object
22517  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22518  {
22519  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22520  }
22521 
22522  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22523  {
22524  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
22525  }
22526 
22527  // insert to array and return iterator
22528  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22529  }
22530 
22534  {
22535  // insert only works for arrays
22537  {
22538  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22539  }
22540 
22541  // check if iterator pos fits to this JSON value
22542  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22543  {
22544  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22545  }
22546 
22547  // insert to array and return iterator
22548  return insert_iterator(pos, ilist.begin(), ilist.end());
22549  }
22550 
22554  {
22555  // insert only works for objects
22557  {
22558  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22559  }
22560 
22561  // check if range iterators belong to the same JSON object
22562  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22563  {
22564  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22565  }
22566 
22567  // passed iterators must belong to objects
22568  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22569  {
22570  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
22571  }
22572 
22573  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22574  }
22575 
22578  void update(const_reference j, bool merge_objects = false)
22579  {
22580  update(j.begin(), j.end(), merge_objects);
22581  }
22582 
22585  void update(const_iterator first, const_iterator last, bool merge_objects = false)
22586  {
22587  // implicitly convert null value to an empty object
22588  if (is_null())
22589  {
22590  m_type = value_t::object;
22591  m_value.object = create<object_t>();
22592  assert_invariant();
22593  }
22594 
22596  {
22597  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
22598  }
22599 
22600  // check if range iterators belong to the same JSON object
22601  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22602  {
22603  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22604  }
22605 
22606  // passed iterators must belong to objects
22607  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22608  {
22609  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
22610  }
22611 
22612  for (auto it = first; it != last; ++it)
22613  {
22614  if (merge_objects && it.value().is_object())
22615  {
22616  auto it2 = m_value.object->find(it.key());
22617  if (it2 != m_value.object->end())
22618  {
22619  it2->second.update(it.value(), true);
22620  continue;
22621  }
22622  }
22623  m_value.object->operator[](it.key()) = it.value();
22624 #if JSON_DIAGNOSTICS
22625  m_value.object->operator[](it.key()).m_parent = this;
22626 #endif
22627  }
22628  }
22629 
22632  void swap(reference other) noexcept (
22633  std::is_nothrow_move_constructible<value_t>::value&&
22634  std::is_nothrow_move_assignable<value_t>::value&&
22635  std::is_nothrow_move_constructible<json_value>::value&&
22636  std::is_nothrow_move_assignable<json_value>::value
22637  )
22638  {
22639  std::swap(m_type, other.m_type);
22640  std::swap(m_value, other.m_value);
22641 
22642  set_parents();
22643  other.set_parents();
22644  assert_invariant();
22645  }
22646 
22649  friend void swap(reference left, reference right) noexcept (
22650  std::is_nothrow_move_constructible<value_t>::value&&
22651  std::is_nothrow_move_assignable<value_t>::value&&
22652  std::is_nothrow_move_constructible<json_value>::value&&
22653  std::is_nothrow_move_assignable<json_value>::value
22654  )
22655  {
22656  left.swap(right);
22657  }
22658 
22661  void swap(array_t& other) // NOLINT(bugprone-exception-escape)
22662  {
22663  // swap only works for arrays
22665  {
22666  using std::swap;
22667  swap(*(m_value.array), other);
22668  }
22669  else
22670  {
22671  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
22672  }
22673  }
22674 
22677  void swap(object_t& other) // NOLINT(bugprone-exception-escape)
22678  {
22679  // swap only works for objects
22681  {
22682  using std::swap;
22683  swap(*(m_value.object), other);
22684  }
22685  else
22686  {
22687  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
22688  }
22689  }
22690 
22693  void swap(string_t& other) // NOLINT(bugprone-exception-escape)
22694  {
22695  // swap only works for strings
22697  {
22698  using std::swap;
22699  swap(*(m_value.string), other);
22700  }
22701  else
22702  {
22703  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
22704  }
22705  }
22706 
22709  void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
22710  {
22711  // swap only works for strings
22713  {
22714  using std::swap;
22715  swap(*(m_value.binary), other);
22716  }
22717  else
22718  {
22719  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
22720  }
22721  }
22722 
22725  void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
22726  {
22727  // swap only works for strings
22729  {
22730  using std::swap;
22731  swap(*(m_value.binary), other);
22732  }
22733  else
22734  {
22735  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
22736  }
22737  }
22738 
22740 
22742  // lexicographical comparison operators //
22744 
22747 
22748  // note parentheses around operands are necessary; see
22749  // https://github.com/nlohmann/json/issues/1530
22750 #define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
22751  const auto lhs_type = lhs.type(); \
22752  const auto rhs_type = rhs.type(); \
22753  \
22754  if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
22755  { \
22756  switch (lhs_type) \
22757  { \
22758  case value_t::array: \
22759  return (*lhs.m_value.array) op (*rhs.m_value.array); \
22760  \
22761  case value_t::object: \
22762  return (*lhs.m_value.object) op (*rhs.m_value.object); \
22763  \
22764  case value_t::null: \
22765  return (null_result); \
22766  \
22767  case value_t::string: \
22768  return (*lhs.m_value.string) op (*rhs.m_value.string); \
22769  \
22770  case value_t::boolean: \
22771  return (lhs.m_value.boolean) op (rhs.m_value.boolean); \
22772  \
22773  case value_t::number_integer: \
22774  return (lhs.m_value.number_integer) op (rhs.m_value.number_integer); \
22775  \
22776  case value_t::number_unsigned: \
22777  return (lhs.m_value.number_unsigned) op (rhs.m_value.number_unsigned); \
22778  \
22779  case value_t::number_float: \
22780  return (lhs.m_value.number_float) op (rhs.m_value.number_float); \
22781  \
22782  case value_t::binary: \
22783  return (*lhs.m_value.binary) op (*rhs.m_value.binary); \
22784  \
22785  case value_t::discarded: \
22786  default: \
22787  return (unordered_result); \
22788  } \
22789  } \
22790  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
22791  { \
22792  return static_cast<number_float_t>(lhs.m_value.number_integer) op rhs.m_value.number_float; \
22793  } \
22794  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
22795  { \
22796  return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_integer); \
22797  } \
22798  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
22799  { \
22800  return static_cast<number_float_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_float; \
22801  } \
22802  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
22803  { \
22804  return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_unsigned); \
22805  } \
22806  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
22807  { \
22808  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_integer; \
22809  } \
22810  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
22811  { \
22812  return lhs.m_value.number_integer op static_cast<number_integer_t>(rhs.m_value.number_unsigned); \
22813  } \
22814  else if(compares_unordered(lhs, rhs))\
22815  {\
22816  return (unordered_result);\
22817  }\
22818  \
22819  return (default_result);
22820 
22822  // returns true if:
22823  // - any operand is NaN and the other operand is of number type
22824  // - any operand is discarded
22825  // in legacy mode, discarded values are considered ordered if
22826  // an operation is computed as an odd number of inverses of others
22827  static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
22828  {
22829  if ((lhs.is_number_float() && std::isnan(lhs.m_value.number_float) && rhs.is_number())
22830  || (rhs.is_number_float() && std::isnan(rhs.m_value.number_float) && lhs.is_number()))
22831  {
22832  return true;
22833  }
22834 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22835  return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
22836 #else
22837  static_cast<void>(inverse);
22838  return lhs.is_discarded() || rhs.is_discarded();
22839 #endif
22840  }
22841 
22842  private:
22843  bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
22844  {
22845  return compares_unordered(*this, rhs, inverse);
22846  }
22847 
22848  public:
22849 #if JSON_HAS_THREE_WAY_COMPARISON
22850  bool operator==(const_reference rhs) const noexcept
22853  {
22854 #ifdef __GNUC__
22855 #pragma GCC diagnostic push
22856 #pragma GCC diagnostic ignored "-Wfloat-equal"
22857 #endif
22858  const_reference lhs = *this;
22859  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
22860 #ifdef __GNUC__
22861 #pragma GCC diagnostic pop
22862 #endif
22863  }
22864 
22867  template<typename ScalarType>
22868  requires std::is_scalar_v<ScalarType>
22869  bool operator==(ScalarType rhs) const noexcept
22870  {
22871  return *this == basic_json(rhs);
22872  }
22873 
22876  bool operator!=(const_reference rhs) const noexcept
22877  {
22878  if (compares_unordered(rhs, true))
22879  {
22880  return false;
22881  }
22882  return !operator==(rhs);
22883  }
22884 
22887  std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
22888  {
22889  const_reference lhs = *this;
22890  // default_result is used if we cannot compare values. In that case,
22891  // we compare types.
22892  JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD*
22893  std::partial_ordering::equivalent,
22894  std::partial_ordering::unordered,
22895  lhs_type <=> rhs_type) // *NOPAD*
22896  }
22897 
22900  template<typename ScalarType>
22901  requires std::is_scalar_v<ScalarType>
22902  std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
22903  {
22904  return *this <=> basic_json(rhs); // *NOPAD*
22905  }
22906 
22907 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22908  // all operators that are computed as an odd number of inverses of others
22909  // need to be overloaded to emulate the legacy comparison behavior
22910 
22914  bool operator<=(const_reference rhs) const noexcept
22915  {
22916  if (compares_unordered(rhs, true))
22917  {
22918  return false;
22919  }
22920  return !(rhs < *this);
22921  }
22922 
22925  template<typename ScalarType>
22926  requires std::is_scalar_v<ScalarType>
22927  bool operator<=(ScalarType rhs) const noexcept
22928  {
22929  return *this <= basic_json(rhs);
22930  }
22931 
22935  bool operator>=(const_reference rhs) const noexcept
22936  {
22937  if (compares_unordered(rhs, true))
22938  {
22939  return false;
22940  }
22941  return !(*this < rhs);
22942  }
22943 
22946  template<typename ScalarType>
22947  requires std::is_scalar_v<ScalarType>
22948  bool operator>=(ScalarType rhs) const noexcept
22949  {
22950  return *this >= basic_json(rhs);
22951  }
22952 #endif
22953 #else
22954  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22957  {
22958 #ifdef __GNUC__
22959 #pragma GCC diagnostic push
22960 #pragma GCC diagnostic ignored "-Wfloat-equal"
22961 #endif
22962  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
22963 #ifdef __GNUC__
22964 #pragma GCC diagnostic pop
22965 #endif
22966  }
22967 
22970  template<typename ScalarType, typename std::enable_if<
22971  std::is_scalar<ScalarType>::value, int>::type = 0>
22972  friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
22973  {
22974  return lhs == basic_json(rhs);
22975  }
22976 
22979  template<typename ScalarType, typename std::enable_if<
22980  std::is_scalar<ScalarType>::value, int>::type = 0>
22981  friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
22982  {
22983  return basic_json(lhs) == rhs;
22984  }
22985 
22988  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22989  {
22990  if (compares_unordered(lhs, rhs, true))
22991  {
22992  return false;
22993  }
22994  return !(lhs == rhs);
22995  }
22996 
22999  template<typename ScalarType, typename std::enable_if<
23000  std::is_scalar<ScalarType>::value, int>::type = 0>
23001  friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23002  {
23003  return lhs != basic_json(rhs);
23004  }
23005 
23008  template<typename ScalarType, typename std::enable_if<
23009  std::is_scalar<ScalarType>::value, int>::type = 0>
23010  friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23011  {
23012  return basic_json(lhs) != rhs;
23013  }
23014 
23017  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23018  {
23019  // default_result is used if we cannot compare values. In that case,
23020  // we compare types. Note we have to call the operator explicitly,
23021  // because MSVC has problems otherwise.
23022  JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))
23023  }
23024 
23027  template<typename ScalarType, typename std::enable_if<
23028  std::is_scalar<ScalarType>::value, int>::type = 0>
23029  friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23030  {
23031  return lhs < basic_json(rhs);
23032  }
23033 
23036  template<typename ScalarType, typename std::enable_if<
23037  std::is_scalar<ScalarType>::value, int>::type = 0>
23038  friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
23039  {
23040  return basic_json(lhs) < rhs;
23041  }
23042 
23045  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
23046  {
23047  if (compares_unordered(lhs, rhs, true))
23048  {
23049  return false;
23050  }
23051  return !(rhs < lhs);
23052  }
23053 
23056  template<typename ScalarType, typename std::enable_if<
23057  std::is_scalar<ScalarType>::value, int>::type = 0>
23058  friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
23059  {
23060  return lhs <= basic_json(rhs);
23061  }
23062 
23065  template<typename ScalarType, typename std::enable_if<
23066  std::is_scalar<ScalarType>::value, int>::type = 0>
23067  friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
23068  {
23069  return basic_json(lhs) <= rhs;
23070  }
23071 
23074  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23075  {
23076  // double inverse
23077  if (compares_unordered(lhs, rhs))
23078  {
23079  return false;
23080  }
23081  return !(lhs <= rhs);
23082  }
23083 
23086  template<typename ScalarType, typename std::enable_if<
23087  std::is_scalar<ScalarType>::value, int>::type = 0>
23088  friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
23089  {
23090  return lhs > basic_json(rhs);
23091  }
23092 
23095  template<typename ScalarType, typename std::enable_if<
23096  std::is_scalar<ScalarType>::value, int>::type = 0>
23097  friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
23098  {
23099  return basic_json(lhs) > rhs;
23100  }
23101 
23104  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23105  {
23106  if (compares_unordered(lhs, rhs, true))
23107  {
23108  return false;
23109  }
23110  return !(lhs < rhs);
23111  }
23112 
23115  template<typename ScalarType, typename std::enable_if<
23116  std::is_scalar<ScalarType>::value, int>::type = 0>
23117  friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
23118  {
23119  return lhs >= basic_json(rhs);
23120  }
23121 
23124  template<typename ScalarType, typename std::enable_if<
23125  std::is_scalar<ScalarType>::value, int>::type = 0>
23126  friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
23127  {
23128  return basic_json(lhs) >= rhs;
23129  }
23130 #endif
23131 
23132 #undef JSON_IMPLEMENT_OPERATOR
23133 
23135 
23137  // serialization //
23139 
23142 #ifndef JSON_NO_IO
23143  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23146  {
23147  // read width member and use it as indentation parameter if nonzero
23148  const bool pretty_print = o.width() > 0;
23149  const auto indentation = pretty_print ? o.width() : 0;
23150 
23151  // reset width to 0 for subsequent calls to this stream
23152  o.width(0);
23153 
23154  // do the actual serialization
23155  serializer s(detail::output_adapter<char>(o), o.fill());
23156  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23157  return o;
23158  }
23159 
23166  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23167  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23168  {
23169  return o << j;
23170  }
23171 #endif // JSON_NO_IO
23172 
23174 
23176  // deserialization //
23178 
23181 
23184  template<typename InputType>
23186  static basic_json parse(InputType&& i,
23187  const parser_callback_t cb = nullptr,
23188  const bool allow_exceptions = true,
23189  const bool ignore_comments = false)
23190  {
23191  basic_json result;
23192  parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23193  return result;
23194  }
23195 
23198  template<typename IteratorType>
23200  static basic_json parse(IteratorType first,
23201  IteratorType last,
23202  const parser_callback_t cb = nullptr,
23203  const bool allow_exceptions = true,
23204  const bool ignore_comments = false)
23205  {
23206  basic_json result;
23207  parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23208  return result;
23209  }
23210 
23212  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23213  static basic_json parse(detail::span_input_adapter&& i,
23214  const parser_callback_t cb = nullptr,
23215  const bool allow_exceptions = true,
23216  const bool ignore_comments = false)
23217  {
23218  basic_json result;
23219  parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23220  return result;
23221  }
23222 
23225  template<typename InputType>
23226  static bool accept(InputType&& i,
23227  const bool ignore_comments = false)
23228  {
23229  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23230  }
23231 
23234  template<typename IteratorType>
23235  static bool accept(IteratorType first, IteratorType last,
23236  const bool ignore_comments = false)
23237  {
23238  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23239  }
23240 
23242  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23243  static bool accept(detail::span_input_adapter&& i,
23244  const bool ignore_comments = false)
23245  {
23246  return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23247  }
23248 
23251  template <typename InputType, typename SAX>
23253  static bool sax_parse(InputType&& i, SAX* sax,
23255  const bool strict = true,
23256  const bool ignore_comments = false)
23257  {
23258  auto ia = detail::input_adapter(std::forward<InputType>(i));
23259  return format == input_format_t::json
23260  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23261  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23262  }
23263 
23266  template<class IteratorType, class SAX>
23268  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23270  const bool strict = true,
23271  const bool ignore_comments = false)
23272  {
23273  auto ia = detail::input_adapter(std::move(first), std::move(last));
23274  return format == input_format_t::json
23275  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23276  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23277  }
23278 
23284  template <typename SAX>
23285  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23287  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23289  const bool strict = true,
23290  const bool ignore_comments = false)
23291  {
23292  auto ia = i.get();
23293  return format == input_format_t::json
23294  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23295  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23296  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23297  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23298  }
23299 #ifndef JSON_NO_IO
23300  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23307  friend std::istream& operator<<(basic_json& j, std::istream& i)
23308  {
23309  return operator>>(i, j);
23310  }
23311 
23314  friend std::istream& operator>>(std::istream& i, basic_json& j)
23315  {
23316  parser(detail::input_adapter(i)).parse(false, j);
23317  return i;
23318  }
23319 #endif // JSON_NO_IO
23320 
23323  // convenience functions //
23325 
23329  const char* type_name() const noexcept
23330  {
23331  switch (m_type)
23332  {
23333  case value_t::null:
23334  return "null";
23335  case value_t::object:
23336  return "object";
23337  case value_t::array:
23338  return "array";
23339  case value_t::string:
23340  return "string";
23341  case value_t::boolean:
23342  return "boolean";
23343  case value_t::binary:
23344  return "binary";
23345  case value_t::discarded:
23346  return "discarded";
23349  case value_t::number_float:
23350  default:
23351  return "number";
23352  }
23353  }
23354 
23355 
23358  // member variables //
23360 
23363 
23365  json_value m_value = {};
23366 
23367 #if JSON_DIAGNOSTICS
23368  basic_json* m_parent = nullptr;
23370 #endif
23371 
23373  // binary serialization/deserialization //
23375 
23378 
23379  public:
23382  static std::vector<std::uint8_t> to_cbor(const basic_json& j)
23383  {
23384  std::vector<std::uint8_t> result;
23385  to_cbor(j, result);
23386  return result;
23387  }
23388 
23392  {
23393  binary_writer<std::uint8_t>(o).write_cbor(j);
23394  }
23395 
23399  {
23400  binary_writer<char>(o).write_cbor(j);
23401  }
23402 
23405  static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
23406  {
23407  std::vector<std::uint8_t> result;
23408  to_msgpack(j, result);
23409  return result;
23410  }
23411 
23415  {
23416  binary_writer<std::uint8_t>(o).write_msgpack(j);
23417  }
23418 
23422  {
23423  binary_writer<char>(o).write_msgpack(j);
23424  }
23425 
23428  static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
23429  const bool use_size = false,
23430  const bool use_type = false)
23431  {
23432  std::vector<std::uint8_t> result;
23433  to_ubjson(j, result, use_size, use_type);
23434  return result;
23435  }
23436 
23440  const bool use_size = false, const bool use_type = false)
23441  {
23442  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
23443  }
23444 
23448  const bool use_size = false, const bool use_type = false)
23449  {
23450  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23451  }
23452 
23455  static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
23456  const bool use_size = false,
23457  const bool use_type = false)
23458  {
23459  std::vector<std::uint8_t> result;
23460  to_bjdata(j, result, use_size, use_type);
23461  return result;
23462  }
23463 
23467  const bool use_size = false, const bool use_type = false)
23468  {
23469  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
23470  }
23471 
23475  const bool use_size = false, const bool use_type = false)
23476  {
23477  binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
23478  }
23479 
23482  static std::vector<std::uint8_t> to_bson(const basic_json& j)
23483  {
23484  std::vector<std::uint8_t> result;
23485  to_bson(j, result);
23486  return result;
23487  }
23488 
23492  {
23493  binary_writer<std::uint8_t>(o).write_bson(j);
23494  }
23495 
23499  {
23500  binary_writer<char>(o).write_bson(j);
23501  }
23502 
23505  template<typename InputType>
23507  static basic_json from_cbor(InputType&& i,
23508  const bool strict = true,
23509  const bool allow_exceptions = true,
23510  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23511  {
23512  basic_json result;
23513  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23514  auto ia = detail::input_adapter(std::forward<InputType>(i));
23515  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23516  return res ? result : basic_json(value_t::discarded);
23517  }
23518 
23521  template<typename IteratorType>
23523  static basic_json from_cbor(IteratorType first, IteratorType last,
23524  const bool strict = true,
23525  const bool allow_exceptions = true,
23526  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23527  {
23528  basic_json result;
23529  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23530  auto ia = detail::input_adapter(std::move(first), std::move(last));
23531  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23532  return res ? result : basic_json(value_t::discarded);
23533  }
23534 
23535  template<typename T>
23537  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23538  static basic_json from_cbor(const T* ptr, std::size_t len,
23539  const bool strict = true,
23540  const bool allow_exceptions = true,
23541  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23542  {
23543  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23544  }
23545 
23546 
23548  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23549  static basic_json from_cbor(detail::span_input_adapter&& i,
23550  const bool strict = true,
23551  const bool allow_exceptions = true,
23552  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23553  {
23554  basic_json result;
23555  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23556  auto ia = i.get();
23557  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23558  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23559  return res ? result : basic_json(value_t::discarded);
23560  }
23561 
23564  template<typename InputType>
23566  static basic_json from_msgpack(InputType&& i,
23567  const bool strict = true,
23568  const bool allow_exceptions = true)
23569  {
23570  basic_json result;
23571  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23572  auto ia = detail::input_adapter(std::forward<InputType>(i));
23573  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23574  return res ? result : basic_json(value_t::discarded);
23575  }
23576 
23579  template<typename IteratorType>
23581  static basic_json from_msgpack(IteratorType first, IteratorType last,
23582  const bool strict = true,
23583  const bool allow_exceptions = true)
23584  {
23585  basic_json result;
23586  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23587  auto ia = detail::input_adapter(std::move(first), std::move(last));
23588  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23589  return res ? result : basic_json(value_t::discarded);
23590  }
23591 
23592  template<typename T>
23594  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23595  static basic_json from_msgpack(const T* ptr, std::size_t len,
23596  const bool strict = true,
23597  const bool allow_exceptions = true)
23598  {
23599  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
23600  }
23601 
23603  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23604  static basic_json from_msgpack(detail::span_input_adapter&& i,
23605  const bool strict = true,
23606  const bool allow_exceptions = true)
23607  {
23608  basic_json result;
23609  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23610  auto ia = i.get();
23611  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23612  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23613  return res ? result : basic_json(value_t::discarded);
23614  }
23615 
23618  template<typename InputType>
23620  static basic_json from_ubjson(InputType&& i,
23621  const bool strict = true,
23622  const bool allow_exceptions = true)
23623  {
23624  basic_json result;
23625  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23626  auto ia = detail::input_adapter(std::forward<InputType>(i));
23627  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23628  return res ? result : basic_json(value_t::discarded);
23629  }
23630 
23633  template<typename IteratorType>
23635  static basic_json from_ubjson(IteratorType first, IteratorType last,
23636  const bool strict = true,
23637  const bool allow_exceptions = true)
23638  {
23639  basic_json result;
23640  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23641  auto ia = detail::input_adapter(std::move(first), std::move(last));
23642  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23643  return res ? result : basic_json(value_t::discarded);
23644  }
23645 
23646  template<typename T>
23648  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23649  static basic_json from_ubjson(const T* ptr, std::size_t len,
23650  const bool strict = true,
23651  const bool allow_exceptions = true)
23652  {
23653  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
23654  }
23655 
23657  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23658  static basic_json from_ubjson(detail::span_input_adapter&& i,
23659  const bool strict = true,
23660  const bool allow_exceptions = true)
23661  {
23662  basic_json result;
23663  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23664  auto ia = i.get();
23665  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23666  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23667  return res ? result : basic_json(value_t::discarded);
23668  }
23669 
23670 
23673  template<typename InputType>
23675  static basic_json from_bjdata(InputType&& i,
23676  const bool strict = true,
23677  const bool allow_exceptions = true)
23678  {
23679  basic_json result;
23680  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23681  auto ia = detail::input_adapter(std::forward<InputType>(i));
23682  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23683  return res ? result : basic_json(value_t::discarded);
23684  }
23685 
23688  template<typename IteratorType>
23690  static basic_json from_bjdata(IteratorType first, IteratorType last,
23691  const bool strict = true,
23692  const bool allow_exceptions = true)
23693  {
23694  basic_json result;
23695  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23696  auto ia = detail::input_adapter(std::move(first), std::move(last));
23697  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23698  return res ? result : basic_json(value_t::discarded);
23699  }
23700 
23703  template<typename InputType>
23705  static basic_json from_bson(InputType&& i,
23706  const bool strict = true,
23707  const bool allow_exceptions = true)
23708  {
23709  basic_json result;
23710  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23711  auto ia = detail::input_adapter(std::forward<InputType>(i));
23712  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23713  return res ? result : basic_json(value_t::discarded);
23714  }
23715 
23718  template<typename IteratorType>
23720  static basic_json from_bson(IteratorType first, IteratorType last,
23721  const bool strict = true,
23722  const bool allow_exceptions = true)
23723  {
23724  basic_json result;
23725  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23726  auto ia = detail::input_adapter(std::move(first), std::move(last));
23727  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23728  return res ? result : basic_json(value_t::discarded);
23729  }
23730 
23731  template<typename T>
23733  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23734  static basic_json from_bson(const T* ptr, std::size_t len,
23735  const bool strict = true,
23736  const bool allow_exceptions = true)
23737  {
23738  return from_bson(ptr, ptr + len, strict, allow_exceptions);
23739  }
23740 
23742  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23743  static basic_json from_bson(detail::span_input_adapter&& i,
23744  const bool strict = true,
23745  const bool allow_exceptions = true)
23746  {
23747  basic_json result;
23748  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23749  auto ia = i.get();
23750  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23751  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23752  return res ? result : basic_json(value_t::discarded);
23753  }
23755 
23757  // JSON Pointer support //
23759 
23762 
23766  {
23767  return ptr.get_unchecked(this);
23768  }
23769 
23770  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23771  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23772  reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23773  {
23774  return ptr.get_unchecked(this);
23775  }
23776 
23780  {
23781  return ptr.get_unchecked(this);
23782  }
23783 
23784  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23785  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23786  const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23787  {
23788  return ptr.get_unchecked(this);
23789  }
23790 
23793  reference at(const json_pointer& ptr)
23794  {
23795  return ptr.get_checked(this);
23796  }
23797 
23798  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23799  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23800  reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23801  {
23802  return ptr.get_checked(this);
23803  }
23804 
23807  const_reference at(const json_pointer& ptr) const
23808  {
23809  return ptr.get_checked(this);
23810  }
23811 
23812  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23813  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23814  const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23815  {
23816  return ptr.get_checked(this);
23817  }
23818 
23821  basic_json flatten() const
23822  {
23823  basic_json result(value_t::object);
23824  json_pointer::flatten("", *this, result);
23825  return result;
23826  }
23827 
23830  basic_json unflatten() const
23831  {
23832  return json_pointer::unflatten(*this);
23833  }
23834 
23836 
23838  // JSON Patch functions //
23840 
23843 
23846  void patch_inplace(const basic_json& json_patch)
23847  {
23848  basic_json& result = *this;
23849  // the valid JSON Patch operations
23850  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
23851 
23852  const auto get_op = [](const std::string & op)
23853  {
23854  if (op == "add")
23855  {
23856  return patch_operations::add;
23857  }
23858  if (op == "remove")
23859  {
23860  return patch_operations::remove;
23861  }
23862  if (op == "replace")
23863  {
23864  return patch_operations::replace;
23865  }
23866  if (op == "move")
23867  {
23868  return patch_operations::move;
23869  }
23870  if (op == "copy")
23871  {
23872  return patch_operations::copy;
23873  }
23874  if (op == "test")
23875  {
23876  return patch_operations::test;
23877  }
23878 
23879  return patch_operations::invalid;
23880  };
23881 
23882  // wrapper for "add" operation; add value at ptr
23883  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
23884  {
23885  // adding to the root of the target document means replacing it
23886  if (ptr.empty())
23887  {
23888  result = val;
23889  return;
23890  }
23891 
23892  // make sure the top element of the pointer exists
23893  json_pointer top_pointer = ptr.top();
23894  if (top_pointer != ptr)
23895  {
23896  result.at(top_pointer);
23897  }
23898 
23899  // get reference to parent of JSON pointer ptr
23900  const auto last_path = ptr.back();
23901  ptr.pop_back();
23902  // parent must exist when performing patch add per RFC6902 specs
23903  basic_json& parent = result.at(ptr);
23904 
23905  switch (parent.m_type)
23906  {
23907  case value_t::null:
23908  case value_t::object:
23909  {
23910  // use operator[] to add value
23911  parent[last_path] = val;
23912  break;
23913  }
23914 
23915  case value_t::array:
23916  {
23917  if (last_path == "-")
23918  {
23919  // special case: append to back
23920  parent.push_back(val);
23921  }
23922  else
23923  {
23924  const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
23925  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
23926  {
23927  // avoid undefined behavior
23928  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
23929  }
23930 
23931  // default case: insert add offset
23932  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
23933  }
23934  break;
23935  }
23936 
23937  // if there exists a parent it cannot be primitive
23938  case value_t::string: // LCOV_EXCL_LINE
23939  case value_t::boolean: // LCOV_EXCL_LINE
23940  case value_t::number_integer: // LCOV_EXCL_LINE
23941  case value_t::number_unsigned: // LCOV_EXCL_LINE
23942  case value_t::number_float: // LCOV_EXCL_LINE
23943  case value_t::binary: // LCOV_EXCL_LINE
23944  case value_t::discarded: // LCOV_EXCL_LINE
23945  default: // LCOV_EXCL_LINE
23946  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
23947  }
23948  };
23949 
23950  // wrapper for "remove" operation; remove value at ptr
23951  const auto operation_remove = [this, &result](json_pointer & ptr)
23952  {
23953  // get reference to parent of JSON pointer ptr
23954  const auto last_path = ptr.back();
23955  ptr.pop_back();
23956  basic_json& parent = result.at(ptr);
23957 
23958  // remove child
23959  if (parent.is_object())
23960  {
23961  // perform range check
23962  auto it = parent.find(last_path);
23963  if (JSON_HEDLEY_LIKELY(it != parent.end()))
23964  {
23965  parent.erase(it);
23966  }
23967  else
23968  {
23969  JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
23970  }
23971  }
23972  else if (parent.is_array())
23973  {
23974  // note erase performs range check
23975  parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
23976  }
23977  };
23978 
23979  // type check: top level value must be an array
23980  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
23981  {
23982  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
23983  }
23984 
23985  // iterate and apply the operations
23986  for (const auto& val : json_patch)
23987  {
23988  // wrapper to get a value for an operation
23989  const auto get_value = [&val](const std::string & op,
23990  const std::string & member,
23991  bool string_type) -> basic_json &
23992  {
23993  // find value
23994  auto it = val.m_value.object->find(member);
23995 
23996  // context-sensitive error message
23997  const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
23998 
23999  // check if desired value is present
24000  if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24001  {
24002  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24003  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
24004  }
24005 
24006  // check if result is of type string
24007  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24008  {
24009  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24010  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
24011  }
24012 
24013  // no error: return value
24014  return it->second;
24015  };
24016 
24017  // type check: every element of the array must be an object
24018  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24019  {
24020  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
24021  }
24022 
24023  // collect mandatory members
24024  const auto op = get_value("op", "op", true).template get<std::string>();
24025  const auto path = get_value(op, "path", true).template get<std::string>();
24026  json_pointer ptr(path);
24027 
24028  switch (get_op(op))
24029  {
24030  case patch_operations::add:
24031  {
24032  operation_add(ptr, get_value("add", "value", false));
24033  break;
24034  }
24035 
24036  case patch_operations::remove:
24037  {
24038  operation_remove(ptr);
24039  break;
24040  }
24041 
24042  case patch_operations::replace:
24043  {
24044  // the "path" location must exist - use at()
24045  result.at(ptr) = get_value("replace", "value", false);
24046  break;
24047  }
24048 
24049  case patch_operations::move:
24050  {
24051  const auto from_path = get_value("move", "from", true).template get<std::string>();
24052  json_pointer from_ptr(from_path);
24053 
24054  // the "from" location must exist - use at()
24055  basic_json v = result.at(from_ptr);
24056 
24057  // The move operation is functionally identical to a
24058  // "remove" operation on the "from" location, followed
24059  // immediately by an "add" operation at the target
24060  // location with the value that was just removed.
24061  operation_remove(from_ptr);
24062  operation_add(ptr, v);
24063  break;
24064  }
24065 
24066  case patch_operations::copy:
24067  {
24068  const auto from_path = get_value("copy", "from", true).template get<std::string>();
24069  const json_pointer from_ptr(from_path);
24070 
24071  // the "from" location must exist - use at()
24072  basic_json v = result.at(from_ptr);
24073 
24074  // The copy is functionally identical to an "add"
24075  // operation at the target location using the value
24076  // specified in the "from" member.
24077  operation_add(ptr, v);
24078  break;
24079  }
24080 
24081  case patch_operations::test:
24082  {
24083  bool success = false;
24084  JSON_TRY
24085  {
24086  // check if "value" matches the one at "path"
24087  // the "path" location must exist - use at()
24088  success = (result.at(ptr) == get_value("test", "value", false));
24089  }
24091  {
24092  // ignore out of range errors: success remains false
24093  }
24094 
24095  // throw an exception if test fails
24096  if (JSON_HEDLEY_UNLIKELY(!success))
24097  {
24098  JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
24099  }
24100 
24101  break;
24102  }
24103 
24104  case patch_operations::invalid:
24105  default:
24106  {
24107  // op must be "add", "remove", "replace", "move", "copy", or
24108  // "test"
24109  JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
24110  }
24111  }
24112  }
24113  }
24114 
24117  basic_json patch(const basic_json& json_patch) const
24118  {
24119  basic_json result = *this;
24120  result.patch_inplace(json_patch);
24121  return result;
24122  }
24123 
24127  static basic_json diff(const basic_json& source, const basic_json& target,
24128  const std::string& path = "")
24129  {
24130  // the patch
24131  basic_json result(value_t::array);
24132 
24133  // if the values are the same, return empty patch
24134  if (source == target)
24135  {
24136  return result;
24137  }
24138 
24139  if (source.type() != target.type())
24140  {
24141  // different types: replace value
24142  result.push_back(
24143  {
24144  {"op", "replace"}, {"path", path}, {"value", target}
24145  });
24146  return result;
24147  }
24148 
24149  switch (source.type())
24150  {
24151  case value_t::array:
24152  {
24153  // first pass: traverse common elements
24154  std::size_t i = 0;
24155  while (i < source.size() && i < target.size())
24156  {
24157  // recursive call to compare array values at index i
24158  auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
24159  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24160  ++i;
24161  }
24162 
24163  // We now reached the end of at least one array
24164  // in a second pass, traverse the remaining elements
24165 
24166  // remove my remaining elements
24167  const auto end_index = static_cast<difference_type>(result.size());
24168  while (i < source.size())
24169  {
24170  // add operations in reverse order to avoid invalid
24171  // indices
24172  result.insert(result.begin() + end_index, object(
24173  {
24174  {"op", "remove"},
24175  {"path", detail::concat(path, '/', std::to_string(i))}
24176  }));
24177  ++i;
24178  }
24179 
24180  // add other remaining elements
24181  while (i < target.size())
24182  {
24183  result.push_back(
24184  {
24185  {"op", "add"},
24186  {"path", detail::concat(path, "/-")},
24187  {"value", target[i]}
24188  });
24189  ++i;
24190  }
24191 
24192  break;
24193  }
24194 
24195  case value_t::object:
24196  {
24197  // first pass: traverse this object's elements
24198  for (auto it = source.cbegin(); it != source.cend(); ++it)
24199  {
24200  // escape the key name to be used in a JSON patch
24201  const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24202 
24203  if (target.find(it.key()) != target.end())
24204  {
24205  // recursive call to compare object values at key it
24206  auto temp_diff = diff(it.value(), target[it.key()], path_key);
24207  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24208  }
24209  else
24210  {
24211  // found a key that is not in o -> remove it
24212  result.push_back(object(
24213  {
24214  {"op", "remove"}, {"path", path_key}
24215  }));
24216  }
24217  }
24218 
24219  // second pass: traverse other object's elements
24220  for (auto it = target.cbegin(); it != target.cend(); ++it)
24221  {
24222  if (source.find(it.key()) == source.end())
24223  {
24224  // found a key that is not in this -> add it
24225  const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24226  result.push_back(
24227  {
24228  {"op", "add"}, {"path", path_key},
24229  {"value", it.value()}
24230  });
24231  }
24232  }
24233 
24234  break;
24235  }
24236 
24237  case value_t::null:
24238  case value_t::string:
24239  case value_t::boolean:
24242  case value_t::number_float:
24243  case value_t::binary:
24244  case value_t::discarded:
24245  default:
24246  {
24247  // both primitive type: replace value
24248  result.push_back(
24249  {
24250  {"op", "replace"}, {"path", path}, {"value", target}
24251  });
24252  break;
24253  }
24254  }
24255 
24256  return result;
24257  }
24259 
24261  // JSON Merge Patch functions //
24263 
24266 
24269  void merge_patch(const basic_json& apply_patch)
24270  {
24271  if (apply_patch.is_object())
24272  {
24273  if (!is_object())
24274  {
24275  *this = object();
24276  }
24277  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24278  {
24279  if (it.value().is_null())
24280  {
24281  erase(it.key());
24282  }
24283  else
24284  {
24285  operator[](it.key()).merge_patch(it.value());
24286  }
24287  }
24288  }
24289  else
24290  {
24291  *this = apply_patch;
24292  }
24293  }
24294 
24296 };
24297 
24301 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
24302 {
24303  return j.dump();
24304 }
24305 
24306 inline namespace literals
24307 {
24308 inline namespace json_literals
24309 {
24310 
24314 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24315 {
24316  return nlohmann::json::parse(s, s + n);
24317 }
24318 
24322 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
24323 {
24324  return nlohmann::json::json_pointer(std::string(s, n));
24325 }
24326 
24327 } // namespace json_literals
24328 } // namespace literals
24330 
24332 // nonmember support //
24334 
24335 namespace std // NOLINT(cert-dcl58-cpp)
24336 {
24337 
24342 {
24343  std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
24344  {
24345  return nlohmann::detail::hash(j);
24346  }
24347 };
24348 
24349 // specialization for std::less<value_t>
24350 template<>
24351 struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
24352 {
24358  ::nlohmann::detail::value_t rhs) const noexcept
24359  {
24360 #if JSON_HAS_THREE_WAY_COMPARISON
24361  return std::is_lt(lhs <=> rhs); // *NOPAD*
24362 #else
24364 #endif
24365  }
24366 };
24367 
24368 // C++20 prohibit function specialization in the std namespace.
24369 #ifndef JSON_HAS_CPP_20
24370 
24374 inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
24375  is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
24376  is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
24377 {
24378  j1.swap(j2);
24379 }
24380 
24381 #endif
24382 
24383 } // namespace std
24384 
24385 #if JSON_USE_GLOBAL_UDLS
24386  using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24387  using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24388 #endif
24389 
24390 // #include <nlohmann/detail/macro_unscope.hpp>
24391 // __ _____ _____ _____
24392 // __| | __| | | | JSON for Modern C++
24393 // | | |__ | | | | | | version 3.11.2
24394 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
24395 //
24396 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
24397 // SPDX-License-Identifier: MIT
24398 
24399 
24400 
24401 // restore clang diagnostic settings
24402 #if defined(__clang__)
24403  #pragma clang diagnostic pop
24404 #endif
24405 
24406 // clean up
24407 #undef JSON_ASSERT
24408 #undef JSON_INTERNAL_CATCH
24409 #undef JSON_THROW
24410 #undef JSON_PRIVATE_UNLESS_TESTED
24411 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24412 #undef NLOHMANN_BASIC_JSON_TPL
24413 #undef JSON_EXPLICIT
24414 #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
24415 #undef JSON_INLINE_VARIABLE
24416 #undef JSON_NO_UNIQUE_ADDRESS
24417 #undef JSON_DISABLE_ENUM_SERIALIZATION
24418 #undef JSON_USE_GLOBAL_UDLS
24419 
24420 #ifndef JSON_TEST_KEEP_MACROS
24421  #undef JSON_CATCH
24422  #undef JSON_TRY
24423  #undef JSON_HAS_CPP_11
24424  #undef JSON_HAS_CPP_14
24425  #undef JSON_HAS_CPP_17
24426  #undef JSON_HAS_CPP_20
24427  #undef JSON_HAS_FILESYSTEM
24428  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
24429  #undef JSON_HAS_THREE_WAY_COMPARISON
24430  #undef JSON_HAS_RANGES
24431  #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
24432 #endif
24433 
24434 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
24435 // __ _____ _____ _____
24436 // __| | __| | | | JSON for Modern C++
24437 // | | |__ | | | | | | version 3.11.2
24438 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
24439 //
24440 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
24441 // SPDX-License-Identifier: MIT
24442 
24443 
24444 
24445 #undef JSON_HEDLEY_ALWAYS_INLINE
24446 #undef JSON_HEDLEY_ARM_VERSION
24447 #undef JSON_HEDLEY_ARM_VERSION_CHECK
24448 #undef JSON_HEDLEY_ARRAY_PARAM
24449 #undef JSON_HEDLEY_ASSUME
24450 #undef JSON_HEDLEY_BEGIN_C_DECLS
24451 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24452 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24453 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24454 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24455 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24456 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
24457 #undef JSON_HEDLEY_CLANG_HAS_WARNING
24458 #undef JSON_HEDLEY_COMPCERT_VERSION
24459 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24460 #undef JSON_HEDLEY_CONCAT
24461 #undef JSON_HEDLEY_CONCAT3
24462 #undef JSON_HEDLEY_CONCAT3_EX
24463 #undef JSON_HEDLEY_CONCAT_EX
24464 #undef JSON_HEDLEY_CONST
24465 #undef JSON_HEDLEY_CONSTEXPR
24466 #undef JSON_HEDLEY_CONST_CAST
24467 #undef JSON_HEDLEY_CPP_CAST
24468 #undef JSON_HEDLEY_CRAY_VERSION
24469 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
24470 #undef JSON_HEDLEY_C_DECL
24471 #undef JSON_HEDLEY_DEPRECATED
24472 #undef JSON_HEDLEY_DEPRECATED_FOR
24473 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24474 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24475 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24476 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24477 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24478 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
24479 #undef JSON_HEDLEY_DIAGNOSTIC_POP
24480 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24481 #undef JSON_HEDLEY_DMC_VERSION
24482 #undef JSON_HEDLEY_DMC_VERSION_CHECK
24483 #undef JSON_HEDLEY_EMPTY_BASES
24484 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24485 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24486 #undef JSON_HEDLEY_END_C_DECLS
24487 #undef JSON_HEDLEY_FLAGS
24488 #undef JSON_HEDLEY_FLAGS_CAST
24489 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24490 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
24491 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24492 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24493 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
24494 #undef JSON_HEDLEY_GCC_HAS_FEATURE
24495 #undef JSON_HEDLEY_GCC_HAS_WARNING
24496 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24497 #undef JSON_HEDLEY_GCC_VERSION
24498 #undef JSON_HEDLEY_GCC_VERSION_CHECK
24499 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24500 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24501 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24502 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24503 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24504 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
24505 #undef JSON_HEDLEY_GNUC_HAS_WARNING
24506 #undef JSON_HEDLEY_GNUC_VERSION
24507 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
24508 #undef JSON_HEDLEY_HAS_ATTRIBUTE
24509 #undef JSON_HEDLEY_HAS_BUILTIN
24510 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24511 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24512 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24513 #undef JSON_HEDLEY_HAS_EXTENSION
24514 #undef JSON_HEDLEY_HAS_FEATURE
24515 #undef JSON_HEDLEY_HAS_WARNING
24516 #undef JSON_HEDLEY_IAR_VERSION
24517 #undef JSON_HEDLEY_IAR_VERSION_CHECK
24518 #undef JSON_HEDLEY_IBM_VERSION
24519 #undef JSON_HEDLEY_IBM_VERSION_CHECK
24520 #undef JSON_HEDLEY_IMPORT
24521 #undef JSON_HEDLEY_INLINE
24522 #undef JSON_HEDLEY_INTEL_CL_VERSION
24523 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
24524 #undef JSON_HEDLEY_INTEL_VERSION
24525 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
24526 #undef JSON_HEDLEY_IS_CONSTANT
24527 #undef JSON_HEDLEY_IS_CONSTEXPR_
24528 #undef JSON_HEDLEY_LIKELY
24529 #undef JSON_HEDLEY_MALLOC
24530 #undef JSON_HEDLEY_MCST_LCC_VERSION
24531 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
24532 #undef JSON_HEDLEY_MESSAGE
24533 #undef JSON_HEDLEY_MSVC_VERSION
24534 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
24535 #undef JSON_HEDLEY_NEVER_INLINE
24536 #undef JSON_HEDLEY_NON_NULL
24537 #undef JSON_HEDLEY_NO_ESCAPE
24538 #undef JSON_HEDLEY_NO_RETURN
24539 #undef JSON_HEDLEY_NO_THROW
24540 #undef JSON_HEDLEY_NULL
24541 #undef JSON_HEDLEY_PELLES_VERSION
24542 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
24543 #undef JSON_HEDLEY_PGI_VERSION
24544 #undef JSON_HEDLEY_PGI_VERSION_CHECK
24545 #undef JSON_HEDLEY_PREDICT
24546 #undef JSON_HEDLEY_PRINTF_FORMAT
24547 #undef JSON_HEDLEY_PRIVATE
24548 #undef JSON_HEDLEY_PUBLIC
24549 #undef JSON_HEDLEY_PURE
24550 #undef JSON_HEDLEY_REINTERPRET_CAST
24551 #undef JSON_HEDLEY_REQUIRE
24552 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24553 #undef JSON_HEDLEY_REQUIRE_MSG
24554 #undef JSON_HEDLEY_RESTRICT
24555 #undef JSON_HEDLEY_RETURNS_NON_NULL
24556 #undef JSON_HEDLEY_SENTINEL
24557 #undef JSON_HEDLEY_STATIC_ASSERT
24558 #undef JSON_HEDLEY_STATIC_CAST
24559 #undef JSON_HEDLEY_STRINGIFY
24560 #undef JSON_HEDLEY_STRINGIFY_EX
24561 #undef JSON_HEDLEY_SUNPRO_VERSION
24562 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24563 #undef JSON_HEDLEY_TINYC_VERSION
24564 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
24565 #undef JSON_HEDLEY_TI_ARMCL_VERSION
24566 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24567 #undef JSON_HEDLEY_TI_CL2000_VERSION
24568 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24569 #undef JSON_HEDLEY_TI_CL430_VERSION
24570 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24571 #undef JSON_HEDLEY_TI_CL6X_VERSION
24572 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24573 #undef JSON_HEDLEY_TI_CL7X_VERSION
24574 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24575 #undef JSON_HEDLEY_TI_CLPRU_VERSION
24576 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24577 #undef JSON_HEDLEY_TI_VERSION
24578 #undef JSON_HEDLEY_TI_VERSION_CHECK
24579 #undef JSON_HEDLEY_UNAVAILABLE
24580 #undef JSON_HEDLEY_UNLIKELY
24581 #undef JSON_HEDLEY_UNPREDICTABLE
24582 #undef JSON_HEDLEY_UNREACHABLE
24583 #undef JSON_HEDLEY_UNREACHABLE_RETURN
24584 #undef JSON_HEDLEY_VERSION
24585 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24586 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
24587 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
24588 #undef JSON_HEDLEY_VERSION_ENCODE
24589 #undef JSON_HEDLEY_WARNING
24590 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
24591 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
24592 #undef JSON_HEDLEY_FALL_THROUGH
24593 
24594 
24595 
24596 #endif // INCLUDE_NLOHMANN_JSON_HPP_
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:5836
detail::iteration_proxy_value::iterator_category
std::input_iterator_tag iterator_category
Definition: json.hpp:5121
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:23439
detail::primitive_iterator_t::is_begin
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:12680
detail::json_sax_acceptor::start_object
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7264
detail::iter_impl::set_end
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:13027
detail::position_t
struct to capture the start position of the current token
Definition: json.hpp:3019
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:21188
JSON_INLINE_VARIABLE
#define JSON_INLINE_VARIABLE
Definition: json.hpp:2489
json_sax::operator=
json_sax & operator=(const json_sax &)=default
detail::json_reverse_iterator::operator--
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.hpp:13615
detail::position_t::lines_read
std::size_t lines_read
the number of lines read
Definition: json.hpp:3026
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:13864
detail::iter_impl::iter_impl
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:12961
detail::dtoa_impl::get_cached_power_for_binary_exponent
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:17111
NLOHMANN_BASIC_JSON_TPL_DECLARATION
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2586
detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:5471
detail::from_json_tuple_impl_base
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:4933
JSON_HEDLEY_DIAGNOSTIC_POP
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:1101
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:17711
detail::void_t
typename make_void< Ts... >::type void_t
Definition: json.hpp:253
basic_json::operator>>
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:23314
detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:5461
detail::get_arithmetic_value
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:4607
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:5138
detail::value_in_range_of_impl1< OfType, T, true >::test
static constexpr bool test(T)
Definition: json.hpp:4071
basic_json::basic_json
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:20017
detail::iteration_proxy_value::operator++
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:5163
detail::dtoa_impl::cached_power::e
int e
Definition: json.hpp:17100
detail::external_constructor< value_t::object >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:5531
basic_json::get_ref
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:21010
detail::json_sax_dom_callback_parser::number_float
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6963
detail::number_integer_function_t
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:8972
detail::type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:4469
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:3554
detail::input_format_t
input_format_t
the supported input formats
Definition: json.hpp:6103
detail::file_input_adapter
Definition: json.hpp:6114
detail::lexer_base::token_type
token_type
token types for the parser
Definition: json.hpp:7339
detail::json_sax_dom_parser::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:6736
json_sax::json_sax
json_sax()=default
ordered_map::size_type
typename Container::size_type size_type
Definition: json.hpp:18916
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:20003
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:21878
detail::nonesuch
Definition: json.hpp:264
detail::primitive_iterator_t::set_begin
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:12668
detail::value_t::boolean
@ boolean
boolean value
detail::binary_writer::write_bson
void write_bson(const BasicJsonType &j)
Definition: json.hpp:14975
basic_json::json_serializer
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:19342
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:23447
detail::exception::diagnostics
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.hpp:4327
basic_json::difference_type
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:19390
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:19515
detail::lexer::scan
token_type scan()
Definition: json.hpp:8810
basic_json::basic_json
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:20312
detail::output_vector_adapter
output adapter for byte vectors
Definition: json.hpp:14839
json_sax::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6601
detail::iteration_proxy_value
Definition: json.hpp:5114
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:5309
detail::from_json_array_impl
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:4750
detail::index_sequence
integer_sequence< size_t, Ints... > index_sequence
Definition: json.hpp:3121
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:3817
detail::iter_impl::iterator_category
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:12859
basic_json::is_structured
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:20473
detail::dtoa_impl::diyfp::diyfp
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:16847
detail::json_sax_acceptor::binary
bool binary(binary_t &)
Definition: json.hpp:7259
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:16947
detail::negation
Definition: json.hpp:3592
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 &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22632
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:23581
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:9179
detail::json_sax_acceptor::start_array
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7279
basic_json::find
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.hpp:21864
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:5122
detail::is_constructible_object_type
Definition: json.hpp:3739
basic_json::find
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.hpp:21832
detail::has_from_json
Definition: json.hpp:3509
detail::json_sax_dom_parser::number_unsigned
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6773
detail::json_reverse_iterator::reference
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:13593
detail::json_ref::json_ref
json_ref(value_type &&value)
Definition: json.hpp:14700
detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:5496
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:3267
detail::is_sax
Definition: json.hpp:9014
detail::is_constructible
Definition: json.hpp:3618
detail::output_adapter
Definition: json.hpp:14912
detail::binary_reader::~binary_reader
~binary_reader()=default
json_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:6604
detail::is_json_ref
Definition: json.hpp:3468
ordered_map::operator[]
const T & operator[](KeyType &&key) const
Definition: json.hpp:18981
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:4005
detail::json_ref::json_ref
json_ref(const value_type &value)
Definition: json.hpp:14704
detail::iteration_proxy_value::iteration_proxy_value
iteration_proxy_value()=default
detail::to_json_fn
Definition: json.hpp:5728
JSON_HEDLEY_PURE
#define JSON_HEDLEY_PURE
Definition: json.hpp:1785
detail::value_in_range_of_impl2< OfType, T, true, true >::test
static constexpr bool test(T val)
Definition: json.hpp:4046
detail::parser::accept
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:12251
byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5831
JSON_HEDLEY_UNLIKELY
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1712
detail::iterator_input_adapter::iterator_input_adapter
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6213
detail::iterator_traits
Definition: json.hpp:3273
detail::json_sax_acceptor::number_unsigned
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:7244
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:3955
basic_json::operator[]
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.hpp:21285
detail::iter_impl::operator+
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:13419
detail::serializer::loc
const std::lconv * loc
the locale
Definition: json.hpp:18853
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:24127
detail::impl::is_transparent
constexpr bool is_transparent()
Definition: json.hpp:4122
detail::iter_impl::operator++
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:13163
ordered_map::erase
size_type erase(KeyType &&key)
Definition: json.hpp:19063
basic_json::at
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:21150
json_pointer
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition: json.hpp:3398
detail::serializer::operator=
serializer & operator=(const serializer &)=delete
detail::concat_length
std::size_t concat_length()
Definition: json.hpp:4162
json_pointer::operator<
friend bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointer for less-than
Definition: json.hpp:14662
basic_json::is_number_integer
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:20501
basic_json::is_number_unsigned
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:20508
basic_json::binary_t
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:19543
detail::input_stream_adapter::get_character
std::char_traits< char >::int_type get_character()
Definition: json.hpp:6187
basic_json::at
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.hpp:21170
json_pointer::operator!=
friend bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:14637
detail::dtoa_impl::find_largest_pow10
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:17275
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:3266
basic_json::swap
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:22709
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:3943
basic_json::operator[]
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.hpp:21307
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:3539
JSON_CATCH
#define JSON_CATCH(exception)
Definition: json.hpp:2515
basic_json::rhs
JSON_PRIVATE_UNLESS_TESTED const_reference rhs
Definition: json.hpp:22827
JSON_INTERNAL_CATCH
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2516
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:12873
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:23391
jwt::json::type::string
@ string
literals
Definition: json.hpp:24306
detail::is_range
Definition: json.hpp:3652
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:5882
detail::primitive_iterator_t::operator+=
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:12739
basic_json::erase
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:21788
detail::json_sax_dom_callback_parser::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6917
basic_json::swap
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:22725
detail::external_constructor< value_t::string >::construct
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:5387
basic_json::operator<<
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:23307
basic_json::back
reference back()
access the last element
Definition: json.hpp:21574
basic_json::parser_callback_t
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:19970
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:8801
byte_container_with_subtype
an internal type for a backed binary type
Definition: json.hpp:5819
detail::iteration_proxy_value::difference_type
std::ptrdiff_t difference_type
Definition: json.hpp:5117
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:15654
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:23705
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:6443
basic_json::get
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20950
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:13591
detail::json_sax_acceptor::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:7227
detail::cbor_tag_handler_t::ignore
@ ignore
ignore tags
detail::out_of_range
exception indicating access out of the defined range
Definition: json.hpp:4486
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:6153
detail::is_iterator_traits
Definition: json.hpp:3634
detail::json_sax_dom_parser::string
bool string(string_t &val)
Definition: json.hpp:6785
detail::json_sax_dom_parser::boolean
bool boolean(bool val)
Definition: json.hpp:6761
detail::json_sax_dom_callback_parser::string
bool string(string_t &val)
Definition: json.hpp:6969
detail::index_sequence_for
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3183
detail::exception::what
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:4304
detail::dtoa_impl::kAlpha
constexpr int kAlpha
Definition: json.hpp:17094
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:13353
detail::binary_writer::write_cbor
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:15004
ordered_map::at
const T & at(const key_type &key) const
Definition: json.hpp:19014
detail::is_sax::value
static constexpr bool value
Definition: json.hpp:9028
detail::iteration_proxy::operator=
iteration_proxy & operator=(iteration_proxy const &)=default
JSON_EXPLICIT
#define JSON_EXPLICIT
Definition: json.hpp:2807
basic_json::operator[]
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:21226
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:20148
basic_json::reverse_iterator
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:19407
basic_json::basic_json
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:19991
json_pointer::json_pointer
friend class json_pointer
Definition: json.hpp:13723
json_pointer::string_t
typename string_t_helper< RefStringType >::type string_t
Definition: json.hpp:13739
detail::binary_writer
serialization to CBOR and MessagePack values
Definition: json.hpp:14954
detail::dtoa_impl::diyfp::mul
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:16865
detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::difference_type
ptrdiff_t difference_type
Definition: json.hpp:3288
detail::json_sax_dom_parser::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6733
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:3289
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:21518
detail::output_stream_adapter::write_character
void write_character(CharType c) override
Definition: json.hpp:14871
basic_json::is_number
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:20494
detail::impl::is_c_string
constexpr bool is_c_string()
Definition: json.hpp:4094
detail::iter_impl::value
reference value() const
return the value of an iterator
Definition: json.hpp:13524
goby::util::e
constexpr T e
Definition: constants.h:35
detail::lexer::get_number_unsigned
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8719
basic_json::is_discarded
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:20550
detail::make_void
Definition: json.hpp:249
basic_json::type
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:20459
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:22323
detail::mapped_type_t
typename T::mapped_type mapped_type_t
Definition: json.hpp:3478
JSON_HEDLEY_DIAGNOSTIC_PUSH
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:1100
detail::input_format_t::ubjson
@ ubjson
ordered_map::erase
size_type erase(const key_type &key)
Definition: json.hpp:19042
detail::primitive_iterator_t::operator-=
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:12745
basic_json::merge_patch
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:24269
detail::iterator_t
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3671
detail
detail namespace with internal helper functions
Definition: json.hpp:246
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 &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22649
detail::external_constructor< value_t::string >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:5367
detail::json_sax_dom_parser::start_object
bool start_object(std::size_t len)
Definition: json.hpp:6797
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:23474
detail::iterator_input_adapter::char_type
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:6211
ordered_map::find
const_iterator find(const key_type &key) const
Definition: json.hpp:19192
detail::external_constructor< value_t::binary >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:5409
json_pointer::json_pointer
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.hpp:13743
detail::null_function_t
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:8964
detail::primitive_iterator_t::get_value
constexpr difference_type get_value() const noexcept
Definition: json.hpp:12662
detail::primitive_iterator_t::operator-
constexpr friend difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12708
basic_json::meta
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:19424
basic_json
namespace for Niels Lohmann
Definition: json.hpp:3393
detail::value_in_range_of_impl2< OfType, T, true, false >::test
static constexpr bool test(T val)
Definition: json.hpp:4025
detail::external_constructor< value_t::number_integer >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:5448
byte_container_with_subtype::operator==
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5854
json_sax
SAX interface.
Definition: json.hpp:6599
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:23675
detail::detector< Default, void_t< Op< Args... > >, Op, Args... >::type
Op< Args... > type
Definition: json.hpp:288
detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::iterator_category
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3286
bool_constant
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:17370
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:24357
detail::iter_impl::operator=
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:12971
detail::is_compatible_string_type
Definition: json.hpp:3744
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:20159
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:4411
basic_json::at
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23807
basic_json::get_binary
binary_t & get_binary()
get a binary value
Definition: json.hpp:21069
detail::external_constructor< value_t::number_unsigned >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:5435
detail::identity_tag
Definition: json.hpp:4544
detail::is_comparable
Definition: json.hpp:3904
detail::parse_event_t::value
@ value
the parser finished reading a JSON value
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:5841
basic_json::operator[]
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:23765
detail::escape
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2974
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:13812
basic_json::const_reference
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:19387
detail::json_sax_dom_parser::number_float
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6779
ordered_map::operator[]
T & operator[](const key_type &key)
Definition: json.hpp:18962
json_pointer::back
const string_t & back() const
return last reference token
Definition: json.hpp:13852
detail::json_sax_dom_parser::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6737
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:9011
detail::dtoa_impl::diyfp::sub
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:16853
detail::integer_sequence::size
static constexpr std::size_t size() noexcept
Definition: json.hpp:3109
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:3265
detail::json_sax_dom_callback_parser::parse_error
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:7102
detail::json_sax_dom_callback_parser::boolean
bool boolean(bool val)
Definition: json.hpp:6945
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:5766
JSON_HEDLEY_WARN_UNUSED_RESULT
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1446
goby::time::str
std::string str(TimeType value=SystemClock::now< TimeType >())
Returns the provided time (or current time if omitted) as a human-readable string.
Definition: convert.h:191
json_pointer::push_back
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13871
detail::input_format_t::bson
@ bson
ordered_map::at
T & at(const key_type &key)
Definition: json.hpp:18986
json_pointer::operator<<
friend std::ostream & operator<<(std::ostream &o, const json_pointer &ptr)
write string representation of the JSON pointer to stream
Definition: json.hpp:13770
detail::value_in_range_of_impl2< OfType, T, false, false >::test
static constexpr bool test(T val)
Definition: json.hpp:4015
detail::lexer::get_number_float
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8725
basic_json::is_number_float
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:20515
detail::actual_object_comparator_t
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.hpp:3578
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:7363
detail::external_constructor
Definition: json.hpp:5348
basic_json::value
ValueType value(KeyType &&key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21443
detail::number_unsigned_function_t
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:8976
detail::iterator_input_adapter_factory
Definition: json.hpp:6413
detail::output_adapter_t
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:14835
ordered_map::find
iterator find(const key_type &key)
Definition: json.hpp:19166
detail::key_function_t
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:8996
detail::contiguous_bytes_input_adapter
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:6508
detail::parse_event_t::key
@ key
the parser read a key of a value in an object
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:6250
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:8980
BinaryType
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:6308
detail::external_constructor< value_t::object >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:5541
detail::dtoa_impl::boundaries::minus
diyfp minus
Definition: json.hpp:16961
basic_json::insert
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.hpp:22482
detail::iterator_input_adapter_factory::iterator_type
IteratorType iterator_type
Definition: json.hpp:6415
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:3846
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:23720
detail::json_sax_dom_parser::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6734
detail::external_constructor< value_t::binary >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:5400
ordered_map::erase
iterator erase(iterator pos)
Definition: json.hpp:19082
detail::void
j template void())
Definition: json.hpp:4822
ordered_map::iterator
typename Container::iterator iterator
Definition: json.hpp:18914
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:4209
detail::output_vector_adapter::output_vector_adapter
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:14842
detail::utility_internal::Gen
Definition: json.hpp:3145
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:23799
detail::utility_internal::Gen::type
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:3148
basic_json::boolean_t
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:19527
detail::iterator_input_adapter_factory::adapter_type
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:6417
NLOHMANN_JSON_NAMESPACE_END
#define NLOHMANN_JSON_NAMESPACE_END
Definition: json.hpp:145
detail::is_complete_type
Definition: json.hpp:3681
bool
detail::dtoa_impl::reinterpret_bits
Target reinterpret_bits(const Source source)
Definition: json.hpp:16831
detail::is_ordered_map::two::x
char x[2]
Definition: json.hpp:3966
detail::dtoa_impl::diyfp::normalize
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:16930
NLOHMANN_BASIC_JSON_TPL
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2595
detail::binary_writer::to_char_type
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:16739
detail::primitive_iterator_t::operator--
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:12726
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:22436
detail::input_format_t::msgpack
@ msgpack
JSON_IMPLEMENT_OPERATOR
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition: json.hpp:22750
detail::is_c_string
Definition: json.hpp:4109
NLOHMANN_JSON_VERSION_PATCH
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:71
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:23507
NLOHMANN_CAN_CALL_STD_FUNC_IMPL
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition: json.hpp:2770
detail::nonesuch::nonesuch
nonesuch()=delete
detail::iteration_proxy::iteration_proxy
iteration_proxy()=default
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)
copy assignment
Definition: json.hpp:20397
detail::json_reverse_iterator::operator++
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.hpp:13603
detail::binary_writer::to_char_type
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16717
detail::json_reverse_iterator::json_reverse_iterator
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:13600
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:2955
detail::iter_impl::operator+=
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13362
detail::detect_erase_with_key_type
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.hpp:3946
detail::cbor_tag_handler_t::store
@ store
store tags as binary type
detail::dtoa_impl::cached_power
Definition: json.hpp:17097
byte_container_with_subtype::container_type
BinaryType container_type
Definition: json.hpp:5822
detail::dtoa_impl::grisu2
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:17611
detail::serializer::undumped_chars
std::size_t undumped_chars
Definition: json.hpp:18283
detail::output_string_adapter::output_string_adapter
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:14892
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:20070
char
detail::binary_reader::operator=
binary_reader & operator=(const binary_reader &)=delete
detail::parse_event_t::object_start
@ object_start
the parser read { and started to process a JSON object
detail::value_in_range_of
constexpr bool value_in_range_of(T val)
Definition: json.hpp:4078
detail::detect_string_can_append_op
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.hpp:4206
detail::json_reverse_iterator::operator-
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:13645
detail::output_adapter_protocol
abstract output adapter interface
Definition: json.hpp:14820
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:23771
detail::is_detected_exact
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:307
byte_container_with_subtype::subtype_type
std::uint64_t subtype_type
Definition: json.hpp:5823
basic_json::m_value
json_value m_value
the value of the current element
Definition: json.hpp:23365
adl_serializer
namespace for Niels Lohmann
Definition: json.hpp:3378
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:5786
detail::is_transparent
Definition: json.hpp:4131
ordered_map::key_type
Key key_type
Definition: json.hpp:18911
basic_json::operator+=
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:22370
basic_json::push_back
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:22354
detail::is_basic_json_context
Definition: json.hpp:3454
detail::serializer::bytes
std::size_t bytes
Definition: json.hpp:18279
detail::json_sax_dom_callback_parser::number_integer
bool number_integer(number_integer_t val)
Definition: json.hpp:6951
detail::json_sax_dom_parser::binary
bool binary(binary_t &val)
Definition: json.hpp:6791
detail::json_reverse_iterator::operator++
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:13609
detail::cbor_tag_handler_t
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:9113
basic_json::allocator_type
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:19395
JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition: json.hpp:78
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:23635
detail::json_ref::operator*
value_type const & operator*() const
Definition: json.hpp:14735
basic_json::type_name
const JSON_HEDLEY_RETURNS_NON_NULL char * type_name() const noexcept
return the type as string
Definition: json.hpp:23329
detail::conjunction< B >
Definition: json.hpp:3586
detail::pointer_t
typename T::pointer pointer_t
Definition: json.hpp:3490
ordered_map
a minimal map-like container that preserves insertion order
Definition: json.hpp:3409
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:23785
detail::lexer::skip_bom
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8787
basic_json::basic_json
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:20198
detail::range_value_t
value_type_t< iterator_traits< iterator_t< T > >> range_value_t
Definition: json.hpp:3674
detail::is_getable
Definition: json.hpp:3516
JSON_HEDLEY_CONST
#define JSON_HEDLEY_CONST
Definition: json.hpp:1816
detail::span_input_adapter::span_input_adapter
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:6543
ordered_map::insert
void insert(InputIt first, InputIt last)
Definition: json.hpp:19227
detail::parser
syntax analysis
Definition: json.hpp:12158
detail::value_t::string
@ string
string value
detail::serializer::~serializer
~serializer()=default
detail::iterator_input_adapter::get_character
std::char_traits< char_type >::int_type get_character()
Definition: json.hpp:6217
basic_json::operator[]
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.hpp:21362
detail::span_input_adapter
Definition: json.hpp:6534
detail::span_input_adapter::get
contiguous_bytes_input_adapter && get()
Definition: json.hpp:6553
basic_json::number_integer_t
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:19531
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:13819
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:17763
detail::from_json_fn
Definition: json.hpp:5027
json_pointer::operator==
friend bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:14612
detail::lexer
lexical analysis
Definition: json.hpp:7412
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
detail::input_format_t::json
@ json
detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:5483
detail::make_integer_sequence
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3167
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:20710
double
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:23690
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:24117
detail::serializer
Definition: json.hpp:17935
detail::integer_sequence
Definition: json.hpp:3106
detail::is_ordered_map::two
Definition: json.hpp:3964
basic_json::size_type
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:19392
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:5776
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:20170
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:23566
detail::iter_impl::operator==
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:13255
detail::iteration_proxy::begin
iteration_proxy_value< IteratorType > begin() const noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:5255
detail::value_in_range_of_impl2< OfType, T, false, true >::test
static constexpr bool test(T val)
Definition: json.hpp:4035
ordered_map::value_type
typename Container::value_type value_type
Definition: json.hpp:18917
basic_json::is_null
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:20480
detail::static_const::value
static constexpr JSON_INLINE_VARIABLE T value
Definition: json.hpp:3197
basic_json::at
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.hpp:21208
JSON_THROW
#define JSON_THROW(exception)
Definition: json.hpp:2513
basic_json::contains
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:21905
basic_json::get_to
ValueType & get_to(ValueType &v) const
Definition: json.hpp:20976
detail::binary_writer::binary_writer
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:14966
detail::iterator_input_adapter
Definition: json.hpp:6208
detail::iter_impl::operator+
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:13408
detail::json_sax_acceptor::end_object
bool end_object()
Definition: json.hpp:7274
detail::serializer::indent_char
const char indent_char
the indentation character
Definition: json.hpp:18863
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:21770
detail::dtoa_impl::diyfp::kPrecision
static constexpr int kPrecision
Definition: json.hpp:16842
detail::external_constructor< value_t::object >::construct
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:5552
JSON_PRIVATE_UNLESS_TESTED
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2549
ordered_map::ordered_map
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.hpp:18931
detail::json_sax_dom_parser::start_array
bool start_array(std::size_t len)
Definition: json.hpp:6829
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:3264
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:5848
detail::iteration_proxy_value::value
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:5228
detail::detected_or_t
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:304
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:23414
detail::iter_impl::operator--
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:13214
detail::iter_impl::operator*
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:13066
detail::detect_string_can_append_iter
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.hpp:4212
detail::output_stream_adapter
output adapter for output streams
Definition: json.hpp:14864
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:20987
detail::dtoa_impl::diyfp
Definition: json.hpp:16840
basic_json::push_back
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:22291
ordered_map::insert
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:19204
detail::dtoa_impl::boundaries::plus
diyfp plus
Definition: json.hpp:16962
detail::wide_string_input_adapter::get_character
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6376
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:4939
ordered_map::operator[]
T & operator[](KeyType &&key)
Definition: json.hpp:18969
basic_json::is_primitive
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:20466
JSON_HEDLEY_RETURNS_NON_NULL
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:2045
detail::primitive_iterator_t::operator<
constexpr friend bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12696
JSON_HEDLEY_NON_NULL
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1604
detail::parse_event_t::object_end
@ object_end
the parser read } and finished processing a JSON object
jwt::json::type::number
@ number
basic_json::at
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:21127
basic_json::insert
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.hpp:22553
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:6924
detail::static_const
Definition: json.hpp:3195
detail::has_to_json
Definition: json.hpp:3549
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) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:24374
ordered_map::ordered_map
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:18929
detail::to_json
void to_json(BasicJsonType &j, const T &b)
Definition: json.hpp:5703
detail::dtoa_impl::compute_boundaries
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:16972
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:13804
detail::iter_impl
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:12833
basic_json::pointer
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:19398
byte_container_with_subtype::clear_subtype
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5889
detail::json_sax_dom_callback_parser::start_object
bool start_object(std::size_t len)
Definition: json.hpp:6981
detail::input_stream_adapter::~input_stream_adapter
~input_stream_adapter()
Definition: json.hpp:6158
detail::little_endianness
static bool little_endianness(int num=1) noexcept
determine system byte order
Definition: json.hpp:9127
detail::int_to_string
void int_to_string(string_type &target, std::size_t value)
Definition: json.hpp:5108
ordered_map::const_iterator
typename Container::const_iterator const_iterator
Definition: json.hpp:18915
detail::to_json_tuple_impl
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:5709
detail::output_vector_adapter::write_character
void write_character(CharType c) override
Definition: json.hpp:14846
detail::json_ref::json_ref
json_ref(Args &&... args)
Definition: json.hpp:14715
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:23482
detail::json_sax_dom_parser::key
bool key(string_t &val)
Definition: json.hpp:6809
detail::detector::value_t
std::false_type value_t
Definition: json.hpp:280
basic_json::back
const_reference back() const
access the last element
Definition: json.hpp:21583
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:20137
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:6852
detail::internal_iterator
an iterator value
Definition: json.hpp:12766
detail::other_error::create
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4507
detail::invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:4451
basic_json::string_t
StringType string_t
a type for a string
Definition: json.hpp:19523
detail::parser::parse
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:12191
ordered_map::at
T & at(KeyType &&key)
Definition: json.hpp:19001
basic_json::operator[]
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23779
detail::detected_t
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:298
detail::iter_impl::value_type
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:12862
detail::file_input_adapter::get_character
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6133
ordered_map::ordered_map
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.hpp:18927
ordered_map::insert
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:19209
basic_json::insert
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.hpp:22502
detail::is_compatible_object_type_impl
Definition: json.hpp:3688
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:19506
detail::end_object_function_t
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:8999
detail::value_t::null
@ null
null value
ordered_map::count
size_type count(KeyType &&key) const
Definition: json.hpp:19154
detail::serializer::ensure_ascii
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition: json.hpp:18276
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:5731
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:23620
detail::primitive_iterator_t::operator--
primitive_iterator_t operator--(int) &noexcept
Definition: json.hpp:12732
detail::is_sax_static_asserts
Definition: json.hpp:9045
detail::internal_iterator::primitive_iterator
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:12773
JSON_TRY
#define JSON_TRY
Definition: json.hpp:2514
detail::make_void::type
void type
Definition: json.hpp:251
json_pointer::empty
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:13878
byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5826
detail::detector
Definition: json.hpp:278
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:17848
detail::input_format_t::cbor
@ cbor
detail::iter_impl::operator>
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:13344
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:24301
detail::binary_function_t
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:8988
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:23466
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:3720
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:4593
basic_json::operator+=
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22283
detail::input_stream_adapter::input_stream_adapter
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:6177
detail::iterator_input_adapter_factory::create
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6419
detail::iter_impl::operator--
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.hpp:13203
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:20126
detail::json_ref::moved_or_copied
value_type moved_or_copied() const
Definition: json.hpp:14726
basic_json::swap
void swap(object_t &other)
exchanges the values
Definition: json.hpp:22677
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:6439
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:21417
basic_json::const_iterator
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:19405
detail::iter_impl::operator-=
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:13399
detail::from_json
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.hpp:4998
detail::value_in_range_of_impl1
Definition: json.hpp:4057
detail::dtoa_impl::boundaries::w
diyfp w
Definition: json.hpp:16960
detail::json_ref::operator->
value_type const * operator->() const
Definition: json.hpp:14740
basic_json::find
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.hpp:21848
jwt::json::type
type
Generic JSON types used in JWTs.
Definition: jwt.h:2071
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:23421
basic_json::basic_json
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:19983
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:22578
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:13789
detail::json_sax_dom_parser::json_sax_dom_parser
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:6744
basic_json::~basic_json
~basic_json() noexcept
destructor
Definition: json.hpp:20418
detail::out_of_range::create
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4490
detail::position_t::chars_read_total
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:3022
ordered_map::erase
iterator erase(iterator first, iterator last)
Definition: json.hpp:19087
basic_json::insert
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.hpp:22455
detail::json_sax_acceptor::end_array
bool end_array()
Definition: json.hpp:7284
ordered_map::find
iterator find(KeyType &&key)
Definition: json.hpp:19180
detail::output_string_adapter
output adapter for basic_string
Definition: json.hpp:14889
detail::parser::sax_parse
bool sax_parse(SAX *sax, const bool strict=true)
Definition: json.hpp:12259
detail::iter_impl::operator-
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:13441
JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
Definition: json.hpp:12049
detail::dtoa_impl::diyfp::f
std::uint64_t f
Definition: json.hpp:16844
detail::is_json_iterator_of
Definition: json.hpp:3883
detail::json_sax_dom_callback_parser::number_unsigned
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6957
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:4000
detail::end_array_function_t
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:9006
detail::string_function_t
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:8984
detail::dtoa_impl::kGamma
constexpr int kGamma
Definition: json.hpp:17095
detail::wide_string_input_adapter::wide_string_input_adapter
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:6373
detail::is_constructible_string_type::laundered_type
ConstructibleStringType laundered_type
Definition: json.hpp:3757
detail::input_stream_adapter::input_stream_adapter
input_stream_adapter(std::istream &i)
Definition: json.hpp:6168
detail::is_compatible_object_type
Definition: json.hpp:3707
detail::json_sax_dom_parser::end_array
bool end_array()
Definition: json.hpp:6841
detail::error_handler_t
error_handler_t
how to treat decoding errors
Definition: json.hpp:17927
detail::iterator_input_adapter_factory::char_type
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6416
detail::dtoa_impl::boundaries
Definition: json.hpp:16958
detail::iteration_proxy::iteration_proxy
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:5245
detail::binary_reader
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:9141
detail::is_compatible_array_type_impl
Definition: json.hpp:3768
basic_json::iterator
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:19403
detail::iter_impl::operator-
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13430
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:23523
detail::output_stream_adapter::output_stream_adapter
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:14867
detail::get
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:5271
detail::serializer::state
std::uint8_t state
Definition: json.hpp:18278
detail::iterator_types
Definition: json.hpp:3255
detail::json_sax_acceptor::boolean
bool boolean(bool)
Definition: json.hpp:7234
detail::unescape
static void unescape(StringType &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2989
detail::is_compatible_integer_type_impl
Definition: json.hpp:3835
detail::exception::id
const int id
the id of the exception
Definition: json.hpp:4310
ordered_map::count
size_type count(const key_type &key) const
Definition: json.hpp:19140
ordered_map::emplace
std::pair< iterator, bool > emplace(KeyType &&key, T &&t)
Definition: json.hpp:18949
is_detected
operator==
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14612
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:12169
basic_json::number_float_t
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:19539
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:3484
detail::iteration_proxy_value::operator==
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:5180
detail::detector::type
Default type
Definition: json.hpp:281
detail::iter_impl::iter_impl
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:12936
basic_json::get_allocator
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:19416
detail::internal_iterator::object_iterator
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:12769
detail::json_reverse_iterator
a template for a reverse iterator class
Definition: json.hpp:13586
detail::primitive_iterator_t::operator+
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:12701
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:6474
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:21541
detail::serializer::string_buffer
std::array< char, 512 > string_buffer
string buffer
Definition: json.hpp:18860
detail::json_sax_dom_parser::number_integer
bool number_integer(number_integer_t val)
Definition: json.hpp:6767
detail::serializer::bytes_after_last_accept
std::size_t bytes_after_last_accept
Definition: json.hpp:18282
detail::is_constructible_array_type_impl
Definition: json.hpp:3790
basic_json::value
ReturnType value(KeyType &&key, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21470
detail::actual_object_comparator::object_t
typename BasicJsonType::object_t object_t
Definition: json.hpp:3571
detail::json_reverse_iterator::operator[]
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13651
detail::input_adapter
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6451
detail::iter_impl::operator<=
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:13335
detail::string_can_append
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition: json.hpp:4197
detail::internal_iterator::array_iterator
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:12771
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:5030
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:23405
detail::uncvref_t
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:3065
detail::concat
OutStringType concat(Args &&... args)
Definition: json.hpp:4277
detail::wide_string_input_adapter
Definition: json.hpp:6368
detail::key_type_t
typename T::key_type key_type_t
Definition: json.hpp:3481
detail::error_handler_t::strict
@ strict
throw a type_error exception in case of invalid UTF-8
detail::iter_impl::operator[]
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13470
detail::primitive_iterator_t::operator++
primitive_iterator_t operator++(int) &noexcept
Definition: json.hpp:12719
json_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6603
detail::value_in_range_of_impl1< OfType, T, false >::test
static constexpr bool test(T val)
Definition: json.hpp:4062
basic_json::basic_json
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:20380
detail::detect_string_can_append_data
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.hpp:4218
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:3696
basic_json::swap
void swap(string_t &other)
exchanges the values
Definition: json.hpp:22693
basic_json::find
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.hpp:21818
detail::lexer::get_number_integer
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8713
detail::is_iterator_of_multibyte::value_type
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:6428
detail::get_template_function
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3505
ordered_map::key_compare
std::equal_to< Key > key_compare
Definition: json.hpp:18921
detail::has_key_compare
Definition: json.hpp:3565
basic_json::out_of_range
detail::out_of_range out_of_range
Definition: json.hpp:19366
basic_json::swap
void swap(array_t &other)
exchanges the values
Definition: json.hpp:22661
jwt::decode
decoded_jwt< json_traits > decode(const typename json_traits::string_type &token, Decode decode)
Definition: jwt.h:4179
operator<
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14662
detail::is_specialization_of
Definition: json.hpp:3894
detail::hash
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5951
detail::json_sax_acceptor::key
bool key(string_t &)
Definition: json.hpp:7269
JSON_HEDLEY_LIKELY
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1711
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:17991
detail::is_ordered_map
Definition: json.hpp:3960
detail::reference_t
typename T::reference reference_t
Definition: json.hpp:3493
detail::json_sax_acceptor::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:7223
detail::conditional_static_cast
T conditional_static_cast(U value)
Definition: json.hpp:3977
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:22585
detail::json_reverse_iterator::value
reference value() const
return the value of an iterator
Definition: json.hpp:13664
detail::priority_tag
Definition: json.hpp:3190
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:20721
json_sax::string
virtual bool string(string_t &val)=0
a string value was read
detail::is_constructible_string_type
Definition: json.hpp:3751
json_pointer::operator/=
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:13779
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:21392
detail::is_ordered_map::value
@ value
Definition: json.hpp:3972
basic_json::operator[]
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:21272
detail::serializer::number_buffer
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition: json.hpp:18850
detail::json_sax_dom_parser::end_object
bool end_object()
Definition: json.hpp:6819
detail::serializer::indent_string
string_t indent_string
the indentation string
Definition: json.hpp:18865
detail::serializer::error_handler
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:18868
detail::json_reverse_iterator::difference_type
std::ptrdiff_t difference_type
Definition: json.hpp:13589
detail::invalid_iterator::create
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4455
detail::dtoa_impl::cached_power::f
std::uint64_t f
Definition: json.hpp:17099
detail::json_sax_acceptor::number_integer
bool number_integer(number_integer_t)
Definition: json.hpp:7239
detail::json_reverse_iterator::operator+=
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13627
ordered_map::require_input_iter
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.hpp:19224
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:3524
detail::binary_writer::to_char_type
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16710
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:3574
detail::container_input_adapter_factory_impl::container_input_adapter_factory
Definition: json.hpp:6468
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:20909
detail::to_json
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5571
detail::is_basic_json
Definition: json.hpp:3445
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:21912
detail::binary_writer::write_msgpack
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:15328
detail::is_default_constructible
Definition: json.hpp:3598
detail::operator<
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:2886
basic_json::erase
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:21665
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:4215
detail::parse_error
exception indicating a parse error
Definition: json.hpp:4398
detail::other_error
exception indicating other library errors
Definition: json.hpp:4503
detail::parser_callback_t
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:12150
detail::json_reverse_iterator::operator--
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:13621
byte_container_with_subtype::set_subtype
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5867
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:23398
json_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6605
detail::iteration_proxy
proxy class for the items() function
Definition: json.hpp:5235
detail::iter_impl::operator!=
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:13291
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:20185
detail::primitive_iterator_t::is_end
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:12686
detail::is_detected
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:292
ordered_map::emplace
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:18934
basic_json::insert
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.hpp:22475
JSON_HEDLEY_DEPRECATED_FOR
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.hpp:1394
basic_json::reference
value_type & reference
the type of an element reference
Definition: json.hpp:19385
detail::json_sax_dom_callback_parser
Definition: json.hpp:6913
detail::is_constructible_array_type
Definition: json.hpp:3830
detail::priority_tag< 0 >
Definition: json.hpp:3191
ordered_map::at
const T & at(KeyType &&key) const
Definition: json.hpp:19029
detail::json_sax_acceptor::string
bool string(string_t &)
Definition: json.hpp:7254
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:13797
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:20963
ordered_map::ordered_map
ordered_map() noexcept(noexcept(Container()))
Definition: json.hpp:18926
detail::json_reverse_iterator::operator-
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13639
detail::lexer::get_string
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8731
detail::type_error::create
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4473
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:23498
detail::lexer::get_token_string
std::string get_token_string() const
Definition: json.hpp:8749
basic_json::inverse
JSON_PRIVATE_UNLESS_TESTED const_reference bool inverse
Definition: json.hpp:22827
detail::lexer::get_position
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8741
detail::actual_object_comparator::object_comparator_t
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.hpp:3572
detail::json_sax_dom_callback_parser::binary
bool binary(binary_t &val)
Definition: json.hpp:6975
basic_json::is_string
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:20536
detail::to_json_function
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3499
JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
Definition: json.hpp:12046
detail::json_sax_dom_callback_parser::key
bool key(string_t &val)
Definition: json.hpp:6999
detail::wide_string_input_helper
Definition: json.hpp:6244
detail::is_detected_convertible
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:311
NLOHMANN_JSON_VERSION_MAJOR
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:69
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:12868
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:17329
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:3024
detail::lexer::lexer
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:7424
detail::value_in_range_of_impl2
Definition: json.hpp:4010
detail::is_detected_lazy
Definition: json.hpp:295
detail::has_non_default_from_json
Definition: json.hpp:3534
detail::iter_impl::difference_type
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:12864
jwt::create
builder< json_traits > create()
Definition: jwt.h:4168
detail::iteration_proxy_value::operator++
iteration_proxy_value operator++(int) &
Definition: json.hpp:5171
detail::iteration_proxy_value::operator!=
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:5186
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:20437
basic_json::is_array
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:20529
detail::detect_string_can_append
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.hpp:4200
detail::json_sax_dom_callback_parser::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6916
detail::json_ref
Definition: json.hpp:3465
NLOHMANN_JSON_VERSION_MINOR
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:70
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:13596
json_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6602
basic_json::operator[]
reference operator[](KeyType &&key)
access specified object element
Definition: json.hpp:21338
detail::difference_type_t
typename T::difference_type difference_type_t
Definition: json.hpp:3487
detail::json_sax_acceptor::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:7226
ordered_map::Container
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:18913
detail::json_sax_dom_callback_parser::end_array
bool end_array()
Definition: json.hpp:7069
detail::serializer::thousands_sep
const char thousands_sep
the locale's thousand separator character
Definition: json.hpp:18855
basic_json::emplace_back
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:22379
detail::iteration_proxy_value::key
const string_type & key() const
return key of the iterator
Definition: json.hpp:5192
basic_json::operator+=
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22346
detail::json_sax_dom_callback_parser::parse_event_t
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:6922
detail::json_reverse_iterator::operator+
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:13633
ordered_map::mapped_type
T mapped_type
Definition: json.hpp:18912
detail::detect_key_compare
typename T::key_compare detect_key_compare
Definition: json.hpp:3562
basic_json::is_binary
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:20543
basic_json::is_boolean
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:20487
detail::value_t
value_t
the JSON type enumeration
Definition: json.hpp:2856
basic_json::get_binary
const binary_t & get_binary() const
get a binary value
Definition: json.hpp:21081
json_pointer::to_string
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:13749
detail::actual_object_comparator
Definition: json.hpp:3569
basic_json::object_comparator_t
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.hpp:19547
detail::iter_impl::iter_impl
iter_impl()=default
detail::exception::name
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:4316
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:9158
std::hash< nlohmann::NLOHMANN_BASIC_JSON_TPL >::operator()
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.hpp:24343
basic_json::emplace
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:22404
detail::is_iterator_of_multibyte
Definition: json.hpp:6426
detail::json_sax_dom_callback_parser::parser_callback_t
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:6921
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:3263
detail::iter_impl::operator<
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:13300
basic_json::operator[]
const_reference operator[](T *key) const
Definition: json.hpp:21329
detail::json_sax_acceptor::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:7225
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:21896
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:23491
json_pointer::pop_back
void pop_back()
remove last reference token
Definition: json.hpp:13840
detail::iter_impl::key
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:13508
detail::json_sax_acceptor::parse_error
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:7289
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:23428
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:3845
detail::error_handler_t::ignore
@ ignore
ignore invalid UTF-8 sequences
detail::primitive_iterator_t::set_end
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:12674
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:20178
detail::json_sax_dom_callback_parser::end_object
bool end_object()
Definition: json.hpp:7016
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:13533
detail::parse_error::create
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4419
detail::external_constructor< value_t::boolean >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:5354
detail::is_compatible_string_type::value
static constexpr auto value
Definition: json.hpp:3746
detail::output_adapter::output_adapter
output_adapter(StringType &s)
Definition: json.hpp:14924
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:23455
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:19348
detail::json_sax_dom_callback_parser::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6918
detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:5512
detail::is_getable::value
static constexpr bool value
Definition: json.hpp:3518
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:6476
basic_json::operator+=
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:22315
detail::exception
general exception of the basic_json class
Definition: json.hpp:4300
detail::file_input_adapter::file_input_adapter
file_input_adapter(std::FILE *f) noexcept
Definition: json.hpp:6120
basic_json::count
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:21888
basic_json::front
const_reference front() const
access the first element
Definition: json.hpp:21567
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:21781
detail::json_sax_acceptor
Definition: json.hpp:7220
detail::exception::diagnostics
static std::string diagnostics(std::nullptr_t)
Definition: json.hpp:4321
detail::dtoa_impl::cached_power::k
int k
Definition: json.hpp:17101
detail::string_can_append_op
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition: json.hpp:4203
detail::iter_impl::operator++
iter_impl operator++(int) &
post-increment (it++)
Definition: json.hpp:13152
detail::json_sax_dom_parser::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6735
detail::utility_internal::Extend
Definition: json.hpp:3127
detail::cbor_tag_handler_t::error
@ error
throw a parse_error exception in case of a tag
json_pointer::parent_pointer
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:13826
detail::integer_sequence::value_type
T value_type
Definition: json.hpp:3108
operator!=
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14637
detail::detect_is_transparent
typename T::is_transparent detect_is_transparent
Definition: json.hpp:3913
detail::json_sax_dom_callback_parser::start_array
bool start_array(std::size_t len)
Definition: json.hpp:7052
basic_json::get_ref
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:20999
basic_json::operator[]
reference operator[](T *key)
Definition: json.hpp:21323
JSON_ASSERT
#define JSON_ASSERT(x)
Definition: json.hpp:2542
byte_container_with_subtype::subtype
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5875
detail::is_compatible_array_type
Definition: json.hpp:3786
detail::combine
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:5933
detail::primitive_iterator_t
Definition: json.hpp:12650
basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21595
basic_json::basic_json
basic_json(const JsonRef &ref)
Definition: json.hpp:20308
detail::json_sax_dom_callback_parser::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6920
detail::iter_impl::operator->
pointer operator->() const
dereference the iterator
Definition: json.hpp:13110
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:6919
friend
detail::is_compatible_type_impl
Definition: json.hpp:3861
basic_json::insert
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.hpp:22533
detail::iter_impl::~iter_impl
~iter_impl()=default
detail::iterator_input_adapter_factory< IteratorType, enable_if_t< is_iterator_of_multibyte< IteratorType >::value > >::iterator_type
IteratorType iterator_type
Definition: json.hpp:6438
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:8774
basic_json::array_t
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:19519
detail::is_constructible_object_type_impl
Definition: json.hpp:3712
detail::output_adapter::output_adapter
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:14916
NLOHMANN_JSON_NAMESPACE_BEGIN
#define NLOHMANN_JSON_NAMESPACE_BEGIN
Definition: json.hpp:135
basic_json::at
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:21104
ordered_map::operator[]
const T & operator[](const key_type &key) const
Definition: json.hpp:18974
byte_container_with_subtype::operator!=
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5860
detail::external_constructor< value_t::string >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:5376
basic_json::json_pointer
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:19340
detail::json_ref::value_type
BasicJsonType value_type
Definition: json.hpp:14698
detail::start_object_function_t
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:8992
jwt::json::type::array
@ array
detail::primitive_iterator_t::operator==
constexpr friend bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12691
detail::serializer::serializer
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:17951
detail::lexer_base
Definition: json.hpp:7335
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:21493
detail::from_json_function
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3502
detail::iteration_proxy::end
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:5261
detail::json_sax_acceptor::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:7224
detail::span_input_adapter::span_input_adapter
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6550
basic_json::number_unsigned_t
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:19535
detail::iter_impl::operator=
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:12946
detail::is_compatible_type
Definition: json.hpp:3873
detail::iterator_category_t
typename T::iterator_category iterator_category_t
Definition: json.hpp:3496
detail::json_sax_dom_callback_parser::is_errored
constexpr bool is_errored() const
Definition: json.hpp:7114
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:19409
detail::make_array
constexpr std::array< T, sizeof...(Args)> make_array(Args &&... args)
Definition: json.hpp:3206
detail::is_range::value
static constexpr bool value
Definition: json.hpp:3667
basic_json::value_t
detail::value_t value_t
Definition: json.hpp:19338
detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::reference
T & reference
Definition: json.hpp:3290
detail::parse_event_t
parse_event_t
Definition: json.hpp:12132
detail::start_array_function_t
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:9003
basic_json::const_pointer
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:19400
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:23382
detail::output_adapter::output_adapter
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:14920
detail::dtoa_impl::diyfp::e
int e
Definition: json.hpp:16845
detail::json_sax_dom_parser::is_errored
constexpr bool is_errored() const
Definition: json.hpp:6864
json_sax::end_object
virtual bool end_object()=0
the end of an object was read
json_sax::boolean
virtual bool boolean(bool val)=0
a boolean value was read
detail::primitive_iterator_t::operator++
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:12713
detail::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3079
detail::is_compatible_integer_type
Definition: json.hpp:3856
B
detail::conjunction
Definition: json.hpp:3585
detail::make_index_sequence
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3175
basic_json::is_object
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:20522
detail::detector< Default, void_t< Op< Args... > >, Op, Args... >::value_t
std::true_type value_t
Definition: json.hpp:287
basic_json::sax_parse
JSON_PRIVATE_UNLESS_TESTED const_reference bool static SAX bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
Definition: json.hpp:23253
JSON_NO_UNIQUE_ADDRESS
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.hpp:2495
detail::json_sax_acceptor::number_float
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:7249
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:4833
detail::json_reverse_iterator::key
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:13657
detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::value_type
T value_type
Definition: json.hpp:3287
detail::parse_error::byte
const std::size_t byte
byte index of the parse error
Definition: json.hpp:4436
detail::is_constructible_string_type::value
static constexpr auto value
Definition: json.hpp:3760
detail::output_string_adapter::write_character
void write_character(CharType c) override
Definition: json.hpp:14896
detail::json_sax_dom_parser
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:6730
detail::concat_into
void concat_into(OutStringType &)
Definition: json.hpp:4193
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:3927
detail::input_format_t::bjdata
@ bjdata
detail::is_constructible_tuple
Definition: json.hpp:3877
detail::external_constructor< value_t::number_float >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:5422
detail::serializer::decimal_point
const char decimal_point
the locale's decimal point character
Definition: json.hpp:18857
detail::json_ref::json_ref
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:14708
detail::boolean_function_t
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:8968