File indexing completed on 2025-02-02 05:33:04

0001 //     __ _____ _____ _____
0002 //  __|  |   __|     |   | |  JSON for Modern C++
0003 // |  |  |__   |  |  | | | |  version 3.11.2
0004 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0005 //
0006 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
0007 // SPDX-License-Identifier: MIT
0008 
0009 /****************************************************************************\
0010  * Note on documentation: The source files contain links to the online      *
0011  * documentation of the public API at https://json.nlohmann.me. This URL    *
0012  * contains the most recent documentation and should also be applicable to  *
0013  * previous versions; documentation for deprecated functions is not         *
0014  * removed, but marked deprecated. See "Generate documentation" section in  *
0015  * file docs/README.md.                                                     *
0016 \****************************************************************************/
0017 
0018 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
0019 #define INCLUDE_NLOHMANN_JSON_HPP_
0020 
0021 #include <algorithm> // all_of, find, for_each
0022 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
0023 #include <functional> // hash, less
0024 #include <initializer_list> // initializer_list
0025 #ifndef JSON_NO_IO
0026     #include <iosfwd> // istream, ostream
0027 #endif  // JSON_NO_IO
0028 #include <iterator> // random_access_iterator_tag
0029 #include <memory> // unique_ptr
0030 #include <numeric> // accumulate
0031 #include <string> // string, stoi, to_string
0032 #include <utility> // declval, forward, move, pair, swap
0033 #include <vector> // vector
0034 
0035 // #include <nlohmann/adl_serializer.hpp>
0036 //     __ _____ _____ _____
0037 //  __|  |   __|     |   | |  JSON for Modern C++
0038 // |  |  |__   |  |  | | | |  version 3.11.2
0039 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0040 //
0041 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
0042 // SPDX-License-Identifier: MIT
0043 
0044 
0045 
0046 #include <utility>
0047 
0048 // #include <nlohmann/detail/abi_macros.hpp>
0049 //     __ _____ _____ _____
0050 //  __|  |   __|     |   | |  JSON for Modern C++
0051 // |  |  |__   |  |  | | | |  version 3.11.2
0052 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0053 //
0054 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
0055 // SPDX-License-Identifier: MIT
0056 
0057 
0058 
0059 // This file contains all macro definitions affecting or depending on the ABI
0060 
0061 #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
0062     #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
0063         #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 2
0064             #warning "Already included a different version of the library!"
0065         #endif
0066     #endif
0067 #endif
0068 
0069 #define NLOHMANN_JSON_VERSION_MAJOR 3   // NOLINT(modernize-macro-to-enum)
0070 #define NLOHMANN_JSON_VERSION_MINOR 11  // NOLINT(modernize-macro-to-enum)
0071 #define NLOHMANN_JSON_VERSION_PATCH 2   // NOLINT(modernize-macro-to-enum)
0072 
0073 #ifndef JSON_DIAGNOSTICS
0074     #define JSON_DIAGNOSTICS 0
0075 #endif
0076 
0077 #ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
0078     #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
0079 #endif
0080 
0081 #if JSON_DIAGNOSTICS
0082     #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
0083 #else
0084     #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
0085 #endif
0086 
0087 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
0088     #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
0089 #else
0090     #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
0091 #endif
0092 
0093 #ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
0094     #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
0095 #endif
0096 
0097 // Construct the namespace ABI tags component
0098 #define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
0099 #define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
0100     NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
0101 
0102 #define NLOHMANN_JSON_ABI_TAGS                                       \
0103     NLOHMANN_JSON_ABI_TAGS_CONCAT(                                   \
0104             NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS,                       \
0105             NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
0106 
0107 // Construct the namespace version component
0108 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
0109     _v ## major ## _ ## minor ## _ ## patch
0110 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
0111     NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
0112 
0113 #if NLOHMANN_JSON_NAMESPACE_NO_VERSION
0114 #define NLOHMANN_JSON_NAMESPACE_VERSION
0115 #else
0116 #define NLOHMANN_JSON_NAMESPACE_VERSION                                 \
0117     NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
0118                                            NLOHMANN_JSON_VERSION_MINOR, \
0119                                            NLOHMANN_JSON_VERSION_PATCH)
0120 #endif
0121 
0122 // Combine namespace components
0123 #define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
0124 #define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
0125     NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
0126 
0127 #ifndef NLOHMANN_JSON_NAMESPACE
0128 #define NLOHMANN_JSON_NAMESPACE               \
0129     nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
0130             NLOHMANN_JSON_ABI_TAGS,           \
0131             NLOHMANN_JSON_NAMESPACE_VERSION)
0132 #endif
0133 
0134 #ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
0135 #define NLOHMANN_JSON_NAMESPACE_BEGIN                \
0136     namespace nlohmann                               \
0137     {                                                \
0138     inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
0139                 NLOHMANN_JSON_ABI_TAGS,              \
0140                 NLOHMANN_JSON_NAMESPACE_VERSION)     \
0141     {
0142 #endif
0143 
0144 #ifndef NLOHMANN_JSON_NAMESPACE_END
0145 #define NLOHMANN_JSON_NAMESPACE_END                                     \
0146     }  /* namespace (inline namespace) NOLINT(readability/namespace) */ \
0147     }  // namespace nlohmann
0148 #endif
0149 
0150 // #include <nlohmann/detail/conversions/from_json.hpp>
0151 //     __ _____ _____ _____
0152 //  __|  |   __|     |   | |  JSON for Modern C++
0153 // |  |  |__   |  |  | | | |  version 3.11.2
0154 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0155 //
0156 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
0157 // SPDX-License-Identifier: MIT
0158 
0159 
0160 
0161 #include <algorithm> // transform
0162 #include <array> // array
0163 #include <forward_list> // forward_list
0164 #include <iterator> // inserter, front_inserter, end
0165 #include <map> // map
0166 #include <string> // string
0167 #include <tuple> // tuple, make_tuple
0168 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
0169 #include <unordered_map> // unordered_map
0170 #include <utility> // pair, declval
0171 #include <valarray> // valarray
0172 
0173 // #include <nlohmann/detail/exceptions.hpp>
0174 //     __ _____ _____ _____
0175 //  __|  |   __|     |   | |  JSON for Modern C++
0176 // |  |  |__   |  |  | | | |  version 3.11.2
0177 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0178 //
0179 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
0180 // SPDX-License-Identifier: MIT
0181 
0182 
0183 
0184 #include <cstddef> // nullptr_t
0185 #include <exception> // exception
0186 #include <stdexcept> // runtime_error
0187 #include <string> // to_string
0188 #include <vector> // vector
0189 
0190 // #include <nlohmann/detail/value_t.hpp>
0191 //     __ _____ _____ _____
0192 //  __|  |   __|     |   | |  JSON for Modern C++
0193 // |  |  |__   |  |  | | | |  version 3.11.2
0194 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0195 //
0196 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
0197 // SPDX-License-Identifier: MIT
0198 
0199 
0200 
0201 #include <array> // array
0202 #include <cstddef> // size_t
0203 #include <cstdint> // uint8_t
0204 #include <string> // string
0205 
0206 // #include <nlohmann/detail/macro_scope.hpp>
0207 //     __ _____ _____ _____
0208 //  __|  |   __|     |   | |  JSON for Modern C++
0209 // |  |  |__   |  |  | | | |  version 3.11.2
0210 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0211 //
0212 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
0213 // SPDX-License-Identifier: MIT
0214 
0215 
0216 
0217 #include <utility> // declval, pair
0218 // #include <nlohmann/detail/meta/detected.hpp>
0219 //     __ _____ _____ _____
0220 //  __|  |   __|     |   | |  JSON for Modern C++
0221 // |  |  |__   |  |  | | | |  version 3.11.2
0222 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0223 //
0224 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
0225 // SPDX-License-Identifier: MIT
0226 
0227 
0228 
0229 #include <type_traits>
0230 
0231 // #include <nlohmann/detail/meta/void_t.hpp>
0232 //     __ _____ _____ _____
0233 //  __|  |   __|     |   | |  JSON for Modern C++
0234 // |  |  |__   |  |  | | | |  version 3.11.2
0235 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0236 //
0237 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
0238 // SPDX-License-Identifier: MIT
0239 
0240 
0241 
0242 // #include <nlohmann/detail/abi_macros.hpp>
0243 
0244 
0245 NLOHMANN_JSON_NAMESPACE_BEGIN
0246 namespace detail
0247 {
0248 
0249 template<typename ...Ts> struct make_void
0250 {
0251     using type = void;
0252 };
0253 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
0254 
0255 }  // namespace detail
0256 NLOHMANN_JSON_NAMESPACE_END
0257 
0258 
0259 NLOHMANN_JSON_NAMESPACE_BEGIN
0260 namespace detail
0261 {
0262 
0263 // https://en.cppreference.com/w/cpp/experimental/is_detected
0264 struct nonesuch
0265 {
0266     nonesuch() = delete;
0267     ~nonesuch() = delete;
0268     nonesuch(nonesuch const&) = delete;
0269     nonesuch(nonesuch const&&) = delete;
0270     void operator=(nonesuch const&) = delete;
0271     void operator=(nonesuch&&) = delete;
0272 };
0273 
0274 template<class Default,
0275          class AlwaysVoid,
0276          template<class...> class Op,
0277          class... Args>
0278 struct detector
0279 {
0280     using value_t = std::false_type;
0281     using type = Default;
0282 };
0283 
0284 template<class Default, template<class...> class Op, class... Args>
0285 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
0286 {
0287     using value_t = std::true_type;
0288     using type = Op<Args...>;
0289 };
0290 
0291 template<template<class...> class Op, class... Args>
0292 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
0293 
0294 template<template<class...> class Op, class... Args>
0295 struct is_detected_lazy : is_detected<Op, Args...> { };
0296 
0297 template<template<class...> class Op, class... Args>
0298 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
0299 
0300 template<class Default, template<class...> class Op, class... Args>
0301 using detected_or = detector<Default, void, Op, Args...>;
0302 
0303 template<class Default, template<class...> class Op, class... Args>
0304 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
0305 
0306 template<class Expected, template<class...> class Op, class... Args>
0307 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
0308 
0309 template<class To, template<class...> class Op, class... Args>
0310 using is_detected_convertible =
0311     std::is_convertible<detected_t<Op, Args...>, To>;
0312 
0313 }  // namespace detail
0314 NLOHMANN_JSON_NAMESPACE_END
0315 
0316 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
0317 
0318 
0319 //     __ _____ _____ _____
0320 //  __|  |   __|     |   | |  JSON for Modern C++
0321 // |  |  |__   |  |  | | | |  version 3.11.2
0322 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0323 //
0324 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
0325 // SPDX-FileCopyrightText: 2016-2021 Evan Nemerson <evan@nemerson.com>
0326 // SPDX-License-Identifier: MIT
0327 
0328 /* Hedley - https://nemequ.github.io/hedley
0329  * Created by Evan Nemerson <evan@nemerson.com>
0330  */
0331 
0332 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
0333 #if defined(JSON_HEDLEY_VERSION)
0334     #undef JSON_HEDLEY_VERSION
0335 #endif
0336 #define JSON_HEDLEY_VERSION 15
0337 
0338 #if defined(JSON_HEDLEY_STRINGIFY_EX)
0339     #undef JSON_HEDLEY_STRINGIFY_EX
0340 #endif
0341 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
0342 
0343 #if defined(JSON_HEDLEY_STRINGIFY)
0344     #undef JSON_HEDLEY_STRINGIFY
0345 #endif
0346 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
0347 
0348 #if defined(JSON_HEDLEY_CONCAT_EX)
0349     #undef JSON_HEDLEY_CONCAT_EX
0350 #endif
0351 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
0352 
0353 #if defined(JSON_HEDLEY_CONCAT)
0354     #undef JSON_HEDLEY_CONCAT
0355 #endif
0356 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
0357 
0358 #if defined(JSON_HEDLEY_CONCAT3_EX)
0359     #undef JSON_HEDLEY_CONCAT3_EX
0360 #endif
0361 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
0362 
0363 #if defined(JSON_HEDLEY_CONCAT3)
0364     #undef JSON_HEDLEY_CONCAT3
0365 #endif
0366 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
0367 
0368 #if defined(JSON_HEDLEY_VERSION_ENCODE)
0369     #undef JSON_HEDLEY_VERSION_ENCODE
0370 #endif
0371 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
0372 
0373 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
0374     #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
0375 #endif
0376 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
0377 
0378 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
0379     #undef JSON_HEDLEY_VERSION_DECODE_MINOR
0380 #endif
0381 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
0382 
0383 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
0384     #undef JSON_HEDLEY_VERSION_DECODE_REVISION
0385 #endif
0386 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
0387 
0388 #if defined(JSON_HEDLEY_GNUC_VERSION)
0389     #undef JSON_HEDLEY_GNUC_VERSION
0390 #endif
0391 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
0392     #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
0393 #elif defined(__GNUC__)
0394     #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
0395 #endif
0396 
0397 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
0398     #undef JSON_HEDLEY_GNUC_VERSION_CHECK
0399 #endif
0400 #if defined(JSON_HEDLEY_GNUC_VERSION)
0401     #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0402 #else
0403     #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
0404 #endif
0405 
0406 #if defined(JSON_HEDLEY_MSVC_VERSION)
0407     #undef JSON_HEDLEY_MSVC_VERSION
0408 #endif
0409 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
0410     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
0411 #elif defined(_MSC_FULL_VER) && !defined(__ICL)
0412     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
0413 #elif defined(_MSC_VER) && !defined(__ICL)
0414     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
0415 #endif
0416 
0417 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
0418     #undef JSON_HEDLEY_MSVC_VERSION_CHECK
0419 #endif
0420 #if !defined(JSON_HEDLEY_MSVC_VERSION)
0421     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
0422 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
0423     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
0424 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
0425     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
0426 #else
0427     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
0428 #endif
0429 
0430 #if defined(JSON_HEDLEY_INTEL_VERSION)
0431     #undef JSON_HEDLEY_INTEL_VERSION
0432 #endif
0433 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
0434     #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
0435 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
0436     #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
0437 #endif
0438 
0439 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
0440     #undef JSON_HEDLEY_INTEL_VERSION_CHECK
0441 #endif
0442 #if defined(JSON_HEDLEY_INTEL_VERSION)
0443     #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0444 #else
0445     #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
0446 #endif
0447 
0448 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
0449     #undef JSON_HEDLEY_INTEL_CL_VERSION
0450 #endif
0451 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
0452     #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
0453 #endif
0454 
0455 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
0456     #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
0457 #endif
0458 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
0459     #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0460 #else
0461     #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
0462 #endif
0463 
0464 #if defined(JSON_HEDLEY_PGI_VERSION)
0465     #undef JSON_HEDLEY_PGI_VERSION
0466 #endif
0467 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
0468     #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
0469 #endif
0470 
0471 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
0472     #undef JSON_HEDLEY_PGI_VERSION_CHECK
0473 #endif
0474 #if defined(JSON_HEDLEY_PGI_VERSION)
0475     #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0476 #else
0477     #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
0478 #endif
0479 
0480 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
0481     #undef JSON_HEDLEY_SUNPRO_VERSION
0482 #endif
0483 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
0484     #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)
0485 #elif defined(__SUNPRO_C)
0486     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
0487 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
0488     #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)
0489 #elif defined(__SUNPRO_CC)
0490     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
0491 #endif
0492 
0493 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
0494     #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
0495 #endif
0496 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
0497     #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0498 #else
0499     #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
0500 #endif
0501 
0502 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
0503     #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
0504 #endif
0505 #if defined(__EMSCRIPTEN__)
0506     #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
0507 #endif
0508 
0509 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
0510     #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
0511 #endif
0512 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
0513     #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0514 #else
0515     #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
0516 #endif
0517 
0518 #if defined(JSON_HEDLEY_ARM_VERSION)
0519     #undef JSON_HEDLEY_ARM_VERSION
0520 #endif
0521 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
0522     #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
0523 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
0524     #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
0525 #endif
0526 
0527 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
0528     #undef JSON_HEDLEY_ARM_VERSION_CHECK
0529 #endif
0530 #if defined(JSON_HEDLEY_ARM_VERSION)
0531     #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0532 #else
0533     #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
0534 #endif
0535 
0536 #if defined(JSON_HEDLEY_IBM_VERSION)
0537     #undef JSON_HEDLEY_IBM_VERSION
0538 #endif
0539 #if defined(__ibmxl__)
0540     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
0541 #elif defined(__xlC__) && defined(__xlC_ver__)
0542     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
0543 #elif defined(__xlC__)
0544     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
0545 #endif
0546 
0547 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
0548     #undef JSON_HEDLEY_IBM_VERSION_CHECK
0549 #endif
0550 #if defined(JSON_HEDLEY_IBM_VERSION)
0551     #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0552 #else
0553     #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
0554 #endif
0555 
0556 #if defined(JSON_HEDLEY_TI_VERSION)
0557     #undef JSON_HEDLEY_TI_VERSION
0558 #endif
0559 #if \
0560     defined(__TI_COMPILER_VERSION__) && \
0561     ( \
0562       defined(__TMS470__) || defined(__TI_ARM__) || \
0563       defined(__MSP430__) || \
0564       defined(__TMS320C2000__) \
0565     )
0566 #if (__TI_COMPILER_VERSION__ >= 16000000)
0567     #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
0568 #endif
0569 #endif
0570 
0571 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
0572     #undef JSON_HEDLEY_TI_VERSION_CHECK
0573 #endif
0574 #if defined(JSON_HEDLEY_TI_VERSION)
0575     #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0576 #else
0577     #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
0578 #endif
0579 
0580 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
0581     #undef JSON_HEDLEY_TI_CL2000_VERSION
0582 #endif
0583 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
0584     #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
0585 #endif
0586 
0587 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
0588     #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
0589 #endif
0590 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
0591     #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0592 #else
0593     #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
0594 #endif
0595 
0596 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
0597     #undef JSON_HEDLEY_TI_CL430_VERSION
0598 #endif
0599 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
0600     #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
0601 #endif
0602 
0603 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
0604     #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
0605 #endif
0606 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
0607     #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0608 #else
0609     #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
0610 #endif
0611 
0612 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
0613     #undef JSON_HEDLEY_TI_ARMCL_VERSION
0614 #endif
0615 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
0616     #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
0617 #endif
0618 
0619 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
0620     #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
0621 #endif
0622 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
0623     #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0624 #else
0625     #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
0626 #endif
0627 
0628 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
0629     #undef JSON_HEDLEY_TI_CL6X_VERSION
0630 #endif
0631 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
0632     #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
0633 #endif
0634 
0635 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
0636     #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
0637 #endif
0638 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
0639     #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0640 #else
0641     #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
0642 #endif
0643 
0644 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
0645     #undef JSON_HEDLEY_TI_CL7X_VERSION
0646 #endif
0647 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
0648     #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
0649 #endif
0650 
0651 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
0652     #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
0653 #endif
0654 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
0655     #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0656 #else
0657     #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
0658 #endif
0659 
0660 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
0661     #undef JSON_HEDLEY_TI_CLPRU_VERSION
0662 #endif
0663 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
0664     #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
0665 #endif
0666 
0667 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
0668     #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
0669 #endif
0670 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
0671     #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0672 #else
0673     #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
0674 #endif
0675 
0676 #if defined(JSON_HEDLEY_CRAY_VERSION)
0677     #undef JSON_HEDLEY_CRAY_VERSION
0678 #endif
0679 #if defined(_CRAYC)
0680     #if defined(_RELEASE_PATCHLEVEL)
0681         #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
0682     #else
0683         #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
0684     #endif
0685 #endif
0686 
0687 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
0688     #undef JSON_HEDLEY_CRAY_VERSION_CHECK
0689 #endif
0690 #if defined(JSON_HEDLEY_CRAY_VERSION)
0691     #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0692 #else
0693     #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
0694 #endif
0695 
0696 #if defined(JSON_HEDLEY_IAR_VERSION)
0697     #undef JSON_HEDLEY_IAR_VERSION
0698 #endif
0699 #if defined(__IAR_SYSTEMS_ICC__)
0700     #if __VER__ > 1000
0701         #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
0702     #else
0703         #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
0704     #endif
0705 #endif
0706 
0707 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
0708     #undef JSON_HEDLEY_IAR_VERSION_CHECK
0709 #endif
0710 #if defined(JSON_HEDLEY_IAR_VERSION)
0711     #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0712 #else
0713     #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
0714 #endif
0715 
0716 #if defined(JSON_HEDLEY_TINYC_VERSION)
0717     #undef JSON_HEDLEY_TINYC_VERSION
0718 #endif
0719 #if defined(__TINYC__)
0720     #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
0721 #endif
0722 
0723 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
0724     #undef JSON_HEDLEY_TINYC_VERSION_CHECK
0725 #endif
0726 #if defined(JSON_HEDLEY_TINYC_VERSION)
0727     #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0728 #else
0729     #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
0730 #endif
0731 
0732 #if defined(JSON_HEDLEY_DMC_VERSION)
0733     #undef JSON_HEDLEY_DMC_VERSION
0734 #endif
0735 #if defined(__DMC__)
0736     #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
0737 #endif
0738 
0739 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
0740     #undef JSON_HEDLEY_DMC_VERSION_CHECK
0741 #endif
0742 #if defined(JSON_HEDLEY_DMC_VERSION)
0743     #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0744 #else
0745     #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
0746 #endif
0747 
0748 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
0749     #undef JSON_HEDLEY_COMPCERT_VERSION
0750 #endif
0751 #if defined(__COMPCERT_VERSION__)
0752     #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
0753 #endif
0754 
0755 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
0756     #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
0757 #endif
0758 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
0759     #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0760 #else
0761     #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
0762 #endif
0763 
0764 #if defined(JSON_HEDLEY_PELLES_VERSION)
0765     #undef JSON_HEDLEY_PELLES_VERSION
0766 #endif
0767 #if defined(__POCC__)
0768     #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
0769 #endif
0770 
0771 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
0772     #undef JSON_HEDLEY_PELLES_VERSION_CHECK
0773 #endif
0774 #if defined(JSON_HEDLEY_PELLES_VERSION)
0775     #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0776 #else
0777     #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
0778 #endif
0779 
0780 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
0781     #undef JSON_HEDLEY_MCST_LCC_VERSION
0782 #endif
0783 #if defined(__LCC__) && defined(__LCC_MINOR__)
0784     #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
0785 #endif
0786 
0787 #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
0788     #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
0789 #endif
0790 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
0791     #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0792 #else
0793     #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
0794 #endif
0795 
0796 #if defined(JSON_HEDLEY_GCC_VERSION)
0797     #undef JSON_HEDLEY_GCC_VERSION
0798 #endif
0799 #if \
0800     defined(JSON_HEDLEY_GNUC_VERSION) && \
0801     !defined(__clang__) && \
0802     !defined(JSON_HEDLEY_INTEL_VERSION) && \
0803     !defined(JSON_HEDLEY_PGI_VERSION) && \
0804     !defined(JSON_HEDLEY_ARM_VERSION) && \
0805     !defined(JSON_HEDLEY_CRAY_VERSION) && \
0806     !defined(JSON_HEDLEY_TI_VERSION) && \
0807     !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
0808     !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
0809     !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
0810     !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
0811     !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
0812     !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
0813     !defined(__COMPCERT__) && \
0814     !defined(JSON_HEDLEY_MCST_LCC_VERSION)
0815     #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
0816 #endif
0817 
0818 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
0819     #undef JSON_HEDLEY_GCC_VERSION_CHECK
0820 #endif
0821 #if defined(JSON_HEDLEY_GCC_VERSION)
0822     #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
0823 #else
0824     #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
0825 #endif
0826 
0827 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
0828     #undef JSON_HEDLEY_HAS_ATTRIBUTE
0829 #endif
0830 #if \
0831   defined(__has_attribute) && \
0832   ( \
0833     (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
0834   )
0835 #  define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
0836 #else
0837 #  define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
0838 #endif
0839 
0840 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
0841     #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
0842 #endif
0843 #if defined(__has_attribute)
0844     #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
0845 #else
0846     #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
0847 #endif
0848 
0849 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
0850     #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
0851 #endif
0852 #if defined(__has_attribute)
0853     #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
0854 #else
0855     #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
0856 #endif
0857 
0858 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
0859     #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
0860 #endif
0861 #if \
0862     defined(__has_cpp_attribute) && \
0863     defined(__cplusplus) && \
0864     (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
0865     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
0866 #else
0867     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
0868 #endif
0869 
0870 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
0871     #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
0872 #endif
0873 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
0874     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
0875 #elif \
0876     !defined(JSON_HEDLEY_PGI_VERSION) && \
0877     !defined(JSON_HEDLEY_IAR_VERSION) && \
0878     (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
0879     (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
0880     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
0881 #else
0882     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
0883 #endif
0884 
0885 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
0886     #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
0887 #endif
0888 #if defined(__has_cpp_attribute) && defined(__cplusplus)
0889     #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
0890 #else
0891     #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
0892 #endif
0893 
0894 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
0895     #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
0896 #endif
0897 #if defined(__has_cpp_attribute) && defined(__cplusplus)
0898     #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
0899 #else
0900     #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
0901 #endif
0902 
0903 #if defined(JSON_HEDLEY_HAS_BUILTIN)
0904     #undef JSON_HEDLEY_HAS_BUILTIN
0905 #endif
0906 #if defined(__has_builtin)
0907     #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
0908 #else
0909     #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
0910 #endif
0911 
0912 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
0913     #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
0914 #endif
0915 #if defined(__has_builtin)
0916     #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
0917 #else
0918     #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
0919 #endif
0920 
0921 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
0922     #undef JSON_HEDLEY_GCC_HAS_BUILTIN
0923 #endif
0924 #if defined(__has_builtin)
0925     #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
0926 #else
0927     #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
0928 #endif
0929 
0930 #if defined(JSON_HEDLEY_HAS_FEATURE)
0931     #undef JSON_HEDLEY_HAS_FEATURE
0932 #endif
0933 #if defined(__has_feature)
0934     #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
0935 #else
0936     #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
0937 #endif
0938 
0939 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
0940     #undef JSON_HEDLEY_GNUC_HAS_FEATURE
0941 #endif
0942 #if defined(__has_feature)
0943     #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
0944 #else
0945     #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
0946 #endif
0947 
0948 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
0949     #undef JSON_HEDLEY_GCC_HAS_FEATURE
0950 #endif
0951 #if defined(__has_feature)
0952     #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
0953 #else
0954     #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
0955 #endif
0956 
0957 #if defined(JSON_HEDLEY_HAS_EXTENSION)
0958     #undef JSON_HEDLEY_HAS_EXTENSION
0959 #endif
0960 #if defined(__has_extension)
0961     #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
0962 #else
0963     #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
0964 #endif
0965 
0966 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
0967     #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
0968 #endif
0969 #if defined(__has_extension)
0970     #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
0971 #else
0972     #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
0973 #endif
0974 
0975 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
0976     #undef JSON_HEDLEY_GCC_HAS_EXTENSION
0977 #endif
0978 #if defined(__has_extension)
0979     #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
0980 #else
0981     #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
0982 #endif
0983 
0984 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
0985     #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
0986 #endif
0987 #if defined(__has_declspec_attribute)
0988     #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
0989 #else
0990     #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
0991 #endif
0992 
0993 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
0994     #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
0995 #endif
0996 #if defined(__has_declspec_attribute)
0997     #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
0998 #else
0999     #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 
1580 JSON_HEDLEY_DIAGNOSTIC_PUSH
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
1606 JSON_HEDLEY_DIAGNOSTIC_POP
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 
2552 /*!
2553 @brief macro to briefly define a mapping between an enum and JSON
2554 @def NLOHMANN_JSON_SERIALIZE_ENUM
2555 @since version 3.4.0
2556 */
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 
2737 /*!
2738 @brief macro
2739 @def NLOHMANN_DEFINE_TYPE_INTRUSIVE
2740 @since version 3.9.0
2741 */
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 
2750 /*!
2751 @brief macro
2752 @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
2753 @since version 3.9.0
2754 */
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 
2824 NLOHMANN_JSON_NAMESPACE_BEGIN
2825 namespace detail
2826 {
2827 
2828 ///////////////////////////
2829 // JSON type enumeration //
2830 ///////////////////////////
2831 
2832 /*!
2833 @brief the JSON type enumeration
2834 
2835 This enumeration collects the different JSON types. It is internally used to
2836 distinguish the stored values, and the functions @ref basic_json::is_null(),
2837 @ref basic_json::is_object(), @ref basic_json::is_array(),
2838 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
2839 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
2840 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
2841 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
2842 @ref basic_json::is_structured() rely on it.
2843 
2844 @note There are three enumeration entries (number_integer, number_unsigned, and
2845 number_float), because the library distinguishes these three types for numbers:
2846 @ref basic_json::number_unsigned_t is used for unsigned integers,
2847 @ref basic_json::number_integer_t is used for signed integers, and
2848 @ref basic_json::number_float_t is used for floating-point numbers or to
2849 approximate integers which do not fit in the limits of their respective type.
2850 
2851 @sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON
2852 value with the default value for a given type
2853 
2854 @since version 1.0.0
2855 */
2856 enum class value_t : std::uint8_t
2857 {
2858     null,             ///< null value
2859     object,           ///< object (unordered set of name/value pairs)
2860     array,            ///< array (ordered collection of values)
2861     string,           ///< string value
2862     boolean,          ///< boolean value
2863     number_integer,   ///< number value (signed integer)
2864     number_unsigned,  ///< number value (unsigned integer)
2865     number_float,     ///< number value (floating-point)
2866     binary,           ///< binary array (ordered collection of bytes)
2867     discarded         ///< discarded by the parser callback function
2868 };
2869 
2870 /*!
2871 @brief comparison operator for JSON types
2872 
2873 Returns an ordering that is similar to Python:
2874 - order: null < boolean < number < object < array < string < binary
2875 - furthermore, each type is not smaller than itself
2876 - discarded values are not comparable
2877 - binary is represented as a b"" string in python and directly comparable to a
2878   string; however, making a binary array directly comparable with a string would
2879   be surprising behavior in a JSON file.
2880 
2881 @since version 1.0.0
2882 */
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
2921 NLOHMANN_JSON_NAMESPACE_END
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 
2937 NLOHMANN_JSON_NAMESPACE_BEGIN
2938 namespace detail
2939 {
2940 
2941 /*!
2942 @brief replace all occurrences of a substring by another string
2943 
2944 @param[in,out] s  the string to manipulate; changed so that all
2945                occurrences of @a f are replaced with @a t
2946 @param[in]     f  the substring to replace with @a t
2947 @param[in]     t  the string to replace @a f
2948 
2949 @pre The search string @a f must not be empty. **This precondition is
2950 enforced with an assertion.**
2951 
2952 @since version 2.0.0
2953 */
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 
2966 /*!
2967  * @brief string escaping as described in RFC 6901 (Sect. 4)
2968  * @param[in] s string to escape
2969  * @return    escaped string
2970  *
2971  * Note the order of escaping "~" to "~0" and "/" to "~1" is important.
2972  */
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 
2981 /*!
2982  * @brief string unescaping as described in RFC 6901 (Sect. 4)
2983  * @param[in] s string to unescape
2984  * @return    unescaped string
2985  *
2986  * Note the order of escaping "~1" to "/" and "~0" to "~" is important.
2987  */
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
2996 NLOHMANN_JSON_NAMESPACE_END
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 
3014 NLOHMANN_JSON_NAMESPACE_BEGIN
3015 namespace detail
3016 {
3017 
3018 /// struct to capture the start position of the current token
3019 struct position_t
3020 {
3021     /// the total number of characters read
3022     std::size_t chars_read_total = 0;
3023     /// the number of characters read in the current line
3024     std::size_t chars_read_current_line = 0;
3025     /// the number of lines read
3026     std::size_t lines_read = 0;
3027 
3028     /// conversion to size_t to preserve SAX interface
3029     constexpr operator size_t() const
3030     {
3031         return chars_read_total;
3032     }
3033 };
3034 
3035 }  // namespace detail
3036 NLOHMANN_JSON_NAMESPACE_END
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 
3060 NLOHMANN_JSON_NAMESPACE_BEGIN
3061 namespace detail
3062 {
3063 
3064 template<typename T>
3065 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
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;
3072 using std::make_index_sequence;
3073 using std::index_sequence_for;
3074 
3075 #else
3076 
3077 // alias templates to reduce boilerplate
3078 template<bool B, typename T = void>
3079 using enable_if_t = typename std::enable_if<B, T>::type;
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 
3084 //// START OF CODE FROM GOOGLE ABSEIL
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>
3106 struct integer_sequence
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 {
3154     using type = integer_sequence<T>;
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>
3167 using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
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>
3175 using make_index_sequence = make_integer_sequence<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>
3183 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
3184 
3185 //// END OF CODE FROM GOOGLE ABSEIL
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>
3195 struct static_const
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
3212 NLOHMANN_JSON_NAMESPACE_END
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 
3250 NLOHMANN_JSON_NAMESPACE_BEGIN
3251 namespace detail
3252 {
3253 
3254 template<typename It, typename = void>
3255 struct iterator_types {};
3256 
3257 template<typename It>
3258 struct iterator_types <
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>
3273 struct iterator_traits
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>
3284 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
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
3294 NLOHMANN_JSON_NAMESPACE_END
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 
3312 NLOHMANN_JSON_NAMESPACE_BEGIN
3313 
3314 NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin);
3315 
3316 NLOHMANN_JSON_NAMESPACE_END
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 
3332 NLOHMANN_JSON_NAMESPACE_BEGIN
3333 
3334 NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end);
3335 
3336 NLOHMANN_JSON_NAMESPACE_END
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 
3363     /*!
3364     @brief namespace for Niels Lohmann
3365     @see https://github.com/nlohmann
3366     @since version 1.0.0
3367     */
3368     NLOHMANN_JSON_NAMESPACE_BEGIN
3369 
3370     /*!
3371     @brief default JSONSerializer template argument
3372 
3373     This serializer ignores the template arguments and uses ADL
3374     ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
3375     for serialization.
3376     */
3377     template<typename T = void, typename SFINAE = void>
3378     struct adl_serializer;
3379 
3380     /// a class to store JSON values
3381     /// @sa https://json.nlohmann.me/api/basic_json/
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 =
3391     adl_serializer,
3392     class BinaryType = std::vector<std::uint8_t>>
3393     class basic_json;
3394 
3395     /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
3396     /// @sa https://json.nlohmann.me/api/json_pointer/
3397     template<typename RefStringType>
3398     class json_pointer;
3399 
3400     /*!
3401     @brief default specialization
3402     @sa https://json.nlohmann.me/api/json/
3403     */
3404     using json = basic_json<>;
3405 
3406     /// @brief a minimal map-like container that preserves insertion order
3407     /// @sa https://json.nlohmann.me/api/ordered_map/
3408     template<class Key, class T, class IgnoredLess, class Allocator>
3409     struct ordered_map;
3410 
3411     /// @brief specialization that maintains the insertion order of object keys
3412     /// @sa https://json.nlohmann.me/api/ordered_json/
3413     using ordered_json = basic_json<nlohmann::ordered_map>;
3414 
3415     NLOHMANN_JSON_NAMESPACE_END
3416 
3417 #endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3418 
3419 
3420 NLOHMANN_JSON_NAMESPACE_BEGIN
3421 /*!
3422 @brief detail namespace with internal helper functions
3423 
3424 This namespace collects functions that should not be exposed,
3425 implementations of some @ref basic_json methods, and meta-programming helpers.
3426 
3427 @since version 2.1.0
3428 */
3429 namespace detail
3430 {
3431 
3432 /////////////
3433 // helpers //
3434 /////////////
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 
3447 NLOHMANN_BASIC_JSON_TPL_DECLARATION
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>
3454 struct is_basic_json_context :
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 
3460 //////////////////////
3461 // json_ref helpers //
3462 //////////////////////
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 
3473 //////////////////////////
3474 // aliases for detected //
3475 //////////////////////////
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>
3516 struct is_getable
3517 {
3518     static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
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 =
3527         is_detected_exact<void, from_json_function, serializer,
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 =
3542         is_detected_exact<T, from_json_function, serializer,
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 =
3557         is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
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>
3569 struct actual_object_comparator
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>
3578 using actual_object_comparator_t = typename actual_object_comparator<BasicJsonType>::type;
3579 
3580 ///////////////////
3581 // is_ functions //
3582 ///////////////////
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>
3637 struct is_iterator_traits<iterator_traits<T>>
3638 {
3639   private:
3640     using traits = iterator_traits<T>;
3641 
3642   public:
3643     static constexpr auto value =
3644         is_detected<value_type_t, traits>::value &&
3645         is_detected<difference_type_t, traits>::value &&
3646         is_detected<pointer_t, traits>::value &&
3647         is_detected<iterator_category_t, traits>::value &&
3648         is_detected<reference_t, traits>::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 =
3664         is_iterator_traits<iterator_traits<iterator>>::value;
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>
3674 using range_value_t = value_type_t<iterator_traits<iterator_t<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>
3691 struct is_compatible_object_type_impl <
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>
3707 struct is_compatible_object_type
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>
3715 struct is_constructible_object_type_impl <
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 =
3723         (is_default_constructible<ConstructibleObjectType>::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 ||
3733          has_non_default_from_json <
3734          BasicJsonType,
3735          typename ConstructibleObjectType::mapped_type >::value);
3736 };
3737 
3738 template<typename BasicJsonType, typename ConstructibleObjectType>
3739 struct is_constructible_object_type
3740     : is_constructible_object_type_impl<BasicJsonType,
3741       ConstructibleObjectType> {};
3742 
3743 template<typename BasicJsonType, typename CompatibleStringType>
3744 struct is_compatible_string_type
3745 {
3746     static constexpr auto value =
3747         is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3748 };
3749 
3750 template<typename BasicJsonType, typename ConstructibleStringType>
3751 struct is_constructible_string_type
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 <
3762         is_constructible<laundered_type, typename BasicJsonType::string_t>,
3763         is_detected_exact<typename BasicJsonType::string_t::value_type,
3764         value_type_t, laundered_type >>::value;
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>
3771 struct is_compatible_array_type_impl <
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,
3782         range_value_t<CompatibleArrayType>>::value;
3783 };
3784 
3785 template<typename BasicJsonType, typename CompatibleArrayType>
3786 struct is_compatible_array_type
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>
3793 struct is_constructible_array_type_impl <
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>
3800 struct is_constructible_array_type_impl <
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&&
3814         is_complete_type <
3815         detected_t<range_value_t, ConstructibleArrayType >>::value >>
3816 {
3817     using value_type = range_value_t<ConstructibleArrayType>;
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 ||
3824         has_non_default_from_json <
3825         BasicJsonType,
3826         value_type >::value;
3827 };
3828 
3829 template<typename BasicJsonType, typename ConstructibleArrayType>
3830 struct is_constructible_array_type
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>
3838 struct is_compatible_integer_type_impl <
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>
3856 struct is_compatible_integer_type
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>
3864 struct is_compatible_type_impl <
3865     BasicJsonType, CompatibleType,
3866     enable_if_t<is_complete_type<CompatibleType>::value >>
3867 {
3868     static constexpr bool value =
3869         has_to_json<BasicJsonType, CompatibleType>::value;
3870 };
3871 
3872 template<typename BasicJsonType, typename CompatibleType>
3873 struct is_compatible_type
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>
3900 using is_json_pointer = is_specialization_of<::nlohmann::json_pointer, uncvref_t<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>
3913 using detect_is_transparent = typename T::is_transparent;
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 <
3920                               is_comparable<Comparator, ObjectKeyType, KeyTypeCVRef>::value
3921                               && !(ExcludeObjectKeyType && std::is_same<KeyType,
3922                                    ObjectKeyType>::value)
3923                               && (!RequireTransparentComparator
3924                                   || is_detected <detect_is_transparent, Comparator>::value)
3925                               && !is_json_pointer<KeyType>::value,
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
3941         && !is_json_iterator_of<BasicJsonType, KeyType>::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 <
3952                                 detect_erase_with_key_type,
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>
3960 struct is_ordered_map
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 >
3977 T conditional_static_cast(U value)
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>
3989 using all_integral = conjunction<std::is_integral<Types>...>;
3990 
3991 template<typename... Types>
3992 using all_signed = conjunction<std::is_signed<Types>...>;
3993 
3994 template<typename... Types>
3995 using all_unsigned = conjunction<std::is_unsigned<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>
4010 struct value_in_range_of_impl2;
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,
4056          typename = detail::enable_if_t<all_integral<OfType, T>::value>>
4057 struct value_in_range_of_impl1;
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     {
4064         return value_in_range_of_impl2<OfType, T>::test(val);
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 {
4080     return value_in_range_of_impl1<OfType, T>::test(val);
4081 }
4082 
4083 template<bool Value>
4084 using bool_constant = std::integral_constant<bool, Value>;
4085 
4086 ///////////////////////////////////////////////////////////////////////////////
4087 // is_c_string
4088 ///////////////////////////////////////////////////////////////////////////////
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>
4112 using is_c_string_uncvref = is_c_string<uncvref_t<T>>;
4113 
4114 ///////////////////////////////////////////////////////////////////////////////
4115 // is_transparent
4116 ///////////////////////////////////////////////////////////////////////////////
4117 
4118 namespace impl
4119 {
4120 
4121 template<typename T>
4122 inline constexpr bool is_transparent()
4123 {
4124     return is_detected<detect_is_transparent, T>::value;
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 
4133 ///////////////////////////////////////////////////////////////////////////////
4134 
4135 }  // namespace detail
4136 NLOHMANN_JSON_NAMESPACE_END
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 
4158 NLOHMANN_JSON_NAMESPACE_BEGIN
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>
4200 using detect_string_can_append = is_detected<string_can_append, StringType, 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>
4206 using detect_string_can_append_op = is_detected<string_can_append_op, StringType, 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>
4212 using detect_string_can_append_iter = is_detected<string_can_append_iter, StringType, 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>
4218 using detect_string_can_append_data = is_detected<string_can_append_data, StringType, Arg>;
4219 
4220 template < typename OutStringType, typename Arg, typename... Args,
4221            enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4222                          && detect_string_can_append_op<OutStringType, Arg>::value, int > = 0 >
4223 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
4224 
4225 template < typename OutStringType, typename Arg, typename... Args,
4226            enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4227                          && !detect_string_can_append_op<OutStringType, Arg>::value
4228                          && detect_string_can_append_iter<OutStringType, Arg>::value, int > = 0 >
4229 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4230 
4231 template < typename OutStringType, typename Arg, typename... Args,
4232            enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4233                          && !detect_string_can_append_op<OutStringType, Arg>::value
4234                          && !detect_string_can_append_iter<OutStringType, Arg>::value
4235                          && detect_string_can_append_data<OutStringType, Arg>::value, int > = 0 >
4236 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4237 
4238 template<typename OutStringType, typename Arg, typename... Args,
4239          enable_if_t<detect_string_can_append<OutStringType, Arg>::value, int> = 0>
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
4286 NLOHMANN_JSON_NAMESPACE_END
4287 
4288 
4289 
4290 NLOHMANN_JSON_NAMESPACE_BEGIN
4291 namespace detail
4292 {
4293 
4294 ////////////////
4295 // exceptions //
4296 ////////////////
4297 
4298 /// @brief general exception of the @ref basic_json class
4299 /// @sa https://json.nlohmann.me/api/basic_json/exception/
4300 class exception : public std::exception
4301 {
4302   public:
4303     /// returns the explanatory string
4304     const char* what() const noexcept override
4305     {
4306         return m.what();
4307     }
4308 
4309     /// the id of the exception
4310     const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4311 
4312   protected:
4313     JSON_HEDLEY_NON_NULL(3)
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:
4392     /// an exception object as storage for error messages
4393     std::runtime_error m;
4394 };
4395 
4396 /// @brief exception indicating a parse error
4397 /// @sa https://json.nlohmann.me/api/basic_json/parse_error/
4398 class parse_error : public exception
4399 {
4400   public:
4401     /*!
4402     @brief create a parse error exception
4403     @param[in] id_       the id of the exception
4404     @param[in] pos       the position where the error occurred (or with
4405                          chars_read_total=0 if the position cannot be
4406                          determined)
4407     @param[in] what_arg  the explanatory string
4408     @return parse_error object
4409     */
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 
4427     /*!
4428     @brief byte index of the parse error
4429 
4430     The byte index of the last read character in the input file.
4431 
4432     @note For an input with n bytes, 1 is the index of the first character and
4433           n+1 is the index of the terminating null byte or the end of file.
4434           This also holds true when reading a byte vector (CBOR or MessagePack).
4435     */
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 
4449 /// @brief exception indicating errors with iterators
4450 /// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/
4451 class invalid_iterator : public exception
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:
4462     JSON_HEDLEY_NON_NULL(3)
4463     invalid_iterator(int id_, const char* what_arg)
4464         : exception(id_, what_arg) {}
4465 };
4466 
4467 /// @brief exception indicating executing a member function with a wrong type
4468 /// @sa https://json.nlohmann.me/api/basic_json/type_error/
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:
4480     JSON_HEDLEY_NON_NULL(3)
4481     type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4482 };
4483 
4484 /// @brief exception indicating access out of the defined range
4485 /// @sa https://json.nlohmann.me/api/basic_json/out_of_range/
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:
4497     JSON_HEDLEY_NON_NULL(3)
4498     out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4499 };
4500 
4501 /// @brief exception indicating other library errors
4502 /// @sa https://json.nlohmann.me/api/basic_json/other_error/
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:
4514     JSON_HEDLEY_NON_NULL(3)
4515     other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4516 };
4517 
4518 }  // namespace detail
4519 NLOHMANN_JSON_NAMESPACE_END
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 
4539 NLOHMANN_JSON_NAMESPACE_BEGIN
4540 namespace detail
4541 {
4542 
4543 // dispatching helper struct
4544 template <class T> struct identity_tag {};
4545 
4546 }  // namespace detail
4547 NLOHMANN_JSON_NAMESPACE_END
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>
4565 NLOHMANN_JSON_NAMESPACE_BEGIN
4566 namespace detail
4567 {
4568 namespace std_fs = std::experimental::filesystem;
4569 }  // namespace detail
4570 NLOHMANN_JSON_NAMESPACE_END
4571 #elif JSON_HAS_FILESYSTEM
4572 #include <filesystem>
4573 NLOHMANN_JSON_NAMESPACE_BEGIN
4574 namespace detail
4575 {
4576 namespace std_fs = std::filesystem;
4577 }  // namespace detail
4578 NLOHMANN_JSON_NAMESPACE_END
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 
4588 NLOHMANN_JSON_NAMESPACE_BEGIN
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     {
4611         case value_t::number_unsigned:
4612         {
4613             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4614             break;
4615         }
4616         case value_t::number_integer:
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 {
4699     typename std::underlying_type<EnumType>::type val;
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&&
4815                !is_constructible_string_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 
4829     from_json_array_impl(j, arr, priority_tag<3> {});
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     {
4900         case value_t::number_unsigned:
4901         {
4902             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4903             break;
4904         }
4905         case value_t::number_integer:
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 
5027 struct from_json_fn
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 to hold default `from_json` function
5042 /// to see why this is required:
5043 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
5044 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)
5048     detail::static_const<detail::from_json_fn>::value;
5049 #ifndef JSON_HAS_CPP_17
5050 }  // namespace
5051 #endif
5052 
5053 NLOHMANN_JSON_NAMESPACE_END
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 
5103 NLOHMANN_JSON_NAMESPACE_BEGIN
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;
5118     using value_type = iteration_proxy_value;
5119     using pointer = value_type *;
5120     using reference = 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:
5125     /// the iterator
5126     IteratorType anchor{};
5127     /// an index for arrays (used to create key names)
5128     std::size_t array_index = 0;
5129     /// last stringified array index
5130     mutable std::size_t array_index_last = 0;
5131     /// a string representation of the array index
5132     mutable string_type array_index_str = "0";
5133     /// an empty string (to return a reference for primitive values)
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;
5146     iteration_proxy_value& operator=(iteration_proxy_value const&) = default;
5147     // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
5148     iteration_proxy_value(iteration_proxy_value&&)
5149     noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5150              && std::is_nothrow_move_constructible<string_type>::value) = default;
5151     iteration_proxy_value& operator=(iteration_proxy_value&&)
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 
5156     /// dereference operator (needed for range-based for)
5157     const iteration_proxy_value& operator*() const
5158     {
5159         return *this;
5160     }
5161 
5162     /// increment operator (needed for range-based for)
5163     iteration_proxy_value& operator++()
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 
5179     /// equality operator (needed for InputIterator)
5180     bool operator==(const iteration_proxy_value& o) const
5181     {
5182         return anchor == o.anchor;
5183     }
5184 
5185     /// inequality operator (needed for range-based for)
5186     bool operator!=(const iteration_proxy_value& o) const
5187     {
5188         return anchor != o.anchor;
5189     }
5190 
5191     /// return key of the iterator
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:
5217             case value_t::number_integer:
5218             case value_t::number_unsigned:
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 
5227     /// return value of the iterator
5228     typename IteratorType::reference value() const
5229     {
5230         return anchor.value();
5231     }
5232 };
5233 
5234 /// proxy class for the items() function
5235 template<typename IteratorType> class iteration_proxy
5236 {
5237   private:
5238     /// the container to iterate
5239     typename IteratorType::pointer container = nullptr;
5240 
5241   public:
5242     explicit iteration_proxy() = default;
5243 
5244     /// construct iteration proxy from a container
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 
5254     /// return iterator begin (needed for range-based for)
5255     iteration_proxy_value<IteratorType> begin() const noexcept
5256     {
5257         return iteration_proxy_value<IteratorType>(container->begin());
5258     }
5259 
5260     /// return iterator end (needed for range-based for)
5261     iteration_proxy_value<IteratorType> end() const noexcept
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
5285 NLOHMANN_JSON_NAMESPACE_END
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 
5333 NLOHMANN_JSON_NAMESPACE_BEGIN
5334 namespace detail
5335 {
5336 
5337 //////////////////
5338 // constructors //
5339 //////////////////
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<>
5351 struct external_constructor<value_t::boolean>
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<>
5364 struct external_constructor<value_t::string>
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,
5385                enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
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<>
5397 struct external_constructor<value_t::binary>
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<>
5419 struct external_constructor<value_t::number_float>
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<>
5432 struct external_constructor<value_t::number_unsigned>
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<>
5445 struct external_constructor<value_t::number_integer>
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<>
5458 struct external_constructor<value_t::array>
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,
5481                enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
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,
5511              enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
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<>
5528 struct external_constructor<value_t::object>
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,
5551                enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
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 
5565 /////////////
5566 // to_json //
5567 /////////////
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 {
5573     external_constructor<value_t::boolean>::construct(j, b);
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 {
5593     external_constructor<value_t::string>::construct(j, s);
5594 }
5595 
5596 template<typename BasicJsonType>
5597 inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5598 {
5599     external_constructor<value_t::string>::construct(j, std::move(s));
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 {
5636     external_constructor<value_t::array>::construct(j, e);
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&&
5643                          !is_compatible_string_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 {
5649     external_constructor<value_t::array>::construct(j, arr);
5650 }
5651 
5652 template<typename BasicJsonType>
5653 inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5654 {
5655     external_constructor<value_t::binary>::construct(j, bin);
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 {
5662     external_constructor<value_t::array>::construct(j, std::move(arr));
5663 }
5664 
5665 template<typename BasicJsonType>
5666 inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5667 {
5668     external_constructor<value_t::array>::construct(j, std::move(arr));
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 {
5675     external_constructor<value_t::object>::construct(j, obj);
5676 }
5677 
5678 template<typename BasicJsonType>
5679 inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5680 {
5681     external_constructor<value_t::object>::construct(j, std::move(obj));
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 {
5691     external_constructor<value_t::array>::construct(j, arr);
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 
5728 struct to_json_fn
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 to hold default `to_json` function
5741 /// to see why this is required:
5742 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
5743 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)
5747     detail::static_const<detail::to_json_fn>::value;
5748 #ifndef JSON_HAS_CPP_17
5749 }  // namespace
5750 #endif
5751 
5752 NLOHMANN_JSON_NAMESPACE_END
5753 
5754 // #include <nlohmann/detail/meta/identity_tag.hpp>
5755 
5756 
5757 NLOHMANN_JSON_NAMESPACE_BEGIN
5758 
5759 /// @sa https://json.nlohmann.me/api/adl_serializer/
5760 template<typename ValueType, typename>
5761 struct adl_serializer
5762 {
5763     /// @brief convert a JSON value to any value type
5764     /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
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 
5773     /// @brief convert a JSON value to any value type
5774     /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
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 
5783     /// @brief convert any value type to a JSON value
5784     /// @sa https://json.nlohmann.me/api/adl_serializer/to_json/
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 
5794 NLOHMANN_JSON_NAMESPACE_END
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 
5814 NLOHMANN_JSON_NAMESPACE_BEGIN
5815 
5816 /// @brief an internal type for a backed binary type
5817 /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/
5818 template<typename BinaryType>
5819 class byte_container_with_subtype : public BinaryType
5820 {
5821   public:
5822     using container_type = BinaryType;
5823     using subtype_type = std::uint64_t;
5824 
5825     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
5826     byte_container_with_subtype() noexcept(noexcept(container_type()))
5827         : container_type()
5828     {}
5829 
5830     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
5831     byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
5832         : container_type(b)
5833     {}
5834 
5835     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
5836     byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5837         : container_type(std::move(b))
5838     {}
5839 
5840     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
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 
5847     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
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 
5854     bool operator==(const byte_container_with_subtype& rhs) const
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 
5860     bool operator!=(const byte_container_with_subtype& rhs) const
5861     {
5862         return !(rhs == *this);
5863     }
5864 
5865     /// @brief sets the binary subtype
5866     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/
5867     void set_subtype(subtype_type subtype_) noexcept
5868     {
5869         m_subtype = subtype_;
5870         m_has_subtype = true;
5871     }
5872 
5873     /// @brief return the binary subtype
5874     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/subtype/
5875     constexpr subtype_type subtype() const noexcept
5876     {
5877         return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5878     }
5879 
5880     /// @brief return whether the value has a subtype
5881     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/
5882     constexpr bool has_subtype() const noexcept
5883     {
5884         return m_has_subtype;
5885     }
5886 
5887     /// @brief clears the binary subtype
5888     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/
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 
5900 NLOHMANN_JSON_NAMESPACE_END
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 
5928 NLOHMANN_JSON_NAMESPACE_BEGIN
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 
5939 /*!
5940 @brief hash a JSON value
5941 
5942 The hash function tries to rely on std::hash where possible. Furthermore, the
5943 type of the JSON value is taken into account to have different hash values for
5944 null, 0, 0U, and false, etc.
5945 
5946 @tparam BasicJsonType basic_json specialization
5947 @param j JSON value to hash
5948 @return hash value of j
5949 */
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
6039 NLOHMANN_JSON_NAMESPACE_END
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 
6098 NLOHMANN_JSON_NAMESPACE_BEGIN
6099 namespace detail
6100 {
6101 
6102 /// the supported input formats
6103 enum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata };
6104 
6105 ////////////////////
6106 // input adapters //
6107 ////////////////////
6108 
6109 #ifndef JSON_NO_IO
6110 /*!
6111 Input adapter for stdio file access. This adapter read only 1 byte and do not use any
6112  buffer. This adapter is a very low level adapter.
6113 */
6114 class file_input_adapter
6115 {
6116   public:
6117     using char_type = char;
6118 
6119     JSON_HEDLEY_NON_NULL(2)
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:
6139     /// the file pointer to read from
6140     std::FILE* m_file;
6141 };
6142 
6143 
6144 /*!
6145 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
6146 beginning of input. Does not support changing the underlying std::streambuf
6147 in mid-input. Maintains underlying std::istream and std::streambuf to support
6148 subsequent use of standard std::istream operations to process any input
6149 characters following those used in parsing the JSON input.  Clears the
6150 std::istream flags; any input errors (e.g., EOF) will be detected by the first
6151 subsequent call for input from the std::istream.
6152 */
6153 class input_stream_adapter
6154 {
6155   public:
6156     using char_type = char;
6157 
6158     ~input_stream_adapter()
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;
6174     input_stream_adapter& operator=(input_stream_adapter&) = delete;
6175     input_stream_adapter& operator=(input_stream_adapter&&) = delete;
6176 
6177     input_stream_adapter(input_stream_adapter&& rhs) noexcept
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:
6199     /// the associated input stream
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>
6208 class iterator_input_adapter
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>
6234     friend struct wide_string_input_helper;
6235 
6236     bool empty() const
6237     {
6238         return current == end;
6239     }
6240 };
6241 
6242 
6243 template<typename BaseInputAdapter, size_t T>
6244 struct wide_string_input_helper;
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>
6368 class wide_string_input_adapter
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 
6402     /// a buffer for UTF-8 bytes
6403     std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
6404 
6405     /// index to the utf8_codes array for the next valid byte
6406     std::size_t utf8_bytes_index = 0;
6407     /// number of valid bytes in the utf8_codes array
6408     std::size_t utf8_bytes_filled = 0;
6409 };
6410 
6411 
6412 template<typename IteratorType, typename Enable = void>
6413 struct iterator_input_adapter_factory
6414 {
6415     using iterator_type = IteratorType;
6416     using char_type = typename std::iterator_traits<iterator_type>::value_type;
6417     using adapter_type = iterator_input_adapter<iterator_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>
6426 struct is_iterator_of_multibyte
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>
6436 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
6437 {
6438     using iterator_type = IteratorType;
6439     using char_type = typename std::iterator_traits<iterator_type>::value_type;
6440     using base_adapter_type = iterator_input_adapter<iterator_type>;
6441     using adapter_type = wide_string_input_adapter<base_adapter_type, char_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>
6468 struct container_input_adapter_factory {};
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>
6485 typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
6486 {
6487     return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
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&&
6515                std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
6516                sizeof(typename std::remove_pointer<CharT>::type) == 1,
6517                int >::type = 0 >
6518 contiguous_bytes_input_adapter input_adapter(CharT b)
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.
6534 class span_input_adapter
6535 {
6536   public:
6537     template < typename CharT,
6538                typename std::enable_if <
6539                    std::is_pointer<CharT>::value&&
6540                    std::is_integral<typename std::remove_pointer<CharT>::type>::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 
6553     contiguous_bytes_input_adapter&& get()
6554     {
6555         return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6556     }
6557 
6558   private:
6559     contiguous_bytes_input_adapter ia;
6560 };
6561 
6562 }  // namespace detail
6563 NLOHMANN_JSON_NAMESPACE_END
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 
6588 NLOHMANN_JSON_NAMESPACE_BEGIN
6589 
6590 /*!
6591 @brief SAX interface
6592 
6593 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
6594 Each function is called in different situations while the input is parsed. The
6595 boolean return value informs the parser whether to continue processing the
6596 input.
6597 */
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 
6607     /*!
6608     @brief a null value was read
6609     @return whether parsing should proceed
6610     */
6611     virtual bool null() = 0;
6612 
6613     /*!
6614     @brief a boolean value was read
6615     @param[in] val  boolean value
6616     @return whether parsing should proceed
6617     */
6618     virtual bool boolean(bool val) = 0;
6619 
6620     /*!
6621     @brief an integer number was read
6622     @param[in] val  integer value
6623     @return whether parsing should proceed
6624     */
6625     virtual bool number_integer(number_integer_t val) = 0;
6626 
6627     /*!
6628     @brief an unsigned integer number was read
6629     @param[in] val  unsigned integer value
6630     @return whether parsing should proceed
6631     */
6632     virtual bool number_unsigned(number_unsigned_t val) = 0;
6633 
6634     /*!
6635     @brief a floating-point number was read
6636     @param[in] val  floating-point value
6637     @param[in] s    raw token value
6638     @return whether parsing should proceed
6639     */
6640     virtual bool number_float(number_float_t val, const string_t& s) = 0;
6641 
6642     /*!
6643     @brief a string value was read
6644     @param[in] val  string value
6645     @return whether parsing should proceed
6646     @note It is safe to move the passed string value.
6647     */
6648     virtual bool string(string_t& val) = 0;
6649 
6650     /*!
6651     @brief a binary value was read
6652     @param[in] val  binary value
6653     @return whether parsing should proceed
6654     @note It is safe to move the passed binary value.
6655     */
6656     virtual bool binary(binary_t& val) = 0;
6657 
6658     /*!
6659     @brief the beginning of an object was read
6660     @param[in] elements  number of object elements or -1 if unknown
6661     @return whether parsing should proceed
6662     @note binary formats may report the number of elements
6663     */
6664     virtual bool start_object(std::size_t elements) = 0;
6665 
6666     /*!
6667     @brief an object key was read
6668     @param[in] val  object key
6669     @return whether parsing should proceed
6670     @note It is safe to move the passed string.
6671     */
6672     virtual bool key(string_t& val) = 0;
6673 
6674     /*!
6675     @brief the end of an object was read
6676     @return whether parsing should proceed
6677     */
6678     virtual bool end_object() = 0;
6679 
6680     /*!
6681     @brief the beginning of an array was read
6682     @param[in] elements  number of array elements or -1 if unknown
6683     @return whether parsing should proceed
6684     @note binary formats may report the number of elements
6685     */
6686     virtual bool start_array(std::size_t elements) = 0;
6687 
6688     /*!
6689     @brief the end of an array was read
6690     @return whether parsing should proceed
6691     */
6692     virtual bool end_array() = 0;
6693 
6694     /*!
6695     @brief a parse error occurred
6696     @param[in] position    the position in the input where the error occurs
6697     @param[in] last_token  the last read token
6698     @param[in] ex          an exception object describing the error
6699     @return whether parsing should proceed (must return false)
6700     */
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 {
6716 /*!
6717 @brief SAX implementation to create a JSON value from SAX events
6718 
6719 This class implements the @ref json_sax interface and processes the SAX events
6720 to create a JSON value which makes it basically a DOM parser. The structure or
6721 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
6722 a pointer to the respective array or object for each recursion depth.
6723 
6724 After successful parsing, the value that is passed by reference to the
6725 constructor contains the parsed value.
6726 
6727 @tparam BasicJsonType  the JSON type
6728 */
6729 template<typename BasicJsonType>
6730 class json_sax_dom_parser
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 
6739     /*!
6740     @param[in,out] r  reference to a JSON value that is manipulated while
6741                        parsing
6742     @param[in] allow_exceptions_  whether parse errors yield exceptions
6743     */
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)
6751     json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
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 
6767     bool number_integer(number_integer_t val)
6768     {
6769         handle_value(val);
6770         return true;
6771     }
6772 
6773     bool number_unsigned(number_unsigned_t val)
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:
6870     /*!
6871     @invariant If the ref stack is empty, then the passed value will be the new
6872                root.
6873     @invariant If the ref stack contains a value, then it is an array or an
6874                object to which we can add elements
6875     */
6876     template<typename Value>
6877     JSON_HEDLEY_RETURNS_NON_NULL
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 
6900     /// the parsed JSON value
6901     BasicJsonType& root;
6902     /// stack to model hierarchy of values
6903     std::vector<BasicJsonType*> ref_stack {};
6904     /// helper to hold the reference for the next object element
6905     BasicJsonType* object_element = nullptr;
6906     /// whether a syntax error occurred
6907     bool errored = false;
6908     /// whether to throw exceptions in case of errors
6909     const bool allow_exceptions = true;
6910 };
6911 
6912 template<typename BasicJsonType>
6913 class json_sax_dom_callback_parser
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;
6921     using parser_callback_t = typename BasicJsonType::parser_callback_t;
6922     using parse_event_t = typename BasicJsonType::parse_event_t;
6923 
6924     json_sax_dom_callback_parser(BasicJsonType& r,
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
6933     json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
6934     json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6935     json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
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 
6951     bool number_integer(number_integer_t val)
6952     {
6953         handle_value(val);
6954         return true;
6955     }
6956 
6957     bool number_unsigned(number_unsigned_t val)
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:
7120     /*!
7121     @param[in] v  value to add to the JSON value we build during parsing
7122     @param[in] skip_callback  whether we should skip calling the callback
7123                function; this is required after start_array() and
7124                start_object() SAX events, because otherwise we would call the
7125                callback function with an empty array or object, respectively.
7126 
7127     @invariant If the ref stack is empty, then the passed value will be the new
7128                root.
7129     @invariant If the ref stack contains a value, then it is an array or an
7130                object to which we can add elements
7131 
7132     @return pair of boolean (whether value should be kept) and pointer (to the
7133             passed value in the ref_stack hierarchy; nullptr if not kept)
7134     */
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 
7199     /// the parsed JSON value
7200     BasicJsonType& root;
7201     /// stack to model hierarchy of values
7202     std::vector<BasicJsonType*> ref_stack {};
7203     /// stack to manage which values to keep
7204     std::vector<bool> keep_stack {};
7205     /// stack to manage which object keys to keep
7206     std::vector<bool> key_keep_stack {};
7207     /// helper to hold the reference for the next object element
7208     BasicJsonType* object_element = nullptr;
7209     /// whether a syntax error occurred
7210     bool errored = false;
7211     /// callback function
7212     const parser_callback_t callback = nullptr;
7213     /// whether to throw exceptions in case of errors
7214     const bool allow_exceptions = true;
7215     /// a discarded value for the callback
7216     BasicJsonType discarded = BasicJsonType::value_t::discarded;
7217 };
7218 
7219 template<typename BasicJsonType>
7220 class json_sax_acceptor
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 
7239     bool number_integer(number_integer_t /*unused*/)
7240     {
7241         return true;
7242     }
7243 
7244     bool number_unsigned(number_unsigned_t /*unused*/)
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
7296 NLOHMANN_JSON_NAMESPACE_END
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 
7326 NLOHMANN_JSON_NAMESPACE_BEGIN
7327 namespace detail
7328 {
7329 
7330 ///////////
7331 // lexer //
7332 ///////////
7333 
7334 template<typename BasicJsonType>
7335 class lexer_base
7336 {
7337   public:
7338     /// token types for the parser
7339     enum class token_type
7340     {
7341         uninitialized,    ///< indicating the scanner is uninitialized
7342         literal_true,     ///< the `true` literal
7343         literal_false,    ///< the `false` literal
7344         literal_null,     ///< the `null` literal
7345         value_string,     ///< a string -- use get_string() for actual value
7346         value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
7347         value_integer,    ///< a signed integer -- use get_number_integer() for actual value
7348         value_float,      ///< an floating point number -- use get_number_float() for actual value
7349         begin_array,      ///< the character for array begin `[`
7350         begin_object,     ///< the character for object begin `{`
7351         end_array,        ///< the character for array end `]`
7352         end_object,       ///< the character for object end `}`
7353         name_separator,   ///< the name separator `:`
7354         value_separator,  ///< the value separator `,`
7355         parse_error,      ///< indicating a parse error
7356         end_of_input,     ///< indicating the end of the input buffer
7357         literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
7358     };
7359 
7360     /// return name of values of type token_type (only used for errors)
7361     JSON_HEDLEY_RETURNS_NON_NULL
7362     JSON_HEDLEY_CONST
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 };
7406 /*!
7407 @brief lexical analysis
7408 
7409 This class organizes the lexical analysis during JSON deserialization.
7410 */
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:
7422     using token_type = typename lexer_base<BasicJsonType>::token_type;
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:
7438     /////////////////////
7439     // locales
7440     /////////////////////
7441 
7442     /// return the locale-dependent decimal point
7443     JSON_HEDLEY_PURE
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 
7451     /////////////////////
7452     // scan functions
7453     /////////////////////
7454 
7455     /*!
7456     @brief get codepoint from 4 hex characters following `\u`
7457 
7458     For input "\u c1 c2 c3 c4" the codepoint is:
7459       (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
7460     = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
7461 
7462     Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
7463     must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
7464     conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
7465     between the ASCII value of the character and the desired integer value.
7466 
7467     @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
7468             non-hex character)
7469     */
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 
7503     /*!
7504     @brief check if the next byte(s) are inside a given range
7505 
7506     Adds the current byte and, for each passed range, reads a new byte and
7507     checks if it is inside the range. If a violation was detected, set up an
7508     error message and return false. Otherwise, return true.
7509 
7510     @param[in] ranges  list of integers; interpreted as list of pairs of
7511                        inclusive lower and upper bound, respectively
7512 
7513     @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
7514          1, 2, or 3 pairs. This precondition is enforced by an assertion.
7515 
7516     @return true if and only if no range violation was detected
7517     */
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 
7540     /*!
7541     @brief scan a string literal
7542 
7543     This function scans a string according to Sect. 7 of RFC 8259. While
7544     scanning, bytes are escaped and copied into buffer token_buffer. Then the
7545     function returns successfully, token_buffer is *not* null-terminated (as it
7546     may contain \0 bytes), and token_buffer.size() is the number of bytes in the
7547     string.
7548 
7549     @return token_type::value_string if string could be successfully scanned,
7550             token_type::parse_error otherwise
7551 
7552     @note In case of errors, variable error_message contains a textual
7553           description.
7554     */
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 
8141     /*!
8142      * @brief scan a comment
8143      * @return whether comment could be scanned successfully
8144      */
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 
8212     JSON_HEDLEY_NON_NULL(2)
8213     static void strtof(float& f, const char* str, char** endptr) noexcept
8214     {
8215         f = std::strtof(str, endptr);
8216     }
8217 
8218     JSON_HEDLEY_NON_NULL(2)
8219     static void strtof(double& f, const char* str, char** endptr) noexcept
8220     {
8221         f = std::strtod(str, endptr);
8222     }
8223 
8224     JSON_HEDLEY_NON_NULL(2)
8225     static void strtof(long double& f, const char* str, char** endptr) noexcept
8226     {
8227         f = std::strtold(str, endptr);
8228     }
8229 
8230     /*!
8231     @brief scan a number literal
8232 
8233     This function scans a string according to Sect. 6 of RFC 8259.
8234 
8235     The function is realized with a deterministic finite state machine derived
8236     from the grammar described in RFC 8259. Starting in state "init", the
8237     input is read and used to determined the next state. Only state "done"
8238     accepts the number. State "error" is a trap state to model errors. In the
8239     table below, "anything" means any character but the ones listed before.
8240 
8241     state    | 0        | 1-9      | e E      | +       | -       | .        | anything
8242     ---------|----------|----------|----------|---------|---------|----------|-----------
8243     init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
8244     minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
8245     zero     | done     | done     | exponent | done    | done    | decimal1 | done
8246     any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
8247     decimal1 | decimal2 | decimal2 | [error]  | [error] | [error] | [error]  | [error]
8248     decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
8249     exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
8250     sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
8251     any2     | any2     | any2     | done     | done    | done    | done     | done
8252 
8253     The state machine is realized with one label per state (prefixed with
8254     "scan_number_") and `goto` statements between them. The state machine
8255     contains cycles, but any cycle can be left when EOF is read. Therefore,
8256     the function is guaranteed to terminate.
8257 
8258     During scanning, the read bytes are stored in token_buffer. This string is
8259     then converted to a signed integer, an unsigned integer, or a
8260     floating-point number.
8261 
8262     @return token_type::value_unsigned, token_type::value_integer, or
8263             token_type::value_float if number could be successfully scanned,
8264             token_type::parse_error otherwise
8265 
8266     @note The scanner is independent of the current locale. Internally, the
8267           locale's decimal point is used instead of `.` to work with the
8268           locale-dependent converters.
8269     */
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 
8595     /*!
8596     @param[in] literal_text  the literal text to expect
8597     @param[in] length        the length of the passed literal text
8598     @param[in] return_type   the token type to return on success
8599     */
8600     JSON_HEDLEY_NON_NULL(2)
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 
8616     /////////////////////
8617     // input management
8618     /////////////////////
8619 
8620     /// reset token_buffer; current character is beginning of token
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 
8667     /*!
8668     @brief unget current character (read it again on next get)
8669 
8670     We implement unget by setting variable next_unget to true. The input is not
8671     changed - we just simulate ungetting by modifying chars_read_total,
8672     chars_read_current_line, and token_string. The next call to get() will
8673     behave as if the unget character is read again.
8674     */
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 
8701     /// add a character to token_buffer
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:
8708     /////////////////////
8709     // value getters
8710     /////////////////////
8711 
8712     /// return integer value
8713     constexpr number_integer_t get_number_integer() const noexcept
8714     {
8715         return value_integer;
8716     }
8717 
8718     /// return unsigned integer value
8719     constexpr number_unsigned_t get_number_unsigned() const noexcept
8720     {
8721         return value_unsigned;
8722     }
8723 
8724     /// return floating-point value
8725     constexpr number_float_t get_number_float() const noexcept
8726     {
8727         return value_float;
8728     }
8729 
8730     /// return current string value (implicitly resets the token; useful only once)
8731     string_t& get_string()
8732     {
8733         return token_buffer;
8734     }
8735 
8736     /////////////////////
8737     // diagnostics
8738     /////////////////////
8739 
8740     /// return position of last read token
8741     constexpr position_t get_position() const noexcept
8742     {
8743         return position;
8744     }
8745 
8746     /// return the last read token (for errors only).  Will never contain EOF
8747     /// (an arbitrary value that is not a valid char value, often -1), because
8748     /// 255 may legitimately occur.  May contain NUL, which should be escaped.
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 
8772     /// return syntax error message
8773     JSON_HEDLEY_RETURNS_NON_NULL
8774     constexpr const char* get_error_message() const noexcept
8775     {
8776         return error_message;
8777     }
8778 
8779     /////////////////////
8780     // actual scanner
8781     /////////////////////
8782 
8783     /*!
8784     @brief skip the UTF-8 byte order mark
8785     @return true iff there is no BOM or the correct BOM has been skipped
8786     */
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 
8801     void skip_whitespace()
8802     {
8803         do
8804         {
8805             get();
8806         }
8807         while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8808     }
8809 
8810     token_type scan()
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:
8899     /// input adapter
8900     InputAdapterType ia;
8901 
8902     /// whether comments should be ignored (true) or signaled as errors (false)
8903     const bool ignore_comments = false;
8904 
8905     /// the current character
8906     char_int_type current = std::char_traits<char_type>::eof();
8907 
8908     /// whether the next get() call should just return current
8909     bool next_unget = false;
8910 
8911     /// the start position of the current token
8912     position_t position {};
8913 
8914     /// raw input token string (for error messages)
8915     std::vector<char_type> token_string {};
8916 
8917     /// buffer for variable-length tokens (numbers, strings)
8918     string_t token_buffer {};
8919 
8920     /// a description of occurred lexer errors
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 
8928     /// the decimal point
8929     const char_int_type decimal_point_char = '.';
8930 };
8931 
8932 }  // namespace detail
8933 NLOHMANN_JSON_NAMESPACE_END
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 
8959 NLOHMANN_JSON_NAMESPACE_BEGIN
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>
8971 using number_integer_function_t =
8972     decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8973 
8974 template<typename T, typename Unsigned>
8975 using number_unsigned_function_t =
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>
8991 using start_object_function_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:
9017     static_assert(is_basic_json<BasicJsonType>::value,
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 =
9029         is_detected_exact<bool, null_function_t, SAX>::value &&
9030         is_detected_exact<bool, boolean_function_t, SAX>::value &&
9031         is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
9032         is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
9033         is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
9034         is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
9035         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
9036         is_detected_exact<bool, start_object_function_t, SAX>::value &&
9037         is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
9038         is_detected_exact<bool, end_object_function_t, SAX>::value &&
9039         is_detected_exact<bool, start_array_function_t, SAX>::value &&
9040         is_detected_exact<bool, end_array_function_t, SAX>::value &&
9041         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
9042 };
9043 
9044 template<typename SAX, typename BasicJsonType>
9045 struct is_sax_static_asserts
9046 {
9047   private:
9048     static_assert(is_basic_json<BasicJsonType>::value,
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:
9059     static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
9060                   "Missing/invalid function: bool null()");
9061     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
9062                   "Missing/invalid function: bool boolean(bool)");
9063     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
9064                   "Missing/invalid function: bool boolean(bool)");
9065     static_assert(
9066         is_detected_exact<bool, number_integer_function_t, SAX,
9067         number_integer_t>::value,
9068         "Missing/invalid function: bool number_integer(number_integer_t)");
9069     static_assert(
9070         is_detected_exact<bool, number_unsigned_function_t, SAX,
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(
9077         is_detected_exact<bool, string_function_t, SAX, string_t>::value,
9078         "Missing/invalid function: bool string(string_t&)");
9079     static_assert(
9080         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
9081         "Missing/invalid function: bool binary(binary_t&)");
9082     static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
9083                   "Missing/invalid function: bool start_object(std::size_t)");
9084     static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
9085                   "Missing/invalid function: bool key(string_t&)");
9086     static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
9087                   "Missing/invalid function: bool end_object()");
9088     static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
9089                   "Missing/invalid function: bool start_array(std::size_t)");
9090     static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
9091                   "Missing/invalid function: bool end_array()");
9092     static_assert(
9093         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
9094         "Missing/invalid function: bool parse_error(std::size_t, const "
9095         "std::string&, const exception&)");
9096 };
9097 
9098 }  // namespace detail
9099 NLOHMANN_JSON_NAMESPACE_END
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 
9108 NLOHMANN_JSON_NAMESPACE_BEGIN
9109 namespace detail
9110 {
9111 
9112 /// how to treat CBOR tags
9113 enum class cbor_tag_handler_t
9114 {
9115     error,   ///< throw a parse_error exception in case of a tag
9116     ignore,  ///< ignore tags
9117     store    ///< store tags as binary type
9118 };
9119 
9120 /*!
9121 @brief determine system byte order
9122 
9123 @return true if and only if system's byte order is little endian
9124 
9125 @note from https://stackoverflow.com/a/1001328/266378
9126 */
9127 static inline bool little_endianness(int num = 1) noexcept
9128 {
9129     return *reinterpret_cast<char*>(&num) == 1;
9130 }
9131 
9132 
9133 ///////////////////
9134 // binary reader //
9135 ///////////////////
9136 
9137 /*!
9138 @brief deserialization of CBOR, MessagePack, and UBJSON values
9139 */
9140 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
9141 class binary_reader
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:
9153     /*!
9154     @brief create a binary reader
9155 
9156     @param[in] adapter  input adapter to read from
9157     */
9158     explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
9159     {
9160         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
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 
9170     /*!
9171     @param[in] format  the binary format to parse
9172     @param[in] sax_    a SAX event processor
9173     @param[in] strict  whether to expect the input to be consumed completed
9174     @param[in] tag_handler  how to treat CBOR tags
9175 
9176     @return whether parsing was successful
9177     */
9178     JSON_HEDLEY_NON_NULL(3)
9179     bool sax_parse(const input_format_t format,
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 
9197             case input_format_t::msgpack:
9198                 result = parse_msgpack_internal();
9199                 break;
9200 
9201             case input_format_t::ubjson:
9202             case input_format_t::bjdata:
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:
9234     //////////
9235     // BSON //
9236     //////////
9237 
9238     /*!
9239     @brief Reads in a BSON-object and passes it to the SAX-parser.
9240     @return whether a valid BSON-value was passed to the SAX parser
9241     */
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 
9260     /*!
9261     @brief Parses a C-style string from the BSON input.
9262     @param[in,out] result  A reference to the string variable where the read
9263                             string is to be stored.
9264     @return `true` if the \x00-byte indicating the end of the string was
9265              encountered before the EOF; false` indicates an unexpected EOF.
9266     */
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 
9285     /*!
9286     @brief Parses a zero-terminated string of length @a len from the BSON
9287            input.
9288     @param[in] len  The length (including the zero-byte at the end) of the
9289                     string to be read.
9290     @param[in,out] result  A reference to the string variable where the read
9291                             string is to be stored.
9292     @tparam NumberType The type of the length @a len
9293     @pre len >= 1
9294     @return `true` if the string was successfully parsed
9295     */
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 
9309     /*!
9310     @brief Parses a byte array input of length @a len from the BSON input.
9311     @param[in] len  The length of the byte array to be read.
9312     @param[in,out] result  A reference to the binary variable where the read
9313                             array is to be stored.
9314     @tparam NumberType The type of the length @a len
9315     @pre len >= 0
9316     @return `true` if the byte array was successfully parsed
9317     */
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 
9336     /*!
9337     @brief Read a BSON document element of the given @a element_type.
9338     @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
9339     @param[in] element_type_parse_position The position in the input stream,
9340                where the `element_type` was read.
9341     @warning Not all BSON element types are supported yet. An unsupported
9342              @a element_type will give rise to a parse_error.114:
9343              Unsupported BSON record type 0x...
9344     @return whether a valid BSON-object/array was passed to the SAX parser
9345     */
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 
9414     /*!
9415     @brief Read a BSON element list (as specified in the BSON-spec)
9416 
9417     The same binary layout is used for objects and arrays, hence it must be
9418     indicated with the argument @a is_array which one is expected
9419     (true --> array, false --> object).
9420 
9421     @param[in] is_array Determines if the element list being read is to be
9422                         treated as an object (@a is_array == false), or as an
9423                         array (@a is_array == true).
9424     @return whether a valid BSON-object/array was passed to the SAX parser
9425     */
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 
9460     /*!
9461     @brief Reads an array from the BSON input and passes it to the SAX-parser.
9462     @return whether a valid BSON-array was passed to the SAX parser
9463     */
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 
9482     //////////
9483     // CBOR //
9484     //////////
9485 
9486     /*!
9487     @param[in] get_char  whether a new character should be retrieved from the
9488                          input (true) or whether the last read character should
9489                          be considered instead (false)
9490     @param[in] tag_handler how CBOR tags should be treated
9491 
9492     @return whether a valid CBOR value was passed to the SAX parser
9493     */
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                 {
9807                     case cbor_tag_handler_t::error:
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 
9814                     case cbor_tag_handler_t::ignore:
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 
9849                     case cbor_tag_handler_t::store:
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 
9974     /*!
9975     @brief reads a CBOR string
9976 
9977     This function first reads starting bytes to determine the expected
9978     string length and then copies this number of bytes into a string.
9979     Additionally, CBOR's strings with indefinite lengths are supported.
9980 
9981     @param[out] result  created string
9982 
9983     @return whether string creation completed
9984     */
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 
10070     /*!
10071     @brief reads a CBOR byte array
10072 
10073     This function first reads starting bytes to determine the expected
10074     byte array length and then copies this number of bytes into the byte array.
10075     Additionally, CBOR's byte arrays with indefinite lengths are supported.
10076 
10077     @param[out] result  created byte array
10078 
10079     @return whether byte array creation completed
10080     */
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 
10170     /*!
10171     @param[in] len  the length of the array or static_cast<std::size_t>(-1) for an
10172                     array of indefinite size
10173     @param[in] tag_handler how CBOR tags should be treated
10174     @return whether array creation completed
10175     */
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 
10208     /*!
10209     @param[in] len  the length of the object or static_cast<std::size_t>(-1) for an
10210                     object of indefinite size
10211     @param[in] tag_handler how CBOR tags should be treated
10212     @return whether object creation completed
10213     */
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 
10263     /////////////
10264     // MsgPack //
10265     /////////////
10266 
10267     /*!
10268     @return whether a valid MessagePack value was passed to the SAX parser
10269     */
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 
10641     /*!
10642     @brief reads a MessagePack string
10643 
10644     This function first reads starting bytes to determine the expected
10645     string length and then copies this number of bytes into a string.
10646 
10647     @param[out] result  created string
10648 
10649     @return whether string creation completed
10650     */
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 
10724     /*!
10725     @brief reads a MessagePack byte array
10726 
10727     This function first reads starting bytes to determine the expected
10728     byte array length and then copies this number of bytes into a byte array.
10729 
10730     @param[out] result  created byte array
10731 
10732     @return whether byte array creation completed
10733     */
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 
10841     /*!
10842     @param[in] len  the length of the array
10843     @return whether array creation completed
10844     */
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 
10863     /*!
10864     @param[in] len  the length of the object
10865     @return whether object creation completed
10866     */
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 
10893     ////////////
10894     // UBJSON //
10895     ////////////
10896 
10897     /*!
10898     @param[in] get_char  whether a new character should be retrieved from the
10899                          input (true, default) or whether the last read
10900                          character should be considered instead
10901 
10902     @return whether a valid UBJSON value was passed to the SAX parser
10903     */
10904     bool parse_ubjson_internal(const bool get_char = true)
10905     {
10906         return get_ubjson_value(get_char ? get_ignore_noop() : current);
10907     }
10908 
10909     /*!
10910     @brief reads a UBJSON string
10911 
10912     This function is either called after reading the 'S' byte explicitly
10913     indicating a string, or in case of an object key where the 'S' byte can be
10914     left out.
10915 
10916     @param[out] result   created string
10917     @param[in] get_char  whether a new character should be retrieved from the
10918                          input (true, default) or whether the last read
10919                          character should be considered instead
10920 
10921     @return whether string creation completed
10922     */
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 
11014     /*!
11015     @param[out] dim  an integer vector storing the ND array dimensions
11016     @return whether reading ND array size vector is successful
11017     */
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 
11072     /*!
11073     @param[out] result  determined size
11074     @param[in,out] is_ndarray  for input, `true` means already inside an ndarray vector
11075                                or ndarray dimension is not allowed; `false` means ndarray
11076                                is allowed; for output, `true` means an ndarray is found;
11077                                is_ndarray can only return `true` when its initial value
11078                                is `false`
11079     @param[in] prefix  type marker if already read, otherwise set to 0
11080 
11081     @return whether size determination completed
11082     */
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 
11295     /*!
11296     @brief determine the type and size for a container
11297 
11298     In the optimized UBJSON format, a type and a size can be provided to allow
11299     for a more compact representation.
11300 
11301     @param[out] result  pair of the size and the type
11302     @param[in] inside_ndarray  whether the parser is parsing an ND array dimensional vector
11303 
11304     @return whether pair creation completed
11305     */
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 
11369     /*!
11370     @param prefix  the previously read or set type prefix
11371     @return whether value creation completed
11372     */
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 
11553     /*!
11554     @return whether array creation completed
11555     */
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 
11661     /*!
11662     @return whether object creation completed
11663     */
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 
11813     ///////////////////////
11814     // Utility functions //
11815     ///////////////////////
11816 
11817     /*!
11818     @brief get next character from the input
11819 
11820     This function provides the interface to the used input adapter. It does
11821     not throw in case the input reached EOF, but returns a -'ve valued
11822     `std::char_traits<char_type>::eof()` in that case.
11823 
11824     @return character read from the input
11825     */
11826     char_int_type get()
11827     {
11828         ++chars_read;
11829         return current = ia.get_character();
11830     }
11831 
11832     /*!
11833     @return character read from the input after ignoring all 'N' entries
11834     */
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 
11890     /*!
11891     @brief create a string by reading characters from the input
11892 
11893     @tparam NumberType the type of the number
11894     @param[in] format the current format (for diagnostics)
11895     @param[in] len number of characters to read
11896     @param[out] result string created by reading @a len bytes
11897 
11898     @return whether string creation completed
11899 
11900     @note We can not reserve @a len bytes for the result, because @a len
11901           may be too large. Usually, @ref unexpect_eof() detects the end of
11902           the input before we run out of string memory.
11903     */
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 
11923     /*!
11924     @brief create a byte array by reading bytes from the input
11925 
11926     @tparam NumberType the type of the number
11927     @param[in] format the current format (for diagnostics)
11928     @param[in] len number of bytes to read
11929     @param[out] result byte array created by reading @a len bytes
11930 
11931     @return whether byte array creation completed
11932 
11933     @note We can not reserve @a len bytes for the result, because @a len
11934           may be too large. Usually, @ref unexpect_eof() detects the end of
11935           the input before we run out of memory.
11936     */
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 
11956     /*!
11957     @param[in] format   the current format (for diagnostics)
11958     @param[in] context  further context information (for diagnostics)
11959     @return whether the last read character is not EOF
11960     */
11961     JSON_HEDLEY_NON_NULL(3)
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 
11972     /*!
11973     @return a string representation of the last read byte
11974     */
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 
11982     /*!
11983     @param[in] format   the current format
11984     @param[in] detail   a detailed error message
11985     @param[in] context  further context information
11986     @return a message string to use in the parse_error exceptions
11987     */
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 
12000             case input_format_t::msgpack:
12001                 error_msg += "MessagePack";
12002                 break;
12003 
12004             case input_format_t::ubjson:
12005                 error_msg += "UBJSON";
12006                 break;
12007 
12008             case input_format_t::bson:
12009                 error_msg += "BSON";
12010                 break;
12011 
12012             case input_format_t::bjdata:
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 
12027     /// input adapter
12028     InputAdapterType ia;
12029 
12030     /// the current character
12031     char_int_type current = std::char_traits<char_type>::eof();
12032 
12033     /// the number of characters read
12034     std::size_t chars_read = 0;
12035 
12036     /// whether we can assume little endianness
12037     const bool is_little_endian = little_endianness();
12038 
12039     /// input format
12040     const input_format_t input_format = input_format_t::json;
12041 
12042     /// the SAX parser
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 
12063   JSON_PRIVATE_UNLESS_TESTED:
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 =
12067         JSON_BINARY_READER_MAKE_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 =
12072         JSON_BINARY_READER_MAKE_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
12084 NLOHMANN_JSON_NAMESPACE_END
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 
12125 NLOHMANN_JSON_NAMESPACE_BEGIN
12126 namespace detail
12127 {
12128 ////////////
12129 // parser //
12130 ////////////
12131 
12132 enum class parse_event_t : std::uint8_t
12133 {
12134     /// the parser read `{` and started to process a JSON object
12135     object_start,
12136     /// the parser read `}` and finished processing a JSON object
12137     object_end,
12138     /// the parser read `[` and started to process a JSON array
12139     array_start,
12140     /// the parser read `]` and finished processing a JSON array
12141     array_end,
12142     /// the parser read a key of a value in an object
12143     key,
12144     /// the parser finished reading a JSON value
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 
12152 /*!
12153 @brief syntax analysis
12154 
12155 This class implements a recursive descent parser.
12156 */
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;
12164     using lexer_t = lexer<BasicJsonType, InputAdapterType>;
12165     using token_type = typename lexer_t::token_type;
12166 
12167   public:
12168     /// a parser reading from an input adapter
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 
12181     /*!
12182     @brief public parser interface
12183 
12184     @param[in] strict      whether to expect the last token to be EOF
12185     @param[in,out] result  parsed JSON value
12186 
12187     @throw parse_error.101 in case of an unexpected token
12188     @throw parse_error.102 if to_unicode fails or surrogate error
12189     @throw parse_error.103 if to_unicode fails
12190     */
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 
12245     /*!
12246     @brief public accept interface
12247 
12248     @param[in] strict  whether to expect the last token to be EOF
12249     @return whether the input is a proper JSON text
12250     */
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>
12258     JSON_HEDLEY_NON_NULL(2)
12259     bool sax_parse(SAX* sax, const bool strict = true)
12260     {
12261         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
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>
12277     JSON_HEDLEY_NON_NULL(2)
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 
12558     /// get next token from lexer
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:
12594     /// callback function
12595     const parser_callback_t<BasicJsonType> callback = nullptr;
12596     /// the type of the last read token
12597     token_type last_token = token_type::uninitialized;
12598     /// the lexer
12599     lexer_t m_lexer;
12600     /// whether to throw exceptions in case of errors
12601     const bool allow_exceptions = true;
12602 };
12603 
12604 }  // namespace detail
12605 NLOHMANN_JSON_NAMESPACE_END
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 
12637 NLOHMANN_JSON_NAMESPACE_BEGIN
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 */
12650 class primitive_iterator_t
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 
12657   JSON_PRIVATE_UNLESS_TESTED:
12658     /// iterator as signed integer type
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 
12667     /// set iterator to a defined beginning
12668     void set_begin() noexcept
12669     {
12670         m_it = begin_value;
12671     }
12672 
12673     /// set iterator to a defined past the end
12674     void set_end() noexcept
12675     {
12676         m_it = end_value;
12677     }
12678 
12679     /// return whether the iterator can be dereferenced
12680     constexpr bool is_begin() const noexcept
12681     {
12682         return m_it == begin_value;
12683     }
12684 
12685     /// return whether the iterator is at end
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 
12713     primitive_iterator_t& operator++() noexcept
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 
12726     primitive_iterator_t& operator--() noexcept
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
12753 NLOHMANN_JSON_NAMESPACE_END
12754 
12755 
12756 NLOHMANN_JSON_NAMESPACE_BEGIN
12757 namespace detail
12758 {
12759 
12760 /*!
12761 @brief an iterator value
12762 
12763 @note This structure could easily be a union, but MSVC currently does not allow
12764 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
12765 */
12766 template<typename BasicJsonType> struct internal_iterator
12767 {
12768     /// iterator for JSON objects
12769     typename BasicJsonType::object_t::iterator object_iterator {};
12770     /// iterator for JSON arrays
12771     typename BasicJsonType::array_t::iterator array_iterator {};
12772     /// generic iterator for all other types
12773     primitive_iterator_t primitive_iterator {};
12774 };
12775 
12776 }  // namespace detail
12777 NLOHMANN_JSON_NAMESPACE_END
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 
12808 NLOHMANN_JSON_NAMESPACE_BEGIN
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 
12816 /*!
12817 @brief a template for a bidirectional iterator for the @ref basic_json class
12818 This class implements a both iterators (iterator and const_iterator) for the
12819 @ref basic_json class.
12820 @note An iterator is called *initialized* when a pointer to a JSON value has
12821       been set (e.g., by a constructor or a copy assignment). If the iterator is
12822       default-constructed, it is *uninitialized* and most methods are undefined.
12823       **The library uses assertions to detect calls on uninitialized iterators.**
12824 @requirement The class satisfies the following concept requirements:
12825 -
12826 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
12827   The iterator that can be moved can be moved in both directions (i.e.
12828   incremented and decremented).
12829 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
12830        iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
12831 */
12832 template<typename BasicJsonType>
12833 class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12834 {
12835     /// the iterator with BasicJsonType of different const-ness
12836     using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
12837     /// allow basic_json to access private members
12838     friend other_iter_impl;
12839     friend BasicJsonType;
12840     friend iteration_proxy<iter_impl>;
12841     friend iteration_proxy_value<iter_impl>;
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
12846     static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
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:
12854     /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
12855     /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
12856     /// A user-defined iterator should provide publicly accessible typedefs named
12857     /// iterator_category, value_type, difference_type, pointer, and reference.
12858     /// Note that value_type is required to be non-const, even for constant iterators.
12859     using iterator_category = std::bidirectional_iterator_tag;
12860 
12861     /// the type of the values when the iterator is dereferenced
12862     using value_type = typename BasicJsonType::value_type;
12863     /// a type to represent differences between iterators
12864     using difference_type = typename BasicJsonType::difference_type;
12865     /// defines a pointer to the type iterated over (value_type)
12866     using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12867           typename BasicJsonType::const_pointer,
12868           typename BasicJsonType::pointer>::type;
12869     /// defines a reference to the type iterated over (value_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 
12880     /*!
12881     @brief constructor for a given JSON instance
12882     @param[in] object  pointer to a JSON object for this iterator
12883     @pre object != nullptr
12884     @post The iterator is initialized; i.e. `m_object != nullptr`.
12885     */
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:
12907             case value_t::number_integer:
12908             case value_t::number_unsigned:
12909             case value_t::number_float:
12910             case value_t::binary:
12911             case value_t::discarded:
12912             default:
12913             {
12914                 m_it.primitive_iterator = primitive_iterator_t();
12915                 break;
12916             }
12917         }
12918     }
12919 
12920     /*!
12921     @note The conventional copy constructor and copy assignment are implicitly
12922           defined. Combined with the following converting constructor and
12923           assignment, they support: (1) copy from iterator to iterator, (2)
12924           copy from const iterator to const iterator, and (3) conversion from
12925           iterator to const iterator. However conversion from const iterator
12926           to iterator is not defined.
12927     */
12928 
12929     /*!
12930     @brief const copy constructor
12931     @param[in] other const iterator to copy from
12932     @note This copy constructor had to be defined explicitly to circumvent a bug
12933           occurring on msvc v19.0 compiler (VS 2015) debug build. For more
12934           information refer to: https://github.com/nlohmann/json/issues/1608
12935     */
12936     iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
12937         : m_object(other.m_object), m_it(other.m_it)
12938     {}
12939 
12940     /*!
12941     @brief converting assignment
12942     @param[in] other const iterator to copy from
12943     @return const/non-const iterator
12944     @note It is not checked whether @a other is initialized.
12945     */
12946     iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
12947     {
12948         if (&other != this)
12949         {
12950             m_object = other.m_object;
12951             m_it = other.m_it;
12952         }
12953         return *this;
12954     }
12955 
12956     /*!
12957     @brief converting constructor
12958     @param[in] other  non-const iterator to copy from
12959     @note It is not checked whether @a other is initialized.
12960     */
12961     iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
12962         : m_object(other.m_object), m_it(other.m_it)
12963     {}
12964 
12965     /*!
12966     @brief converting assignment
12967     @param[in] other  non-const iterator to copy from
12968     @return const/non-const iterator
12969     @note It is not checked whether @a other is initialized.
12970     */
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 
12978   JSON_PRIVATE_UNLESS_TESTED:
12979     /*!
12980     @brief set the iterator to the first value
12981     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12982     */
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
13004                 m_it.primitive_iterator.set_end();
13005                 break;
13006             }
13007 
13008             case value_t::string:
13009             case value_t::boolean:
13010             case value_t::number_integer:
13011             case value_t::number_unsigned:
13012             case value_t::number_float:
13013             case value_t::binary:
13014             case value_t::discarded:
13015             default:
13016             {
13017                 m_it.primitive_iterator.set_begin();
13018                 break;
13019             }
13020         }
13021     }
13022 
13023     /*!
13024     @brief set the iterator past the last value
13025     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13026     */
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:
13048             case value_t::number_integer:
13049             case value_t::number_unsigned:
13050             case value_t::number_float:
13051             case value_t::binary:
13052             case value_t::discarded:
13053             default:
13054             {
13055                 m_it.primitive_iterator.set_end();
13056                 break;
13057             }
13058         }
13059     }
13060 
13061   public:
13062     /*!
13063     @brief return a reference to the value pointed to by the iterator
13064     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13065     */
13066     reference operator*() const
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:
13089             case value_t::number_integer:
13090             case value_t::number_unsigned:
13091             case value_t::number_float:
13092             case value_t::binary:
13093             case value_t::discarded:
13094             default:
13095             {
13096                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13097                 {
13098                     return *m_object;
13099                 }
13100 
13101                 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13102             }
13103         }
13104     }
13105 
13106     /*!
13107     @brief dereference the iterator
13108     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13109     */
13110     pointer operator->() const
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:
13131             case value_t::number_integer:
13132             case value_t::number_unsigned:
13133             case value_t::number_float:
13134             case value_t::binary:
13135             case value_t::discarded:
13136             default:
13137             {
13138                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13139                 {
13140                     return m_object;
13141                 }
13142 
13143                 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13144             }
13145         }
13146     }
13147 
13148     /*!
13149     @brief post-increment (it++)
13150     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13151     */
13152     iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
13153     {
13154         auto result = *this;
13155         ++(*this);
13156         return result;
13157     }
13158 
13159     /*!
13160     @brief pre-increment (++it)
13161     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13162     */
13163     iter_impl& operator++()
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:
13184             case value_t::number_integer:
13185             case value_t::number_unsigned:
13186             case value_t::number_float:
13187             case value_t::binary:
13188             case value_t::discarded:
13189             default:
13190             {
13191                 ++m_it.primitive_iterator;
13192                 break;
13193             }
13194         }
13195 
13196         return *this;
13197     }
13198 
13199     /*!
13200     @brief post-decrement (it--)
13201     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13202     */
13203     iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
13204     {
13205         auto result = *this;
13206         --(*this);
13207         return result;
13208     }
13209 
13210     /*!
13211     @brief pre-decrement (--it)
13212     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13213     */
13214     iter_impl& operator--()
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:
13235             case value_t::number_integer:
13236             case value_t::number_unsigned:
13237             case value_t::number_float:
13238             case value_t::binary:
13239             case value_t::discarded:
13240             default:
13241             {
13242                 --m_it.primitive_iterator;
13243                 break;
13244             }
13245         }
13246 
13247         return *this;
13248     }
13249 
13250     /*!
13251     @brief comparison: equal
13252     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13253     */
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:
13276             case value_t::number_integer:
13277             case value_t::number_unsigned:
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 
13286     /*!
13287     @brief comparison: not equal
13288     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13289     */
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 
13296     /*!
13297     @brief comparison: smaller
13298     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13299     */
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:
13321             case value_t::number_integer:
13322             case value_t::number_unsigned:
13323             case value_t::number_float:
13324             case value_t::binary:
13325             case value_t::discarded:
13326             default:
13327                 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
13328         }
13329     }
13330 
13331     /*!
13332     @brief comparison: less than or equal
13333     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13334     */
13335     bool operator<=(const iter_impl& other) const
13336     {
13337         return !other.operator < (*this);
13338     }
13339 
13340     /*!
13341     @brief comparison: greater than
13342     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13343     */
13344     bool operator>(const iter_impl& other) const
13345     {
13346         return !operator<=(other);
13347     }
13348 
13349     /*!
13350     @brief comparison: greater than or equal
13351     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13352     */
13353     bool operator>=(const iter_impl& other) const
13354     {
13355         return !operator<(other);
13356     }
13357 
13358     /*!
13359     @brief add to iterator
13360     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13361     */
13362     iter_impl& operator+=(difference_type i)
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:
13380             case value_t::number_integer:
13381             case value_t::number_unsigned:
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 
13395     /*!
13396     @brief subtract from iterator
13397     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13398     */
13399     iter_impl& operator-=(difference_type i)
13400     {
13401         return operator+=(-i);
13402     }
13403 
13404     /*!
13405     @brief add to iterator
13406     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13407     */
13408     iter_impl operator+(difference_type i) const
13409     {
13410         auto result = *this;
13411         result += i;
13412         return result;
13413     }
13414 
13415     /*!
13416     @brief addition of distance and iterator
13417     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13418     */
13419     friend iter_impl operator+(difference_type i, const iter_impl& it)
13420     {
13421         auto result = it;
13422         result += i;
13423         return result;
13424     }
13425 
13426     /*!
13427     @brief subtract from iterator
13428     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13429     */
13430     iter_impl operator-(difference_type i) const
13431     {
13432         auto result = *this;
13433         result -= i;
13434         return result;
13435     }
13436 
13437     /*!
13438     @brief return difference
13439     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13440     */
13441     difference_type operator-(const iter_impl& other) const
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:
13456             case value_t::number_integer:
13457             case value_t::number_unsigned:
13458             case value_t::number_float:
13459             case value_t::binary:
13460             case value_t::discarded:
13461             default:
13462                 return m_it.primitive_iterator - other.m_it.primitive_iterator;
13463         }
13464     }
13465 
13466     /*!
13467     @brief access to successor
13468     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13469     */
13470     reference operator[](difference_type n) const
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:
13487             case value_t::number_integer:
13488             case value_t::number_unsigned:
13489             case value_t::number_float:
13490             case value_t::binary:
13491             case value_t::discarded:
13492             default:
13493             {
13494                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
13495                 {
13496                     return *m_object;
13497                 }
13498 
13499                 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13500             }
13501         }
13502     }
13503 
13504     /*!
13505     @brief return the key of an object iterator
13506     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13507     */
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 
13520     /*!
13521     @brief return the value of an iterator
13522     @pre The iterator is initialized; i.e. `m_object != nullptr`.
13523     */
13524     reference value() const
13525     {
13526         return operator*();
13527     }
13528 
13529   JSON_PRIVATE_UNLESS_TESTED:
13530     /// associated JSON instance
13531     pointer m_object = nullptr;
13532     /// the actual iterator of the associated instance
13533     internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
13534 };
13535 
13536 }  // namespace detail
13537 NLOHMANN_JSON_NAMESPACE_END
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 
13559 NLOHMANN_JSON_NAMESPACE_BEGIN
13560 namespace detail
13561 {
13562 
13563 //////////////////////
13564 // reverse_iterator //
13565 //////////////////////
13566 
13567 /*!
13568 @brief a template for a reverse iterator class
13569 
13570 @tparam Base the base iterator type to reverse. Valid types are @ref
13571 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
13572 create @ref const_reverse_iterator).
13573 
13574 @requirement The class satisfies the following concept requirements:
13575 -
13576 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
13577   The iterator that can be moved can be moved in both directions (i.e.
13578   incremented and decremented).
13579 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
13580   It is possible to write to the pointed-to element (only if @a Base is
13581   @ref iterator).
13582 
13583 @since version 1.0.0
13584 */
13585 template<typename Base>
13586 class json_reverse_iterator : public std::reverse_iterator<Base>
13587 {
13588   public:
13589     using difference_type = std::ptrdiff_t;
13590     /// shortcut to the reverse iterator adapter
13591     using base_iterator = std::reverse_iterator<Base>;
13592     /// the reference type for the pointed-to element
13593     using reference = typename Base::reference;
13594 
13595     /// create reverse iterator from iterator
13596     explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
13597         : base_iterator(it) {}
13598 
13599     /// create reverse iterator from base class
13600     explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
13601 
13602     /// post-increment (it++)
13603     json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
13604     {
13605         return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
13606     }
13607 
13608     /// pre-increment (++it)
13609     json_reverse_iterator& operator++()
13610     {
13611         return static_cast<json_reverse_iterator&>(base_iterator::operator++());
13612     }
13613 
13614     /// post-decrement (it--)
13615     json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
13616     {
13617         return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
13618     }
13619 
13620     /// pre-decrement (--it)
13621     json_reverse_iterator& operator--()
13622     {
13623         return static_cast<json_reverse_iterator&>(base_iterator::operator--());
13624     }
13625 
13626     /// add to iterator
13627     json_reverse_iterator& operator+=(difference_type i)
13628     {
13629         return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
13630     }
13631 
13632     /// add to iterator
13633     json_reverse_iterator operator+(difference_type i) const
13634     {
13635         return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
13636     }
13637 
13638     /// subtract from iterator
13639     json_reverse_iterator operator-(difference_type i) const
13640     {
13641         return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
13642     }
13643 
13644     /// return difference
13645     difference_type operator-(const json_reverse_iterator& other) const
13646     {
13647         return base_iterator(*this) - base_iterator(other);
13648     }
13649 
13650     /// access to successor
13651     reference operator[](difference_type n) const
13652     {
13653         return *(this->operator+(n));
13654     }
13655 
13656     /// return the key of an object iterator
13657     auto key() const -> decltype(std::declval<Base>().key())
13658     {
13659         auto it = --this->base();
13660         return it.key();
13661     }
13662 
13663     /// return the value of an iterator
13664     reference value() const
13665     {
13666         auto it = --this->base();
13667         return it.operator * ();
13668     }
13669 };
13670 
13671 }  // namespace detail
13672 NLOHMANN_JSON_NAMESPACE_END
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 
13711 NLOHMANN_JSON_NAMESPACE_BEGIN
13712 
13713 /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
13714 /// @sa https://json.nlohmann.me/api/json_pointer/
13715 template<typename RefStringType>
13716 class json_pointer
13717 {
13718     // allow basic_json to access private members
13719     NLOHMANN_BASIC_JSON_TPL_DECLARATION
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 
13731     NLOHMANN_BASIC_JSON_TPL_DECLARATION
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 
13741     /// @brief create JSON pointer
13742     /// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/
13743     explicit json_pointer(const string_t& s = "")
13744         : reference_tokens(split(s))
13745     {}
13746 
13747     /// @brief return a string representation of the JSON pointer
13748     /// @sa https://json.nlohmann.me/api/json_pointer/to_string/
13749     string_t to_string() const
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 
13759     /// @brief return a string representation of the JSON pointer
13760     /// @sa https://json.nlohmann.me/api/json_pointer/operator_string/
13761     JSON_HEDLEY_DEPRECATED_FOR(3.11.0, to_string())
13762     operator string_t() const
13763     {
13764         return to_string();
13765     }
13766 
13767 #ifndef JSON_NO_IO
13768     /// @brief write string representation of the JSON pointer to stream
13769     /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/
13770     friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
13771     {
13772         o << ptr.to_string();
13773         return o;
13774     }
13775 #endif
13776 
13777     /// @brief append another JSON pointer at the end of this JSON pointer
13778     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
13779     json_pointer& operator/=(const json_pointer& ptr)
13780     {
13781         reference_tokens.insert(reference_tokens.end(),
13782                                 ptr.reference_tokens.begin(),
13783                                 ptr.reference_tokens.end());
13784         return *this;
13785     }
13786 
13787     /// @brief append an unescaped reference token at the end of this JSON pointer
13788     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
13789     json_pointer& operator/=(string_t token)
13790     {
13791         push_back(std::move(token));
13792         return *this;
13793     }
13794 
13795     /// @brief append an array index at the end of this JSON pointer
13796     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
13797     json_pointer& operator/=(std::size_t array_idx)
13798     {
13799         return *this /= std::to_string(array_idx);
13800     }
13801 
13802     /// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
13803     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
13804     friend json_pointer operator/(const json_pointer& lhs,
13805                                   const json_pointer& rhs)
13806     {
13807         return json_pointer(lhs) /= rhs;
13808     }
13809 
13810     /// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
13811     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
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 
13817     /// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
13818     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
13819     friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13820     {
13821         return json_pointer(lhs) /= array_idx;
13822     }
13823 
13824     /// @brief returns the parent of this JSON pointer
13825     /// @sa https://json.nlohmann.me/api/json_pointer/parent_pointer/
13826     json_pointer parent_pointer() const
13827     {
13828         if (empty())
13829         {
13830             return *this;
13831         }
13832 
13833         json_pointer res = *this;
13834         res.pop_back();
13835         return res;
13836     }
13837 
13838     /// @brief remove last reference token
13839     /// @sa https://json.nlohmann.me/api/json_pointer/pop_back/
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 
13850     /// @brief return last reference token
13851     /// @sa https://json.nlohmann.me/api/json_pointer/back/
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 
13862     /// @brief append an unescaped token at the end of the reference pointer
13863     /// @sa https://json.nlohmann.me/api/json_pointer/push_back/
13864     void push_back(const string_t& token)
13865     {
13866         reference_tokens.push_back(token);
13867     }
13868 
13869     /// @brief append an unescaped token at the end of the reference pointer
13870     /// @sa https://json.nlohmann.me/api/json_pointer/push_back/
13871     void push_back(string_t&& token)
13872     {
13873         reference_tokens.push_back(std::move(token));
13874     }
13875 
13876     /// @brief return whether pointer points to the root document
13877     /// @sa https://json.nlohmann.me/api/json_pointer/empty/
13878     bool empty() const noexcept
13879     {
13880         return reference_tokens.empty();
13881     }
13882 
13883   private:
13884     /*!
13885     @param[in] s  reference token to be converted into an array index
13886 
13887     @return integer representation of @a s
13888 
13889     @throw parse_error.106  if an array index begins with '0'
13890     @throw parse_error.109  if an array index begins not with a digit
13891     @throw out_of_range.404 if string @a s could not be converted to an integer
13892     @throw out_of_range.410 if an array index exceeds size_type
13893     */
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 
13932   JSON_PRIVATE_UNLESS_TESTED:
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:
13946     /*!
13947     @brief create and return a reference to the pointed to value
13948 
13949     @complexity Linear in the number of reference tokens.
13950 
13951     @throw parse_error.109 if array index is not a number
13952     @throw type_error.313 if value cannot be unflattened
13953     */
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 
13980                 case detail::value_t::object:
13981                 {
13982                     // create an entry in the object
13983                     result = &result->operator[](reference_token);
13984                     break;
13985                 }
13986 
13987                 case detail::value_t::array:
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                 */
14000                 case detail::value_t::string:
14001                 case detail::value_t::boolean:
14002                 case detail::value_t::number_integer:
14003                 case detail::value_t::number_unsigned:
14004                 case detail::value_t::number_float:
14005                 case detail::value_t::binary:
14006                 case detail::value_t::discarded:
14007                 default:
14008                     JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
14009             }
14010         }
14011 
14012         return *result;
14013     }
14014 
14015     /*!
14016     @brief return a reference to the pointed to value
14017 
14018     @note This version does not throw if a value is not present, but tries to
14019           create nested values instead. For instance, calling this function
14020           with pointer `"/this/that"` on a null value is equivalent to calling
14021           `operator[]("this").operator[]("that")` on that value, effectively
14022           changing the null value to an object.
14023 
14024     @param[in] ptr  a JSON value
14025 
14026     @return reference to the JSON value pointed to by the JSON pointer
14027 
14028     @complexity Linear in the length of the JSON pointer.
14029 
14030     @throw parse_error.106   if an array index begins with '0'
14031     @throw parse_error.109   if an array index was not a number
14032     @throw out_of_range.404  if the JSON pointer can not be resolved
14033     */
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 == "-")
14052                        ? detail::value_t::array
14053                        : detail::value_t::object;
14054             }
14055 
14056             switch (ptr->type())
14057             {
14058                 case detail::value_t::object:
14059                 {
14060                     // use unchecked object access
14061                     ptr = &ptr->operator[](reference_token);
14062                     break;
14063                 }
14064 
14065                 case detail::value_t::array:
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:
14081                 case detail::value_t::string:
14082                 case detail::value_t::boolean:
14083                 case detail::value_t::number_integer:
14084                 case detail::value_t::number_unsigned:
14085                 case detail::value_t::number_float:
14086                 case detail::value_t::binary:
14087                 case detail::value_t::discarded:
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 
14096     /*!
14097     @throw parse_error.106   if an array index begins with '0'
14098     @throw parse_error.109   if an array index was not a number
14099     @throw out_of_range.402  if the array index '-' is used
14100     @throw out_of_range.404  if the JSON pointer can not be resolved
14101     */
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             {
14109                 case detail::value_t::object:
14110                 {
14111                     // note: at performs range check
14112                     ptr = &ptr->at(reference_token);
14113                     break;
14114                 }
14115 
14116                 case detail::value_t::array:
14117                 {
14118                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14119                     {
14120                         // "-" always fails the range check
14121                         JSON_THROW(detail::out_of_range::create(402, detail::concat(
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:
14132                 case detail::value_t::string:
14133                 case detail::value_t::boolean:
14134                 case detail::value_t::number_integer:
14135                 case detail::value_t::number_unsigned:
14136                 case detail::value_t::number_float:
14137                 case detail::value_t::binary:
14138                 case detail::value_t::discarded:
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 
14147     /*!
14148     @brief return a const reference to the pointed to value
14149 
14150     @param[in] ptr  a JSON value
14151 
14152     @return const reference to the JSON value pointed to by the JSON
14153     pointer
14154 
14155     @throw parse_error.106   if an array index begins with '0'
14156     @throw parse_error.109   if an array index was not a number
14157     @throw out_of_range.402  if the array index '-' is used
14158     @throw out_of_range.404  if the JSON pointer can not be resolved
14159     */
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             {
14167                 case detail::value_t::object:
14168                 {
14169                     // use unchecked object access
14170                     ptr = &ptr->operator[](reference_token);
14171                     break;
14172                 }
14173 
14174                 case detail::value_t::array:
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:
14188                 case detail::value_t::string:
14189                 case detail::value_t::boolean:
14190                 case detail::value_t::number_integer:
14191                 case detail::value_t::number_unsigned:
14192                 case detail::value_t::number_float:
14193                 case detail::value_t::binary:
14194                 case detail::value_t::discarded:
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 
14203     /*!
14204     @throw parse_error.106   if an array index begins with '0'
14205     @throw parse_error.109   if an array index was not a number
14206     @throw out_of_range.402  if the array index '-' is used
14207     @throw out_of_range.404  if the JSON pointer can not be resolved
14208     */
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             {
14216                 case detail::value_t::object:
14217                 {
14218                     // note: at performs range check
14219                     ptr = &ptr->at(reference_token);
14220                     break;
14221                 }
14222 
14223                 case detail::value_t::array:
14224                 {
14225                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14226                     {
14227                         // "-" always fails the range check
14228                         JSON_THROW(detail::out_of_range::create(402, detail::concat(
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:
14239                 case detail::value_t::string:
14240                 case detail::value_t::boolean:
14241                 case detail::value_t::number_integer:
14242                 case detail::value_t::number_unsigned:
14243                 case detail::value_t::number_float:
14244                 case detail::value_t::binary:
14245                 case detail::value_t::discarded:
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 
14254     /*!
14255     @throw parse_error.106   if an array index begins with '0'
14256     @throw parse_error.109   if an array index was not a number
14257     */
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             {
14265                 case detail::value_t::object:
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 
14277                 case detail::value_t::array:
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:
14318                 case detail::value_t::string:
14319                 case detail::value_t::boolean:
14320                 case detail::value_t::number_integer:
14321                 case detail::value_t::number_unsigned:
14322                 case detail::value_t::number_float:
14323                 case detail::value_t::binary:
14324                 case detail::value_t::discarded:
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 
14338     /*!
14339     @brief split the string input to reference tokens
14340 
14341     @note This function is only called by the json_pointer constructor.
14342           All exceptions below are documented there.
14343 
14344     @throw parse_error.107  if the pointer is not empty or begins with '/'
14345     @throw parse_error.108  if character '~' is not followed by '0' or '1'
14346     */
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:
14408     /*!
14409     @param[in] reference_string  the reference string to the current value
14410     @param[in] value             the value to consider
14411     @param[in,out] result        the result object to insert values to
14412 
14413     @note Empty objects or arrays are flattened to `null`.
14414     */
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         {
14422             case detail::value_t::array:
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 
14441             case detail::value_t::object:
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:
14460             case detail::value_t::string:
14461             case detail::value_t::boolean:
14462             case detail::value_t::number_integer:
14463             case detail::value_t::number_unsigned:
14464             case detail::value_t::number_float:
14465             case detail::value_t::binary:
14466             case detail::value_t::discarded:
14467             default:
14468             {
14469                 // add primitive value with its reference string
14470                 result[reference_string] = value;
14471                 break;
14472             }
14473         }
14474     }
14475 
14476     /*!
14477     @param[in] value  flattened JSON
14478 
14479     @return unflattened JSON
14480 
14481     @throw parse_error.109 if array index is not a number
14482     @throw type_error.314  if value is not an object
14483     @throw type_error.315  if object values are not primitive
14484     @throw type_error.313  if value cannot be unflattened
14485     */
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     /// @brief compares two JSON pointers for equality
14533     /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
14534     template<typename RefStringTypeRhs>
14535     bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept
14536     {
14537         return reference_tokens == rhs.reference_tokens;
14538     }
14539 
14540     /// @brief compares JSON pointer and string for equality
14541     /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
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 
14548     /// @brief 3-way compares two JSON pointers
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     /// @brief compares two JSON pointers for equality
14556     /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
14557     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 
14562     /// @brief compares JSON pointer and string for equality
14563     /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
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 
14569     /// @brief compares string and JSON pointer for equality
14570     /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
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 
14576     /// @brief compares two JSON pointers for inequality
14577     /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
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 
14583     /// @brief compares JSON pointer and string for inequality
14584     /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
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 
14590     /// @brief compares string and JSON pointer for inequality
14591     /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
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 
14597     /// @brief compares two JSON pointer for less-than
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:
14605     /// the reference tokens
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>
14612 inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
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>
14620 JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))
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>
14629 JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))
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>
14637 inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
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>
14645 JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))
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>
14654 JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))
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>
14662 inline bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
14663                       const json_pointer<RefStringTypeRhs>& rhs) noexcept
14664 {
14665     return lhs.reference_tokens < rhs.reference_tokens;
14666 }
14667 #endif
14668 
14669 NLOHMANN_JSON_NAMESPACE_END
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 
14690 NLOHMANN_JSON_NAMESPACE_BEGIN
14691 namespace detail
14692 {
14693 
14694 template<typename BasicJsonType>
14695 class json_ref
14696 {
14697   public:
14698     using value_type = BasicJsonType;
14699 
14700     json_ref(value_type&& value)
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 
14726     value_type moved_or_copied() const
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
14751 NLOHMANN_JSON_NAMESPACE_END
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 
14815 NLOHMANN_JSON_NAMESPACE_BEGIN
14816 namespace detail
14817 {
14818 
14819 /// abstract output adapter interface
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;
14827     output_adapter_protocol(const 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 
14833 /// a type to simplify interfaces
14834 template<typename CharType>
14835 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
14836 
14837 /// output adapter for byte vectors
14838 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
14839 class output_vector_adapter : public output_adapter_protocol<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 
14851     JSON_HEDLEY_NON_NULL(2)
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 /// output adapter for output streams
14863 template<typename CharType>
14864 class output_stream_adapter : public output_adapter_protocol<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 
14876     JSON_HEDLEY_NON_NULL(2)
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 
14887 /// output adapter for basic_string
14888 template<typename CharType, typename StringType = std::basic_string<CharType>>
14889 class output_string_adapter : public output_adapter_protocol<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 
14901     JSON_HEDLEY_NON_NULL(2)
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>>
14912 class output_adapter
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 
14927     operator output_adapter_t<CharType>()
14928     {
14929         return oa;
14930     }
14931 
14932   private:
14933     output_adapter_t<CharType> oa = nullptr;
14934 };
14935 
14936 }  // namespace detail
14937 NLOHMANN_JSON_NAMESPACE_END
14938 
14939 // #include <nlohmann/detail/string_concat.hpp>
14940 
14941 
14942 NLOHMANN_JSON_NAMESPACE_BEGIN
14943 namespace detail
14944 {
14945 
14946 ///////////////////
14947 // binary writer //
14948 ///////////////////
14949 
14950 /*!
14951 @brief serialization to CBOR and MessagePack values
14952 */
14953 template<typename BasicJsonType, typename CharType>
14954 class binary_writer
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:
14961     /*!
14962     @brief create a binary writer
14963 
14964     @param[in] adapter  output adapter to write to
14965     */
14966     explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
14967     {
14968         JSON_ASSERT(oa);
14969     }
14970 
14971     /*!
14972     @param[in] j  JSON value to serialize
14973     @pre       j.type() == value_t::object
14974     */
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:
14989             case value_t::number_integer:
14990             case value_t::number_unsigned:
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 
15001     /*!
15002     @param[in] j  JSON value to serialize
15003     */
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 
15022             case value_t::number_integer:
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 
15087             case value_t::number_unsigned:
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 
15325     /*!
15326     @param[in] j  JSON value to serialize
15327     */
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 
15346             case value_t::number_integer:
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 
15422             case value_t::number_unsigned:
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 
15647     /*!
15648     @param[in] j  JSON value to serialize
15649     @param[in] use_count   whether to use '#' prefixes (optimized format)
15650     @param[in] use_type    whether to use '$' prefixes (optimized format)
15651     @param[in] add_prefix  whether prefixes need to be used for this value
15652     @param[in] use_bjdata  whether write in BJData format, default is false
15653     */
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 
15680             case value_t::number_integer:
15681             {
15682                 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata);
15683                 break;
15684             }
15685 
15686             case value_t::number_unsigned:
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:
15867     //////////
15868     // BSON //
15869     //////////
15870 
15871     /*!
15872     @return The size of a BSON document entry header, including the id marker
15873             and the entry name size (and its null-terminator).
15874     */
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 
15887     /*!
15888     @brief Writes the given @a element_type and @a name to the output adapter
15889     */
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 
15899     /*!
15900     @brief Writes a BSON element with key @a name and boolean value @a value
15901     */
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 
15909     /*!
15910     @brief Writes a BSON element with key @a name and double value @a value
15911     */
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 
15919     /*!
15920     @return The size of the BSON-encoded string in @a value
15921     */
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 
15927     /*!
15928     @brief Writes a BSON element with key @a name and string value @a value
15929     */
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 
15941     /*!
15942     @brief Writes a BSON element with key @a name and null value
15943     */
15944     void write_bson_null(const string_t& name)
15945     {
15946         write_bson_entry_header(name, 0x0A);
15947     }
15948 
15949     /*!
15950     @return The size of the BSON-encoded integer @a value
15951     */
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 
15959     /*!
15960     @brief Writes a BSON element with key @a name and integer @a value
15961     */
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 
15977     /*!
15978     @return The size of the BSON-encoded unsigned integer in @a j
15979     */
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 
15987     /*!
15988     @brief Writes a BSON element with key @a name and unsigned @a value
15989     */
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 
16009     /*!
16010     @brief Writes a BSON element with key @a name and object @a value
16011     */
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 
16019     /*!
16020     @return The size of the BSON-encoded array @a value
16021     */
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 
16034     /*!
16035     @return The size of the BSON-encoded binary array @a value
16036     */
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 
16042     /*!
16043     @brief Writes a BSON element with key @a name and array @a value
16044     */
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 
16061     /*!
16062     @brief Writes a BSON element with key @a name and binary value @a value
16063     */
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 
16075     /*!
16076     @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
16077     @return The calculated size for the BSON document entry for @a j with the given @a name.
16078     */
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 
16100             case value_t::number_integer:
16101                 return header_size + calc_bson_integer_size(j.m_value.number_integer);
16102 
16103             case value_t::number_unsigned:
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 
16121     /*!
16122     @brief Serializes the JSON value @a j to BSON and associates it with the
16123            key @a name.
16124     @param name The name to associate with the JSON entity @a j within the
16125                 current BSON document
16126     */
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 
16147             case value_t::number_integer:
16148                 return write_bson_integer(name, j.m_value.number_integer);
16149 
16150             case value_t::number_unsigned:
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 
16168     /*!
16169     @brief Calculates the size of the BSON serialization of the given
16170            JSON-object @a j.
16171     @param[in] value  JSON value to serialize
16172     @pre       value.type() == value_t::object
16173     */
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 
16185     /*!
16186     @param[in] value  JSON value to serialize
16187     @pre       value.type() == value_t::object
16188     */
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 
16201     //////////
16202     // CBOR //
16203     //////////
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 
16215     /////////////
16216     // MsgPack //
16217     /////////////
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 
16229     ////////////
16230     // UBJSON //
16231     ////////////
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 
16416     /*!
16417     @brief determine the type prefix of container values
16418     */
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 
16429             case value_t::number_integer:
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 
16463             case value_t::number_unsigned:
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 
16530     /*!
16531     @return false if the object is successfully converted to a bjdata ndarray, true if the type or size is invalid
16532     */
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 
16642     ///////////////////////
16643     // Utility functions //
16644     ///////////////////////
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,
16727              enable_if_t<std::is_unsigned<C>::value>* = nullptr>
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 &&
16737                    std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
16738                    > * = nullptr >
16739     static constexpr CharType to_char_type(InputCharType x) noexcept
16740     {
16741         return x;
16742     }
16743 
16744   private:
16745     /// whether we can assume little endianness
16746     const bool is_little_endian = little_endianness();
16747 
16748     /// the output
16749     output_adapter_t<CharType> oa = nullptr;
16750 };
16751 
16752 }  // namespace detail
16753 NLOHMANN_JSON_NAMESPACE_END
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 
16804 NLOHMANN_JSON_NAMESPACE_BEGIN
16805 namespace detail
16806 {
16807 
16808 /*!
16809 @brief implements the Grisu2 algorithm for binary to decimal floating-point
16810 conversion.
16811 
16812 This implementation is a slightly modified version of the reference
16813 implementation which may be obtained from
16814 http://florian.loitsch.com/publications (bench.tar.gz).
16815 
16816 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
16817 
16818 For a detailed description of the algorithm see:
16819 
16820 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
16821     Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
16822     Language Design and Implementation, PLDI 2010
16823 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
16824     Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
16825     Design and Implementation, PLDI 1996
16826 */
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 
16849     /*!
16850     @brief returns x - y
16851     @pre x.e == y.e and x.f >= y.f
16852     */
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 
16861     /*!
16862     @brief returns x * y
16863     @note The result is rounded. (Only the upper q bits are returned.)
16864     */
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 
16926     /*!
16927     @brief normalize x such that the significand is >= 2^(q-1)
16928     @pre x.f != 0
16929     */
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 
16943     /*!
16944     @brief normalize x such that the result has the exponent E
16945     @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
16946     */
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 
16958 struct boundaries
16959 {
16960     diyfp w;
16961     diyfp minus;
16962     diyfp plus;
16963 };
16964 
16965 /*!
16966 Compute the (normalized) diyfp representing the input number 'value' and its
16967 boundaries.
16968 
16969 @pre value must be finite and positive
16970 */
16971 template<typename FloatType>
16972 boundaries compute_boundaries(FloatType value)
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 
16992     using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
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 
17104 /*!
17105 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
17106 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
17107 satisfies (Definition 3.2 from [1])
17108 
17109      alpha <= e_c + e + q <= gamma.
17110 */
17111 inline cached_power get_cached_power_for_binary_exponent(int e)
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 
17271 /*!
17272 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
17273 For n == 0, returns 1 and sets pow10 := 1.
17274 */
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 
17366 /*!
17367 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
17368 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
17369 */
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 
17605 /*!
17606 v = buf * 10^decimal_exponent
17607 len is the length of the buffer (number of decimal digits)
17608 The buffer must be large enough, i.e. >= max_digits10.
17609 */
17610 JSON_HEDLEY_NON_NULL(1)
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 
17664 /*!
17665 v = buf * 10^decimal_exponent
17666 len is the length of the buffer (number of decimal digits)
17667 The buffer must be large enough, i.e. >= max_digits10.
17668 */
17669 template<typename FloatType>
17670 JSON_HEDLEY_NON_NULL(1)
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 
17704 /*!
17705 @brief appends a decimal representation of e to buf
17706 @return a pointer to the element following the exponent.
17707 @pre -1000 < e < 1000
17708 */
17709 JSON_HEDLEY_NON_NULL(1)
17710 JSON_HEDLEY_RETURNS_NON_NULL
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 
17752 /*!
17753 @brief prettify v = buf * 10^decimal_exponent
17754 
17755 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
17756 notation. Otherwise it will be printed in exponential notation.
17757 
17758 @pre min_exp < 0
17759 @pre max_exp > 0
17760 */
17761 JSON_HEDLEY_NON_NULL(1)
17762 JSON_HEDLEY_RETURNS_NON_NULL
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 
17835 /*!
17836 @brief generates a decimal representation of the floating-point number value in [first, last).
17837 
17838 The format of the resulting decimal representation is similar to printf's %g
17839 format. Returns an iterator pointing past-the-end of the decimal representation.
17840 
17841 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
17842 @note The buffer must be large enough.
17843 @note The result is NOT null-terminated.
17844 */
17845 template<typename FloatType>
17846 JSON_HEDLEY_NON_NULL(1, 2)
17847 JSON_HEDLEY_RETURNS_NON_NULL
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
17901 NLOHMANN_JSON_NAMESPACE_END
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 
17918 NLOHMANN_JSON_NAMESPACE_BEGIN
17919 namespace detail
17920 {
17921 
17922 ///////////////////
17923 // serialization //
17924 ///////////////////
17925 
17926 /// how to treat decoding errors
17927 enum class error_handler_t
17928 {
17929     strict,  ///< throw a type_error exception in case of invalid UTF-8
17930     replace, ///< replace invalid UTF-8 sequences with U+FFFD
17931     ignore   ///< ignore invalid UTF-8 sequences
17932 };
17933 
17934 template<typename BasicJsonType>
17935 class serializer
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:
17946     /*!
17947     @param[in] s  output stream to serialize to
17948     @param[in] ichar  indentation character to use
17949     @param[in] error_handler_  how to react on decoding errors
17950     */
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 
17969     /*!
17970     @brief internal implementation of the serialization function
17971 
17972     This function is called by the public member function dump and organizes
17973     the serialization internally. The indentation level is propagated as
17974     additional parameter. In case of arrays and objects, the function is
17975     called recursively.
17976 
17977     - strings and object keys are escaped using `escape_string()`
17978     - integer numbers are converted implicitly via `operator<<`
17979     - floating-point numbers are converted to a string using `"%g"` format
17980     - binary values are serialized as objects containing the subtype and the
17981       byte array
17982 
17983     @param[in] val               value to serialize
17984     @param[in] pretty_print      whether the output shall be pretty-printed
17985     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
17986     in the output are escaped with `\uXXXX` sequences, and the result consists
17987     of ASCII characters only.
17988     @param[in] indent_step       the indent level
17989     @param[in] current_indent    the current indent level (only used internally)
17990     */
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 
18225             case value_t::number_integer:
18226             {
18227                 dump_integer(val.m_value.number_integer);
18228                 return;
18229             }
18230 
18231             case value_t::number_unsigned:
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 
18260   JSON_PRIVATE_UNLESS_TESTED:
18261     /*!
18262     @brief dump escaped string
18263 
18264     Escape a string by replacing certain special characters by a sequence of an
18265     escape character (backslash) and another character and other control
18266     characters by a sequence of "\u" followed by a four-digit hex
18267     representation. The escaped string is written to output stream @a o.
18268 
18269     @param[in] s  the string to escape
18270     @param[in] ensure_ascii  whether to escape non-ASCII characters with
18271                              \uXXXX sequences
18272 
18273     @complexity Linear in the length of string @a s.
18274     */
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
18386                     bytes_after_last_accept = bytes;
18387                     undumped_chars = 0;
18388                     break;
18389                 }
18390 
18391                 case UTF8_REJECT:  // decode found invalid UTF-8 byte
18392                 {
18393                     switch (error_handler)
18394                     {
18395                         case error_handler_t::strict:
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 
18400                         case error_handler_t::ignore:
18401                         case error_handler_t::replace:
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
18414                             bytes = bytes_after_last_accept;
18415 
18416                             if (error_handler == error_handler_t::replace)
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                                 {
18430                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
18431                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
18432                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
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 
18444                                 bytes_after_last_accept = bytes;
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             {
18487                 case error_handler_t::strict:
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 
18492                 case error_handler_t::ignore:
18493                 {
18494                     // write all accepted bytes
18495                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
18496                     break;
18497                 }
18498 
18499                 case error_handler_t::replace:
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:
18522     /*!
18523     @brief count digits
18524 
18525     Count the number of decimal (base 10) digits for an input unsigned integer.
18526 
18527     @param[in] x  unsigned integer number to count its digits
18528     @return    number of decimal digits
18529     */
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 
18556     /*!
18557      * @brief convert a byte to a uppercase hex representation
18558      * @param[in] byte byte to represent
18559      * @return representation ("00".."FF")
18560      */
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 
18583     /*!
18584     @brief dump an integer
18585 
18586     Dump a given integer to output stream @a o. Works internally with
18587     @a number_buffer.
18588 
18589     @param[in] x  integer number (signed or unsigned) to dump
18590     @tparam NumberType either @a number_integer_t or @a number_unsigned_t
18591     */
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 
18675     /*!
18676     @brief dump a floating-point number
18677 
18678     Dump a given floating-point number to output stream @a o. Works internally
18679     with @a number_buffer.
18680 
18681     @param[in] x  floating-point number to dump
18682     */
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 
18763     /*!
18764     @brief check whether a string is UTF-8 encoded
18765 
18766     The function checks each byte of a string whether it is UTF-8 encoded. The
18767     result of the check is stored in the @a state parameter. The function must
18768     be called initially with state 0 (accept). State 1 means the string must
18769     be rejected, because the current byte is not allowed. If the string is
18770     completely processed, but the state is non-zero, the string ended
18771     prematurely; that is, the last byte indicated more bytes should have
18772     followed.
18773 
18774     @param[in,out] state  the state of the decoding
18775     @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)
18776     @param[in] byte       next byte to decode
18777     @return               new state
18778 
18779     @note The function has been edited: a std::array is used.
18780 
18781     @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
18782     @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
18783     */
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:
18846     /// the output of the serializer
18847     output_adapter_t<char> o = nullptr;
18848 
18849     /// a (hopefully) large enough character buffer
18850     std::array<char, 64> number_buffer{{}};
18851 
18852     /// the locale
18853     const std::lconv* loc = nullptr;
18854     /// the locale's thousand separator character
18855     const char thousands_sep = '\0';
18856     /// the locale's decimal point character
18857     const char decimal_point = '\0';
18858 
18859     /// string buffer
18860     std::array<char, 512> string_buffer{{}};
18861 
18862     /// the indentation character
18863     const char indent_char;
18864     /// the indentation string
18865     string_t indent_string;
18866 
18867     /// error_handler how to react on decoding errors
18868     const error_handler_t error_handler;
18869 };
18870 
18871 }  // namespace detail
18872 NLOHMANN_JSON_NAMESPACE_END
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 
18903 NLOHMANN_JSON_NAMESPACE_BEGIN
18904 
18905 /// ordered_map: a minimal map-like container that preserves insertion order
18906 /// for use within nlohmann::basic_json<ordered_map>
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<
18948                  detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
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<
18968                  detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
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<
18980                  detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
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<
19000                  detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
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<
19028                  detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
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 
19042     size_type erase(const key_type& key)
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<
19062                  detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
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 
19082     iterator erase(iterator pos)
19083     {
19084         return erase(pos, std::next(pos));
19085     }
19086 
19087     iterator erase(iterator first, iterator last)
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<
19153                  detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
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<
19179                  detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
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:
19236     JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();
19237 };
19238 
19239 NLOHMANN_JSON_NAMESPACE_END
19240 
19241 
19242 #if defined(JSON_HAS_CPP_17)
19243     #include <any>
19244     #include <string_view>
19245 #endif
19246 
19247 /*!
19248 @brief namespace for Niels Lohmann
19249 @see https://github.com/nlohmann
19250 @since version 1.0.0
19251 */
19252 NLOHMANN_JSON_NAMESPACE_BEGIN
19253 
19254 /*!
19255 @brief a class to store JSON values
19256 
19257 @internal
19258 @invariant The member variables @a m_value and @a m_type have the following
19259 relationship:
19260 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
19261 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
19262 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
19263 The invariants are checked by member function assert_invariant().
19264 
19265 @note ObjectType trick from https://stackoverflow.com/a/9860911
19266 @endinternal
19267 
19268 @since version 1.0.0
19269 
19270 @nosubgrouping
19271 */
19272 NLOHMANN_BASIC_JSON_TPL_DECLARATION
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 
19298     /// workaround type for MSVC
19299     using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
19300 
19301   JSON_PRIVATE_UNLESS_TESTED:
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,
19308         detail::parser_callback_t<basic_json>cb = nullptr,
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 
19334   JSON_PRIVATE_UNLESS_TESTED:
19335     using serializer = ::nlohmann::detail::serializer<basic_json>;
19336 
19337   public:
19338     using value_t = detail::value_t;
19339     /// JSON Pointer, see @ref nlohmann::json_pointer
19340     using json_pointer = ::nlohmann::json_pointer<StringType>;
19341     template<typename T, typename SFINAE>
19342     using json_serializer = JSONSerializer<T, SFINAE>;
19343     /// how to treat decoding errors
19344     using error_handler_t = detail::error_handler_t;
19345     /// how to treat CBOR tags
19346     using cbor_tag_handler_t = detail::cbor_tag_handler_t;
19347     /// helper type for initializer lists of basic_json values
19348     using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
19349 
19350     using input_format_t = detail::input_format_t;
19351     /// SAX interface type, see @ref nlohmann::json_sax
19352     using json_sax_t = json_sax<basic_json>;
19353 
19354     ////////////////
19355     // exceptions //
19356     ////////////////
19357 
19358     /// @name exceptions
19359     /// Classes to implement user-defined exceptions.
19360     /// @{
19361 
19362     using exception = detail::exception;
19363     using parse_error = detail::parse_error;
19364     using invalid_iterator = detail::invalid_iterator;
19365     using type_error = detail::type_error;
19366     using out_of_range = detail::out_of_range;
19367     using other_error = detail::other_error;
19368 
19369     /// @}
19370 
19371 
19372     /////////////////////
19373     // container types //
19374     /////////////////////
19375 
19376     /// @name container types
19377     /// The canonic container types to use @ref basic_json like any other STL
19378     /// container.
19379     /// @{
19380 
19381     /// the type of elements in a basic_json container
19382     using value_type = basic_json;
19383 
19384     /// the type of an element reference
19385     using reference = value_type&;
19386     /// the type of an element const reference
19387     using const_reference = const value_type&;
19388 
19389     /// a type to represent differences between iterators
19390     using difference_type = std::ptrdiff_t;
19391     /// a type to represent container sizes
19392     using size_type = std::size_t;
19393 
19394     /// the allocator type
19395     using allocator_type = AllocatorType<basic_json>;
19396 
19397     /// the type of an element pointer
19398     using pointer = typename std::allocator_traits<allocator_type>::pointer;
19399     /// the type of an element const pointer
19400     using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
19401 
19402     /// an iterator for a basic_json container
19403     using iterator = iter_impl<basic_json>;
19404     /// a const iterator for a basic_json container
19405     using const_iterator = iter_impl<const basic_json>;
19406     /// a reverse iterator for a basic_json container
19407     using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
19408     /// a const reverse iterator for a basic_json container
19409     using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
19410 
19411     /// @}
19412 
19413 
19414     /// @brief returns the allocator associated with the container
19415     /// @sa https://json.nlohmann.me/api/basic_json/get_allocator/
19416     static allocator_type get_allocator()
19417     {
19418         return allocator_type();
19419     }
19420 
19421     /// @brief returns version information on the library
19422     /// @sa https://json.nlohmann.me/api/basic_json/meta/
19423     JSON_HEDLEY_WARN_UNUSED_RESULT
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"] =
19432             detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR), '.',
19433                            std::to_string(NLOHMANN_JSON_VERSION_MINOR), '.',
19434                            std::to_string(NLOHMANN_JSON_VERSION_PATCH));
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 
19488     ///////////////////////////
19489     // JSON value data types //
19490     ///////////////////////////
19491 
19492     /// @name JSON value data types
19493     /// The data types to store a JSON value. These types are derived from
19494     /// the template arguments passed to class @ref basic_json.
19495     /// @{
19496 
19497     /// @brief default object key comparator type
19498     /// The actual object key comparator type (@ref object_comparator_t) may be
19499     /// different.
19500     /// @sa https://json.nlohmann.me/api/basic_json/default_object_comparator_t/
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 
19509     /// @brief a type for an object
19510     /// @sa https://json.nlohmann.me/api/basic_json/object_t/
19511     using object_t = ObjectType<StringType,
19512           basic_json,
19513           default_object_comparator_t,
19514           AllocatorType<std::pair<const StringType,
19515           basic_json>>>;
19516 
19517     /// @brief a type for an array
19518     /// @sa https://json.nlohmann.me/api/basic_json/array_t/
19519     using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
19520 
19521     /// @brief a type for a string
19522     /// @sa https://json.nlohmann.me/api/basic_json/string_t/
19523     using string_t = StringType;
19524 
19525     /// @brief a type for a boolean
19526     /// @sa https://json.nlohmann.me/api/basic_json/boolean_t/
19527     using boolean_t = BooleanType;
19528 
19529     /// @brief a type for a number (integer)
19530     /// @sa https://json.nlohmann.me/api/basic_json/number_integer_t/
19531     using number_integer_t = NumberIntegerType;
19532 
19533     /// @brief a type for a number (unsigned)
19534     /// @sa https://json.nlohmann.me/api/basic_json/number_unsigned_t/
19535     using number_unsigned_t = NumberUnsignedType;
19536 
19537     /// @brief a type for a number (floating-point)
19538     /// @sa https://json.nlohmann.me/api/basic_json/number_float_t/
19539     using number_float_t = NumberFloatType;
19540 
19541     /// @brief a type for a packed binary type
19542     /// @sa https://json.nlohmann.me/api/basic_json/binary_t/
19543     using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
19544 
19545     /// @brief object key comparator type
19546     /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/
19547     using object_comparator_t = detail::actual_object_comparator_t<basic_json>;
19548 
19549     /// @}
19550 
19551   private:
19552 
19553     /// helper for exception-safe object creation
19554     template<typename T, typename... Args>
19555     JSON_HEDLEY_RETURNS_NON_NULL
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 
19571     ////////////////////////
19572     // JSON value storage //
19573     ////////////////////////
19574 
19575   JSON_PRIVATE_UNLESS_TESTED:
19576     /*!
19577     @brief a JSON value
19578 
19579     The actual storage for a JSON value of the @ref basic_json class. This
19580     union combines the different storage types for the JSON value types
19581     defined in @ref value_t.
19582 
19583     JSON type | value_t type    | used type
19584     --------- | --------------- | ------------------------
19585     object    | object          | pointer to @ref object_t
19586     array     | array           | pointer to @ref array_t
19587     string    | string          | pointer to @ref string_t
19588     boolean   | boolean         | @ref boolean_t
19589     number    | number_integer  | @ref number_integer_t
19590     number    | number_unsigned | @ref number_unsigned_t
19591     number    | number_float    | @ref number_float_t
19592     binary    | binary          | pointer to @ref binary_t
19593     null      | null            | *no value is stored*
19594 
19595     @note Variable-length types (objects, arrays, and strings) are stored as
19596     pointers. The size of the union should not exceed 64 bits if the default
19597     value types are used.
19598 
19599     @since version 1.0.0
19600     */
19601     union json_value
19602     {
19603         /// object (stored with pointer to save storage)
19604         object_t* object;
19605         /// array (stored with pointer to save storage)
19606         array_t* array;
19607         /// string (stored with pointer to save storage)
19608         string_t* string;
19609         /// binary (stored with pointer to save storage)
19610         binary_t* binary;
19611         /// boolean
19612         boolean_t boolean;
19613         /// number (integer)
19614         number_integer_t number_integer;
19615         /// number (unsigned integer)
19616         number_unsigned_t number_unsigned;
19617         /// number (floating-point)
19618         number_float_t number_float;
19619 
19620         /// default constructor (for null values)
19621         json_value() = default;
19622         /// constructor for booleans
19623         json_value(boolean_t v) noexcept : boolean(v) {}
19624         /// constructor for numbers (integer)
19625         json_value(number_integer_t v) noexcept : number_integer(v) {}
19626         /// constructor for numbers (unsigned)
19627         json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
19628         /// constructor for numbers (floating-point)
19629         json_value(number_float_t v) noexcept : number_float(v) {}
19630         /// constructor for empty values of a given type
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 
19665                 case value_t::number_integer:
19666                 {
19667                     number_integer = static_cast<number_integer_t>(0);
19668                     break;
19669                 }
19670 
19671                 case value_t::number_unsigned:
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
19693                     if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
19694                     {
19695                         JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.2", nullptr)); // LCOV_EXCL_LINE
19696                     }
19697                     break;
19698                 }
19699             }
19700         }
19701 
19702         /// constructor for strings
19703         json_value(const string_t& value) : string(create<string_t>(value)) {}
19704 
19705         /// constructor for rvalue strings
19706         json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
19707 
19708         /// constructor for objects
19709         json_value(const object_t& value) : object(create<object_t>(value)) {}
19710 
19711         /// constructor for rvalue objects
19712         json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
19713 
19714         /// constructor for arrays
19715         json_value(const array_t& value) : array(create<array_t>(value)) {}
19716 
19717         /// constructor for rvalue arrays
19718         json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
19719 
19720         /// constructor for binary arrays
19721         json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
19722 
19723         /// constructor for rvalue binary arrays
19724         json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
19725 
19726         /// constructor for binary arrays (internal type)
19727         json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
19728 
19729         /// constructor for rvalue binary arrays (internal type)
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:
19819                 case value_t::number_integer:
19820                 case value_t::number_unsigned:
19821                 case value_t::number_float:
19822                 case value_t::discarded:
19823                 default:
19824                 {
19825                     break;
19826                 }
19827             }
19828         }
19829     };
19830 
19831   private:
19832     /*!
19833     @brief checks the class invariants
19834 
19835     This function asserts the class invariants. It needs to be called at the
19836     end of every constructor to make sure that created objects respect the
19837     invariant. Furthermore, it has to be called each time the type of a JSON
19838     value is changed, because the invariant expresses a relationship between
19839     @a m_type and @a m_value.
19840 
19841     Furthermore, the parent relation is checked for arrays and objects: If
19842     @a check_parents true and the value is an array or object, then the
19843     container's elements must have the current value as parent.
19844 
19845     @param[in] check_parents  whether the parent relation should be checked.
19846                The value is true by default and should only be set to false
19847                during destruction of objects when the invariant does not
19848                need to hold.
19849     */
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:
19897             case value_t::number_integer:
19898             case value_t::number_unsigned:
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
19927             JSON_ASSERT(type() == value_t::array);
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
19942         if (detail::is_ordered_map<object_t>::value)
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:
19960     //////////////////////////
19961     // JSON parser callback //
19962     //////////////////////////
19963 
19964     /// @brief parser event types
19965     /// @sa https://json.nlohmann.me/api/basic_json/parse_event_t/
19966     using parse_event_t = detail::parse_event_t;
19967 
19968     /// @brief per-element parser callback type
19969     /// @sa https://json.nlohmann.me/api/basic_json/parser_callback_t/
19970     using parser_callback_t = detail::parser_callback_t<basic_json>;
19971 
19972     //////////////////
19973     // constructors //
19974     //////////////////
19975 
19976     /// @name constructors and destructors
19977     /// Constructors of class @ref basic_json, copy/move constructor, copy
19978     /// assignment, static functions creating objects, and the destructor.
19979     /// @{
19980 
19981     /// @brief create an empty value with a given type
19982     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
19983     basic_json(const value_t v)
19984         : m_type(v), m_value(v)
19985     {
19986         assert_invariant();
19987     }
19988 
19989     /// @brief create a null object
19990     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
19991     basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
19992         : basic_json(value_t::null)
19993     {
19994         assert_invariant();
19995     }
19996 
19997     /// @brief create a JSON value from compatible types
19998     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
19999     template < typename CompatibleType,
20000                typename U = detail::uncvref_t<CompatibleType>,
20001                detail::enable_if_t <
20002                    !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
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 
20012     /// @brief create a JSON value from an existing one
20013     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
20014     template < typename BasicJsonType,
20015                detail::enable_if_t <
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;
20036             case value_t::number_integer:
20037                 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
20038                 break;
20039             case value_t::number_unsigned:
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 
20068     /// @brief create a container (array or object) from an initializer list
20069     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
20070     basic_json(initializer_list_t init,
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;
20102             m_value = 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 
20123     /// @brief explicitly create a binary array (without subtype)
20124     /// @sa https://json.nlohmann.me/api/basic_json/binary/
20125     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
20134     /// @brief explicitly create a binary array (with subtype)
20135     /// @sa https://json.nlohmann.me/api/basic_json/binary/
20136     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
20145     /// @brief explicitly create a binary array
20146     /// @sa https://json.nlohmann.me/api/basic_json/binary/
20147     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
20156     /// @brief explicitly create a binary array (with subtype)
20157     /// @sa https://json.nlohmann.me/api/basic_json/binary/
20158     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
20167     /// @brief explicitly create an array from an initializer list
20168     /// @sa https://json.nlohmann.me/api/basic_json/array/
20169     JSON_HEDLEY_WARN_UNUSED_RESULT
20170     static basic_json array(initializer_list_t init = {})
20171     {
20172         return basic_json(init, false, value_t::array);
20173     }
20174 
20175     /// @brief explicitly create an object from an initializer list
20176     /// @sa https://json.nlohmann.me/api/basic_json/object/
20177     JSON_HEDLEY_WARN_UNUSED_RESULT
20178     static basic_json object(initializer_list_t init = {})
20179     {
20180         return basic_json(init, false, value_t::object);
20181     }
20182 
20183     /// @brief construct an array with count copies of given value
20184     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
20185     basic_json(size_type cnt, const basic_json& val)
20186         : m_type(value_t::array)
20187     {
20188         m_value.array = create<array_t>(cnt, val);
20189         set_parents();
20190         assert_invariant();
20191     }
20192 
20193     /// @brief construct a JSON container given an iterator range
20194     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
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:
20217             case value_t::number_integer:
20218             case value_t::number_unsigned:
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         {
20240             case value_t::number_integer:
20241             {
20242                 m_value.number_integer = first.m_object->m_value.number_integer;
20243                 break;
20244             }
20245 
20246             case value_t::number_unsigned:
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 
20301     ///////////////////////////////////////
20302     // other constructors and destructor //
20303     ///////////////////////////////////////
20304 
20305     template<typename JsonRef,
20306              detail::enable_if_t<detail::conjunction<detail::is_json_ref<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 
20310     /// @brief copy constructor
20311     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
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 
20344             case value_t::number_integer:
20345             {
20346                 m_value = other.m_value.number_integer;
20347                 break;
20348             }
20349 
20350             case value_t::number_unsigned:
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 
20378     /// @brief move constructor
20379     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
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 
20395     /// @brief copy assignment
20396     /// @sa https://json.nlohmann.me/api/basic_json/operator=/
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 
20416     /// @brief destructor
20417     /// @sa https://json.nlohmann.me/api/basic_json/~basic_json/
20418     ~basic_json() noexcept
20419     {
20420         assert_invariant(false);
20421         m_value.destroy(m_type);
20422     }
20423 
20424     /// @}
20425 
20426   public:
20427     ///////////////////////
20428     // object inspection //
20429     ///////////////////////
20430 
20431     /// @name object inspection
20432     /// Functions to inspect the type of a JSON value.
20433     /// @{
20434 
20435     /// @brief serialization
20436     /// @sa https://json.nlohmann.me/api/basic_json/dump/
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 
20457     /// @brief return the type of the JSON value (explicit)
20458     /// @sa https://json.nlohmann.me/api/basic_json/type/
20459     constexpr value_t type() const noexcept
20460     {
20461         return m_type;
20462     }
20463 
20464     /// @brief return whether type is primitive
20465     /// @sa https://json.nlohmann.me/api/basic_json/is_primitive/
20466     constexpr bool is_primitive() const noexcept
20467     {
20468         return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20469     }
20470 
20471     /// @brief return whether type is structured
20472     /// @sa https://json.nlohmann.me/api/basic_json/is_structured/
20473     constexpr bool is_structured() const noexcept
20474     {
20475         return is_array() || is_object();
20476     }
20477 
20478     /// @brief return whether value is null
20479     /// @sa https://json.nlohmann.me/api/basic_json/is_null/
20480     constexpr bool is_null() const noexcept
20481     {
20482         return m_type == value_t::null;
20483     }
20484 
20485     /// @brief return whether value is a boolean
20486     /// @sa https://json.nlohmann.me/api/basic_json/is_boolean/
20487     constexpr bool is_boolean() const noexcept
20488     {
20489         return m_type == value_t::boolean;
20490     }
20491 
20492     /// @brief return whether value is a number
20493     /// @sa https://json.nlohmann.me/api/basic_json/is_number/
20494     constexpr bool is_number() const noexcept
20495     {
20496         return is_number_integer() || is_number_float();
20497     }
20498 
20499     /// @brief return whether value is an integer number
20500     /// @sa https://json.nlohmann.me/api/basic_json/is_number_integer/
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 
20506     /// @brief return whether value is an unsigned integer number
20507     /// @sa https://json.nlohmann.me/api/basic_json/is_number_unsigned/
20508     constexpr bool is_number_unsigned() const noexcept
20509     {
20510         return m_type == value_t::number_unsigned;
20511     }
20512 
20513     /// @brief return whether value is a floating-point number
20514     /// @sa https://json.nlohmann.me/api/basic_json/is_number_float/
20515     constexpr bool is_number_float() const noexcept
20516     {
20517         return m_type == value_t::number_float;
20518     }
20519 
20520     /// @brief return whether value is an object
20521     /// @sa https://json.nlohmann.me/api/basic_json/is_object/
20522     constexpr bool is_object() const noexcept
20523     {
20524         return m_type == value_t::object;
20525     }
20526 
20527     /// @brief return whether value is an array
20528     /// @sa https://json.nlohmann.me/api/basic_json/is_array/
20529     constexpr bool is_array() const noexcept
20530     {
20531         return m_type == value_t::array;
20532     }
20533 
20534     /// @brief return whether value is a string
20535     /// @sa https://json.nlohmann.me/api/basic_json/is_string/
20536     constexpr bool is_string() const noexcept
20537     {
20538         return m_type == value_t::string;
20539     }
20540 
20541     /// @brief return whether value is a binary array
20542     /// @sa https://json.nlohmann.me/api/basic_json/is_binary/
20543     constexpr bool is_binary() const noexcept
20544     {
20545         return m_type == value_t::binary;
20546     }
20547 
20548     /// @brief return whether value is discarded
20549     /// @sa https://json.nlohmann.me/api/basic_json/is_discarded/
20550     constexpr bool is_discarded() const noexcept
20551     {
20552         return m_type == value_t::discarded;
20553     }
20554 
20555     /// @brief return the type of the JSON value (implicit)
20556     /// @sa https://json.nlohmann.me/api/basic_json/operator_value_t/
20557     constexpr operator value_t() const noexcept
20558     {
20559         return m_type;
20560     }
20561 
20562     /// @}
20563 
20564   private:
20565     //////////////////
20566     // value access //
20567     //////////////////
20568 
20569     /// get a boolean (explicit)
20570     boolean_t get_impl(boolean_t* /*unused*/) const
20571     {
20572         if (JSON_HEDLEY_LIKELY(is_boolean()))
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 
20580     /// get a pointer to the value (object)
20581     object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20582     {
20583         return is_object() ? m_value.object : nullptr;
20584     }
20585 
20586     /// get a pointer to the value (object)
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 
20592     /// get a pointer to the value (array)
20593     array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20594     {
20595         return is_array() ? m_value.array : nullptr;
20596     }
20597 
20598     /// get a pointer to the value (array)
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 
20604     /// get a pointer to the value (string)
20605     string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20606     {
20607         return is_string() ? m_value.string : nullptr;
20608     }
20609 
20610     /// get a pointer to the value (string)
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 
20616     /// get a pointer to the value (boolean)
20617     boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20618     {
20619         return is_boolean() ? &m_value.boolean : nullptr;
20620     }
20621 
20622     /// get a pointer to the value (boolean)
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 
20628     /// get a pointer to the value (integer number)
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 
20634     /// get a pointer to the value (integer number)
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 
20640     /// get a pointer to the value (unsigned number)
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 
20646     /// get a pointer to the value (unsigned number)
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 
20652     /// get a pointer to the value (floating-point number)
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 
20658     /// get a pointer to the value (floating-point number)
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 
20664     /// get a pointer to the value (binary)
20665     binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20666     {
20667         return is_binary() ? m_value.binary : nullptr;
20668     }
20669 
20670     /// get a pointer to the value (binary)
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 
20676     /*!
20677     @brief helper function to implement get_ref()
20678 
20679     This function helps to implement get_ref() without code duplication for
20680     const and non-const overloads
20681 
20682     @tparam ThisType will be deduced as `basic_json` or `const basic_json`
20683 
20684     @throw type_error.303 if ReferenceType does not match underlying value
20685     type of the current JSON
20686     */
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:
20702     /// @name value access
20703     /// Direct access to the stored value of a JSON value.
20704     /// @{
20705 
20706     /// @brief get a pointer value (implicit)
20707     /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/
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 
20716     /// @brief get a pointer value (implicit)
20717     /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/
20718     template < typename PointerType, typename std::enable_if <
20719                    std::is_pointer<PointerType>::value&&
20720                    std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
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:
20728     /*!
20729     @brief get a value (explicit)
20730 
20731     Explicit type conversion between the JSON value and a compatible value
20732     which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20733     and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20734     The value is converted by calling the @ref json_serializer<ValueType>
20735     `from_json()` method.
20736 
20737     The function is equivalent to executing
20738     @code {.cpp}
20739     ValueType ret;
20740     JSONSerializer<ValueType>::from_json(*this, ret);
20741     return ret;
20742     @endcode
20743 
20744     This overloads is chosen if:
20745     - @a ValueType is not @ref basic_json,
20746     - @ref json_serializer<ValueType> has a `from_json()` method of the form
20747       `void from_json(const basic_json&, ValueType&)`, and
20748     - @ref json_serializer<ValueType> does not have a `from_json()` method of
20749       the form `ValueType from_json(const basic_json&)`
20750 
20751     @tparam ValueType the returned value type
20752 
20753     @return copy of the JSON value, converted to @a ValueType
20754 
20755     @throw what @ref json_serializer<ValueType> `from_json()` method throws
20756 
20757     @liveexample{The example below shows several conversions from JSON values
20758     to other types. There a few things to note: (1) Floating-point numbers can
20759     be converted to integers\, (2) A JSON array can be converted to a standard
20760     `std::vector<short>`\, (3) A JSON object can be converted to C++
20761     associative containers such as `std::unordered_map<std::string\,
20762     json>`.,get__ValueType_const}
20763 
20764     @since version 2.1.0
20765     */
20766     template < typename ValueType,
20767                detail::enable_if_t <
20768                    detail::is_default_constructible<ValueType>::value&&
20769                    detail::has_from_json<basic_json_t, ValueType>::value,
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();
20775         JSONSerializer<ValueType>::from_json(*this, ret);
20776         return ret;
20777     }
20778 
20779     /*!
20780     @brief get a value (explicit); special case
20781 
20782     Explicit type conversion between the JSON value and a compatible value
20783     which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20784     and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20785     The value is converted by calling the @ref json_serializer<ValueType>
20786     `from_json()` method.
20787 
20788     The function is equivalent to executing
20789     @code {.cpp}
20790     return JSONSerializer<ValueType>::from_json(*this);
20791     @endcode
20792 
20793     This overloads is chosen if:
20794     - @a ValueType is not @ref basic_json and
20795     - @ref json_serializer<ValueType> has a `from_json()` method of the form
20796       `ValueType from_json(const basic_json&)`
20797 
20798     @note If @ref json_serializer<ValueType> has both overloads of
20799     `from_json()`, this one is chosen.
20800 
20801     @tparam ValueType the returned value type
20802 
20803     @return copy of the JSON value, converted to @a ValueType
20804 
20805     @throw what @ref json_serializer<ValueType> `from_json()` method throws
20806 
20807     @since version 2.1.0
20808     */
20809     template < typename ValueType,
20810                detail::enable_if_t <
20811                    detail::has_non_default_from_json<basic_json_t, ValueType>::value,
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     {
20816         return JSONSerializer<ValueType>::from_json(*this);
20817     }
20818 
20819     /*!
20820     @brief get special-case overload
20821 
20822     This overloads converts the current @ref basic_json in a different
20823     @ref basic_json type
20824 
20825     @tparam BasicJsonType == @ref basic_json
20826 
20827     @return a copy of *this, converted into @a BasicJsonType
20828 
20829     @complexity Depending on the implementation of the called `from_json()`
20830                 method.
20831 
20832     @since version 3.2.0
20833     */
20834     template < typename BasicJsonType,
20835                detail::enable_if_t <
20836                    detail::is_basic_json<BasicJsonType>::value,
20837                    int > = 0 >
20838     BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20839     {
20840         return *this;
20841     }
20842 
20843     /*!
20844     @brief get special-case overload
20845 
20846     This overloads avoids a lot of template boilerplate, it can be seen as the
20847     identity method
20848 
20849     @tparam BasicJsonType == @ref basic_json
20850 
20851     @return a copy of *this
20852 
20853     @complexity Constant.
20854 
20855     @since version 2.1.0
20856     */
20857     template<typename BasicJsonType,
20858              detail::enable_if_t<
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 
20866     /*!
20867     @brief get a pointer value (explicit)
20868     @copydoc get()
20869     */
20870     template<typename PointerType,
20871              detail::enable_if_t<
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:
20882     /*!
20883     @brief get a (pointer) value (explicit)
20884 
20885     Performs explicit type conversion between the JSON value and a compatible value if required.
20886 
20887     - If the requested type is a pointer to the internally stored JSON value that pointer is returned.
20888     No copies are made.
20889 
20890     - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
20891     from the current @ref basic_json.
20892 
20893     - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
20894     method.
20895 
20896     @tparam ValueTypeCV the provided value type
20897     @tparam ValueType the returned value type
20898 
20899     @return copy of the JSON value, converted to @tparam ValueType if necessary
20900 
20901     @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
20902 
20903     @since version 2.1.0
20904     */
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 
20921     /*!
20922     @brief get a pointer value (explicit)
20923 
20924     Explicit pointer access to the internally stored JSON value. No copies are
20925     made.
20926 
20927     @warning The pointer becomes invalid if the underlying JSON object
20928     changes.
20929 
20930     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
20931     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
20932     @ref number_unsigned_t, or @ref number_float_t.
20933 
20934     @return pointer to the internally stored JSON value if the requested
20935     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
20936 
20937     @complexity Constant.
20938 
20939     @liveexample{The example below shows how pointers to internal values of a
20940     JSON value can be requested. Note that no type conversions are made and a
20941     `nullptr` is returned if the value and the requested pointer type does not
20942     match.,get__PointerType}
20943 
20944     @sa see @ref get_ptr() for explicit pointer-member access
20945 
20946     @since version 1.0.0
20947     */
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 
20956     /// @brief get a value (explicit)
20957     /// @sa https://json.nlohmann.me/api/basic_json/get_to/
20958     template < typename ValueType,
20959                detail::enable_if_t <
20960                    !detail::is_basic_json<ValueType>::value&&
20961                    detail::has_from_json<basic_json_t, ValueType>::value,
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     {
20966         JSONSerializer<ValueType>::from_json(*this, v);
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,
20973              detail::enable_if_t <
20974                  detail::is_basic_json<ValueType>::value,
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)
20985         detail::enable_if_t <
20986             detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
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     {
20991         JSONSerializer<Array>::from_json(*this, v);
20992         return v;
20993     }
20994 
20995     /// @brief get a reference value (implicit)
20996     /// @sa https://json.nlohmann.me/api/basic_json/get_ref/
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 
21005     /// @brief get a reference value (implicit)
21006     /// @sa https://json.nlohmann.me/api/basic_json/get_ref/
21007     template < typename ReferenceType, typename std::enable_if <
21008                    std::is_reference<ReferenceType>::value&&
21009                    std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
21010     ReferenceType get_ref() const
21011     {
21012         // delegate call to get_ref_impl
21013         return get_ref_impl<ReferenceType>(*this);
21014     }
21015 
21016     /*!
21017     @brief get a value (implicit)
21018 
21019     Implicit type conversion between the JSON value and a compatible value.
21020     The call is realized by calling @ref get() const.
21021 
21022     @tparam ValueType non-pointer type compatible to the JSON value, for
21023     instance `int` for JSON integer numbers, `bool` for JSON booleans, or
21024     `std::vector` types for JSON arrays. The character type of @ref string_t
21025     as well as an initializer list of this type is excluded to avoid
21026     ambiguities as these types implicitly convert to `std::string`.
21027 
21028     @return copy of the JSON value, converted to type @a ValueType
21029 
21030     @throw type_error.302 in case passed type @a ValueType is incompatible
21031     to the JSON value type (e.g., the JSON value is of type boolean, but a
21032     string is requested); see example below
21033 
21034     @complexity Linear in the size of the JSON value.
21035 
21036     @liveexample{The example below shows several conversions from JSON values
21037     to other types. There a few things to note: (1) Floating-point numbers can
21038     be converted to integers\, (2) A JSON array can be converted to a standard
21039     `std::vector<short>`\, (3) A JSON object can be converted to C++
21040     associative containers such as `std::unordered_map<std::string\,
21041     json>`.,operator__ValueType}
21042 
21043     @since version 1.0.0
21044     */
21045     template < typename ValueType, typename std::enable_if <
21046                    detail::conjunction <
21047                        detail::negation<std::is_pointer<ValueType>>,
21048                        detail::negation<std::is_same<ValueType, std::nullptr_t>>,
21049                        detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
21050                                         detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
21051                                         detail::negation<detail::is_basic_json<ValueType>>,
21052                                         detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
21053 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
21054                                                 detail::negation<std::is_same<ValueType, std::string_view>>,
21055 #endif
21056 #if defined(JSON_HAS_CPP_17)
21057                                                 detail::negation<std::is_same<ValueType, std::any>>,
21058 #endif
21059                                                 detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
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 
21067     /// @brief get a binary value
21068     /// @sa https://json.nlohmann.me/api/basic_json/get_binary/
21069     binary_t& get_binary()
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 
21079     /// @brief get a binary value
21080     /// @sa https://json.nlohmann.me/api/basic_json/get_binary/
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 
21091     /// @}
21092 
21093 
21094     ////////////////////
21095     // element access //
21096     ////////////////////
21097 
21098     /// @name element access
21099     /// Access to the JSON value.
21100     /// @{
21101 
21102     /// @brief access specified array element with bounds checking
21103     /// @sa https://json.nlohmann.me/api/basic_json/at/
21104     reference at(size_type idx)
21105     {
21106         // at only works for arrays
21107         if (JSON_HEDLEY_LIKELY(is_array()))
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 
21125     /// @brief access specified array element with bounds checking
21126     /// @sa https://json.nlohmann.me/api/basic_json/at/
21127     const_reference at(size_type idx) const
21128     {
21129         // at only works for arrays
21130         if (JSON_HEDLEY_LIKELY(is_array()))
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 
21148     /// @brief access specified object element with bounds checking
21149     /// @sa https://json.nlohmann.me/api/basic_json/at/
21150     reference at(const typename object_t::key_type& key)
21151     {
21152         // at only works for objects
21153         if (JSON_HEDLEY_UNLIKELY(!is_object()))
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 
21166     /// @brief access specified object element with bounds checking
21167     /// @sa https://json.nlohmann.me/api/basic_json/at/
21168     template<class KeyType, detail::enable_if_t<
21169                  detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
21170     reference at(KeyType && key)
21171     {
21172         // at only works for objects
21173         if (JSON_HEDLEY_UNLIKELY(!is_object()))
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 
21186     /// @brief access specified object element with bounds checking
21187     /// @sa https://json.nlohmann.me/api/basic_json/at/
21188     const_reference at(const typename object_t::key_type& key) const
21189     {
21190         // at only works for objects
21191         if (JSON_HEDLEY_UNLIKELY(!is_object()))
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 
21204     /// @brief access specified object element with bounds checking
21205     /// @sa https://json.nlohmann.me/api/basic_json/at/
21206     template<class KeyType, detail::enable_if_t<
21207                  detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
21208     const_reference at(KeyType && key) const
21209     {
21210         // at only works for objects
21211         if (JSON_HEDLEY_UNLIKELY(!is_object()))
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 
21224     /// @brief access specified array element
21225     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
21226     reference operator[](size_type idx)
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
21237         if (JSON_HEDLEY_LIKELY(is_array()))
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 
21270     /// @brief access specified array element
21271     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
21272     const_reference operator[](size_type idx) const
21273     {
21274         // const operator[] only works for arrays
21275         if (JSON_HEDLEY_LIKELY(is_array()))
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 
21283     /// @brief access specified object element
21284     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
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
21296         if (JSON_HEDLEY_LIKELY(is_object()))
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 
21305     /// @brief access specified object element
21306     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
21307     const_reference operator[](const typename object_t::key_type& key) const
21308     {
21309         // const operator[] only works for objects
21310         if (JSON_HEDLEY_LIKELY(is_object()))
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>
21323     reference operator[](T* key)
21324     {
21325         return operator[](typename object_t::key_type(key));
21326     }
21327 
21328     template<typename T>
21329     const_reference operator[](T* key) const
21330     {
21331         return operator[](typename object_t::key_type(key));
21332     }
21333 
21334     /// @brief access specified object element
21335     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
21336     template<class KeyType, detail::enable_if_t<
21337                  detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int > = 0 >
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
21349         if (JSON_HEDLEY_LIKELY(is_object()))
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 
21358     /// @brief access specified object element
21359     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
21360     template<class KeyType, detail::enable_if_t<
21361                  detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int > = 0 >
21362     const_reference operator[](KeyType && key) const
21363     {
21364         // const operator[] only works for objects
21365         if (JSON_HEDLEY_LIKELY(is_object()))
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 <
21382         detail::is_c_string_uncvref<ValueType>::value,
21383         string_t, typename std::decay<ValueType>::type >;
21384 
21385   public:
21386     /// @brief access specified object element with default value
21387     /// @sa https://json.nlohmann.me/api/basic_json/value/
21388     template < class ValueType, detail::enable_if_t <
21389                    !detail::is_transparent<object_comparator_t>::value
21390                    && detail::is_getable<basic_json_t, ValueType>::value
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
21395         if (JSON_HEDLEY_LIKELY(is_object()))
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 
21410     /// @brief access specified object element with default value
21411     /// @sa https://json.nlohmann.me/api/basic_json/value/
21412     template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21413                detail::enable_if_t <
21414                    !detail::is_transparent<object_comparator_t>::value
21415                    && detail::is_getable<basic_json_t, ReturnType>::value
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
21420         if (JSON_HEDLEY_LIKELY(is_object()))
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 
21435     /// @brief access specified object element with default value
21436     /// @sa https://json.nlohmann.me/api/basic_json/value/
21437     template < class ValueType, class KeyType, detail::enable_if_t <
21438                    detail::is_transparent<object_comparator_t>::value
21439                    && !detail::is_json_pointer<KeyType>::value
21440                    && is_comparable_with_object_key<KeyType>::value
21441                    && detail::is_getable<basic_json_t, ValueType>::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
21446         if (JSON_HEDLEY_LIKELY(is_object()))
21447         {
21448             // if key is found, return value and given default value otherwise
21449             const auto it = find(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 
21461     /// @brief access specified object element via JSON Pointer with default value
21462     /// @sa https://json.nlohmann.me/api/basic_json/value/
21463     template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,
21464                detail::enable_if_t <
21465                    detail::is_transparent<object_comparator_t>::value
21466                    && !detail::is_json_pointer<KeyType>::value
21467                    && is_comparable_with_object_key<KeyType>::value
21468                    && detail::is_getable<basic_json_t, ReturnType>::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
21473         if (JSON_HEDLEY_LIKELY(is_object()))
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 
21488     /// @brief access specified object element via JSON Pointer with default value
21489     /// @sa https://json.nlohmann.me/api/basic_json/value/
21490     template < class ValueType, detail::enable_if_t <
21491                    detail::is_getable<basic_json_t, ValueType>::value
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
21496         if (JSON_HEDLEY_LIKELY(is_object()))
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             }
21503             JSON_INTERNAL_CATCH (out_of_range&)
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 
21512     /// @brief access specified object element via JSON Pointer with default value
21513     /// @sa https://json.nlohmann.me/api/basic_json/value/
21514     template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21515                detail::enable_if_t <
21516                    detail::is_getable<basic_json_t, ReturnType>::value
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
21521         if (JSON_HEDLEY_LIKELY(is_object()))
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             }
21528             JSON_INTERNAL_CATCH (out_of_range&)
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 <
21538                    detail::is_basic_json<BasicJsonType>::value
21539                    && detail::is_getable<basic_json_t, ValueType>::value
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 
21547     template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
21548                detail::enable_if_t <
21549                    detail::is_basic_json<BasicJsonType>::value
21550                    && detail::is_getable<basic_json_t, ReturnType>::value
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 
21558     /// @brief access the first element
21559     /// @sa https://json.nlohmann.me/api/basic_json/front/
21560     reference front()
21561     {
21562         return *begin();
21563     }
21564 
21565     /// @brief access the first element
21566     /// @sa https://json.nlohmann.me/api/basic_json/front/
21567     const_reference front() const
21568     {
21569         return *cbegin();
21570     }
21571 
21572     /// @brief access the last element
21573     /// @sa https://json.nlohmann.me/api/basic_json/back/
21574     reference back()
21575     {
21576         auto tmp = end();
21577         --tmp;
21578         return *tmp;
21579     }
21580 
21581     /// @brief access the last element
21582     /// @sa https://json.nlohmann.me/api/basic_json/back/
21583     const_reference back() const
21584     {
21585         auto tmp = cend();
21586         --tmp;
21587         return *tmp;
21588     }
21589 
21590     /// @brief remove element given an iterator
21591     /// @sa https://json.nlohmann.me/api/basic_json/erase/
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:
21609             case value_t::number_integer:
21610             case value_t::number_unsigned:
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 
21660     /// @brief remove elements given an iterator range
21661     /// @sa https://json.nlohmann.me/api/basic_json/erase/
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:
21679             case value_t::number_integer:
21680             case value_t::number_unsigned:
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 <
21735                    detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
21736     size_type erase_internal(KeyType && key)
21737     {
21738         // this erase only works for objects
21739         if (JSON_HEDLEY_UNLIKELY(!is_object()))
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 <
21748                    !detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
21749     size_type erase_internal(KeyType && key)
21750     {
21751         // this erase only works for objects
21752         if (JSON_HEDLEY_UNLIKELY(!is_object()))
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 
21768     /// @brief remove element from a JSON object given a key
21769     /// @sa https://json.nlohmann.me/api/basic_json/erase/
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 
21777     /// @brief remove element from a JSON object given a key
21778     /// @sa https://json.nlohmann.me/api/basic_json/erase/
21779     template<class KeyType, detail::enable_if_t<
21780                  detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
21781     size_type erase(KeyType && key)
21782     {
21783         return erase_internal(std::forward<KeyType>(key));
21784     }
21785 
21786     /// @brief remove element from a JSON array given an index
21787     /// @sa https://json.nlohmann.me/api/basic_json/erase/
21788     void erase(const size_type idx)
21789     {
21790         // this erase only works for arrays
21791         if (JSON_HEDLEY_LIKELY(is_array()))
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 
21806     /// @}
21807 
21808 
21809     ////////////
21810     // lookup //
21811     ////////////
21812 
21813     /// @name lookup
21814     /// @{
21815 
21816     /// @brief find an element in a JSON object
21817     /// @sa https://json.nlohmann.me/api/basic_json/find/
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 
21830     /// @brief find an element in a JSON object
21831     /// @sa https://json.nlohmann.me/api/basic_json/find/
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 
21844     /// @brief find an element in a JSON object
21845     /// @sa https://json.nlohmann.me/api/basic_json/find/
21846     template<class KeyType, detail::enable_if_t<
21847                  detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
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 
21860     /// @brief find an element in a JSON object
21861     /// @sa https://json.nlohmann.me/api/basic_json/find/
21862     template<class KeyType, detail::enable_if_t<
21863                  detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
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 
21876     /// @brief returns the number of occurrences of a key in a JSON object
21877     /// @sa https://json.nlohmann.me/api/basic_json/count/
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 
21884     /// @brief returns the number of occurrences of a key in a JSON object
21885     /// @sa https://json.nlohmann.me/api/basic_json/count/
21886     template<class KeyType, detail::enable_if_t<
21887                  detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
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 
21894     /// @brief check the existence of an element in a JSON object
21895     /// @sa https://json.nlohmann.me/api/basic_json/contains/
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 
21901     /// @brief check the existence of an element in a JSON object
21902     /// @sa https://json.nlohmann.me/api/basic_json/contains/
21903     template<class KeyType, detail::enable_if_t<
21904                  detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
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 
21910     /// @brief check the existence of an element in a JSON object given a JSON pointer
21911     /// @sa https://json.nlohmann.me/api/basic_json/contains/
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 
21924     /// @}
21925 
21926 
21927     ///////////////
21928     // iterators //
21929     ///////////////
21930 
21931     /// @name iterators
21932     /// @{
21933 
21934     /// @brief returns an iterator to the first element
21935     /// @sa https://json.nlohmann.me/api/basic_json/begin/
21936     iterator begin() noexcept
21937     {
21938         iterator result(this);
21939         result.set_begin();
21940         return result;
21941     }
21942 
21943     /// @brief returns an iterator to the first element
21944     /// @sa https://json.nlohmann.me/api/basic_json/begin/
21945     const_iterator begin() const noexcept
21946     {
21947         return cbegin();
21948     }
21949 
21950     /// @brief returns a const iterator to the first element
21951     /// @sa https://json.nlohmann.me/api/basic_json/cbegin/
21952     const_iterator cbegin() const noexcept
21953     {
21954         const_iterator result(this);
21955         result.set_begin();
21956         return result;
21957     }
21958 
21959     /// @brief returns an iterator to one past the last element
21960     /// @sa https://json.nlohmann.me/api/basic_json/end/
21961     iterator end() noexcept
21962     {
21963         iterator result(this);
21964         result.set_end();
21965         return result;
21966     }
21967 
21968     /// @brief returns an iterator to one past the last element
21969     /// @sa https://json.nlohmann.me/api/basic_json/end/
21970     const_iterator end() const noexcept
21971     {
21972         return cend();
21973     }
21974 
21975     /// @brief returns an iterator to one past the last element
21976     /// @sa https://json.nlohmann.me/api/basic_json/cend/
21977     const_iterator cend() const noexcept
21978     {
21979         const_iterator result(this);
21980         result.set_end();
21981         return result;
21982     }
21983 
21984     /// @brief returns an iterator to the reverse-beginning
21985     /// @sa https://json.nlohmann.me/api/basic_json/rbegin/
21986     reverse_iterator rbegin() noexcept
21987     {
21988         return reverse_iterator(end());
21989     }
21990 
21991     /// @brief returns an iterator to the reverse-beginning
21992     /// @sa https://json.nlohmann.me/api/basic_json/rbegin/
21993     const_reverse_iterator rbegin() const noexcept
21994     {
21995         return crbegin();
21996     }
21997 
21998     /// @brief returns an iterator to the reverse-end
21999     /// @sa https://json.nlohmann.me/api/basic_json/rend/
22000     reverse_iterator rend() noexcept
22001     {
22002         return reverse_iterator(begin());
22003     }
22004 
22005     /// @brief returns an iterator to the reverse-end
22006     /// @sa https://json.nlohmann.me/api/basic_json/rend/
22007     const_reverse_iterator rend() const noexcept
22008     {
22009         return crend();
22010     }
22011 
22012     /// @brief returns a const reverse iterator to the last element
22013     /// @sa https://json.nlohmann.me/api/basic_json/crbegin/
22014     const_reverse_iterator crbegin() const noexcept
22015     {
22016         return const_reverse_iterator(cend());
22017     }
22018 
22019     /// @brief returns a const reverse iterator to one before the first
22020     /// @sa https://json.nlohmann.me/api/basic_json/crend/
22021     const_reverse_iterator crend() const noexcept
22022     {
22023         return const_reverse_iterator(cbegin());
22024     }
22025 
22026   public:
22027     /// @brief wrapper to access iterator member functions in range-based for
22028     /// @sa https://json.nlohmann.me/api/basic_json/items/
22029     /// @deprecated This function is deprecated since 3.1.0 and will be removed in
22030     ///             version 4.0.0 of the library. Please use @ref items() instead;
22031     ///             that is, replace `json::iterator_wrapper(j)` with `j.items()`.
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 
22038     /// @brief wrapper to access iterator member functions in range-based for
22039     /// @sa https://json.nlohmann.me/api/basic_json/items/
22040     /// @deprecated This function is deprecated since 3.1.0 and will be removed in
22041     ///         version 4.0.0 of the library. Please use @ref items() instead;
22042     ///         that is, replace `json::iterator_wrapper(j)` with `j.items()`.
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 
22049     /// @brief helper to access iterator member functions in range-based for
22050     /// @sa https://json.nlohmann.me/api/basic_json/items/
22051     iteration_proxy<iterator> items() noexcept
22052     {
22053         return iteration_proxy<iterator>(*this);
22054     }
22055 
22056     /// @brief helper to access iterator member functions in range-based for
22057     /// @sa https://json.nlohmann.me/api/basic_json/items/
22058     iteration_proxy<const_iterator> items() const noexcept
22059     {
22060         return iteration_proxy<const_iterator>(*this);
22061     }
22062 
22063     /// @}
22064 
22065 
22066     //////////////
22067     // capacity //
22068     //////////////
22069 
22070     /// @name capacity
22071     /// @{
22072 
22073     /// @brief checks whether the container is empty.
22074     /// @sa https://json.nlohmann.me/api/basic_json/empty/
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:
22099             case value_t::number_integer:
22100             case value_t::number_unsigned:
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 
22112     /// @brief returns the number of elements
22113     /// @sa https://json.nlohmann.me/api/basic_json/size/
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:
22138             case value_t::number_integer:
22139             case value_t::number_unsigned:
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 
22151     /// @brief returns the maximum possible number of elements
22152     /// @sa https://json.nlohmann.me/api/basic_json/max_size/
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:
22172             case value_t::number_integer:
22173             case value_t::number_unsigned:
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 
22185     /// @}
22186 
22187 
22188     ///////////////
22189     // modifiers //
22190     ///////////////
22191 
22192     /// @name modifiers
22193     /// @{
22194 
22195     /// @brief clears the contents
22196     /// @sa https://json.nlohmann.me/api/basic_json/clear/
22197     void clear() noexcept
22198     {
22199         switch (m_type)
22200         {
22201             case value_t::number_integer:
22202             {
22203                 m_value.number_integer = 0;
22204                 break;
22205             }
22206 
22207             case value_t::number_unsigned:
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 
22256     /// @brief add an object to an array
22257     /// @sa https://json.nlohmann.me/api/basic_json/push_back/
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;
22270             m_value = 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 
22281     /// @brief add an object to an array
22282     /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
22283     reference operator+=(basic_json&& val)
22284     {
22285         push_back(std::move(val));
22286         return *this;
22287     }
22288 
22289     /// @brief add an object to an array
22290     /// @sa https://json.nlohmann.me/api/basic_json/push_back/
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;
22303             m_value = 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 
22313     /// @brief add an object to an array
22314     /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
22315     reference operator+=(const basic_json& val)
22316     {
22317         push_back(val);
22318         return *this;
22319     }
22320 
22321     /// @brief add an object to an object
22322     /// @sa https://json.nlohmann.me/api/basic_json/push_back/
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;
22335             m_value = 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 
22344     /// @brief add an object to an object
22345     /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
22346     reference operator+=(const typename object_t::value_type& val)
22347     {
22348         push_back(val);
22349         return *this;
22350     }
22351 
22352     /// @brief add an object to an object
22353     /// @sa https://json.nlohmann.me/api/basic_json/push_back/
22354     void push_back(initializer_list_t init)
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 
22368     /// @brief add an object to an object
22369     /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
22370     reference operator+=(initializer_list_t init)
22371     {
22372         push_back(init);
22373         return *this;
22374     }
22375 
22376     /// @brief add an object to an array
22377     /// @sa https://json.nlohmann.me/api/basic_json/emplace_back/
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;
22391             m_value = 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 
22401     /// @brief add an object to an object if key does not exist
22402     /// @sa https://json.nlohmann.me/api/basic_json/emplace/
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;
22416             m_value = 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 
22432     /// Helper for insertion of an iterator
22433     /// @note: This uses std::distance to support GCC 4.8,
22434     ///        see https://github.com/nlohmann/json/pull/1257
22435     template<typename... Args>
22436     iterator insert_iterator(const_iterator pos, Args&& ... 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 
22453     /// @brief inserts element into array
22454     /// @sa https://json.nlohmann.me/api/basic_json/insert/
22455     iterator insert(const_iterator pos, const basic_json& val)
22456     {
22457         // insert only works for arrays
22458         if (JSON_HEDLEY_LIKELY(is_array()))
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 
22473     /// @brief inserts element into array
22474     /// @sa https://json.nlohmann.me/api/basic_json/insert/
22475     iterator insert(const_iterator pos, basic_json&& val)
22476     {
22477         return insert(pos, val);
22478     }
22479 
22480     /// @brief inserts copies of element into array
22481     /// @sa https://json.nlohmann.me/api/basic_json/insert/
22482     iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
22483     {
22484         // insert only works for arrays
22485         if (JSON_HEDLEY_LIKELY(is_array()))
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 
22500     /// @brief inserts range of elements into array
22501     /// @sa https://json.nlohmann.me/api/basic_json/insert/
22502     iterator insert(const_iterator pos, const_iterator first, const_iterator last)
22503     {
22504         // insert only works for arrays
22505         if (JSON_HEDLEY_UNLIKELY(!is_array()))
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 
22531     /// @brief inserts elements from initializer list into array
22532     /// @sa https://json.nlohmann.me/api/basic_json/insert/
22533     iterator insert(const_iterator pos, initializer_list_t ilist)
22534     {
22535         // insert only works for arrays
22536         if (JSON_HEDLEY_UNLIKELY(!is_array()))
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 
22551     /// @brief inserts range of elements into object
22552     /// @sa https://json.nlohmann.me/api/basic_json/insert/
22553     void insert(const_iterator first, const_iterator last)
22554     {
22555         // insert only works for objects
22556         if (JSON_HEDLEY_UNLIKELY(!is_object()))
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 
22576     /// @brief updates a JSON object from another object, overwriting existing keys
22577     /// @sa https://json.nlohmann.me/api/basic_json/update/
22578     void update(const_reference j, bool merge_objects = false)
22579     {
22580         update(j.begin(), j.end(), merge_objects);
22581     }
22582 
22583     /// @brief updates a JSON object from another object, overwriting existing keys
22584     /// @sa https://json.nlohmann.me/api/basic_json/update/
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 
22595         if (JSON_HEDLEY_UNLIKELY(!is_object()))
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 
22630     /// @brief exchanges the values
22631     /// @sa https://json.nlohmann.me/api/basic_json/swap/
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 
22647     /// @brief exchanges the values
22648     /// @sa https://json.nlohmann.me/api/basic_json/swap/
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 
22659     /// @brief exchanges the values
22660     /// @sa https://json.nlohmann.me/api/basic_json/swap/
22661     void swap(array_t& other) // NOLINT(bugprone-exception-escape)
22662     {
22663         // swap only works for arrays
22664         if (JSON_HEDLEY_LIKELY(is_array()))
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 
22675     /// @brief exchanges the values
22676     /// @sa https://json.nlohmann.me/api/basic_json/swap/
22677     void swap(object_t& other) // NOLINT(bugprone-exception-escape)
22678     {
22679         // swap only works for objects
22680         if (JSON_HEDLEY_LIKELY(is_object()))
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 
22691     /// @brief exchanges the values
22692     /// @sa https://json.nlohmann.me/api/basic_json/swap/
22693     void swap(string_t& other) // NOLINT(bugprone-exception-escape)
22694     {
22695         // swap only works for strings
22696         if (JSON_HEDLEY_LIKELY(is_string()))
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 
22707     /// @brief exchanges the values
22708     /// @sa https://json.nlohmann.me/api/basic_json/swap/
22709     void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
22710     {
22711         // swap only works for strings
22712         if (JSON_HEDLEY_LIKELY(is_binary()))
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 
22723     /// @brief exchanges the values
22724     /// @sa https://json.nlohmann.me/api/basic_json/swap/
22725     void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
22726     {
22727         // swap only works for strings
22728         if (JSON_HEDLEY_LIKELY(is_binary()))
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 
22739     /// @}
22740 
22741     //////////////////////////////////////////
22742     // lexicographical comparison operators //
22743     //////////////////////////////////////////
22744 
22745     /// @name lexicographical comparison operators
22746     /// @{
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 
22821   JSON_PRIVATE_UNLESS_TESTED:
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     /// @brief comparison: equal
22851     /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
22852     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 
22865     /// @brief comparison: equal
22866     /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
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 
22874     /// @brief comparison: not equal
22875     /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
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 
22885     /// @brief comparison: 3-way
22886     /// @sa https://json.nlohmann.me/api/basic_json/operator_spaceship/
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 
22898     /// @brief comparison: 3-way
22899     /// @sa https://json.nlohmann.me/api/basic_json/operator_spaceship/
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 
22911     /// @brief comparison: less than or equal
22912     /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
22913     JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)
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 
22923     /// @brief comparison: less than or equal
22924     /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
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 
22932     /// @brief comparison: greater than or equal
22933     /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
22934     JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)
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 
22944     /// @brief comparison: greater than or equal
22945     /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
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     /// @brief comparison: equal
22955     /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
22956     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 
22968     /// @brief comparison: equal
22969     /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
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 
22977     /// @brief comparison: equal
22978     /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
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 
22986     /// @brief comparison: not equal
22987     /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
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 
22997     /// @brief comparison: not equal
22998     /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
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 
23006     /// @brief comparison: not equal
23007     /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
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 
23015     /// @brief comparison: less than
23016     /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
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 
23025     /// @brief comparison: less than
23026     /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
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 
23034     /// @brief comparison: less than
23035     /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
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 
23043     /// @brief comparison: less than or equal
23044     /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
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 
23054     /// @brief comparison: less than or equal
23055     /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
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 
23063     /// @brief comparison: less than or equal
23064     /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
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 
23072     /// @brief comparison: greater than
23073     /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
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 
23084     /// @brief comparison: greater than
23085     /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
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 
23093     /// @brief comparison: greater than
23094     /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
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 
23102     /// @brief comparison: greater than or equal
23103     /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
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 
23113     /// @brief comparison: greater than or equal
23114     /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
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 
23122     /// @brief comparison: greater than or equal
23123     /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
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 
23134     /// @}
23135 
23136     ///////////////////
23137     // serialization //
23138     ///////////////////
23139 
23140     /// @name serialization
23141     /// @{
23142 #ifndef JSON_NO_IO
23143     /// @brief serialize to stream
23144     /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/
23145     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 
23160     /// @brief serialize to stream
23161     /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/
23162     /// @deprecated This function is deprecated since 3.0.0 and will be removed in
23163     ///             version 4.0.0 of the library. Please use
23164     ///             operator<<(std::ostream&, const basic_json&) instead; that is,
23165     ///             replace calls like `j >> o;` with `o << j;`.
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     /// @}
23173 
23174 
23175     /////////////////////
23176     // deserialization //
23177     /////////////////////
23178 
23179     /// @name deserialization
23180     /// @{
23181 
23182     /// @brief deserialize from a compatible input
23183     /// @sa https://json.nlohmann.me/api/basic_json/parse/
23184     template<typename InputType>
23185     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23196     /// @brief deserialize from a pair of character iterators
23197     /// @sa https://json.nlohmann.me/api/basic_json/parse/
23198     template<typename IteratorType>
23199     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23211     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23223     /// @brief check if the input is valid JSON
23224     /// @sa https://json.nlohmann.me/api/basic_json/accept/
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 
23232     /// @brief check if the input is valid JSON
23233     /// @sa https://json.nlohmann.me/api/basic_json/accept/
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 
23241     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23249     /// @brief generate SAX events
23250     /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
23251     template <typename InputType, typename SAX>
23252     JSON_HEDLEY_NON_NULL(2)
23253     static bool sax_parse(InputType&& i, SAX* sax,
23254                           input_format_t format = input_format_t::json,
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 
23264     /// @brief generate SAX events
23265     /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
23266     template<class IteratorType, class SAX>
23267     JSON_HEDLEY_NON_NULL(3)
23268     static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23269                           input_format_t format = input_format_t::json,
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 
23279     /// @brief generate SAX events
23280     /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
23281     /// @deprecated This function is deprecated since 3.8.0 and will be removed in
23282     ///             version 4.0.0 of the library. Please use
23283     ///             sax_parse(ptr, ptr + len) instead.
23284     template <typename SAX>
23285     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23286     JSON_HEDLEY_NON_NULL(2)
23287     static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23288                           input_format_t format = input_format_t::json,
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     /// @brief deserialize from stream
23301     /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
23302     /// @deprecated This stream operator is deprecated since 3.0.0 and will be removed in
23303     ///             version 4.0.0 of the library. Please use
23304     ///             operator>>(std::istream&, basic_json&) instead; that is,
23305     ///             replace calls like `j << i;` with `i >> j;`.
23306     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 
23312     /// @brief deserialize from stream
23313     /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
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     /// @}
23321 
23322     ///////////////////////////
23323     // convenience functions //
23324     ///////////////////////////
23325 
23326     /// @brief return the type as string
23327     /// @sa https://json.nlohmann.me/api/basic_json/type_name/
23328     JSON_HEDLEY_RETURNS_NON_NULL
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";
23347             case value_t::number_integer:
23348             case value_t::number_unsigned:
23349             case value_t::number_float:
23350             default:
23351                 return "number";
23352         }
23353     }
23354 
23355 
23356   JSON_PRIVATE_UNLESS_TESTED:
23357     //////////////////////
23358     // member variables //
23359     //////////////////////
23360 
23361     /// the type of the current element
23362     value_t m_type = value_t::null;
23363 
23364     /// the value of the current element
23365     json_value m_value = {};
23366 
23367 #if JSON_DIAGNOSTICS
23368     /// a pointer to a parent value (for debugging purposes)
23369     basic_json* m_parent = nullptr;
23370 #endif
23371 
23372     //////////////////////////////////////////
23373     // binary serialization/deserialization //
23374     //////////////////////////////////////////
23375 
23376     /// @name binary serialization/deserialization support
23377     /// @{
23378 
23379   public:
23380     /// @brief create a CBOR serialization of a given JSON value
23381     /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
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 
23389     /// @brief create a CBOR serialization of a given JSON value
23390     /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
23391     static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
23392     {
23393         binary_writer<std::uint8_t>(o).write_cbor(j);
23394     }
23395 
23396     /// @brief create a CBOR serialization of a given JSON value
23397     /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
23398     static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
23399     {
23400         binary_writer<char>(o).write_cbor(j);
23401     }
23402 
23403     /// @brief create a MessagePack serialization of a given JSON value
23404     /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
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 
23412     /// @brief create a MessagePack serialization of a given JSON value
23413     /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
23414     static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
23415     {
23416         binary_writer<std::uint8_t>(o).write_msgpack(j);
23417     }
23418 
23419     /// @brief create a MessagePack serialization of a given JSON value
23420     /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
23421     static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
23422     {
23423         binary_writer<char>(o).write_msgpack(j);
23424     }
23425 
23426     /// @brief create a UBJSON serialization of a given JSON value
23427     /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
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 
23437     /// @brief create a UBJSON serialization of a given JSON value
23438     /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
23439     static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
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 
23445     /// @brief create a UBJSON serialization of a given JSON value
23446     /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
23447     static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
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 
23453     /// @brief create a BJData serialization of a given JSON value
23454     /// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/
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 
23464     /// @brief create a BJData serialization of a given JSON value
23465     /// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/
23466     static void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o,
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 
23472     /// @brief create a BJData serialization of a given JSON value
23473     /// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/
23474     static void to_bjdata(const basic_json& j, detail::output_adapter<char> o,
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 
23480     /// @brief create a BSON serialization of a given JSON value
23481     /// @sa https://json.nlohmann.me/api/basic_json/to_bson/
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 
23489     /// @brief create a BSON serialization of a given JSON value
23490     /// @sa https://json.nlohmann.me/api/basic_json/to_bson/
23491     static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
23492     {
23493         binary_writer<std::uint8_t>(o).write_bson(j);
23494     }
23495 
23496     /// @brief create a BSON serialization of a given JSON value
23497     /// @sa https://json.nlohmann.me/api/basic_json/to_bson/
23498     static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23499     {
23500         binary_writer<char>(o).write_bson(j);
23501     }
23502 
23503     /// @brief create a JSON value from an input in CBOR format
23504     /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/
23505     template<typename InputType>
23506     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23519     /// @brief create a JSON value from an input in CBOR format
23520     /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/
23521     template<typename IteratorType>
23522     JSON_HEDLEY_WARN_UNUSED_RESULT
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>
23536     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23547     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23562     /// @brief create a JSON value from an input in MessagePack format
23563     /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/
23564     template<typename InputType>
23565     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23577     /// @brief create a JSON value from an input in MessagePack format
23578     /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/
23579     template<typename IteratorType>
23580     JSON_HEDLEY_WARN_UNUSED_RESULT
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>
23593     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23602     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23616     /// @brief create a JSON value from an input in UBJSON format
23617     /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/
23618     template<typename InputType>
23619     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23631     /// @brief create a JSON value from an input in UBJSON format
23632     /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/
23633     template<typename IteratorType>
23634     JSON_HEDLEY_WARN_UNUSED_RESULT
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>
23647     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23656     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23671     /// @brief create a JSON value from an input in BJData format
23672     /// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/
23673     template<typename InputType>
23674     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23686     /// @brief create a JSON value from an input in BJData format
23687     /// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/
23688     template<typename IteratorType>
23689     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23701     /// @brief create a JSON value from an input in BSON format
23702     /// @sa https://json.nlohmann.me/api/basic_json/from_bson/
23703     template<typename InputType>
23704     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23716     /// @brief create a JSON value from an input in BSON format
23717     /// @sa https://json.nlohmann.me/api/basic_json/from_bson/
23718     template<typename IteratorType>
23719     JSON_HEDLEY_WARN_UNUSED_RESULT
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>
23732     JSON_HEDLEY_WARN_UNUSED_RESULT
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 
23741     JSON_HEDLEY_WARN_UNUSED_RESULT
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     }
23754     /// @}
23755 
23756     //////////////////////////
23757     // JSON Pointer support //
23758     //////////////////////////
23759 
23760     /// @name JSON Pointer functions
23761     /// @{
23762 
23763     /// @brief access specified element via JSON Pointer
23764     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
23765     reference operator[](const json_pointer& ptr)
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 
23777     /// @brief access specified element via JSON Pointer
23778     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
23779     const_reference operator[](const json_pointer& ptr) const
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 
23791     /// @brief access specified element via JSON Pointer
23792     /// @sa https://json.nlohmann.me/api/basic_json/at/
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 
23805     /// @brief access specified element via JSON Pointer
23806     /// @sa https://json.nlohmann.me/api/basic_json/at/
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 
23819     /// @brief return flattened JSON value
23820     /// @sa https://json.nlohmann.me/api/basic_json/flatten/
23821     basic_json flatten() const
23822     {
23823         basic_json result(value_t::object);
23824         json_pointer::flatten("", *this, result);
23825         return result;
23826     }
23827 
23828     /// @brief unflatten a previously flattened JSON value
23829     /// @sa https://json.nlohmann.me/api/basic_json/unflatten/
23830     basic_json unflatten() const
23831     {
23832         return json_pointer::unflatten(*this);
23833     }
23834 
23835     /// @}
23836 
23837     //////////////////////////
23838     // JSON Patch functions //
23839     //////////////////////////
23840 
23841     /// @name JSON Patch functions
23842     /// @{
23843 
23844     /// @brief applies a JSON patch in-place without copying the object
23845     /// @sa https://json.nlohmann.me/api/basic_json/patch/
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                     }
24090                     JSON_INTERNAL_CATCH (out_of_range&)
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 
24115     /// @brief applies a JSON patch to a copy of the current object
24116     /// @sa https://json.nlohmann.me/api/basic_json/patch/
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 
24124     /// @brief creates a diff as a JSON patch
24125     /// @sa https://json.nlohmann.me/api/basic_json/diff/
24126     JSON_HEDLEY_WARN_UNUSED_RESULT
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:
24240             case value_t::number_integer:
24241             case value_t::number_unsigned:
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     }
24258     /// @}
24259 
24260     ////////////////////////////////
24261     // JSON Merge Patch functions //
24262     ////////////////////////////////
24263 
24264     /// @name JSON Merge Patch functions
24265     /// @{
24266 
24267     /// @brief applies a JSON Merge Patch
24268     /// @sa https://json.nlohmann.me/api/basic_json/merge_patch/
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 
24295     /// @}
24296 };
24297 
24298 /// @brief user-defined to_string function for JSON values
24299 /// @sa https://json.nlohmann.me/api/basic_json/to_string/
24300 NLOHMANN_BASIC_JSON_TPL_DECLARATION
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 
24311 /// @brief user-defined string literal for JSON values
24312 /// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/
24313 JSON_HEDLEY_NON_NULL(1)
24314 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24315 {
24316     return nlohmann::json::parse(s, s + n);
24317 }
24318 
24319 /// @brief user-defined string literal for JSON pointer
24320 /// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/
24321 JSON_HEDLEY_NON_NULL(1)
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
24329 NLOHMANN_JSON_NAMESPACE_END
24330 
24331 ///////////////////////
24332 // nonmember support //
24333 ///////////////////////
24334 
24335 namespace std // NOLINT(cert-dcl58-cpp)
24336 {
24337 
24338 /// @brief hash value for JSON objects
24339 /// @sa https://json.nlohmann.me/api/basic_json/std_hash/
24340 NLOHMANN_BASIC_JSON_TPL_DECLARATION
24341 struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL>
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 {
24353     /*!
24354     @brief compare two value_t enum values
24355     @since version 3.0.0
24356     */
24357     bool operator()(::nlohmann::detail::value_t lhs,
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
24363         return ::nlohmann::detail::operator<(lhs, rhs);
24364 #endif
24365     }
24366 };
24367 
24368 // C++20 prohibit function specialization in the std namespace.
24369 #ifndef JSON_HAS_CPP_20
24370 
24371 /// @brief exchanges the values of two JSON objects
24372 /// @sa https://json.nlohmann.me/api/basic_json/std_swap/
24373 NLOHMANN_BASIC_JSON_TPL_DECLARATION
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_