Path: blob/a-new-beginning/SharedDependencies/Sources/nlohmann/include/json.hpp
2 views
// __ _____ _____ _____1// __| | __| | | | JSON for Modern C++2// | | |__ | | | | | | version 3.11.33// |_____|_____|_____|_|___| https://github.com/nlohmann/json4//5// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>6// SPDX-License-Identifier: MIT78/****************************************************************************\9* Note on documentation: The source files contain links to the online *10* documentation of the public API at https://json.nlohmann.me. This URL *11* contains the most recent documentation and should also be applicable to *12* previous versions; documentation for deprecated functions is not *13* removed, but marked deprecated. See "Generate documentation" section in *14* file docs/README.md. *15\****************************************************************************/1617#ifndef INCLUDE_NLOHMANN_JSON_HPP_18#define INCLUDE_NLOHMANN_JSON_HPP_1920#include <algorithm> // all_of, find, for_each21#include <cstddef> // nullptr_t, ptrdiff_t, size_t22#include <functional> // hash, less23#include <initializer_list> // initializer_list24#ifndef JSON_NO_IO25#include <iosfwd> // istream, ostream26#endif // JSON_NO_IO27#include <iterator> // random_access_iterator_tag28#include <memory> // unique_ptr29#include <string> // string, stoi, to_string30#include <utility> // declval, forward, move, pair, swap31#include <vector> // vector3233// #include <nlohmann/adl_serializer.hpp>34// __ _____ _____ _____35// __| | __| | | | JSON for Modern C++36// | | |__ | | | | | | version 3.11.337// |_____|_____|_____|_|___| https://github.com/nlohmann/json38//39// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>40// SPDX-License-Identifier: MIT41424344#include <utility>4546// #include <nlohmann/detail/abi_macros.hpp>47// __ _____ _____ _____48// __| | __| | | | JSON for Modern C++49// | | |__ | | | | | | version 3.11.350// |_____|_____|_____|_|___| https://github.com/nlohmann/json51//52// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>53// SPDX-License-Identifier: MIT54555657// This file contains all macro definitions affecting or depending on the ABI5859#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK60#if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)61#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 362#warning "Already included a different version of the library!"63#endif64#endif65#endif6667#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)68#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum)69#define NLOHMANN_JSON_VERSION_PATCH 3 // NOLINT(modernize-macro-to-enum)7071#ifndef JSON_DIAGNOSTICS72#define JSON_DIAGNOSTICS 073#endif7475#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON76#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 077#endif7879#if JSON_DIAGNOSTICS80#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag81#else82#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS83#endif8485#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON86#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp87#else88#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON89#endif9091#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION92#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 093#endif9495// Construct the namespace ABI tags component96#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b97#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \98NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)99100#define NLOHMANN_JSON_ABI_TAGS \101NLOHMANN_JSON_ABI_TAGS_CONCAT( \102NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \103NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)104105// Construct the namespace version component106#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \107_v ## major ## _ ## minor ## _ ## patch108#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \109NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)110111#if NLOHMANN_JSON_NAMESPACE_NO_VERSION112#define NLOHMANN_JSON_NAMESPACE_VERSION113#else114#define NLOHMANN_JSON_NAMESPACE_VERSION \115NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \116NLOHMANN_JSON_VERSION_MINOR, \117NLOHMANN_JSON_VERSION_PATCH)118#endif119120// Combine namespace components121#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b122#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \123NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)124125#ifndef NLOHMANN_JSON_NAMESPACE126#define NLOHMANN_JSON_NAMESPACE \127nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \128NLOHMANN_JSON_ABI_TAGS, \129NLOHMANN_JSON_NAMESPACE_VERSION)130#endif131132#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN133#define NLOHMANN_JSON_NAMESPACE_BEGIN \134namespace nlohmann \135{ \136inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \137NLOHMANN_JSON_ABI_TAGS, \138NLOHMANN_JSON_NAMESPACE_VERSION) \139{140#endif141142#ifndef NLOHMANN_JSON_NAMESPACE_END143#define NLOHMANN_JSON_NAMESPACE_END \144} /* namespace (inline namespace) NOLINT(readability/namespace) */ \145} // namespace nlohmann146#endif147148// #include <nlohmann/detail/conversions/from_json.hpp>149// __ _____ _____ _____150// __| | __| | | | JSON for Modern C++151// | | |__ | | | | | | version 3.11.3152// |_____|_____|_____|_|___| https://github.com/nlohmann/json153//154// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>155// SPDX-License-Identifier: MIT156157158159#include <algorithm> // transform160#include <array> // array161#include <forward_list> // forward_list162#include <iterator> // inserter, front_inserter, end163#include <map> // map164#include <string> // string165#include <tuple> // tuple, make_tuple166#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible167#include <unordered_map> // unordered_map168#include <utility> // pair, declval169#include <valarray> // valarray170171// #include <nlohmann/detail/exceptions.hpp>172// __ _____ _____ _____173// __| | __| | | | JSON for Modern C++174// | | |__ | | | | | | version 3.11.3175// |_____|_____|_____|_|___| https://github.com/nlohmann/json176//177// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>178// SPDX-License-Identifier: MIT179180181182#include <cstddef> // nullptr_t183#include <exception> // exception184#if JSON_DIAGNOSTICS185#include <numeric> // accumulate186#endif187#include <stdexcept> // runtime_error188#include <string> // to_string189#include <vector> // vector190191// #include <nlohmann/detail/value_t.hpp>192// __ _____ _____ _____193// __| | __| | | | JSON for Modern C++194// | | |__ | | | | | | version 3.11.3195// |_____|_____|_____|_|___| https://github.com/nlohmann/json196//197// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>198// SPDX-License-Identifier: MIT199200201202#include <array> // array203#include <cstddef> // size_t204#include <cstdint> // uint8_t205#include <string> // string206207// #include <nlohmann/detail/macro_scope.hpp>208// __ _____ _____ _____209// __| | __| | | | JSON for Modern C++210// | | |__ | | | | | | version 3.11.3211// |_____|_____|_____|_|___| https://github.com/nlohmann/json212//213// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>214// SPDX-License-Identifier: MIT215216217218#include <utility> // declval, pair219// #include <nlohmann/detail/meta/detected.hpp>220// __ _____ _____ _____221// __| | __| | | | JSON for Modern C++222// | | |__ | | | | | | version 3.11.3223// |_____|_____|_____|_|___| https://github.com/nlohmann/json224//225// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>226// SPDX-License-Identifier: MIT227228229230#include <type_traits>231232// #include <nlohmann/detail/meta/void_t.hpp>233// __ _____ _____ _____234// __| | __| | | | JSON for Modern C++235// | | |__ | | | | | | version 3.11.3236// |_____|_____|_____|_|___| https://github.com/nlohmann/json237//238// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>239// SPDX-License-Identifier: MIT240241242243// #include <nlohmann/detail/abi_macros.hpp>244245246NLOHMANN_JSON_NAMESPACE_BEGIN247namespace detail248{249250template<typename ...Ts> struct make_void251{252using type = void;253};254template<typename ...Ts> using void_t = typename make_void<Ts...>::type;255256} // namespace detail257NLOHMANN_JSON_NAMESPACE_END258259260NLOHMANN_JSON_NAMESPACE_BEGIN261namespace detail262{263264// https://en.cppreference.com/w/cpp/experimental/is_detected265struct nonesuch266{267nonesuch() = delete;268~nonesuch() = delete;269nonesuch(nonesuch const&) = delete;270nonesuch(nonesuch const&&) = delete;271void operator=(nonesuch const&) = delete;272void operator=(nonesuch&&) = delete;273};274275template<class Default,276class AlwaysVoid,277template<class...> class Op,278class... Args>279struct detector280{281using value_t = std::false_type;282using type = Default;283};284285template<class Default, template<class...> class Op, class... Args>286struct detector<Default, void_t<Op<Args...>>, Op, Args...>287{288using value_t = std::true_type;289using type = Op<Args...>;290};291292template<template<class...> class Op, class... Args>293using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;294295template<template<class...> class Op, class... Args>296struct is_detected_lazy : is_detected<Op, Args...> { };297298template<template<class...> class Op, class... Args>299using detected_t = typename detector<nonesuch, void, Op, Args...>::type;300301template<class Default, template<class...> class Op, class... Args>302using detected_or = detector<Default, void, Op, Args...>;303304template<class Default, template<class...> class Op, class... Args>305using detected_or_t = typename detected_or<Default, Op, Args...>::type;306307template<class Expected, template<class...> class Op, class... Args>308using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;309310template<class To, template<class...> class Op, class... Args>311using is_detected_convertible =312std::is_convertible<detected_t<Op, Args...>, To>;313314} // namespace detail315NLOHMANN_JSON_NAMESPACE_END316317// #include <nlohmann/thirdparty/hedley/hedley.hpp>318319320// __ _____ _____ _____321// __| | __| | | | JSON for Modern C++322// | | |__ | | | | | | version 3.11.3323// |_____|_____|_____|_|___| https://github.com/nlohmann/json324//325// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>326// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson <[email protected]>327// SPDX-License-Identifier: MIT328329/* Hedley - https://nemequ.github.io/hedley330* Created by Evan Nemerson <[email protected]>331*/332333#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)334#if defined(JSON_HEDLEY_VERSION)335#undef JSON_HEDLEY_VERSION336#endif337#define JSON_HEDLEY_VERSION 15338339#if defined(JSON_HEDLEY_STRINGIFY_EX)340#undef JSON_HEDLEY_STRINGIFY_EX341#endif342#define JSON_HEDLEY_STRINGIFY_EX(x) #x343344#if defined(JSON_HEDLEY_STRINGIFY)345#undef JSON_HEDLEY_STRINGIFY346#endif347#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)348349#if defined(JSON_HEDLEY_CONCAT_EX)350#undef JSON_HEDLEY_CONCAT_EX351#endif352#define JSON_HEDLEY_CONCAT_EX(a,b) a##b353354#if defined(JSON_HEDLEY_CONCAT)355#undef JSON_HEDLEY_CONCAT356#endif357#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)358359#if defined(JSON_HEDLEY_CONCAT3_EX)360#undef JSON_HEDLEY_CONCAT3_EX361#endif362#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c363364#if defined(JSON_HEDLEY_CONCAT3)365#undef JSON_HEDLEY_CONCAT3366#endif367#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)368369#if defined(JSON_HEDLEY_VERSION_ENCODE)370#undef JSON_HEDLEY_VERSION_ENCODE371#endif372#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))373374#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)375#undef JSON_HEDLEY_VERSION_DECODE_MAJOR376#endif377#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)378379#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)380#undef JSON_HEDLEY_VERSION_DECODE_MINOR381#endif382#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)383384#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)385#undef JSON_HEDLEY_VERSION_DECODE_REVISION386#endif387#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)388389#if defined(JSON_HEDLEY_GNUC_VERSION)390#undef JSON_HEDLEY_GNUC_VERSION391#endif392#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)393#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)394#elif defined(__GNUC__)395#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)396#endif397398#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)399#undef JSON_HEDLEY_GNUC_VERSION_CHECK400#endif401#if defined(JSON_HEDLEY_GNUC_VERSION)402#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))403#else404#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)405#endif406407#if defined(JSON_HEDLEY_MSVC_VERSION)408#undef JSON_HEDLEY_MSVC_VERSION409#endif410#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)411#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)412#elif defined(_MSC_FULL_VER) && !defined(__ICL)413#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)414#elif defined(_MSC_VER) && !defined(__ICL)415#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)416#endif417418#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)419#undef JSON_HEDLEY_MSVC_VERSION_CHECK420#endif421#if !defined(JSON_HEDLEY_MSVC_VERSION)422#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)423#elif defined(_MSC_VER) && (_MSC_VER >= 1400)424#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))425#elif defined(_MSC_VER) && (_MSC_VER >= 1200)426#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))427#else428#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))429#endif430431#if defined(JSON_HEDLEY_INTEL_VERSION)432#undef JSON_HEDLEY_INTEL_VERSION433#endif434#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)435#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)436#elif defined(__INTEL_COMPILER) && !defined(__ICL)437#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)438#endif439440#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)441#undef JSON_HEDLEY_INTEL_VERSION_CHECK442#endif443#if defined(JSON_HEDLEY_INTEL_VERSION)444#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))445#else446#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)447#endif448449#if defined(JSON_HEDLEY_INTEL_CL_VERSION)450#undef JSON_HEDLEY_INTEL_CL_VERSION451#endif452#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)453#define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)454#endif455456#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)457#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK458#endif459#if defined(JSON_HEDLEY_INTEL_CL_VERSION)460#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))461#else462#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)463#endif464465#if defined(JSON_HEDLEY_PGI_VERSION)466#undef JSON_HEDLEY_PGI_VERSION467#endif468#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)469#define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)470#endif471472#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)473#undef JSON_HEDLEY_PGI_VERSION_CHECK474#endif475#if defined(JSON_HEDLEY_PGI_VERSION)476#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))477#else478#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)479#endif480481#if defined(JSON_HEDLEY_SUNPRO_VERSION)482#undef JSON_HEDLEY_SUNPRO_VERSION483#endif484#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)485#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)486#elif defined(__SUNPRO_C)487#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)488#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)489#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)490#elif defined(__SUNPRO_CC)491#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)492#endif493494#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)495#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK496#endif497#if defined(JSON_HEDLEY_SUNPRO_VERSION)498#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))499#else500#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)501#endif502503#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)504#undef JSON_HEDLEY_EMSCRIPTEN_VERSION505#endif506#if defined(__EMSCRIPTEN__)507#define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)508#endif509510#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)511#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK512#endif513#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)514#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))515#else516#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)517#endif518519#if defined(JSON_HEDLEY_ARM_VERSION)520#undef JSON_HEDLEY_ARM_VERSION521#endif522#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)523#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)524#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)525#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)526#endif527528#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)529#undef JSON_HEDLEY_ARM_VERSION_CHECK530#endif531#if defined(JSON_HEDLEY_ARM_VERSION)532#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))533#else534#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)535#endif536537#if defined(JSON_HEDLEY_IBM_VERSION)538#undef JSON_HEDLEY_IBM_VERSION539#endif540#if defined(__ibmxl__)541#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)542#elif defined(__xlC__) && defined(__xlC_ver__)543#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)544#elif defined(__xlC__)545#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)546#endif547548#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)549#undef JSON_HEDLEY_IBM_VERSION_CHECK550#endif551#if defined(JSON_HEDLEY_IBM_VERSION)552#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))553#else554#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)555#endif556557#if defined(JSON_HEDLEY_TI_VERSION)558#undef JSON_HEDLEY_TI_VERSION559#endif560#if \561defined(__TI_COMPILER_VERSION__) && \562( \563defined(__TMS470__) || defined(__TI_ARM__) || \564defined(__MSP430__) || \565defined(__TMS320C2000__) \566)567#if (__TI_COMPILER_VERSION__ >= 16000000)568#define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))569#endif570#endif571572#if defined(JSON_HEDLEY_TI_VERSION_CHECK)573#undef JSON_HEDLEY_TI_VERSION_CHECK574#endif575#if defined(JSON_HEDLEY_TI_VERSION)576#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))577#else578#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)579#endif580581#if defined(JSON_HEDLEY_TI_CL2000_VERSION)582#undef JSON_HEDLEY_TI_CL2000_VERSION583#endif584#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)585#define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))586#endif587588#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)589#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK590#endif591#if defined(JSON_HEDLEY_TI_CL2000_VERSION)592#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))593#else594#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)595#endif596597#if defined(JSON_HEDLEY_TI_CL430_VERSION)598#undef JSON_HEDLEY_TI_CL430_VERSION599#endif600#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)601#define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))602#endif603604#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)605#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK606#endif607#if defined(JSON_HEDLEY_TI_CL430_VERSION)608#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))609#else610#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)611#endif612613#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)614#undef JSON_HEDLEY_TI_ARMCL_VERSION615#endif616#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))617#define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))618#endif619620#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)621#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK622#endif623#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)624#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))625#else626#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)627#endif628629#if defined(JSON_HEDLEY_TI_CL6X_VERSION)630#undef JSON_HEDLEY_TI_CL6X_VERSION631#endif632#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)633#define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))634#endif635636#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)637#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK638#endif639#if defined(JSON_HEDLEY_TI_CL6X_VERSION)640#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))641#else642#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)643#endif644645#if defined(JSON_HEDLEY_TI_CL7X_VERSION)646#undef JSON_HEDLEY_TI_CL7X_VERSION647#endif648#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)649#define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))650#endif651652#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)653#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK654#endif655#if defined(JSON_HEDLEY_TI_CL7X_VERSION)656#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))657#else658#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)659#endif660661#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)662#undef JSON_HEDLEY_TI_CLPRU_VERSION663#endif664#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)665#define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))666#endif667668#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)669#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK670#endif671#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)672#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))673#else674#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)675#endif676677#if defined(JSON_HEDLEY_CRAY_VERSION)678#undef JSON_HEDLEY_CRAY_VERSION679#endif680#if defined(_CRAYC)681#if defined(_RELEASE_PATCHLEVEL)682#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)683#else684#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)685#endif686#endif687688#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)689#undef JSON_HEDLEY_CRAY_VERSION_CHECK690#endif691#if defined(JSON_HEDLEY_CRAY_VERSION)692#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))693#else694#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)695#endif696697#if defined(JSON_HEDLEY_IAR_VERSION)698#undef JSON_HEDLEY_IAR_VERSION699#endif700#if defined(__IAR_SYSTEMS_ICC__)701#if __VER__ > 1000702#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))703#else704#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)705#endif706#endif707708#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)709#undef JSON_HEDLEY_IAR_VERSION_CHECK710#endif711#if defined(JSON_HEDLEY_IAR_VERSION)712#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))713#else714#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)715#endif716717#if defined(JSON_HEDLEY_TINYC_VERSION)718#undef JSON_HEDLEY_TINYC_VERSION719#endif720#if defined(__TINYC__)721#define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)722#endif723724#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)725#undef JSON_HEDLEY_TINYC_VERSION_CHECK726#endif727#if defined(JSON_HEDLEY_TINYC_VERSION)728#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))729#else730#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)731#endif732733#if defined(JSON_HEDLEY_DMC_VERSION)734#undef JSON_HEDLEY_DMC_VERSION735#endif736#if defined(__DMC__)737#define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)738#endif739740#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)741#undef JSON_HEDLEY_DMC_VERSION_CHECK742#endif743#if defined(JSON_HEDLEY_DMC_VERSION)744#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))745#else746#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)747#endif748749#if defined(JSON_HEDLEY_COMPCERT_VERSION)750#undef JSON_HEDLEY_COMPCERT_VERSION751#endif752#if defined(__COMPCERT_VERSION__)753#define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)754#endif755756#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)757#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK758#endif759#if defined(JSON_HEDLEY_COMPCERT_VERSION)760#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))761#else762#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)763#endif764765#if defined(JSON_HEDLEY_PELLES_VERSION)766#undef JSON_HEDLEY_PELLES_VERSION767#endif768#if defined(__POCC__)769#define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)770#endif771772#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)773#undef JSON_HEDLEY_PELLES_VERSION_CHECK774#endif775#if defined(JSON_HEDLEY_PELLES_VERSION)776#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))777#else778#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)779#endif780781#if defined(JSON_HEDLEY_MCST_LCC_VERSION)782#undef JSON_HEDLEY_MCST_LCC_VERSION783#endif784#if defined(__LCC__) && defined(__LCC_MINOR__)785#define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)786#endif787788#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)789#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK790#endif791#if defined(JSON_HEDLEY_MCST_LCC_VERSION)792#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))793#else794#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)795#endif796797#if defined(JSON_HEDLEY_GCC_VERSION)798#undef JSON_HEDLEY_GCC_VERSION799#endif800#if \801defined(JSON_HEDLEY_GNUC_VERSION) && \802!defined(__clang__) && \803!defined(JSON_HEDLEY_INTEL_VERSION) && \804!defined(JSON_HEDLEY_PGI_VERSION) && \805!defined(JSON_HEDLEY_ARM_VERSION) && \806!defined(JSON_HEDLEY_CRAY_VERSION) && \807!defined(JSON_HEDLEY_TI_VERSION) && \808!defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \809!defined(JSON_HEDLEY_TI_CL430_VERSION) && \810!defined(JSON_HEDLEY_TI_CL2000_VERSION) && \811!defined(JSON_HEDLEY_TI_CL6X_VERSION) && \812!defined(JSON_HEDLEY_TI_CL7X_VERSION) && \813!defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \814!defined(__COMPCERT__) && \815!defined(JSON_HEDLEY_MCST_LCC_VERSION)816#define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION817#endif818819#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)820#undef JSON_HEDLEY_GCC_VERSION_CHECK821#endif822#if defined(JSON_HEDLEY_GCC_VERSION)823#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))824#else825#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)826#endif827828#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)829#undef JSON_HEDLEY_HAS_ATTRIBUTE830#endif831#if \832defined(__has_attribute) && \833( \834(!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \835)836# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)837#else838# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)839#endif840841#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)842#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE843#endif844#if defined(__has_attribute)845#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)846#else847#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)848#endif849850#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)851#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE852#endif853#if defined(__has_attribute)854#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)855#else856#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)857#endif858859#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)860#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE861#endif862#if \863defined(__has_cpp_attribute) && \864defined(__cplusplus) && \865(!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))866#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)867#else868#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)869#endif870871#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)872#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS873#endif874#if !defined(__cplusplus) || !defined(__has_cpp_attribute)875#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)876#elif \877!defined(JSON_HEDLEY_PGI_VERSION) && \878!defined(JSON_HEDLEY_IAR_VERSION) && \879(!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \880(!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))881#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)882#else883#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)884#endif885886#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)887#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE888#endif889#if defined(__has_cpp_attribute) && defined(__cplusplus)890#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)891#else892#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)893#endif894895#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)896#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE897#endif898#if defined(__has_cpp_attribute) && defined(__cplusplus)899#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)900#else901#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)902#endif903904#if defined(JSON_HEDLEY_HAS_BUILTIN)905#undef JSON_HEDLEY_HAS_BUILTIN906#endif907#if defined(__has_builtin)908#define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)909#else910#define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)911#endif912913#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)914#undef JSON_HEDLEY_GNUC_HAS_BUILTIN915#endif916#if defined(__has_builtin)917#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)918#else919#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)920#endif921922#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)923#undef JSON_HEDLEY_GCC_HAS_BUILTIN924#endif925#if defined(__has_builtin)926#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)927#else928#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)929#endif930931#if defined(JSON_HEDLEY_HAS_FEATURE)932#undef JSON_HEDLEY_HAS_FEATURE933#endif934#if defined(__has_feature)935#define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)936#else937#define JSON_HEDLEY_HAS_FEATURE(feature) (0)938#endif939940#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)941#undef JSON_HEDLEY_GNUC_HAS_FEATURE942#endif943#if defined(__has_feature)944#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)945#else946#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)947#endif948949#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)950#undef JSON_HEDLEY_GCC_HAS_FEATURE951#endif952#if defined(__has_feature)953#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)954#else955#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)956#endif957958#if defined(JSON_HEDLEY_HAS_EXTENSION)959#undef JSON_HEDLEY_HAS_EXTENSION960#endif961#if defined(__has_extension)962#define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)963#else964#define JSON_HEDLEY_HAS_EXTENSION(extension) (0)965#endif966967#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)968#undef JSON_HEDLEY_GNUC_HAS_EXTENSION969#endif970#if defined(__has_extension)971#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)972#else973#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)974#endif975976#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)977#undef JSON_HEDLEY_GCC_HAS_EXTENSION978#endif979#if defined(__has_extension)980#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)981#else982#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)983#endif984985#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)986#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE987#endif988#if defined(__has_declspec_attribute)989#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)990#else991#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)992#endif993994#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)995#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE996#endif997#if defined(__has_declspec_attribute)998#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)999#else1000#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)1001#endif10021003#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)1004#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE1005#endif1006#if defined(__has_declspec_attribute)1007#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)1008#else1009#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)1010#endif10111012#if defined(JSON_HEDLEY_HAS_WARNING)1013#undef JSON_HEDLEY_HAS_WARNING1014#endif1015#if defined(__has_warning)1016#define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)1017#else1018#define JSON_HEDLEY_HAS_WARNING(warning) (0)1019#endif10201021#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)1022#undef JSON_HEDLEY_GNUC_HAS_WARNING1023#endif1024#if defined(__has_warning)1025#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)1026#else1027#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)1028#endif10291030#if defined(JSON_HEDLEY_GCC_HAS_WARNING)1031#undef JSON_HEDLEY_GCC_HAS_WARNING1032#endif1033#if defined(__has_warning)1034#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)1035#else1036#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)1037#endif10381039#if \1040(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \1041defined(__clang__) || \1042JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \1043JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1044JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \1045JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \1046JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1047JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1048JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \1049JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \1050JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \1051JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \1052JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1053JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1054JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \1055JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \1056JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \1057(JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))1058#define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)1059#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)1060#define JSON_HEDLEY_PRAGMA(value) __pragma(value)1061#else1062#define JSON_HEDLEY_PRAGMA(value)1063#endif10641065#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)1066#undef JSON_HEDLEY_DIAGNOSTIC_PUSH1067#endif1068#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)1069#undef JSON_HEDLEY_DIAGNOSTIC_POP1070#endif1071#if defined(__clang__)1072#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")1073#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")1074#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1075#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")1076#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")1077#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)1078#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")1079#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")1080#elif \1081JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \1082JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)1083#define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))1084#define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))1085#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)1086#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")1087#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")1088#elif \1089JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1090JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1091JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \1092JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \1093JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1094JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)1095#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")1096#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")1097#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)1098#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")1099#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")1100#else1101#define JSON_HEDLEY_DIAGNOSTIC_PUSH1102#define JSON_HEDLEY_DIAGNOSTIC_POP1103#endif11041105/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for1106HEDLEY INTERNAL USE ONLY. API subject to change without notice. */1107#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)1108#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_1109#endif1110#if defined(__cplusplus)1111# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")1112# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")1113# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")1114# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \1115JSON_HEDLEY_DIAGNOSTIC_PUSH \1116_Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \1117_Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \1118_Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \1119xpr \1120JSON_HEDLEY_DIAGNOSTIC_POP1121# else1122# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \1123JSON_HEDLEY_DIAGNOSTIC_PUSH \1124_Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \1125_Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \1126xpr \1127JSON_HEDLEY_DIAGNOSTIC_POP1128# endif1129# else1130# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \1131JSON_HEDLEY_DIAGNOSTIC_PUSH \1132_Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \1133xpr \1134JSON_HEDLEY_DIAGNOSTIC_POP1135# endif1136# endif1137#endif1138#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)1139#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x1140#endif11411142#if defined(JSON_HEDLEY_CONST_CAST)1143#undef JSON_HEDLEY_CONST_CAST1144#endif1145#if defined(__cplusplus)1146# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))1147#elif \1148JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \1149JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \1150JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1151# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \1152JSON_HEDLEY_DIAGNOSTIC_PUSH \1153JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \1154((T) (expr)); \1155JSON_HEDLEY_DIAGNOSTIC_POP \1156}))1157#else1158# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))1159#endif11601161#if defined(JSON_HEDLEY_REINTERPRET_CAST)1162#undef JSON_HEDLEY_REINTERPRET_CAST1163#endif1164#if defined(__cplusplus)1165#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))1166#else1167#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))1168#endif11691170#if defined(JSON_HEDLEY_STATIC_CAST)1171#undef JSON_HEDLEY_STATIC_CAST1172#endif1173#if defined(__cplusplus)1174#define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))1175#else1176#define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))1177#endif11781179#if defined(JSON_HEDLEY_CPP_CAST)1180#undef JSON_HEDLEY_CPP_CAST1181#endif1182#if defined(__cplusplus)1183# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")1184# define JSON_HEDLEY_CPP_CAST(T, expr) \1185JSON_HEDLEY_DIAGNOSTIC_PUSH \1186_Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \1187((T) (expr)) \1188JSON_HEDLEY_DIAGNOSTIC_POP1189# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)1190# define JSON_HEDLEY_CPP_CAST(T, expr) \1191JSON_HEDLEY_DIAGNOSTIC_PUSH \1192_Pragma("diag_suppress=Pe137") \1193JSON_HEDLEY_DIAGNOSTIC_POP1194# else1195# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))1196# endif1197#else1198# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)1199#endif12001201#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)1202#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED1203#endif1204#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")1205#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")1206#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1207#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")1208#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)1209#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))1210#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)1211#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")1212#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)1213#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")1214#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)1215#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")1216#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)1217#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))1218#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1219#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")1220#elif \1221JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1222(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1223JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1224(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1225JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1226(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1227JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1228(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1229JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1230JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1231JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)1232#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")1233#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)1234#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")1235#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)1236#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")1237#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1238#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")1239#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)1240#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")1241#else1242#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED1243#endif12441245#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)1246#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS1247#endif1248#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")1249#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")1250#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1251#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")1252#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)1253#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))1254#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)1255#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")1256#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)1257#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")1258#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)1259#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))1260#elif \1261JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \1262JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \1263JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1264JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)1265#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")1266#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)1267#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")1268#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1269#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")1270#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1271#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")1272#else1273#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS1274#endif12751276#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)1277#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES1278#endif1279#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")1280#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")1281#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)1282#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")1283#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)1284#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")1285#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)1286#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))1287#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)1288#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))1289#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)1290#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")1291#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)1292#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")1293#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)1294#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")1295#elif \1296JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \1297JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \1298JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)1299#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")1300#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1301#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")1302#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1303#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")1304#else1305#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES1306#endif13071308#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)1309#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL1310#endif1311#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")1312#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")1313#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1314#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")1315#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)1316#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")1317#else1318#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL1319#endif13201321#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)1322#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION1323#endif1324#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")1325#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")1326#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)1327#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")1328#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)1329#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))1330#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1331#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")1332#else1333#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION1334#endif13351336#if defined(JSON_HEDLEY_DEPRECATED)1337#undef JSON_HEDLEY_DEPRECATED1338#endif1339#if defined(JSON_HEDLEY_DEPRECATED_FOR)1340#undef JSON_HEDLEY_DEPRECATED_FOR1341#endif1342#if \1343JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \1344JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)1345#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))1346#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))1347#elif \1348(JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \1349JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \1350JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1351JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \1352JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \1353JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \1354JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \1355JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \1356JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \1357JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1358JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \1359JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1360#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))1361#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))1362#elif defined(__cplusplus) && (__cplusplus >= 201402L)1363#define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])1364#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])1365#elif \1366JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \1367JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \1368JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1369JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1370(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1371JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1372(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1373JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1374(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1375JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1376(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1377JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1378JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1379JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1380JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \1381JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)1382#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))1383#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))1384#elif \1385JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \1386JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \1387JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)1388#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)1389#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)1390#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1391#define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")1392#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")1393#else1394#define JSON_HEDLEY_DEPRECATED(since)1395#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)1396#endif13971398#if defined(JSON_HEDLEY_UNAVAILABLE)1399#undef JSON_HEDLEY_UNAVAILABLE1400#endif1401#if \1402JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \1403JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \1404JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1405JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1406#define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))1407#else1408#define JSON_HEDLEY_UNAVAILABLE(available_since)1409#endif14101411#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)1412#undef JSON_HEDLEY_WARN_UNUSED_RESULT1413#endif1414#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)1415#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG1416#endif1417#if \1418JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \1419JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \1420JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1421JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1422(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1423JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1424(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1425JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1426(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1427JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1428(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1429JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1430JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1431JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1432(JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \1433JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \1434JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1435#define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))1436#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))1437#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)1438#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])1439#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])1440#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)1441#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])1442#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])1443#elif defined(_Check_return_) /* SAL */1444#define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_1445#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_1446#else1447#define JSON_HEDLEY_WARN_UNUSED_RESULT1448#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)1449#endif14501451#if defined(JSON_HEDLEY_SENTINEL)1452#undef JSON_HEDLEY_SENTINEL1453#endif1454#if \1455JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \1456JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \1457JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1458JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \1459JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1460#define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))1461#else1462#define JSON_HEDLEY_SENTINEL(position)1463#endif14641465#if defined(JSON_HEDLEY_NO_RETURN)1466#undef JSON_HEDLEY_NO_RETURN1467#endif1468#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1469#define JSON_HEDLEY_NO_RETURN __noreturn1470#elif \1471JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1472JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1473#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))1474#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L1475#define JSON_HEDLEY_NO_RETURN _Noreturn1476#elif defined(__cplusplus) && (__cplusplus >= 201103L)1477#define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])1478#elif \1479JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \1480JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \1481JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1482JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1483JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1484JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1485(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1486JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1487(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1488JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1489(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1490JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1491(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1492JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1493JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1494JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1495JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)1496#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))1497#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)1498#define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")1499#elif \1500JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \1501JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)1502#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)1503#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)1504#define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")1505#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)1506#define JSON_HEDLEY_NO_RETURN __attribute((noreturn))1507#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)1508#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)1509#else1510#define JSON_HEDLEY_NO_RETURN1511#endif15121513#if defined(JSON_HEDLEY_NO_ESCAPE)1514#undef JSON_HEDLEY_NO_ESCAPE1515#endif1516#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)1517#define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))1518#else1519#define JSON_HEDLEY_NO_ESCAPE1520#endif15211522#if defined(JSON_HEDLEY_UNREACHABLE)1523#undef JSON_HEDLEY_UNREACHABLE1524#endif1525#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)1526#undef JSON_HEDLEY_UNREACHABLE_RETURN1527#endif1528#if defined(JSON_HEDLEY_ASSUME)1529#undef JSON_HEDLEY_ASSUME1530#endif1531#if \1532JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \1533JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1534JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)1535#define JSON_HEDLEY_ASSUME(expr) __assume(expr)1536#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)1537#define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)1538#elif \1539JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \1540JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)1541#if defined(__cplusplus)1542#define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)1543#else1544#define JSON_HEDLEY_ASSUME(expr) _nassert(expr)1545#endif1546#endif1547#if \1548(JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \1549JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \1550JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \1551JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1552JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \1553JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \1554JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1555#define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()1556#elif defined(JSON_HEDLEY_ASSUME)1557#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)1558#endif1559#if !defined(JSON_HEDLEY_ASSUME)1560#if defined(JSON_HEDLEY_UNREACHABLE)1561#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))1562#else1563#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)1564#endif1565#endif1566#if defined(JSON_HEDLEY_UNREACHABLE)1567#if \1568JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \1569JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)1570#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))1571#else1572#define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()1573#endif1574#else1575#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)1576#endif1577#if !defined(JSON_HEDLEY_UNREACHABLE)1578#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)1579#endif15801581JSON_HEDLEY_DIAGNOSTIC_PUSH1582#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")1583#pragma clang diagnostic ignored "-Wpedantic"1584#endif1585#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)1586#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"1587#endif1588#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)1589#if defined(__clang__)1590#pragma clang diagnostic ignored "-Wvariadic-macros"1591#elif defined(JSON_HEDLEY_GCC_VERSION)1592#pragma GCC diagnostic ignored "-Wvariadic-macros"1593#endif1594#endif1595#if defined(JSON_HEDLEY_NON_NULL)1596#undef JSON_HEDLEY_NON_NULL1597#endif1598#if \1599JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \1600JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \1601JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1602JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)1603#define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))1604#else1605#define JSON_HEDLEY_NON_NULL(...)1606#endif1607JSON_HEDLEY_DIAGNOSTIC_POP16081609#if defined(JSON_HEDLEY_PRINTF_FORMAT)1610#undef JSON_HEDLEY_PRINTF_FORMAT1611#endif1612#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)1613#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))1614#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)1615#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))1616#elif \1617JSON_HEDLEY_HAS_ATTRIBUTE(format) || \1618JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \1619JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1620JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \1621JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1622JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1623(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1624JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1625(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1626JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1627(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1628JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1629(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1630JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1631JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1632JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1633JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1634#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))1635#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)1636#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))1637#else1638#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)1639#endif16401641#if defined(JSON_HEDLEY_CONSTEXPR)1642#undef JSON_HEDLEY_CONSTEXPR1643#endif1644#if defined(__cplusplus)1645#if __cplusplus >= 201103L1646#define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)1647#endif1648#endif1649#if !defined(JSON_HEDLEY_CONSTEXPR)1650#define JSON_HEDLEY_CONSTEXPR1651#endif16521653#if defined(JSON_HEDLEY_PREDICT)1654#undef JSON_HEDLEY_PREDICT1655#endif1656#if defined(JSON_HEDLEY_LIKELY)1657#undef JSON_HEDLEY_LIKELY1658#endif1659#if defined(JSON_HEDLEY_UNLIKELY)1660#undef JSON_HEDLEY_UNLIKELY1661#endif1662#if defined(JSON_HEDLEY_UNPREDICTABLE)1663#undef JSON_HEDLEY_UNPREDICTABLE1664#endif1665#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)1666#define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))1667#endif1668#if \1669(JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \1670JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \1671JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1672# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))1673# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))1674# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))1675# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )1676# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )1677#elif \1678(JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \1679JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \1680JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1681(JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \1682JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1683JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1684JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1685JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \1686JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \1687JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \1688JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \1689JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1690JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1691JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \1692JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \1693JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1694# define JSON_HEDLEY_PREDICT(expr, expected, probability) \1695(((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))1696# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \1697(__extension__ ({ \1698double hedley_probability_ = (probability); \1699((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \1700}))1701# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \1702(__extension__ ({ \1703double hedley_probability_ = (probability); \1704((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \1705}))1706# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)1707# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)1708#else1709# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))1710# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))1711# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))1712# define JSON_HEDLEY_LIKELY(expr) (!!(expr))1713# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))1714#endif1715#if !defined(JSON_HEDLEY_UNPREDICTABLE)1716#define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)1717#endif17181719#if defined(JSON_HEDLEY_MALLOC)1720#undef JSON_HEDLEY_MALLOC1721#endif1722#if \1723JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \1724JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \1725JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1726JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1727JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1728JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \1729JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1730(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1731JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1732(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1733JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1734(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1735JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1736(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1737JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1738JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1739JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1740JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1741#define JSON_HEDLEY_MALLOC __attribute__((__malloc__))1742#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)1743#define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")1744#elif \1745JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \1746JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)1747#define JSON_HEDLEY_MALLOC __declspec(restrict)1748#else1749#define JSON_HEDLEY_MALLOC1750#endif17511752#if defined(JSON_HEDLEY_PURE)1753#undef JSON_HEDLEY_PURE1754#endif1755#if \1756JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \1757JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \1758JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1759JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1760JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1761JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1762JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1763(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1764JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1765(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1766JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1767(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1768JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1769(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1770JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1771JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1772JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1773JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \1774JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1775# define JSON_HEDLEY_PURE __attribute__((__pure__))1776#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)1777# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")1778#elif defined(__cplusplus) && \1779( \1780JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \1781JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \1782JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \1783)1784# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")1785#else1786# define JSON_HEDLEY_PURE1787#endif17881789#if defined(JSON_HEDLEY_CONST)1790#undef JSON_HEDLEY_CONST1791#endif1792#if \1793JSON_HEDLEY_HAS_ATTRIBUTE(const) || \1794JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \1795JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1796JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1797JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1798JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1799JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1800(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1801JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1802(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1803JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1804(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1805JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1806(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1807JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1808JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1809JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1810JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \1811JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1812#define JSON_HEDLEY_CONST __attribute__((__const__))1813#elif \1814JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)1815#define JSON_HEDLEY_CONST _Pragma("no_side_effect")1816#else1817#define JSON_HEDLEY_CONST JSON_HEDLEY_PURE1818#endif18191820#if defined(JSON_HEDLEY_RESTRICT)1821#undef JSON_HEDLEY_RESTRICT1822#endif1823#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)1824#define JSON_HEDLEY_RESTRICT restrict1825#elif \1826JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \1827JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \1828JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1829JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \1830JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1831JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1832JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \1833JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1834JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \1835JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \1836JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1837(JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \1838JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \1839defined(__clang__) || \1840JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1841#define JSON_HEDLEY_RESTRICT __restrict1842#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)1843#define JSON_HEDLEY_RESTRICT _Restrict1844#else1845#define JSON_HEDLEY_RESTRICT1846#endif18471848#if defined(JSON_HEDLEY_INLINE)1849#undef JSON_HEDLEY_INLINE1850#endif1851#if \1852(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \1853(defined(__cplusplus) && (__cplusplus >= 199711L))1854#define JSON_HEDLEY_INLINE inline1855#elif \1856defined(JSON_HEDLEY_GCC_VERSION) || \1857JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)1858#define JSON_HEDLEY_INLINE __inline__1859#elif \1860JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \1861JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \1862JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1863JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \1864JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \1865JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \1866JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \1867JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1868JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1869JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1870#define JSON_HEDLEY_INLINE __inline1871#else1872#define JSON_HEDLEY_INLINE1873#endif18741875#if defined(JSON_HEDLEY_ALWAYS_INLINE)1876#undef JSON_HEDLEY_ALWAYS_INLINE1877#endif1878#if \1879JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \1880JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \1881JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1882JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1883JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1884JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1885JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1886(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1887JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1888(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1889JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1890(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1891JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1892(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1893JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1894JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1895JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1896JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \1897JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)1898# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE1899#elif \1900JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \1901JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)1902# define JSON_HEDLEY_ALWAYS_INLINE __forceinline1903#elif defined(__cplusplus) && \1904( \1905JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1906JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1907JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1908JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \1909JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1910JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \1911)1912# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")1913#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1914# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")1915#else1916# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE1917#endif19181919#if defined(JSON_HEDLEY_NEVER_INLINE)1920#undef JSON_HEDLEY_NEVER_INLINE1921#endif1922#if \1923JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \1924JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \1925JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1926JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1927JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1928JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1929JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1930(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1931JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1932(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1933JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1934(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1935JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1936(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1937JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1938JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1939JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1940JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \1941JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)1942#define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))1943#elif \1944JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \1945JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)1946#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)1947#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)1948#define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")1949#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)1950#define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")1951#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1952#define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")1953#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)1954#define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))1955#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)1956#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)1957#else1958#define JSON_HEDLEY_NEVER_INLINE1959#endif19601961#if defined(JSON_HEDLEY_PRIVATE)1962#undef JSON_HEDLEY_PRIVATE1963#endif1964#if defined(JSON_HEDLEY_PUBLIC)1965#undef JSON_HEDLEY_PUBLIC1966#endif1967#if defined(JSON_HEDLEY_IMPORT)1968#undef JSON_HEDLEY_IMPORT1969#endif1970#if defined(_WIN32) || defined(__CYGWIN__)1971# define JSON_HEDLEY_PRIVATE1972# define JSON_HEDLEY_PUBLIC __declspec(dllexport)1973# define JSON_HEDLEY_IMPORT __declspec(dllimport)1974#else1975# if \1976JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \1977JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \1978JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1979JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1980JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1981JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \1982( \1983defined(__TI_EABI__) && \1984( \1985(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1986JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \1987) \1988) || \1989JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)1990# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))1991# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))1992# else1993# define JSON_HEDLEY_PRIVATE1994# define JSON_HEDLEY_PUBLIC1995# endif1996# define JSON_HEDLEY_IMPORT extern1997#endif19981999#if defined(JSON_HEDLEY_NO_THROW)2000#undef JSON_HEDLEY_NO_THROW2001#endif2002#if \2003JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \2004JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \2005JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \2006JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)2007#define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))2008#elif \2009JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \2010JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \2011JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)2012#define JSON_HEDLEY_NO_THROW __declspec(nothrow)2013#else2014#define JSON_HEDLEY_NO_THROW2015#endif20162017#if defined(JSON_HEDLEY_FALL_THROUGH)2018#undef JSON_HEDLEY_FALL_THROUGH2019#endif2020#if \2021JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \2022JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \2023JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)2024#define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))2025#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)2026#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])2027#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)2028#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])2029#elif defined(__fallthrough) /* SAL */2030#define JSON_HEDLEY_FALL_THROUGH __fallthrough2031#else2032#define JSON_HEDLEY_FALL_THROUGH2033#endif20342035#if defined(JSON_HEDLEY_RETURNS_NON_NULL)2036#undef JSON_HEDLEY_RETURNS_NON_NULL2037#endif2038#if \2039JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \2040JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \2041JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)2042#define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))2043#elif defined(_Ret_notnull_) /* SAL */2044#define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_2045#else2046#define JSON_HEDLEY_RETURNS_NON_NULL2047#endif20482049#if defined(JSON_HEDLEY_ARRAY_PARAM)2050#undef JSON_HEDLEY_ARRAY_PARAM2051#endif2052#if \2053defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \2054!defined(__STDC_NO_VLA__) && \2055!defined(__cplusplus) && \2056!defined(JSON_HEDLEY_PGI_VERSION) && \2057!defined(JSON_HEDLEY_TINYC_VERSION)2058#define JSON_HEDLEY_ARRAY_PARAM(name) (name)2059#else2060#define JSON_HEDLEY_ARRAY_PARAM(name)2061#endif20622063#if defined(JSON_HEDLEY_IS_CONSTANT)2064#undef JSON_HEDLEY_IS_CONSTANT2065#endif2066#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)2067#undef JSON_HEDLEY_REQUIRE_CONSTEXPR2068#endif2069/* JSON_HEDLEY_IS_CONSTEXPR_ is for2070HEDLEY INTERNAL USE ONLY. API subject to change without notice. */2071#if defined(JSON_HEDLEY_IS_CONSTEXPR_)2072#undef JSON_HEDLEY_IS_CONSTEXPR_2073#endif2074#if \2075JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \2076JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \2077JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \2078JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \2079JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \2080JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \2081JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \2082(JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \2083JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \2084JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)2085#define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)2086#endif2087#if !defined(__cplusplus)2088# if \2089JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \2090JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \2091JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \2092JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \2093JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \2094JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \2095JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)2096#if defined(__INTPTR_TYPE__)2097#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)2098#else2099#include <stdint.h>2100#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)2101#endif2102# elif \2103( \2104defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \2105!defined(JSON_HEDLEY_SUNPRO_VERSION) && \2106!defined(JSON_HEDLEY_PGI_VERSION) && \2107!defined(JSON_HEDLEY_IAR_VERSION)) || \2108(JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \2109JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \2110JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \2111JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \2112JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)2113#if defined(__INTPTR_TYPE__)2114#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)2115#else2116#include <stdint.h>2117#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)2118#endif2119# elif \2120defined(JSON_HEDLEY_GCC_VERSION) || \2121defined(JSON_HEDLEY_INTEL_VERSION) || \2122defined(JSON_HEDLEY_TINYC_VERSION) || \2123defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \2124JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \2125defined(JSON_HEDLEY_TI_CL2000_VERSION) || \2126defined(JSON_HEDLEY_TI_CL6X_VERSION) || \2127defined(JSON_HEDLEY_TI_CL7X_VERSION) || \2128defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \2129defined(__clang__)2130# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \2131sizeof(void) != \2132sizeof(*( \21331 ? \2134((void*) ((expr) * 0L) ) : \2135((struct { char v[sizeof(void) * 2]; } *) 1) \2136) \2137) \2138)2139# endif2140#endif2141#if defined(JSON_HEDLEY_IS_CONSTEXPR_)2142#if !defined(JSON_HEDLEY_IS_CONSTANT)2143#define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)2144#endif2145#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))2146#else2147#if !defined(JSON_HEDLEY_IS_CONSTANT)2148#define JSON_HEDLEY_IS_CONSTANT(expr) (0)2149#endif2150#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)2151#endif21522153#if defined(JSON_HEDLEY_BEGIN_C_DECLS)2154#undef JSON_HEDLEY_BEGIN_C_DECLS2155#endif2156#if defined(JSON_HEDLEY_END_C_DECLS)2157#undef JSON_HEDLEY_END_C_DECLS2158#endif2159#if defined(JSON_HEDLEY_C_DECL)2160#undef JSON_HEDLEY_C_DECL2161#endif2162#if defined(__cplusplus)2163#define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {2164#define JSON_HEDLEY_END_C_DECLS }2165#define JSON_HEDLEY_C_DECL extern "C"2166#else2167#define JSON_HEDLEY_BEGIN_C_DECLS2168#define JSON_HEDLEY_END_C_DECLS2169#define JSON_HEDLEY_C_DECL2170#endif21712172#if defined(JSON_HEDLEY_STATIC_ASSERT)2173#undef JSON_HEDLEY_STATIC_ASSERT2174#endif2175#if \2176!defined(__cplusplus) && ( \2177(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \2178(JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \2179JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \2180JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \2181defined(_Static_assert) \2182)2183# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)2184#elif \2185(defined(__cplusplus) && (__cplusplus >= 201103L)) || \2186JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \2187JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)2188# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))2189#else2190# define JSON_HEDLEY_STATIC_ASSERT(expr, message)2191#endif21922193#if defined(JSON_HEDLEY_NULL)2194#undef JSON_HEDLEY_NULL2195#endif2196#if defined(__cplusplus)2197#if __cplusplus >= 201103L2198#define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)2199#elif defined(NULL)2200#define JSON_HEDLEY_NULL NULL2201#else2202#define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)2203#endif2204#elif defined(NULL)2205#define JSON_HEDLEY_NULL NULL2206#else2207#define JSON_HEDLEY_NULL ((void*) 0)2208#endif22092210#if defined(JSON_HEDLEY_MESSAGE)2211#undef JSON_HEDLEY_MESSAGE2212#endif2213#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")2214# define JSON_HEDLEY_MESSAGE(msg) \2215JSON_HEDLEY_DIAGNOSTIC_PUSH \2216JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \2217JSON_HEDLEY_PRAGMA(message msg) \2218JSON_HEDLEY_DIAGNOSTIC_POP2219#elif \2220JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \2221JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)2222# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)2223#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)2224# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)2225#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)2226# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))2227#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)2228# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))2229#else2230# define JSON_HEDLEY_MESSAGE(msg)2231#endif22322233#if defined(JSON_HEDLEY_WARNING)2234#undef JSON_HEDLEY_WARNING2235#endif2236#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")2237# define JSON_HEDLEY_WARNING(msg) \2238JSON_HEDLEY_DIAGNOSTIC_PUSH \2239JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \2240JSON_HEDLEY_PRAGMA(clang warning msg) \2241JSON_HEDLEY_DIAGNOSTIC_POP2242#elif \2243JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \2244JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \2245JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)2246# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)2247#elif \2248JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \2249JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)2250# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))2251#else2252# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)2253#endif22542255#if defined(JSON_HEDLEY_REQUIRE)2256#undef JSON_HEDLEY_REQUIRE2257#endif2258#if defined(JSON_HEDLEY_REQUIRE_MSG)2259#undef JSON_HEDLEY_REQUIRE_MSG2260#endif2261#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)2262# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")2263# define JSON_HEDLEY_REQUIRE(expr) \2264JSON_HEDLEY_DIAGNOSTIC_PUSH \2265_Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \2266__attribute__((diagnose_if(!(expr), #expr, "error"))) \2267JSON_HEDLEY_DIAGNOSTIC_POP2268# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \2269JSON_HEDLEY_DIAGNOSTIC_PUSH \2270_Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \2271__attribute__((diagnose_if(!(expr), msg, "error"))) \2272JSON_HEDLEY_DIAGNOSTIC_POP2273# else2274# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))2275# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))2276# endif2277#else2278# define JSON_HEDLEY_REQUIRE(expr)2279# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)2280#endif22812282#if defined(JSON_HEDLEY_FLAGS)2283#undef JSON_HEDLEY_FLAGS2284#endif2285#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))2286#define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))2287#else2288#define JSON_HEDLEY_FLAGS2289#endif22902291#if defined(JSON_HEDLEY_FLAGS_CAST)2292#undef JSON_HEDLEY_FLAGS_CAST2293#endif2294#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)2295# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \2296JSON_HEDLEY_DIAGNOSTIC_PUSH \2297_Pragma("warning(disable:188)") \2298((T) (expr)); \2299JSON_HEDLEY_DIAGNOSTIC_POP \2300}))2301#else2302# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)2303#endif23042305#if defined(JSON_HEDLEY_EMPTY_BASES)2306#undef JSON_HEDLEY_EMPTY_BASES2307#endif2308#if \2309(JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \2310JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)2311#define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)2312#else2313#define JSON_HEDLEY_EMPTY_BASES2314#endif23152316/* Remaining macros are deprecated. */23172318#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)2319#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK2320#endif2321#if defined(__clang__)2322#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)2323#else2324#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)2325#endif23262327#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)2328#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE2329#endif2330#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)23312332#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)2333#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE2334#endif2335#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)23362337#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)2338#undef JSON_HEDLEY_CLANG_HAS_BUILTIN2339#endif2340#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)23412342#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)2343#undef JSON_HEDLEY_CLANG_HAS_FEATURE2344#endif2345#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)23462347#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)2348#undef JSON_HEDLEY_CLANG_HAS_EXTENSION2349#endif2350#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)23512352#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)2353#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE2354#endif2355#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)23562357#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)2358#undef JSON_HEDLEY_CLANG_HAS_WARNING2359#endif2360#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)23612362#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */236323642365// This file contains all internal macro definitions (except those affecting ABI)2366// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them23672368// #include <nlohmann/detail/abi_macros.hpp>236923702371// exclude unsupported compilers2372#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)2373#if defined(__clang__)2374#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 304002375#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"2376#endif2377#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))2378#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 408002379#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"2380#endif2381#endif2382#endif23832384// C++ language standard detection2385// if the user manually specified the used c++ version this is skipped2386#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)2387#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)2388#define JSON_HAS_CPP_202389#define JSON_HAS_CPP_172390#define JSON_HAS_CPP_142391#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #4642392#define JSON_HAS_CPP_172393#define JSON_HAS_CPP_142394#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)2395#define JSON_HAS_CPP_142396#endif2397// the cpp 11 flag is always specified because it is the minimal required version2398#define JSON_HAS_CPP_112399#endif24002401#ifdef __has_include2402#if __has_include(<version>)2403#include <version>2404#endif2405#endif24062407#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)2408#ifdef JSON_HAS_CPP_172409#if defined(__cpp_lib_filesystem)2410#define JSON_HAS_FILESYSTEM 12411#elif defined(__cpp_lib_experimental_filesystem)2412#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 12413#elif !defined(__has_include)2414#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 12415#elif __has_include(<filesystem>)2416#define JSON_HAS_FILESYSTEM 12417#elif __has_include(<experimental/filesystem>)2418#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 12419#endif24202421// std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/2422#if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 82423#undef JSON_HAS_FILESYSTEM2424#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM2425#endif24262427// no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support2428#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 82429#undef JSON_HAS_FILESYSTEM2430#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM2431#endif24322433// no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support2434#if defined(__clang_major__) && __clang_major__ < 72435#undef JSON_HAS_FILESYSTEM2436#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM2437#endif24382439// no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support2440#if defined(_MSC_VER) && _MSC_VER < 19142441#undef JSON_HAS_FILESYSTEM2442#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM2443#endif24442445// no filesystem support before iOS 132446#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 1300002447#undef JSON_HAS_FILESYSTEM2448#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM2449#endif24502451// no filesystem support before macOS Catalina2452#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1015002453#undef JSON_HAS_FILESYSTEM2454#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM2455#endif2456#endif2457#endif24582459#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM2460#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 02461#endif24622463#ifndef JSON_HAS_FILESYSTEM2464#define JSON_HAS_FILESYSTEM 02465#endif24662467#ifndef JSON_HAS_THREE_WAY_COMPARISON2468#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \2469&& defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L2470#define JSON_HAS_THREE_WAY_COMPARISON 12471#else2472#define JSON_HAS_THREE_WAY_COMPARISON 02473#endif2474#endif24752476#ifndef JSON_HAS_RANGES2477// ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error2478#if defined(__GLIBCXX__) && __GLIBCXX__ == 202104272479#define JSON_HAS_RANGES 02480#elif defined(__cpp_lib_ranges)2481#define JSON_HAS_RANGES 12482#else2483#define JSON_HAS_RANGES 02484#endif2485#endif24862487#ifndef JSON_HAS_STATIC_RTTI2488#if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 02489#define JSON_HAS_STATIC_RTTI 12490#else2491#define JSON_HAS_STATIC_RTTI 02492#endif2493#endif24942495#ifdef JSON_HAS_CPP_172496#define JSON_INLINE_VARIABLE inline2497#else2498#define JSON_INLINE_VARIABLE2499#endif25002501#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)2502#define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]2503#else2504#define JSON_NO_UNIQUE_ADDRESS2505#endif25062507// disable documentation warnings on clang2508#if defined(__clang__)2509#pragma clang diagnostic push2510#pragma clang diagnostic ignored "-Wdocumentation"2511#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"2512#endif25132514// allow disabling exceptions2515#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)2516#define JSON_THROW(exception) throw exception2517#define JSON_TRY try2518#define JSON_CATCH(exception) catch(exception)2519#define JSON_INTERNAL_CATCH(exception) catch(exception)2520#else2521#include <cstdlib>2522#define JSON_THROW(exception) std::abort()2523#define JSON_TRY if(true)2524#define JSON_CATCH(exception) if(false)2525#define JSON_INTERNAL_CATCH(exception) if(false)2526#endif25272528// override exception macros2529#if defined(JSON_THROW_USER)2530#undef JSON_THROW2531#define JSON_THROW JSON_THROW_USER2532#endif2533#if defined(JSON_TRY_USER)2534#undef JSON_TRY2535#define JSON_TRY JSON_TRY_USER2536#endif2537#if defined(JSON_CATCH_USER)2538#undef JSON_CATCH2539#define JSON_CATCH JSON_CATCH_USER2540#undef JSON_INTERNAL_CATCH2541#define JSON_INTERNAL_CATCH JSON_CATCH_USER2542#endif2543#if defined(JSON_INTERNAL_CATCH_USER)2544#undef JSON_INTERNAL_CATCH2545#define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER2546#endif25472548// allow overriding assert2549#if !defined(JSON_ASSERT)2550#include <cassert> // assert2551#define JSON_ASSERT(x) assert(x)2552#endif25532554// allow to access some private functions (needed by the test suite)2555#if defined(JSON_TESTS_PRIVATE)2556#define JSON_PRIVATE_UNLESS_TESTED public2557#else2558#define JSON_PRIVATE_UNLESS_TESTED private2559#endif25602561/*!2562@brief macro to briefly define a mapping between an enum and JSON2563@def NLOHMANN_JSON_SERIALIZE_ENUM2564@since version 3.4.02565*/2566#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \2567template<typename BasicJsonType> \2568inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \2569{ \2570static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \2571static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \2572auto it = std::find_if(std::begin(m), std::end(m), \2573[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \2574{ \2575return ej_pair.first == e; \2576}); \2577j = ((it != std::end(m)) ? it : std::begin(m))->second; \2578} \2579template<typename BasicJsonType> \2580inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \2581{ \2582static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \2583static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \2584auto it = std::find_if(std::begin(m), std::end(m), \2585[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \2586{ \2587return ej_pair.second == j; \2588}); \2589e = ((it != std::end(m)) ? it : std::begin(m))->first; \2590}25912592// Ugly macros to avoid uglier copy-paste when specializing basic_json. They2593// may be removed in the future once the class is split.25942595#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \2596template<template<typename, typename, typename...> class ObjectType, \2597template<typename, typename...> class ArrayType, \2598class StringType, class BooleanType, class NumberIntegerType, \2599class NumberUnsignedType, class NumberFloatType, \2600template<typename> class AllocatorType, \2601template<typename, typename = void> class JSONSerializer, \2602class BinaryType, \2603class CustomBaseClass>26042605#define NLOHMANN_BASIC_JSON_TPL \2606basic_json<ObjectType, ArrayType, StringType, BooleanType, \2607NumberIntegerType, NumberUnsignedType, NumberFloatType, \2608AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>26092610// Macros to simplify conversion from/to types26112612#define NLOHMANN_JSON_EXPAND( x ) x2613#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,...) NAME2614#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \2615NLOHMANN_JSON_PASTE64, \2616NLOHMANN_JSON_PASTE63, \2617NLOHMANN_JSON_PASTE62, \2618NLOHMANN_JSON_PASTE61, \2619NLOHMANN_JSON_PASTE60, \2620NLOHMANN_JSON_PASTE59, \2621NLOHMANN_JSON_PASTE58, \2622NLOHMANN_JSON_PASTE57, \2623NLOHMANN_JSON_PASTE56, \2624NLOHMANN_JSON_PASTE55, \2625NLOHMANN_JSON_PASTE54, \2626NLOHMANN_JSON_PASTE53, \2627NLOHMANN_JSON_PASTE52, \2628NLOHMANN_JSON_PASTE51, \2629NLOHMANN_JSON_PASTE50, \2630NLOHMANN_JSON_PASTE49, \2631NLOHMANN_JSON_PASTE48, \2632NLOHMANN_JSON_PASTE47, \2633NLOHMANN_JSON_PASTE46, \2634NLOHMANN_JSON_PASTE45, \2635NLOHMANN_JSON_PASTE44, \2636NLOHMANN_JSON_PASTE43, \2637NLOHMANN_JSON_PASTE42, \2638NLOHMANN_JSON_PASTE41, \2639NLOHMANN_JSON_PASTE40, \2640NLOHMANN_JSON_PASTE39, \2641NLOHMANN_JSON_PASTE38, \2642NLOHMANN_JSON_PASTE37, \2643NLOHMANN_JSON_PASTE36, \2644NLOHMANN_JSON_PASTE35, \2645NLOHMANN_JSON_PASTE34, \2646NLOHMANN_JSON_PASTE33, \2647NLOHMANN_JSON_PASTE32, \2648NLOHMANN_JSON_PASTE31, \2649NLOHMANN_JSON_PASTE30, \2650NLOHMANN_JSON_PASTE29, \2651NLOHMANN_JSON_PASTE28, \2652NLOHMANN_JSON_PASTE27, \2653NLOHMANN_JSON_PASTE26, \2654NLOHMANN_JSON_PASTE25, \2655NLOHMANN_JSON_PASTE24, \2656NLOHMANN_JSON_PASTE23, \2657NLOHMANN_JSON_PASTE22, \2658NLOHMANN_JSON_PASTE21, \2659NLOHMANN_JSON_PASTE20, \2660NLOHMANN_JSON_PASTE19, \2661NLOHMANN_JSON_PASTE18, \2662NLOHMANN_JSON_PASTE17, \2663NLOHMANN_JSON_PASTE16, \2664NLOHMANN_JSON_PASTE15, \2665NLOHMANN_JSON_PASTE14, \2666NLOHMANN_JSON_PASTE13, \2667NLOHMANN_JSON_PASTE12, \2668NLOHMANN_JSON_PASTE11, \2669NLOHMANN_JSON_PASTE10, \2670NLOHMANN_JSON_PASTE9, \2671NLOHMANN_JSON_PASTE8, \2672NLOHMANN_JSON_PASTE7, \2673NLOHMANN_JSON_PASTE6, \2674NLOHMANN_JSON_PASTE5, \2675NLOHMANN_JSON_PASTE4, \2676NLOHMANN_JSON_PASTE3, \2677NLOHMANN_JSON_PASTE2, \2678NLOHMANN_JSON_PASTE1)(__VA_ARGS__))2679#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)2680#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)2681#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)2682#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)2683#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)2684#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)2685#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)2686#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)2687#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)2688#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)2689#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)2690#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)2691#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)2692#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)2693#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)2694#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)2695#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)2696#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)2697#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)2698#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)2699#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)2700#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)2701#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)2702#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)2703#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)2704#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)2705#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)2706#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)2707#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)2708#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)2709#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)2710#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)2711#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)2712#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)2713#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)2714#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)2715#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)2716#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)2717#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)2718#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)2719#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)2720#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)2721#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)2722#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)2723#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)2724#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)2725#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)2726#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)2727#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)2728#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)2729#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)2730#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)2731#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)2732#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)2733#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)2734#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)2735#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)2736#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)2737#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)2738#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)2739#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)2740#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)2741#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)27422743#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;2744#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);2745#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);27462747/*!2748@brief macro2749@def NLOHMANN_DEFINE_TYPE_INTRUSIVE2750@since version 3.9.02751*/2752#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \2753friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \2754friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }27552756#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \2757friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \2758friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }27592760#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \2761friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }27622763/*!2764@brief macro2765@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE2766@since version 3.9.02767*/2768#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \2769inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \2770inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }27712772#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \2773inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }27742775#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \2776inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \2777inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }27782779// inspired from https://stackoverflow.com/a/267455912780// allows to call any std function as if (e.g. with begin):2781// using std::begin; begin(x);2782//2783// it allows using the detected idiom to retrieve the return type2784// of such an expression2785#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \2786namespace detail { \2787using std::std_name; \2788\2789template<typename... T> \2790using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \2791} \2792\2793namespace detail2 { \2794struct std_name##_tag \2795{ \2796}; \2797\2798template<typename... T> \2799std_name##_tag std_name(T&&...); \2800\2801template<typename... T> \2802using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \2803\2804template<typename... T> \2805struct would_call_std_##std_name \2806{ \2807static constexpr auto const value = ::nlohmann::detail:: \2808is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \2809}; \2810} /* namespace detail2 */ \2811\2812template<typename... T> \2813struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \2814{ \2815}28162817#ifndef JSON_USE_IMPLICIT_CONVERSIONS2818#define JSON_USE_IMPLICIT_CONVERSIONS 12819#endif28202821#if JSON_USE_IMPLICIT_CONVERSIONS2822#define JSON_EXPLICIT2823#else2824#define JSON_EXPLICIT explicit2825#endif28262827#ifndef JSON_DISABLE_ENUM_SERIALIZATION2828#define JSON_DISABLE_ENUM_SERIALIZATION 02829#endif28302831#ifndef JSON_USE_GLOBAL_UDLS2832#define JSON_USE_GLOBAL_UDLS 12833#endif28342835#if JSON_HAS_THREE_WAY_COMPARISON2836#include <compare> // partial_ordering2837#endif28382839NLOHMANN_JSON_NAMESPACE_BEGIN2840namespace detail2841{28422843///////////////////////////2844// JSON type enumeration //2845///////////////////////////28462847/*!2848@brief the JSON type enumeration28492850This enumeration collects the different JSON types. It is internally used to2851distinguish the stored values, and the functions @ref basic_json::is_null(),2852@ref basic_json::is_object(), @ref basic_json::is_array(),2853@ref basic_json::is_string(), @ref basic_json::is_boolean(),2854@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),2855@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),2856@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and2857@ref basic_json::is_structured() rely on it.28582859@note There are three enumeration entries (number_integer, number_unsigned, and2860number_float), because the library distinguishes these three types for numbers:2861@ref basic_json::number_unsigned_t is used for unsigned integers,2862@ref basic_json::number_integer_t is used for signed integers, and2863@ref basic_json::number_float_t is used for floating-point numbers or to2864approximate integers which do not fit in the limits of their respective type.28652866@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON2867value with the default value for a given type28682869@since version 1.0.02870*/2871enum class value_t : std::uint8_t2872{2873null, ///< null value2874object, ///< object (unordered set of name/value pairs)2875array, ///< array (ordered collection of values)2876string, ///< string value2877boolean, ///< boolean value2878number_integer, ///< number value (signed integer)2879number_unsigned, ///< number value (unsigned integer)2880number_float, ///< number value (floating-point)2881binary, ///< binary array (ordered collection of bytes)2882discarded ///< discarded by the parser callback function2883};28842885/*!2886@brief comparison operator for JSON types28872888Returns an ordering that is similar to Python:2889- order: null < boolean < number < object < array < string < binary2890- furthermore, each type is not smaller than itself2891- discarded values are not comparable2892- binary is represented as a b"" string in python and directly comparable to a2893string; however, making a binary array directly comparable with a string would2894be surprising behavior in a JSON file.28952896@since version 1.0.02897*/2898#if JSON_HAS_THREE_WAY_COMPARISON2899inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*2900#else2901inline bool operator<(const value_t lhs, const value_t rhs) noexcept2902#endif2903{2904static constexpr std::array<std::uint8_t, 9> order = {{29050 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,29061 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,29076 /* binary */2908}2909};29102911const auto l_index = static_cast<std::size_t>(lhs);2912const auto r_index = static_cast<std::size_t>(rhs);2913#if JSON_HAS_THREE_WAY_COMPARISON2914if (l_index < order.size() && r_index < order.size())2915{2916return order[l_index] <=> order[r_index]; // *NOPAD*2917}2918return std::partial_ordering::unordered;2919#else2920return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];2921#endif2922}29232924// GCC selects the built-in operator< over an operator rewritten from2925// a user-defined spaceship operator2926// Clang, MSVC, and ICC select the rewritten candidate2927// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)2928#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)2929inline bool operator<(const value_t lhs, const value_t rhs) noexcept2930{2931return std::is_lt(lhs <=> rhs); // *NOPAD*2932}2933#endif29342935} // namespace detail2936NLOHMANN_JSON_NAMESPACE_END29372938// #include <nlohmann/detail/string_escape.hpp>2939// __ _____ _____ _____2940// __| | __| | | | JSON for Modern C++2941// | | |__ | | | | | | version 3.11.32942// |_____|_____|_____|_|___| https://github.com/nlohmann/json2943//2944// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>2945// SPDX-License-Identifier: MIT2946294729482949// #include <nlohmann/detail/abi_macros.hpp>295029512952NLOHMANN_JSON_NAMESPACE_BEGIN2953namespace detail2954{29552956/*!2957@brief replace all occurrences of a substring by another string29582959@param[in,out] s the string to manipulate; changed so that all2960occurrences of @a f are replaced with @a t2961@param[in] f the substring to replace with @a t2962@param[in] t the string to replace @a f29632964@pre The search string @a f must not be empty. **This precondition is2965enforced with an assertion.**29662967@since version 2.0.02968*/2969template<typename StringType>2970inline void replace_substring(StringType& s, const StringType& f,2971const StringType& t)2972{2973JSON_ASSERT(!f.empty());2974for (auto pos = s.find(f); // find first occurrence of f2975pos != StringType::npos; // make sure f was found2976s.replace(pos, f.size(), t), // replace with t, and2977pos = s.find(f, pos + t.size())) // find next occurrence of f2978{}2979}29802981/*!2982* @brief string escaping as described in RFC 6901 (Sect. 4)2983* @param[in] s string to escape2984* @return escaped string2985*2986* Note the order of escaping "~" to "~0" and "/" to "~1" is important.2987*/2988template<typename StringType>2989inline StringType escape(StringType s)2990{2991replace_substring(s, StringType{"~"}, StringType{"~0"});2992replace_substring(s, StringType{"/"}, StringType{"~1"});2993return s;2994}29952996/*!2997* @brief string unescaping as described in RFC 6901 (Sect. 4)2998* @param[in] s string to unescape2999* @return unescaped string3000*3001* Note the order of escaping "~1" to "/" and "~0" to "~" is important.3002*/3003template<typename StringType>3004static void unescape(StringType& s)3005{3006replace_substring(s, StringType{"~1"}, StringType{"/"});3007replace_substring(s, StringType{"~0"}, StringType{"~"});3008}30093010} // namespace detail3011NLOHMANN_JSON_NAMESPACE_END30123013// #include <nlohmann/detail/input/position_t.hpp>3014// __ _____ _____ _____3015// __| | __| | | | JSON for Modern C++3016// | | |__ | | | | | | version 3.11.33017// |_____|_____|_____|_|___| https://github.com/nlohmann/json3018//3019// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>3020// SPDX-License-Identifier: MIT3021302230233024#include <cstddef> // size_t30253026// #include <nlohmann/detail/abi_macros.hpp>302730283029NLOHMANN_JSON_NAMESPACE_BEGIN3030namespace detail3031{30323033/// struct to capture the start position of the current token3034struct position_t3035{3036/// the total number of characters read3037std::size_t chars_read_total = 0;3038/// the number of characters read in the current line3039std::size_t chars_read_current_line = 0;3040/// the number of lines read3041std::size_t lines_read = 0;30423043/// conversion to size_t to preserve SAX interface3044constexpr operator size_t() const3045{3046return chars_read_total;3047}3048};30493050} // namespace detail3051NLOHMANN_JSON_NAMESPACE_END30523053// #include <nlohmann/detail/macro_scope.hpp>30543055// #include <nlohmann/detail/meta/cpp_future.hpp>3056// __ _____ _____ _____3057// __| | __| | | | JSON for Modern C++3058// | | |__ | | | | | | version 3.11.33059// |_____|_____|_____|_|___| https://github.com/nlohmann/json3060//3061// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>3062// SPDX-FileCopyrightText: 2018 The Abseil Authors3063// SPDX-License-Identifier: MIT3064306530663067#include <array> // array3068#include <cstddef> // size_t3069#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type3070#include <utility> // index_sequence, make_index_sequence, index_sequence_for30713072// #include <nlohmann/detail/macro_scope.hpp>307330743075NLOHMANN_JSON_NAMESPACE_BEGIN3076namespace detail3077{30783079template<typename T>3080using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;30813082#ifdef JSON_HAS_CPP_1430833084// the following utilities are natively available in C++143085using std::enable_if_t;3086using std::index_sequence;3087using std::make_index_sequence;3088using std::index_sequence_for;30893090#else30913092// alias templates to reduce boilerplate3093template<bool B, typename T = void>3094using enable_if_t = typename std::enable_if<B, T>::type;30953096// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h3097// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.30983099//// START OF CODE FROM GOOGLE ABSEIL31003101// integer_sequence3102//3103// Class template representing a compile-time integer sequence. An instantiation3104// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its3105// type through its template arguments (which is a common need when3106// working with C++11 variadic templates). `absl::integer_sequence` is designed3107// to be a drop-in replacement for C++14's `std::integer_sequence`.3108//3109// Example:3110//3111// template< class T, T... Ints >3112// void user_function(integer_sequence<T, Ints...>);3113//3114// int main()3115// {3116// // user_function's `T` will be deduced to `int` and `Ints...`3117// // will be deduced to `0, 1, 2, 3, 4`.3118// user_function(make_integer_sequence<int, 5>());3119// }3120template <typename T, T... Ints>3121struct integer_sequence3122{3123using value_type = T;3124static constexpr std::size_t size() noexcept3125{3126return sizeof...(Ints);3127}3128};31293130// index_sequence3131//3132// A helper template for an `integer_sequence` of `size_t`,3133// `absl::index_sequence` is designed to be a drop-in replacement for C++14's3134// `std::index_sequence`.3135template <size_t... Ints>3136using index_sequence = integer_sequence<size_t, Ints...>;31373138namespace utility_internal3139{31403141template <typename Seq, size_t SeqSize, size_t Rem>3142struct Extend;31433144// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.3145template <typename T, T... Ints, size_t SeqSize>3146struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>3147{3148using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;3149};31503151template <typename T, T... Ints, size_t SeqSize>3152struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>3153{3154using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;3155};31563157// Recursion helper for 'make_integer_sequence<T, N>'.3158// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.3159template <typename T, size_t N>3160struct Gen3161{3162using type =3163typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;3164};31653166template <typename T>3167struct Gen<T, 0>3168{3169using type = integer_sequence<T>;3170};31713172} // namespace utility_internal31733174// Compile-time sequences of integers31753176// make_integer_sequence3177//3178// This template alias is equivalent to3179// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in3180// replacement for C++14's `std::make_integer_sequence`.3181template <typename T, T N>3182using make_integer_sequence = typename utility_internal::Gen<T, N>::type;31833184// make_index_sequence3185//3186// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,3187// and is designed to be a drop-in replacement for C++14's3188// `std::make_index_sequence`.3189template <size_t N>3190using make_index_sequence = make_integer_sequence<size_t, N>;31913192// index_sequence_for3193//3194// Converts a typename pack into an index sequence of the same length, and3195// is designed to be a drop-in replacement for C++14's3196// `std::index_sequence_for()`3197template <typename... Ts>3198using index_sequence_for = make_index_sequence<sizeof...(Ts)>;31993200//// END OF CODE FROM GOOGLE ABSEIL32013202#endif32033204// dispatch utility (taken from ranges-v3)3205template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};3206template<> struct priority_tag<0> {};32073208// taken from ranges-v33209template<typename T>3210struct static_const3211{3212static JSON_INLINE_VARIABLE constexpr T value{};3213};32143215#ifndef JSON_HAS_CPP_173216template<typename T>3217constexpr T static_const<T>::value;3218#endif32193220template<typename T, typename... Args>3221inline constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args)3222{3223return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}};3224}32253226} // namespace detail3227NLOHMANN_JSON_NAMESPACE_END32283229// #include <nlohmann/detail/meta/type_traits.hpp>3230// __ _____ _____ _____3231// __| | __| | | | JSON for Modern C++3232// | | |__ | | | | | | version 3.11.33233// |_____|_____|_____|_|___| https://github.com/nlohmann/json3234//3235// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>3236// SPDX-License-Identifier: MIT3237323832393240#include <limits> // numeric_limits3241#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type3242#include <utility> // declval3243#include <tuple> // tuple3244#include <string> // char_traits32453246// #include <nlohmann/detail/iterators/iterator_traits.hpp>3247// __ _____ _____ _____3248// __| | __| | | | JSON for Modern C++3249// | | |__ | | | | | | version 3.11.33250// |_____|_____|_____|_|___| https://github.com/nlohmann/json3251//3252// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>3253// SPDX-License-Identifier: MIT3254325532563257#include <iterator> // random_access_iterator_tag32583259// #include <nlohmann/detail/abi_macros.hpp>32603261// #include <nlohmann/detail/meta/void_t.hpp>32623263// #include <nlohmann/detail/meta/cpp_future.hpp>326432653266NLOHMANN_JSON_NAMESPACE_BEGIN3267namespace detail3268{32693270template<typename It, typename = void>3271struct iterator_types {};32723273template<typename It>3274struct iterator_types <3275It,3276void_t<typename It::difference_type, typename It::value_type, typename It::pointer,3277typename It::reference, typename It::iterator_category >>3278{3279using difference_type = typename It::difference_type;3280using value_type = typename It::value_type;3281using pointer = typename It::pointer;3282using reference = typename It::reference;3283using iterator_category = typename It::iterator_category;3284};32853286// This is required as some compilers implement std::iterator_traits in a way that3287// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.3288template<typename T, typename = void>3289struct iterator_traits3290{3291};32923293template<typename T>3294struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>3295: iterator_types<T>3296{3297};32983299template<typename T>3300struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>3301{3302using iterator_category = std::random_access_iterator_tag;3303using value_type = T;3304using difference_type = ptrdiff_t;3305using pointer = T*;3306using reference = T&;3307};33083309} // namespace detail3310NLOHMANN_JSON_NAMESPACE_END33113312// #include <nlohmann/detail/macro_scope.hpp>33133314// #include <nlohmann/detail/meta/call_std/begin.hpp>3315// __ _____ _____ _____3316// __| | __| | | | JSON for Modern C++3317// | | |__ | | | | | | version 3.11.33318// |_____|_____|_____|_|___| https://github.com/nlohmann/json3319//3320// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>3321// SPDX-License-Identifier: MIT3322332333243325// #include <nlohmann/detail/macro_scope.hpp>332633273328NLOHMANN_JSON_NAMESPACE_BEGIN33293330NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin);33313332NLOHMANN_JSON_NAMESPACE_END33333334// #include <nlohmann/detail/meta/call_std/end.hpp>3335// __ _____ _____ _____3336// __| | __| | | | JSON for Modern C++3337// | | |__ | | | | | | version 3.11.33338// |_____|_____|_____|_|___| https://github.com/nlohmann/json3339//3340// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>3341// SPDX-License-Identifier: MIT3342334333443345// #include <nlohmann/detail/macro_scope.hpp>334633473348NLOHMANN_JSON_NAMESPACE_BEGIN33493350NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end);33513352NLOHMANN_JSON_NAMESPACE_END33533354// #include <nlohmann/detail/meta/cpp_future.hpp>33553356// #include <nlohmann/detail/meta/detected.hpp>33573358// #include <nlohmann/json_fwd.hpp>3359// __ _____ _____ _____3360// __| | __| | | | JSON for Modern C++3361// | | |__ | | | | | | version 3.11.33362// |_____|_____|_____|_|___| https://github.com/nlohmann/json3363//3364// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>3365// SPDX-License-Identifier: MIT33663367#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_3368#define INCLUDE_NLOHMANN_JSON_FWD_HPP_33693370#include <cstdint> // int64_t, uint64_t3371#include <map> // map3372#include <memory> // allocator3373#include <string> // string3374#include <vector> // vector33753376// #include <nlohmann/detail/abi_macros.hpp>337733783379/*!3380@brief namespace for Niels Lohmann3381@see https://github.com/nlohmann3382@since version 1.0.03383*/3384NLOHMANN_JSON_NAMESPACE_BEGIN33853386/*!3387@brief default JSONSerializer template argument33883389This serializer ignores the template arguments and uses ADL3390([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))3391for serialization.3392*/3393template<typename T = void, typename SFINAE = void>3394struct adl_serializer;33953396/// a class to store JSON values3397/// @sa https://json.nlohmann.me/api/basic_json/3398template<template<typename U, typename V, typename... Args> class ObjectType =3399std::map,3400template<typename U, typename... Args> class ArrayType = std::vector,3401class StringType = std::string, class BooleanType = bool,3402class NumberIntegerType = std::int64_t,3403class NumberUnsignedType = std::uint64_t,3404class NumberFloatType = double,3405template<typename U> class AllocatorType = std::allocator,3406template<typename T, typename SFINAE = void> class JSONSerializer =3407adl_serializer,3408class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError3409class CustomBaseClass = void>3410class basic_json;34113412/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document3413/// @sa https://json.nlohmann.me/api/json_pointer/3414template<typename RefStringType>3415class json_pointer;34163417/*!3418@brief default specialization3419@sa https://json.nlohmann.me/api/json/3420*/3421using json = basic_json<>;34223423/// @brief a minimal map-like container that preserves insertion order3424/// @sa https://json.nlohmann.me/api/ordered_map/3425template<class Key, class T, class IgnoredLess, class Allocator>3426struct ordered_map;34273428/// @brief specialization that maintains the insertion order of object keys3429/// @sa https://json.nlohmann.me/api/ordered_json/3430using ordered_json = basic_json<nlohmann::ordered_map>;34313432NLOHMANN_JSON_NAMESPACE_END34333434#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_343534363437NLOHMANN_JSON_NAMESPACE_BEGIN3438/*!3439@brief detail namespace with internal helper functions34403441This namespace collects functions that should not be exposed,3442implementations of some @ref basic_json methods, and meta-programming helpers.34433444@since version 2.1.03445*/3446namespace detail3447{34483449/////////////3450// helpers //3451/////////////34523453// Note to maintainers:3454//3455// Every trait in this file expects a non CV-qualified type.3456// The only exceptions are in the 'aliases for detected' section3457// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))3458//3459// In this case, T has to be properly CV-qualified to constraint the function arguments3460// (e.g. to_json(BasicJsonType&, const T&))34613462template<typename> struct is_basic_json : std::false_type {};34633464NLOHMANN_BASIC_JSON_TPL_DECLARATION3465struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};34663467// used by exceptions create() member functions3468// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t3469// false_type otherwise3470template<typename BasicJsonContext>3471struct is_basic_json_context :3472std::integral_constant < bool,3473is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value3474|| std::is_same<BasicJsonContext, std::nullptr_t>::value >3475{};34763477//////////////////////3478// json_ref helpers //3479//////////////////////34803481template<typename>3482class json_ref;34833484template<typename>3485struct is_json_ref : std::false_type {};34863487template<typename T>3488struct is_json_ref<json_ref<T>> : std::true_type {};34893490//////////////////////////3491// aliases for detected //3492//////////////////////////34933494template<typename T>3495using mapped_type_t = typename T::mapped_type;34963497template<typename T>3498using key_type_t = typename T::key_type;34993500template<typename T>3501using value_type_t = typename T::value_type;35023503template<typename T>3504using difference_type_t = typename T::difference_type;35053506template<typename T>3507using pointer_t = typename T::pointer;35083509template<typename T>3510using reference_t = typename T::reference;35113512template<typename T>3513using iterator_category_t = typename T::iterator_category;35143515template<typename T, typename... Args>3516using to_json_function = decltype(T::to_json(std::declval<Args>()...));35173518template<typename T, typename... Args>3519using from_json_function = decltype(T::from_json(std::declval<Args>()...));35203521template<typename T, typename U>3522using get_template_function = decltype(std::declval<T>().template get<U>());35233524// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists3525template<typename BasicJsonType, typename T, typename = void>3526struct has_from_json : std::false_type {};35273528// trait checking if j.get<T> is valid3529// use this trait instead of std::is_constructible or std::is_convertible,3530// both rely on, or make use of implicit conversions, and thus fail when T3531// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)3532template <typename BasicJsonType, typename T>3533struct is_getable3534{3535static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;3536};35373538template<typename BasicJsonType, typename T>3539struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>3540{3541using serializer = typename BasicJsonType::template json_serializer<T, void>;35423543static constexpr bool value =3544is_detected_exact<void, from_json_function, serializer,3545const BasicJsonType&, T&>::value;3546};35473548// This trait checks if JSONSerializer<T>::from_json(json const&) exists3549// this overload is used for non-default-constructible user-defined-types3550template<typename BasicJsonType, typename T, typename = void>3551struct has_non_default_from_json : std::false_type {};35523553template<typename BasicJsonType, typename T>3554struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>3555{3556using serializer = typename BasicJsonType::template json_serializer<T, void>;35573558static constexpr bool value =3559is_detected_exact<T, from_json_function, serializer,3560const BasicJsonType&>::value;3561};35623563// This trait checks if BasicJsonType::json_serializer<T>::to_json exists3564// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.3565template<typename BasicJsonType, typename T, typename = void>3566struct has_to_json : std::false_type {};35673568template<typename BasicJsonType, typename T>3569struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>3570{3571using serializer = typename BasicJsonType::template json_serializer<T, void>;35723573static constexpr bool value =3574is_detected_exact<void, to_json_function, serializer, BasicJsonType&,3575T>::value;3576};35773578template<typename T>3579using detect_key_compare = typename T::key_compare;35803581template<typename T>3582struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};35833584// obtains the actual object key comparator3585template<typename BasicJsonType>3586struct actual_object_comparator3587{3588using object_t = typename BasicJsonType::object_t;3589using object_comparator_t = typename BasicJsonType::default_object_comparator_t;3590using type = typename std::conditional < has_key_compare<object_t>::value,3591typename object_t::key_compare, object_comparator_t>::type;3592};35933594template<typename BasicJsonType>3595using actual_object_comparator_t = typename actual_object_comparator<BasicJsonType>::type;35963597/////////////////3598// char_traits //3599/////////////////36003601// Primary template of char_traits calls std char_traits3602template<typename T>3603struct char_traits : std::char_traits<T>3604{};36053606// Explicitly define char traits for unsigned char since it is not standard3607template<>3608struct char_traits<unsigned char> : std::char_traits<char>3609{3610using char_type = unsigned char;3611using int_type = uint64_t;36123613// Redefine to_int_type function3614static int_type to_int_type(char_type c) noexcept3615{3616return static_cast<int_type>(c);3617}36183619static char_type to_char_type(int_type i) noexcept3620{3621return static_cast<char_type>(i);3622}36233624static constexpr int_type eof() noexcept3625{3626return static_cast<int_type>(EOF);3627}3628};36293630// Explicitly define char traits for signed char since it is not standard3631template<>3632struct char_traits<signed char> : std::char_traits<char>3633{3634using char_type = signed char;3635using int_type = uint64_t;36363637// Redefine to_int_type function3638static int_type to_int_type(char_type c) noexcept3639{3640return static_cast<int_type>(c);3641}36423643static char_type to_char_type(int_type i) noexcept3644{3645return static_cast<char_type>(i);3646}36473648static constexpr int_type eof() noexcept3649{3650return static_cast<int_type>(EOF);3651}3652};36533654///////////////////3655// is_ functions //3656///////////////////36573658// https://en.cppreference.com/w/cpp/types/conjunction3659template<class...> struct conjunction : std::true_type { };3660template<class B> struct conjunction<B> : B { };3661template<class B, class... Bn>3662struct conjunction<B, Bn...>3663: std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};36643665// https://en.cppreference.com/w/cpp/types/negation3666template<class B> struct negation : std::integral_constant < bool, !B::value > { };36673668// Reimplementation of is_constructible and is_default_constructible, due to them being broken for3669// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).3670// This causes compile errors in e.g. clang 3.5 or gcc 4.9.3671template <typename T>3672struct is_default_constructible : std::is_default_constructible<T> {};36733674template <typename T1, typename T2>3675struct is_default_constructible<std::pair<T1, T2>>3676: conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};36773678template <typename T1, typename T2>3679struct is_default_constructible<const std::pair<T1, T2>>3680: conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};36813682template <typename... Ts>3683struct is_default_constructible<std::tuple<Ts...>>3684: conjunction<is_default_constructible<Ts>...> {};36853686template <typename... Ts>3687struct is_default_constructible<const std::tuple<Ts...>>3688: conjunction<is_default_constructible<Ts>...> {};36893690template <typename T, typename... Args>3691struct is_constructible : std::is_constructible<T, Args...> {};36923693template <typename T1, typename T2>3694struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};36953696template <typename T1, typename T2>3697struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};36983699template <typename... Ts>3700struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};37013702template <typename... Ts>3703struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};37043705template<typename T, typename = void>3706struct is_iterator_traits : std::false_type {};37073708template<typename T>3709struct is_iterator_traits<iterator_traits<T>>3710{3711private:3712using traits = iterator_traits<T>;37133714public:3715static constexpr auto value =3716is_detected<value_type_t, traits>::value &&3717is_detected<difference_type_t, traits>::value &&3718is_detected<pointer_t, traits>::value &&3719is_detected<iterator_category_t, traits>::value &&3720is_detected<reference_t, traits>::value;3721};37223723template<typename T>3724struct is_range3725{3726private:3727using t_ref = typename std::add_lvalue_reference<T>::type;37283729using iterator = detected_t<result_of_begin, t_ref>;3730using sentinel = detected_t<result_of_end, t_ref>;37313732// to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator3733// and https://en.cppreference.com/w/cpp/iterator/sentinel_for3734// but reimplementing these would be too much work, as a lot of other concepts are used underneath3735static constexpr auto is_iterator_begin =3736is_iterator_traits<iterator_traits<iterator>>::value;37373738public:3739static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;3740};37413742template<typename R>3743using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;37443745template<typename T>3746using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;37473748// The following implementation of is_complete_type is taken from3749// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/3750// and is written by Xiang Fan who agreed to using it in this library.37513752template<typename T, typename = void>3753struct is_complete_type : std::false_type {};37543755template<typename T>3756struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};37573758template<typename BasicJsonType, typename CompatibleObjectType,3759typename = void>3760struct is_compatible_object_type_impl : std::false_type {};37613762template<typename BasicJsonType, typename CompatibleObjectType>3763struct is_compatible_object_type_impl <3764BasicJsonType, CompatibleObjectType,3765enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&3766is_detected<key_type_t, CompatibleObjectType>::value >>3767{3768using object_t = typename BasicJsonType::object_t;37693770// macOS's is_constructible does not play well with nonesuch...3771static constexpr bool value =3772is_constructible<typename object_t::key_type,3773typename CompatibleObjectType::key_type>::value &&3774is_constructible<typename object_t::mapped_type,3775typename CompatibleObjectType::mapped_type>::value;3776};37773778template<typename BasicJsonType, typename CompatibleObjectType>3779struct is_compatible_object_type3780: is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};37813782template<typename BasicJsonType, typename ConstructibleObjectType,3783typename = void>3784struct is_constructible_object_type_impl : std::false_type {};37853786template<typename BasicJsonType, typename ConstructibleObjectType>3787struct is_constructible_object_type_impl <3788BasicJsonType, ConstructibleObjectType,3789enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&3790is_detected<key_type_t, ConstructibleObjectType>::value >>3791{3792using object_t = typename BasicJsonType::object_t;37933794static constexpr bool value =3795(is_default_constructible<ConstructibleObjectType>::value &&3796(std::is_move_assignable<ConstructibleObjectType>::value ||3797std::is_copy_assignable<ConstructibleObjectType>::value) &&3798(is_constructible<typename ConstructibleObjectType::key_type,3799typename object_t::key_type>::value &&3800std::is_same <3801typename object_t::mapped_type,3802typename ConstructibleObjectType::mapped_type >::value)) ||3803(has_from_json<BasicJsonType,3804typename ConstructibleObjectType::mapped_type>::value ||3805has_non_default_from_json <3806BasicJsonType,3807typename ConstructibleObjectType::mapped_type >::value);3808};38093810template<typename BasicJsonType, typename ConstructibleObjectType>3811struct is_constructible_object_type3812: is_constructible_object_type_impl<BasicJsonType,3813ConstructibleObjectType> {};38143815template<typename BasicJsonType, typename CompatibleStringType>3816struct is_compatible_string_type3817{3818static constexpr auto value =3819is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;3820};38213822template<typename BasicJsonType, typename ConstructibleStringType>3823struct is_constructible_string_type3824{3825// launder type through decltype() to fix compilation failure on ICPC3826#ifdef __INTEL_COMPILER3827using laundered_type = decltype(std::declval<ConstructibleStringType>());3828#else3829using laundered_type = ConstructibleStringType;3830#endif38313832static constexpr auto value =3833conjunction <3834is_constructible<laundered_type, typename BasicJsonType::string_t>,3835is_detected_exact<typename BasicJsonType::string_t::value_type,3836value_type_t, laundered_type >>::value;3837};38383839template<typename BasicJsonType, typename CompatibleArrayType, typename = void>3840struct is_compatible_array_type_impl : std::false_type {};38413842template<typename BasicJsonType, typename CompatibleArrayType>3843struct is_compatible_array_type_impl <3844BasicJsonType, CompatibleArrayType,3845enable_if_t <3846is_detected<iterator_t, CompatibleArrayType>::value&&3847is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&3848// special case for types like std::filesystem::path whose iterator's value_type are themselves3849// c.f. https://github.com/nlohmann/json/pull/30733850!std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>3851{3852static constexpr bool value =3853is_constructible<BasicJsonType,3854range_value_t<CompatibleArrayType>>::value;3855};38563857template<typename BasicJsonType, typename CompatibleArrayType>3858struct is_compatible_array_type3859: is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};38603861template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>3862struct is_constructible_array_type_impl : std::false_type {};38633864template<typename BasicJsonType, typename ConstructibleArrayType>3865struct is_constructible_array_type_impl <3866BasicJsonType, ConstructibleArrayType,3867enable_if_t<std::is_same<ConstructibleArrayType,3868typename BasicJsonType::value_type>::value >>3869: std::true_type {};38703871template<typename BasicJsonType, typename ConstructibleArrayType>3872struct is_constructible_array_type_impl <3873BasicJsonType, ConstructibleArrayType,3874enable_if_t < !std::is_same<ConstructibleArrayType,3875typename BasicJsonType::value_type>::value&&3876!is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&3877is_default_constructible<ConstructibleArrayType>::value&&3878(std::is_move_assignable<ConstructibleArrayType>::value ||3879std::is_copy_assignable<ConstructibleArrayType>::value)&&3880is_detected<iterator_t, ConstructibleArrayType>::value&&3881is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&3882is_detected<range_value_t, ConstructibleArrayType>::value&&3883// special case for types like std::filesystem::path whose iterator's value_type are themselves3884// c.f. https://github.com/nlohmann/json/pull/30733885!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&3886is_complete_type <3887detected_t<range_value_t, ConstructibleArrayType >>::value >>3888{3889using value_type = range_value_t<ConstructibleArrayType>;38903891static constexpr bool value =3892std::is_same<value_type,3893typename BasicJsonType::array_t::value_type>::value ||3894has_from_json<BasicJsonType,3895value_type>::value ||3896has_non_default_from_json <3897BasicJsonType,3898value_type >::value;3899};39003901template<typename BasicJsonType, typename ConstructibleArrayType>3902struct is_constructible_array_type3903: is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};39043905template<typename RealIntegerType, typename CompatibleNumberIntegerType,3906typename = void>3907struct is_compatible_integer_type_impl : std::false_type {};39083909template<typename RealIntegerType, typename CompatibleNumberIntegerType>3910struct is_compatible_integer_type_impl <3911RealIntegerType, CompatibleNumberIntegerType,3912enable_if_t < std::is_integral<RealIntegerType>::value&&3913std::is_integral<CompatibleNumberIntegerType>::value&&3914!std::is_same<bool, CompatibleNumberIntegerType>::value >>3915{3916// is there an assert somewhere on overflows?3917using RealLimits = std::numeric_limits<RealIntegerType>;3918using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;39193920static constexpr auto value =3921is_constructible<RealIntegerType,3922CompatibleNumberIntegerType>::value &&3923CompatibleLimits::is_integer &&3924RealLimits::is_signed == CompatibleLimits::is_signed;3925};39263927template<typename RealIntegerType, typename CompatibleNumberIntegerType>3928struct is_compatible_integer_type3929: is_compatible_integer_type_impl<RealIntegerType,3930CompatibleNumberIntegerType> {};39313932template<typename BasicJsonType, typename CompatibleType, typename = void>3933struct is_compatible_type_impl: std::false_type {};39343935template<typename BasicJsonType, typename CompatibleType>3936struct is_compatible_type_impl <3937BasicJsonType, CompatibleType,3938enable_if_t<is_complete_type<CompatibleType>::value >>3939{3940static constexpr bool value =3941has_to_json<BasicJsonType, CompatibleType>::value;3942};39433944template<typename BasicJsonType, typename CompatibleType>3945struct is_compatible_type3946: is_compatible_type_impl<BasicJsonType, CompatibleType> {};39473948template<typename T1, typename T2>3949struct is_constructible_tuple : std::false_type {};39503951template<typename T1, typename... Args>3952struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};39533954template<typename BasicJsonType, typename T>3955struct is_json_iterator_of : std::false_type {};39563957template<typename BasicJsonType>3958struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};39593960template<typename BasicJsonType>3961struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type3962{};39633964// checks if a given type T is a template specialization of Primary3965template<template <typename...> class Primary, typename T>3966struct is_specialization_of : std::false_type {};39673968template<template <typename...> class Primary, typename... Args>3969struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};39703971template<typename T>3972using is_json_pointer = is_specialization_of<::nlohmann::json_pointer, uncvref_t<T>>;39733974// checks if A and B are comparable using Compare functor3975template<typename Compare, typename A, typename B, typename = void>3976struct is_comparable : std::false_type {};39773978template<typename Compare, typename A, typename B>3979struct is_comparable<Compare, A, B, void_t<3980decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),3981decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))3982>> : std::true_type {};39833984template<typename T>3985using detect_is_transparent = typename T::is_transparent;39863987// type trait to check if KeyType can be used as object key (without a BasicJsonType)3988// see is_usable_as_basic_json_key_type below3989template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,3990bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>3991using is_usable_as_key_type = typename std::conditional <3992is_comparable<Comparator, ObjectKeyType, KeyTypeCVRef>::value3993&& !(ExcludeObjectKeyType && std::is_same<KeyType,3994ObjectKeyType>::value)3995&& (!RequireTransparentComparator3996|| is_detected <detect_is_transparent, Comparator>::value)3997&& !is_json_pointer<KeyType>::value,3998std::true_type,3999std::false_type >::type;40004001// type trait to check if KeyType can be used as object key4002// true if:4003// - KeyType is comparable with BasicJsonType::object_t::key_type4004// - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type4005// - the comparator is transparent or RequireTransparentComparator is false4006// - KeyType is not a JSON iterator or json_pointer4007template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,4008bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>4009using is_usable_as_basic_json_key_type = typename std::conditional <4010is_usable_as_key_type<typename BasicJsonType::object_comparator_t,4011typename BasicJsonType::object_t::key_type, KeyTypeCVRef,4012RequireTransparentComparator, ExcludeObjectKeyType>::value4013&& !is_json_iterator_of<BasicJsonType, KeyType>::value,4014std::true_type,4015std::false_type >::type;40164017template<typename ObjectType, typename KeyType>4018using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));40194020// type trait to check if object_t has an erase() member functions accepting KeyType4021template<typename BasicJsonType, typename KeyType>4022using has_erase_with_key_type = typename std::conditional <4023is_detected <4024detect_erase_with_key_type,4025typename BasicJsonType::object_t, KeyType >::value,4026std::true_type,4027std::false_type >::type;40284029// a naive helper to check if a type is an ordered_map (exploits the fact that4030// ordered_map inherits capacity() from std::vector)4031template <typename T>4032struct is_ordered_map4033{4034using one = char;40354036struct two4037{4038char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)4039};40404041template <typename C> static one test( decltype(&C::capacity) ) ;4042template <typename C> static two test(...);40434044enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)4045};40464047// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)4048template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >4049T conditional_static_cast(U value)4050{4051return static_cast<T>(value);4052}40534054template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>4055T conditional_static_cast(U value)4056{4057return value;4058}40594060template<typename... Types>4061using all_integral = conjunction<std::is_integral<Types>...>;40624063template<typename... Types>4064using all_signed = conjunction<std::is_signed<Types>...>;40654066template<typename... Types>4067using all_unsigned = conjunction<std::is_unsigned<Types>...>;40684069// there's a disjunction trait in another PR; replace when merged4070template<typename... Types>4071using same_sign = std::integral_constant < bool,4072all_signed<Types...>::value || all_unsigned<Types...>::value >;40734074template<typename OfType, typename T>4075using never_out_of_range = std::integral_constant < bool,4076(std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))4077|| (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;40784079template<typename OfType, typename T,4080bool OfTypeSigned = std::is_signed<OfType>::value,4081bool TSigned = std::is_signed<T>::value>4082struct value_in_range_of_impl2;40834084template<typename OfType, typename T>4085struct value_in_range_of_impl2<OfType, T, false, false>4086{4087static constexpr bool test(T val)4088{4089using CommonType = typename std::common_type<OfType, T>::type;4090return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());4091}4092};40934094template<typename OfType, typename T>4095struct value_in_range_of_impl2<OfType, T, true, false>4096{4097static constexpr bool test(T val)4098{4099using CommonType = typename std::common_type<OfType, T>::type;4100return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());4101}4102};41034104template<typename OfType, typename T>4105struct value_in_range_of_impl2<OfType, T, false, true>4106{4107static constexpr bool test(T val)4108{4109using CommonType = typename std::common_type<OfType, T>::type;4110return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());4111}4112};41134114template<typename OfType, typename T>4115struct value_in_range_of_impl2<OfType, T, true, true>4116{4117static constexpr bool test(T val)4118{4119using CommonType = typename std::common_type<OfType, T>::type;4120return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())4121&& static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());4122}4123};41244125template<typename OfType, typename T,4126bool NeverOutOfRange = never_out_of_range<OfType, T>::value,4127typename = detail::enable_if_t<all_integral<OfType, T>::value>>4128struct value_in_range_of_impl1;41294130template<typename OfType, typename T>4131struct value_in_range_of_impl1<OfType, T, false>4132{4133static constexpr bool test(T val)4134{4135return value_in_range_of_impl2<OfType, T>::test(val);4136}4137};41384139template<typename OfType, typename T>4140struct value_in_range_of_impl1<OfType, T, true>4141{4142static constexpr bool test(T /*val*/)4143{4144return true;4145}4146};41474148template<typename OfType, typename T>4149inline constexpr bool value_in_range_of(T val)4150{4151return value_in_range_of_impl1<OfType, T>::test(val);4152}41534154template<bool Value>4155using bool_constant = std::integral_constant<bool, Value>;41564157///////////////////////////////////////////////////////////////////////////////4158// is_c_string4159///////////////////////////////////////////////////////////////////////////////41604161namespace impl4162{41634164template<typename T>4165inline constexpr bool is_c_string()4166{4167using TUnExt = typename std::remove_extent<T>::type;4168using TUnCVExt = typename std::remove_cv<TUnExt>::type;4169using TUnPtr = typename std::remove_pointer<T>::type;4170using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;4171return4172(std::is_array<T>::value && std::is_same<TUnCVExt, char>::value)4173|| (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);4174}41754176} // namespace impl41774178// checks whether T is a [cv] char */[cv] char[] C string4179template<typename T>4180struct is_c_string : bool_constant<impl::is_c_string<T>()> {};41814182template<typename T>4183using is_c_string_uncvref = is_c_string<uncvref_t<T>>;41844185///////////////////////////////////////////////////////////////////////////////4186// is_transparent4187///////////////////////////////////////////////////////////////////////////////41884189namespace impl4190{41914192template<typename T>4193inline constexpr bool is_transparent()4194{4195return is_detected<detect_is_transparent, T>::value;4196}41974198} // namespace impl41994200// checks whether T has a member named is_transparent4201template<typename T>4202struct is_transparent : bool_constant<impl::is_transparent<T>()> {};42034204///////////////////////////////////////////////////////////////////////////////42054206} // namespace detail4207NLOHMANN_JSON_NAMESPACE_END42084209// #include <nlohmann/detail/string_concat.hpp>4210// __ _____ _____ _____4211// __| | __| | | | JSON for Modern C++4212// | | |__ | | | | | | version 3.11.34213// |_____|_____|_____|_|___| https://github.com/nlohmann/json4214//4215// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>4216// SPDX-License-Identifier: MIT4217421842194220#include <cstring> // strlen4221#include <string> // string4222#include <utility> // forward42234224// #include <nlohmann/detail/meta/cpp_future.hpp>42254226// #include <nlohmann/detail/meta/detected.hpp>422742284229NLOHMANN_JSON_NAMESPACE_BEGIN4230namespace detail4231{42324233inline std::size_t concat_length()4234{4235return 0;4236}42374238template<typename... Args>4239inline std::size_t concat_length(const char* cstr, const Args& ... rest);42404241template<typename StringType, typename... Args>4242inline std::size_t concat_length(const StringType& str, const Args& ... rest);42434244template<typename... Args>4245inline std::size_t concat_length(const char /*c*/, const Args& ... rest)4246{4247return 1 + concat_length(rest...);4248}42494250template<typename... Args>4251inline std::size_t concat_length(const char* cstr, const Args& ... rest)4252{4253// cppcheck-suppress ignoredReturnValue4254return ::strlen(cstr) + concat_length(rest...);4255}42564257template<typename StringType, typename... Args>4258inline std::size_t concat_length(const StringType& str, const Args& ... rest)4259{4260return str.size() + concat_length(rest...);4261}42624263template<typename OutStringType>4264inline void concat_into(OutStringType& /*out*/)4265{}42664267template<typename StringType, typename Arg>4268using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));42694270template<typename StringType, typename Arg>4271using detect_string_can_append = is_detected<string_can_append, StringType, Arg>;42724273template<typename StringType, typename Arg>4274using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());42754276template<typename StringType, typename Arg>4277using detect_string_can_append_op = is_detected<string_can_append_op, StringType, Arg>;42784279template<typename StringType, typename Arg>4280using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));42814282template<typename StringType, typename Arg>4283using detect_string_can_append_iter = is_detected<string_can_append_iter, StringType, Arg>;42844285template<typename StringType, typename Arg>4286using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));42874288template<typename StringType, typename Arg>4289using detect_string_can_append_data = is_detected<string_can_append_data, StringType, Arg>;42904291template < typename OutStringType, typename Arg, typename... Args,4292enable_if_t < !detect_string_can_append<OutStringType, Arg>::value4293&& detect_string_can_append_op<OutStringType, Arg>::value, int > = 0 >4294inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);42954296template < typename OutStringType, typename Arg, typename... Args,4297enable_if_t < !detect_string_can_append<OutStringType, Arg>::value4298&& !detect_string_can_append_op<OutStringType, Arg>::value4299&& detect_string_can_append_iter<OutStringType, Arg>::value, int > = 0 >4300inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);43014302template < typename OutStringType, typename Arg, typename... Args,4303enable_if_t < !detect_string_can_append<OutStringType, Arg>::value4304&& !detect_string_can_append_op<OutStringType, Arg>::value4305&& !detect_string_can_append_iter<OutStringType, Arg>::value4306&& detect_string_can_append_data<OutStringType, Arg>::value, int > = 0 >4307inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);43084309template<typename OutStringType, typename Arg, typename... Args,4310enable_if_t<detect_string_can_append<OutStringType, Arg>::value, int> = 0>4311inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)4312{4313out.append(std::forward<Arg>(arg));4314concat_into(out, std::forward<Args>(rest)...);4315}43164317template < typename OutStringType, typename Arg, typename... Args,4318enable_if_t < !detect_string_can_append<OutStringType, Arg>::value4319&& detect_string_can_append_op<OutStringType, Arg>::value, int > >4320inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)4321{4322out += std::forward<Arg>(arg);4323concat_into(out, std::forward<Args>(rest)...);4324}43254326template < typename OutStringType, typename Arg, typename... Args,4327enable_if_t < !detect_string_can_append<OutStringType, Arg>::value4328&& !detect_string_can_append_op<OutStringType, Arg>::value4329&& detect_string_can_append_iter<OutStringType, Arg>::value, int > >4330inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)4331{4332out.append(arg.begin(), arg.end());4333concat_into(out, std::forward<Args>(rest)...);4334}43354336template < typename OutStringType, typename Arg, typename... Args,4337enable_if_t < !detect_string_can_append<OutStringType, Arg>::value4338&& !detect_string_can_append_op<OutStringType, Arg>::value4339&& !detect_string_can_append_iter<OutStringType, Arg>::value4340&& detect_string_can_append_data<OutStringType, Arg>::value, int > >4341inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)4342{4343out.append(arg.data(), arg.size());4344concat_into(out, std::forward<Args>(rest)...);4345}43464347template<typename OutStringType = std::string, typename... Args>4348inline OutStringType concat(Args && ... args)4349{4350OutStringType str;4351str.reserve(concat_length(args...));4352concat_into(str, std::forward<Args>(args)...);4353return str;4354}43554356} // namespace detail4357NLOHMANN_JSON_NAMESPACE_END435843594360NLOHMANN_JSON_NAMESPACE_BEGIN4361namespace detail4362{43634364////////////////4365// exceptions //4366////////////////43674368/// @brief general exception of the @ref basic_json class4369/// @sa https://json.nlohmann.me/api/basic_json/exception/4370class exception : public std::exception4371{4372public:4373/// returns the explanatory string4374const char* what() const noexcept override4375{4376return m.what();4377}43784379/// the id of the exception4380const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)43814382protected:4383JSON_HEDLEY_NON_NULL(3)4384exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)43854386static std::string name(const std::string& ename, int id_)4387{4388return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");4389}43904391static std::string diagnostics(std::nullptr_t /*leaf_element*/)4392{4393return "";4394}43954396template<typename BasicJsonType>4397static std::string diagnostics(const BasicJsonType* leaf_element)4398{4399#if JSON_DIAGNOSTICS4400std::vector<std::string> tokens;4401for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)4402{4403switch (current->m_parent->type())4404{4405case value_t::array:4406{4407for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i)4408{4409if (¤t->m_parent->m_data.m_value.array->operator[](i) == current)4410{4411tokens.emplace_back(std::to_string(i));4412break;4413}4414}4415break;4416}44174418case value_t::object:4419{4420for (const auto& element : *current->m_parent->m_data.m_value.object)4421{4422if (&element.second == current)4423{4424tokens.emplace_back(element.first.c_str());4425break;4426}4427}4428break;4429}44304431case value_t::null: // LCOV_EXCL_LINE4432case value_t::string: // LCOV_EXCL_LINE4433case value_t::boolean: // LCOV_EXCL_LINE4434case value_t::number_integer: // LCOV_EXCL_LINE4435case value_t::number_unsigned: // LCOV_EXCL_LINE4436case value_t::number_float: // LCOV_EXCL_LINE4437case value_t::binary: // LCOV_EXCL_LINE4438case value_t::discarded: // LCOV_EXCL_LINE4439default: // LCOV_EXCL_LINE4440break; // LCOV_EXCL_LINE4441}4442}44434444if (tokens.empty())4445{4446return "";4447}44484449auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},4450[](const std::string & a, const std::string & b)4451{4452return concat(a, '/', detail::escape(b));4453});4454return concat('(', str, ") ");4455#else4456static_cast<void>(leaf_element);4457return "";4458#endif4459}44604461private:4462/// an exception object as storage for error messages4463std::runtime_error m;4464};44654466/// @brief exception indicating a parse error4467/// @sa https://json.nlohmann.me/api/basic_json/parse_error/4468class parse_error : public exception4469{4470public:4471/*!4472@brief create a parse error exception4473@param[in] id_ the id of the exception4474@param[in] pos the position where the error occurred (or with4475chars_read_total=0 if the position cannot be4476determined)4477@param[in] what_arg the explanatory string4478@return parse_error object4479*/4480template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>4481static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)4482{4483const std::string w = concat(exception::name("parse_error", id_), "parse error",4484position_string(pos), ": ", exception::diagnostics(context), what_arg);4485return {id_, pos.chars_read_total, w.c_str()};4486}44874488template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>4489static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)4490{4491const std::string w = concat(exception::name("parse_error", id_), "parse error",4492(byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),4493": ", exception::diagnostics(context), what_arg);4494return {id_, byte_, w.c_str()};4495}44964497/*!4498@brief byte index of the parse error44994500The byte index of the last read character in the input file.45014502@note For an input with n bytes, 1 is the index of the first character and4503n+1 is the index of the terminating null byte or the end of file.4504This also holds true when reading a byte vector (CBOR or MessagePack).4505*/4506const std::size_t byte;45074508private:4509parse_error(int id_, std::size_t byte_, const char* what_arg)4510: exception(id_, what_arg), byte(byte_) {}45114512static std::string position_string(const position_t& pos)4513{4514return concat(" at line ", std::to_string(pos.lines_read + 1),4515", column ", std::to_string(pos.chars_read_current_line));4516}4517};45184519/// @brief exception indicating errors with iterators4520/// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/4521class invalid_iterator : public exception4522{4523public:4524template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>4525static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)4526{4527const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);4528return {id_, w.c_str()};4529}45304531private:4532JSON_HEDLEY_NON_NULL(3)4533invalid_iterator(int id_, const char* what_arg)4534: exception(id_, what_arg) {}4535};45364537/// @brief exception indicating executing a member function with a wrong type4538/// @sa https://json.nlohmann.me/api/basic_json/type_error/4539class type_error : public exception4540{4541public:4542template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>4543static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)4544{4545const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);4546return {id_, w.c_str()};4547}45484549private:4550JSON_HEDLEY_NON_NULL(3)4551type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}4552};45534554/// @brief exception indicating access out of the defined range4555/// @sa https://json.nlohmann.me/api/basic_json/out_of_range/4556class out_of_range : public exception4557{4558public:4559template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>4560static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)4561{4562const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);4563return {id_, w.c_str()};4564}45654566private:4567JSON_HEDLEY_NON_NULL(3)4568out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}4569};45704571/// @brief exception indicating other library errors4572/// @sa https://json.nlohmann.me/api/basic_json/other_error/4573class other_error : public exception4574{4575public:4576template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>4577static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)4578{4579const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);4580return {id_, w.c_str()};4581}45824583private:4584JSON_HEDLEY_NON_NULL(3)4585other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}4586};45874588} // namespace detail4589NLOHMANN_JSON_NAMESPACE_END45904591// #include <nlohmann/detail/macro_scope.hpp>45924593// #include <nlohmann/detail/meta/cpp_future.hpp>45944595// #include <nlohmann/detail/meta/identity_tag.hpp>4596// __ _____ _____ _____4597// __| | __| | | | JSON for Modern C++4598// | | |__ | | | | | | version 3.11.34599// |_____|_____|_____|_|___| https://github.com/nlohmann/json4600//4601// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>4602// SPDX-License-Identifier: MIT4603460446054606// #include <nlohmann/detail/abi_macros.hpp>460746084609NLOHMANN_JSON_NAMESPACE_BEGIN4610namespace detail4611{46124613// dispatching helper struct4614template <class T> struct identity_tag {};46154616} // namespace detail4617NLOHMANN_JSON_NAMESPACE_END46184619// #include <nlohmann/detail/meta/std_fs.hpp>4620// __ _____ _____ _____4621// __| | __| | | | JSON for Modern C++4622// | | |__ | | | | | | version 3.11.34623// |_____|_____|_____|_|___| https://github.com/nlohmann/json4624//4625// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>4626// SPDX-License-Identifier: MIT4627462846294630// #include <nlohmann/detail/macro_scope.hpp>463146324633#if JSON_HAS_EXPERIMENTAL_FILESYSTEM4634#include <experimental/filesystem>4635NLOHMANN_JSON_NAMESPACE_BEGIN4636namespace detail4637{4638namespace std_fs = std::experimental::filesystem;4639} // namespace detail4640NLOHMANN_JSON_NAMESPACE_END4641#elif JSON_HAS_FILESYSTEM4642#include <filesystem>4643NLOHMANN_JSON_NAMESPACE_BEGIN4644namespace detail4645{4646namespace std_fs = std::filesystem;4647} // namespace detail4648NLOHMANN_JSON_NAMESPACE_END4649#endif46504651// #include <nlohmann/detail/meta/type_traits.hpp>46524653// #include <nlohmann/detail/string_concat.hpp>46544655// #include <nlohmann/detail/value_t.hpp>465646574658NLOHMANN_JSON_NAMESPACE_BEGIN4659namespace detail4660{46614662template<typename BasicJsonType>4663inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)4664{4665if (JSON_HEDLEY_UNLIKELY(!j.is_null()))4666{4667JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));4668}4669n = nullptr;4670}46714672// overloads for basic_json template parameters4673template < typename BasicJsonType, typename ArithmeticType,4674enable_if_t < std::is_arithmetic<ArithmeticType>::value&&4675!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,4676int > = 0 >4677void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)4678{4679switch (static_cast<value_t>(j))4680{4681case value_t::number_unsigned:4682{4683val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());4684break;4685}4686case value_t::number_integer:4687{4688val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());4689break;4690}4691case value_t::number_float:4692{4693val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());4694break;4695}46964697case value_t::null:4698case value_t::object:4699case value_t::array:4700case value_t::string:4701case value_t::boolean:4702case value_t::binary:4703case value_t::discarded:4704default:4705JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));4706}4707}47084709template<typename BasicJsonType>4710inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)4711{4712if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))4713{4714JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));4715}4716b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();4717}47184719template<typename BasicJsonType>4720inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)4721{4722if (JSON_HEDLEY_UNLIKELY(!j.is_string()))4723{4724JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));4725}4726s = *j.template get_ptr<const typename BasicJsonType::string_t*>();4727}47284729template <4730typename BasicJsonType, typename StringType,4731enable_if_t <4732std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value4733&& is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value4734&& !std::is_same<typename BasicJsonType::string_t, StringType>::value4735&& !is_json_ref<StringType>::value, int > = 0 >4736inline void from_json(const BasicJsonType& j, StringType& s)4737{4738if (JSON_HEDLEY_UNLIKELY(!j.is_string()))4739{4740JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));4741}47424743s = *j.template get_ptr<const typename BasicJsonType::string_t*>();4744}47454746template<typename BasicJsonType>4747inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)4748{4749get_arithmetic_value(j, val);4750}47514752template<typename BasicJsonType>4753inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)4754{4755get_arithmetic_value(j, val);4756}47574758template<typename BasicJsonType>4759inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)4760{4761get_arithmetic_value(j, val);4762}47634764#if !JSON_DISABLE_ENUM_SERIALIZATION4765template<typename BasicJsonType, typename EnumType,4766enable_if_t<std::is_enum<EnumType>::value, int> = 0>4767inline void from_json(const BasicJsonType& j, EnumType& e)4768{4769typename std::underlying_type<EnumType>::type val;4770get_arithmetic_value(j, val);4771e = static_cast<EnumType>(val);4772}4773#endif // JSON_DISABLE_ENUM_SERIALIZATION47744775// forward_list doesn't have an insert method4776template<typename BasicJsonType, typename T, typename Allocator,4777enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>4778inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)4779{4780if (JSON_HEDLEY_UNLIKELY(!j.is_array()))4781{4782JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));4783}4784l.clear();4785std::transform(j.rbegin(), j.rend(),4786std::front_inserter(l), [](const BasicJsonType & i)4787{4788return i.template get<T>();4789});4790}47914792// valarray doesn't have an insert method4793template<typename BasicJsonType, typename T,4794enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>4795inline void from_json(const BasicJsonType& j, std::valarray<T>& l)4796{4797if (JSON_HEDLEY_UNLIKELY(!j.is_array()))4798{4799JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));4800}4801l.resize(j.size());4802std::transform(j.begin(), j.end(), std::begin(l),4803[](const BasicJsonType & elem)4804{4805return elem.template get<T>();4806});4807}48084809template<typename BasicJsonType, typename T, std::size_t N>4810auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)4811-> decltype(j.template get<T>(), void())4812{4813for (std::size_t i = 0; i < N; ++i)4814{4815arr[i] = j.at(i).template get<T>();4816}4817}48184819template<typename BasicJsonType>4820inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)4821{4822arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();4823}48244825template<typename BasicJsonType, typename T, std::size_t N>4826auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,4827priority_tag<2> /*unused*/)4828-> decltype(j.template get<T>(), void())4829{4830for (std::size_t i = 0; i < N; ++i)4831{4832arr[i] = j.at(i).template get<T>();4833}4834}48354836template<typename BasicJsonType, typename ConstructibleArrayType,4837enable_if_t<4838std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,4839int> = 0>4840auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)4841-> decltype(4842arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),4843j.template get<typename ConstructibleArrayType::value_type>(),4844void())4845{4846using std::end;48474848ConstructibleArrayType ret;4849ret.reserve(j.size());4850std::transform(j.begin(), j.end(),4851std::inserter(ret, end(ret)), [](const BasicJsonType & i)4852{4853// get<BasicJsonType>() returns *this, this won't call a from_json4854// method when value_type is BasicJsonType4855return i.template get<typename ConstructibleArrayType::value_type>();4856});4857arr = std::move(ret);4858}48594860template<typename BasicJsonType, typename ConstructibleArrayType,4861enable_if_t<4862std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,4863int> = 0>4864inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,4865priority_tag<0> /*unused*/)4866{4867using std::end;48684869ConstructibleArrayType ret;4870std::transform(4871j.begin(), j.end(), std::inserter(ret, end(ret)),4872[](const BasicJsonType & i)4873{4874// get<BasicJsonType>() returns *this, this won't call a from_json4875// method when value_type is BasicJsonType4876return i.template get<typename ConstructibleArrayType::value_type>();4877});4878arr = std::move(ret);4879}48804881template < typename BasicJsonType, typename ConstructibleArrayType,4882enable_if_t <4883is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&4884!is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&4885!is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&4886!std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&4887!is_basic_json<ConstructibleArrayType>::value,4888int > = 0 >4889auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)4890-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),4891j.template get<typename ConstructibleArrayType::value_type>(),4892void())4893{4894if (JSON_HEDLEY_UNLIKELY(!j.is_array()))4895{4896JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));4897}48984899from_json_array_impl(j, arr, priority_tag<3> {});4900}49014902template < typename BasicJsonType, typename T, std::size_t... Idx >4903std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,4904identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)4905{4906return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };4907}49084909template < typename BasicJsonType, typename T, std::size_t N >4910auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)4911-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))4912{4913if (JSON_HEDLEY_UNLIKELY(!j.is_array()))4914{4915JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));4916}49174918return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});4919}49204921template<typename BasicJsonType>4922inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)4923{4924if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))4925{4926JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));4927}49284929bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();4930}49314932template<typename BasicJsonType, typename ConstructibleObjectType,4933enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>4934inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)4935{4936if (JSON_HEDLEY_UNLIKELY(!j.is_object()))4937{4938JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));4939}49404941ConstructibleObjectType ret;4942const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();4943using value_type = typename ConstructibleObjectType::value_type;4944std::transform(4945inner_object->begin(), inner_object->end(),4946std::inserter(ret, ret.begin()),4947[](typename BasicJsonType::object_t::value_type const & p)4948{4949return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());4950});4951obj = std::move(ret);4952}49534954// overload for arithmetic types, not chosen for basic_json template arguments4955// (BooleanType, etc..); note: Is it really necessary to provide explicit4956// overloads for boolean_t etc. in case of a custom BooleanType which is not4957// an arithmetic type?4958template < typename BasicJsonType, typename ArithmeticType,4959enable_if_t <4960std::is_arithmetic<ArithmeticType>::value&&4961!std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&4962!std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&4963!std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&4964!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,4965int > = 0 >4966inline void from_json(const BasicJsonType& j, ArithmeticType& val)4967{4968switch (static_cast<value_t>(j))4969{4970case value_t::number_unsigned:4971{4972val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());4973break;4974}4975case value_t::number_integer:4976{4977val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());4978break;4979}4980case value_t::number_float:4981{4982val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());4983break;4984}4985case value_t::boolean:4986{4987val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());4988break;4989}49904991case value_t::null:4992case value_t::object:4993case value_t::array:4994case value_t::string:4995case value_t::binary:4996case value_t::discarded:4997default:4998JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));4999}5000}50015002template<typename BasicJsonType, typename... Args, std::size_t... Idx>5003std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)5004{5005return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);5006}50075008template < typename BasicJsonType, class A1, class A2 >5009std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)5010{5011return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),5012std::forward<BasicJsonType>(j).at(1).template get<A2>()};5013}50145015template<typename BasicJsonType, typename A1, typename A2>5016inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)5017{5018p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});5019}50205021template<typename BasicJsonType, typename... Args>5022std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)5023{5024return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});5025}50265027template<typename BasicJsonType, typename... Args>5028inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)5029{5030t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});5031}50325033template<typename BasicJsonType, typename TupleRelated>5034auto from_json(BasicJsonType&& j, TupleRelated&& t)5035-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))5036{5037if (JSON_HEDLEY_UNLIKELY(!j.is_array()))5038{5039JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));5040}50415042return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});5043}50445045template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,5046typename = enable_if_t < !std::is_constructible <5047typename BasicJsonType::string_t, Key >::value >>5048inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)5049{5050if (JSON_HEDLEY_UNLIKELY(!j.is_array()))5051{5052JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));5053}5054m.clear();5055for (const auto& p : j)5056{5057if (JSON_HEDLEY_UNLIKELY(!p.is_array()))5058{5059JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));5060}5061m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());5062}5063}50645065template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,5066typename = enable_if_t < !std::is_constructible <5067typename BasicJsonType::string_t, Key >::value >>5068inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)5069{5070if (JSON_HEDLEY_UNLIKELY(!j.is_array()))5071{5072JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));5073}5074m.clear();5075for (const auto& p : j)5076{5077if (JSON_HEDLEY_UNLIKELY(!p.is_array()))5078{5079JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));5080}5081m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());5082}5083}50845085#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM5086template<typename BasicJsonType>5087inline void from_json(const BasicJsonType& j, std_fs::path& p)5088{5089if (JSON_HEDLEY_UNLIKELY(!j.is_string()))5090{5091JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));5092}5093p = *j.template get_ptr<const typename BasicJsonType::string_t*>();5094}5095#endif50965097struct from_json_fn5098{5099template<typename BasicJsonType, typename T>5100auto operator()(const BasicJsonType& j, T&& val) const5101noexcept(noexcept(from_json(j, std::forward<T>(val))))5102-> decltype(from_json(j, std::forward<T>(val)))5103{5104return from_json(j, std::forward<T>(val));5105}5106};51075108} // namespace detail51095110#ifndef JSON_HAS_CPP_175111/// namespace to hold default `from_json` function5112/// to see why this is required:5113/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html5114namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)5115{5116#endif5117JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)5118detail::static_const<detail::from_json_fn>::value;5119#ifndef JSON_HAS_CPP_175120} // namespace5121#endif51225123NLOHMANN_JSON_NAMESPACE_END51245125// #include <nlohmann/detail/conversions/to_json.hpp>5126// __ _____ _____ _____5127// __| | __| | | | JSON for Modern C++5128// | | |__ | | | | | | version 3.11.35129// |_____|_____|_____|_|___| https://github.com/nlohmann/json5130//5131// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>5132// SPDX-License-Identifier: MIT5133513451355136#include <algorithm> // copy5137#include <iterator> // begin, end5138#include <string> // string5139#include <tuple> // tuple, get5140#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type5141#include <utility> // move, forward, declval, pair5142#include <valarray> // valarray5143#include <vector> // vector51445145// #include <nlohmann/detail/iterators/iteration_proxy.hpp>5146// __ _____ _____ _____5147// __| | __| | | | JSON for Modern C++5148// | | |__ | | | | | | version 3.11.35149// |_____|_____|_____|_|___| https://github.com/nlohmann/json5150//5151// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>5152// SPDX-License-Identifier: MIT5153515451555156#include <cstddef> // size_t5157#include <iterator> // input_iterator_tag5158#include <string> // string, to_string5159#include <tuple> // tuple_size, get, tuple_element5160#include <utility> // move51615162#if JSON_HAS_RANGES5163#include <ranges> // enable_borrowed_range5164#endif51655166// #include <nlohmann/detail/abi_macros.hpp>51675168// #include <nlohmann/detail/meta/type_traits.hpp>51695170// #include <nlohmann/detail/value_t.hpp>517151725173NLOHMANN_JSON_NAMESPACE_BEGIN5174namespace detail5175{51765177template<typename string_type>5178void int_to_string( string_type& target, std::size_t value )5179{5180// For ADL5181using std::to_string;5182target = to_string(value);5183}5184template<typename IteratorType> class iteration_proxy_value5185{5186public:5187using difference_type = std::ptrdiff_t;5188using value_type = iteration_proxy_value;5189using pointer = value_type *;5190using reference = value_type &;5191using iterator_category = std::input_iterator_tag;5192using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;51935194private:5195/// the iterator5196IteratorType anchor{};5197/// an index for arrays (used to create key names)5198std::size_t array_index = 0;5199/// last stringified array index5200mutable std::size_t array_index_last = 0;5201/// a string representation of the array index5202mutable string_type array_index_str = "0";5203/// an empty string (to return a reference for primitive values)5204string_type empty_str{};52055206public:5207explicit iteration_proxy_value() = default;5208explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)5209noexcept(std::is_nothrow_move_constructible<IteratorType>::value5210&& std::is_nothrow_default_constructible<string_type>::value)5211: anchor(std::move(it))5212, array_index(array_index_)5213{}52145215iteration_proxy_value(iteration_proxy_value const&) = default;5216iteration_proxy_value& operator=(iteration_proxy_value const&) = default;5217// older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions5218iteration_proxy_value(iteration_proxy_value&&)5219noexcept(std::is_nothrow_move_constructible<IteratorType>::value5220&& std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)5221iteration_proxy_value& operator=(iteration_proxy_value&&)5222noexcept(std::is_nothrow_move_assignable<IteratorType>::value5223&& std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)5224~iteration_proxy_value() = default;52255226/// dereference operator (needed for range-based for)5227const iteration_proxy_value& operator*() const5228{5229return *this;5230}52315232/// increment operator (needed for range-based for)5233iteration_proxy_value& operator++()5234{5235++anchor;5236++array_index;52375238return *this;5239}52405241iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)5242{5243auto tmp = iteration_proxy_value(anchor, array_index);5244++anchor;5245++array_index;5246return tmp;5247}52485249/// equality operator (needed for InputIterator)5250bool operator==(const iteration_proxy_value& o) const5251{5252return anchor == o.anchor;5253}52545255/// inequality operator (needed for range-based for)5256bool operator!=(const iteration_proxy_value& o) const5257{5258return anchor != o.anchor;5259}52605261/// return key of the iterator5262const string_type& key() const5263{5264JSON_ASSERT(anchor.m_object != nullptr);52655266switch (anchor.m_object->type())5267{5268// use integer array index as key5269case value_t::array:5270{5271if (array_index != array_index_last)5272{5273int_to_string( array_index_str, array_index );5274array_index_last = array_index;5275}5276return array_index_str;5277}52785279// use key from the object5280case value_t::object:5281return anchor.key();52825283// use an empty key for all primitive types5284case value_t::null:5285case value_t::string:5286case value_t::boolean:5287case value_t::number_integer:5288case value_t::number_unsigned:5289case value_t::number_float:5290case value_t::binary:5291case value_t::discarded:5292default:5293return empty_str;5294}5295}52965297/// return value of the iterator5298typename IteratorType::reference value() const5299{5300return anchor.value();5301}5302};53035304/// proxy class for the items() function5305template<typename IteratorType> class iteration_proxy5306{5307private:5308/// the container to iterate5309typename IteratorType::pointer container = nullptr;53105311public:5312explicit iteration_proxy() = default;53135314/// construct iteration proxy from a container5315explicit iteration_proxy(typename IteratorType::reference cont) noexcept5316: container(&cont) {}53175318iteration_proxy(iteration_proxy const&) = default;5319iteration_proxy& operator=(iteration_proxy const&) = default;5320iteration_proxy(iteration_proxy&&) noexcept = default;5321iteration_proxy& operator=(iteration_proxy&&) noexcept = default;5322~iteration_proxy() = default;53235324/// return iterator begin (needed for range-based for)5325iteration_proxy_value<IteratorType> begin() const noexcept5326{5327return iteration_proxy_value<IteratorType>(container->begin());5328}53295330/// return iterator end (needed for range-based for)5331iteration_proxy_value<IteratorType> end() const noexcept5332{5333return iteration_proxy_value<IteratorType>(container->end());5334}5335};53365337// Structured Bindings Support5338// For further reference see https://blog.tartanllama.xyz/structured-bindings/5339// And see https://github.com/nlohmann/json/pull/13915340template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>5341auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())5342{5343return i.key();5344}5345// Structured Bindings Support5346// For further reference see https://blog.tartanllama.xyz/structured-bindings/5347// And see https://github.com/nlohmann/json/pull/13915348template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>5349auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())5350{5351return i.value();5352}53535354} // namespace detail5355NLOHMANN_JSON_NAMESPACE_END53565357// The Addition to the STD Namespace is required to add5358// Structured Bindings Support to the iteration_proxy_value class5359// For further reference see https://blog.tartanllama.xyz/structured-bindings/5360// And see https://github.com/nlohmann/json/pull/13915361namespace std5362{53635364#if defined(__clang__)5365// Fix: https://github.com/nlohmann/json/issues/14015366#pragma clang diagnostic push5367#pragma clang diagnostic ignored "-Wmismatched-tags"5368#endif5369template<typename IteratorType>5370class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)5371: public std::integral_constant<std::size_t, 2> {};53725373template<std::size_t N, typename IteratorType>5374class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)5375{5376public:5377using type = decltype(5378get<N>(std::declval <5379::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));5380};5381#if defined(__clang__)5382#pragma clang diagnostic pop5383#endif53845385} // namespace std53865387#if JSON_HAS_RANGES5388template <typename IteratorType>5389inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;5390#endif53915392// #include <nlohmann/detail/macro_scope.hpp>53935394// #include <nlohmann/detail/meta/cpp_future.hpp>53955396// #include <nlohmann/detail/meta/std_fs.hpp>53975398// #include <nlohmann/detail/meta/type_traits.hpp>53995400// #include <nlohmann/detail/value_t.hpp>540154025403NLOHMANN_JSON_NAMESPACE_BEGIN5404namespace detail5405{54065407//////////////////5408// constructors //5409//////////////////54105411/*5412* Note all external_constructor<>::construct functions need to call5413* j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an5414* allocated value (e.g., a string). See bug issue5415* https://github.com/nlohmann/json/issues/2865 for more information.5416*/54175418template<value_t> struct external_constructor;54195420template<>5421struct external_constructor<value_t::boolean>5422{5423template<typename BasicJsonType>5424static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept5425{5426j.m_data.m_value.destroy(j.m_data.m_type);5427j.m_data.m_type = value_t::boolean;5428j.m_data.m_value = b;5429j.assert_invariant();5430}5431};54325433template<>5434struct external_constructor<value_t::string>5435{5436template<typename BasicJsonType>5437static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)5438{5439j.m_data.m_value.destroy(j.m_data.m_type);5440j.m_data.m_type = value_t::string;5441j.m_data.m_value = s;5442j.assert_invariant();5443}54445445template<typename BasicJsonType>5446static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)5447{5448j.m_data.m_value.destroy(j.m_data.m_type);5449j.m_data.m_type = value_t::string;5450j.m_data.m_value = std::move(s);5451j.assert_invariant();5452}54535454template < typename BasicJsonType, typename CompatibleStringType,5455enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,5456int > = 0 >5457static void construct(BasicJsonType& j, const CompatibleStringType& str)5458{5459j.m_data.m_value.destroy(j.m_data.m_type);5460j.m_data.m_type = value_t::string;5461j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);5462j.assert_invariant();5463}5464};54655466template<>5467struct external_constructor<value_t::binary>5468{5469template<typename BasicJsonType>5470static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)5471{5472j.m_data.m_value.destroy(j.m_data.m_type);5473j.m_data.m_type = value_t::binary;5474j.m_data.m_value = typename BasicJsonType::binary_t(b);5475j.assert_invariant();5476}54775478template<typename BasicJsonType>5479static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)5480{5481j.m_data.m_value.destroy(j.m_data.m_type);5482j.m_data.m_type = value_t::binary;5483j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));5484j.assert_invariant();5485}5486};54875488template<>5489struct external_constructor<value_t::number_float>5490{5491template<typename BasicJsonType>5492static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept5493{5494j.m_data.m_value.destroy(j.m_data.m_type);5495j.m_data.m_type = value_t::number_float;5496j.m_data.m_value = val;5497j.assert_invariant();5498}5499};55005501template<>5502struct external_constructor<value_t::number_unsigned>5503{5504template<typename BasicJsonType>5505static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept5506{5507j.m_data.m_value.destroy(j.m_data.m_type);5508j.m_data.m_type = value_t::number_unsigned;5509j.m_data.m_value = val;5510j.assert_invariant();5511}5512};55135514template<>5515struct external_constructor<value_t::number_integer>5516{5517template<typename BasicJsonType>5518static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept5519{5520j.m_data.m_value.destroy(j.m_data.m_type);5521j.m_data.m_type = value_t::number_integer;5522j.m_data.m_value = val;5523j.assert_invariant();5524}5525};55265527template<>5528struct external_constructor<value_t::array>5529{5530template<typename BasicJsonType>5531static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)5532{5533j.m_data.m_value.destroy(j.m_data.m_type);5534j.m_data.m_type = value_t::array;5535j.m_data.m_value = arr;5536j.set_parents();5537j.assert_invariant();5538}55395540template<typename BasicJsonType>5541static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)5542{5543j.m_data.m_value.destroy(j.m_data.m_type);5544j.m_data.m_type = value_t::array;5545j.m_data.m_value = std::move(arr);5546j.set_parents();5547j.assert_invariant();5548}55495550template < typename BasicJsonType, typename CompatibleArrayType,5551enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,5552int > = 0 >5553static void construct(BasicJsonType& j, const CompatibleArrayType& arr)5554{5555using std::begin;5556using std::end;55575558j.m_data.m_value.destroy(j.m_data.m_type);5559j.m_data.m_type = value_t::array;5560j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));5561j.set_parents();5562j.assert_invariant();5563}55645565template<typename BasicJsonType>5566static void construct(BasicJsonType& j, const std::vector<bool>& arr)5567{5568j.m_data.m_value.destroy(j.m_data.m_type);5569j.m_data.m_type = value_t::array;5570j.m_data.m_value = value_t::array;5571j.m_data.m_value.array->reserve(arr.size());5572for (const bool x : arr)5573{5574j.m_data.m_value.array->push_back(x);5575j.set_parent(j.m_data.m_value.array->back());5576}5577j.assert_invariant();5578}55795580template<typename BasicJsonType, typename T,5581enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>5582static void construct(BasicJsonType& j, const std::valarray<T>& arr)5583{5584j.m_data.m_value.destroy(j.m_data.m_type);5585j.m_data.m_type = value_t::array;5586j.m_data.m_value = value_t::array;5587j.m_data.m_value.array->resize(arr.size());5588if (arr.size() > 0)5589{5590std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());5591}5592j.set_parents();5593j.assert_invariant();5594}5595};55965597template<>5598struct external_constructor<value_t::object>5599{5600template<typename BasicJsonType>5601static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)5602{5603j.m_data.m_value.destroy(j.m_data.m_type);5604j.m_data.m_type = value_t::object;5605j.m_data.m_value = obj;5606j.set_parents();5607j.assert_invariant();5608}56095610template<typename BasicJsonType>5611static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)5612{5613j.m_data.m_value.destroy(j.m_data.m_type);5614j.m_data.m_type = value_t::object;5615j.m_data.m_value = std::move(obj);5616j.set_parents();5617j.assert_invariant();5618}56195620template < typename BasicJsonType, typename CompatibleObjectType,5621enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >5622static void construct(BasicJsonType& j, const CompatibleObjectType& obj)5623{5624using std::begin;5625using std::end;56265627j.m_data.m_value.destroy(j.m_data.m_type);5628j.m_data.m_type = value_t::object;5629j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));5630j.set_parents();5631j.assert_invariant();5632}5633};56345635/////////////5636// to_json //5637/////////////56385639template<typename BasicJsonType, typename T,5640enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>5641inline void to_json(BasicJsonType& j, T b) noexcept5642{5643external_constructor<value_t::boolean>::construct(j, b);5644}56455646template < typename BasicJsonType, typename BoolRef,5647enable_if_t <5648((std::is_same<std::vector<bool>::reference, BoolRef>::value5649&& !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)5650|| (std::is_same<std::vector<bool>::const_reference, BoolRef>::value5651&& !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,5652typename BasicJsonType::boolean_t >::value))5653&& std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 >5654inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept5655{5656external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));5657}56585659template<typename BasicJsonType, typename CompatibleString,5660enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>5661inline void to_json(BasicJsonType& j, const CompatibleString& s)5662{5663external_constructor<value_t::string>::construct(j, s);5664}56655666template<typename BasicJsonType>5667inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)5668{5669external_constructor<value_t::string>::construct(j, std::move(s));5670}56715672template<typename BasicJsonType, typename FloatType,5673enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>5674inline void to_json(BasicJsonType& j, FloatType val) noexcept5675{5676external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));5677}56785679template<typename BasicJsonType, typename CompatibleNumberUnsignedType,5680enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>5681inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept5682{5683external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));5684}56855686template<typename BasicJsonType, typename CompatibleNumberIntegerType,5687enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>5688inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept5689{5690external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));5691}56925693#if !JSON_DISABLE_ENUM_SERIALIZATION5694template<typename BasicJsonType, typename EnumType,5695enable_if_t<std::is_enum<EnumType>::value, int> = 0>5696inline void to_json(BasicJsonType& j, EnumType e) noexcept5697{5698using underlying_type = typename std::underlying_type<EnumType>::type;5699static constexpr value_t integral_value_t = std::is_unsigned<underlying_type>::value ? value_t::number_unsigned : value_t::number_integer;5700external_constructor<integral_value_t>::construct(j, static_cast<underlying_type>(e));5701}5702#endif // JSON_DISABLE_ENUM_SERIALIZATION57035704template<typename BasicJsonType>5705inline void to_json(BasicJsonType& j, const std::vector<bool>& e)5706{5707external_constructor<value_t::array>::construct(j, e);5708}57095710template < typename BasicJsonType, typename CompatibleArrayType,5711enable_if_t < is_compatible_array_type<BasicJsonType,5712CompatibleArrayType>::value&&5713!is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&5714!is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&5715!std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&5716!is_basic_json<CompatibleArrayType>::value,5717int > = 0 >5718inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)5719{5720external_constructor<value_t::array>::construct(j, arr);5721}57225723template<typename BasicJsonType>5724inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)5725{5726external_constructor<value_t::binary>::construct(j, bin);5727}57285729template<typename BasicJsonType, typename T,5730enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>5731inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)5732{5733external_constructor<value_t::array>::construct(j, std::move(arr));5734}57355736template<typename BasicJsonType>5737inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)5738{5739external_constructor<value_t::array>::construct(j, std::move(arr));5740}57415742template < typename BasicJsonType, typename CompatibleObjectType,5743enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >5744inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)5745{5746external_constructor<value_t::object>::construct(j, obj);5747}57485749template<typename BasicJsonType>5750inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)5751{5752external_constructor<value_t::object>::construct(j, std::move(obj));5753}57545755template <5756typename BasicJsonType, typename T, std::size_t N,5757enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,5758const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)5759int > = 0 >5760inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)5761{5762external_constructor<value_t::array>::construct(j, arr);5763}57645765template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >5766inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)5767{5768j = { p.first, p.second };5769}57705771// for https://github.com/nlohmann/json/pull/11345772template<typename BasicJsonType, typename T,5773enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>5774inline void to_json(BasicJsonType& j, const T& b)5775{5776j = { {b.key(), b.value()} };5777}57785779template<typename BasicJsonType, typename Tuple, std::size_t... Idx>5780inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)5781{5782j = { std::get<Idx>(t)... };5783}57845785template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>5786inline void to_json(BasicJsonType& j, const T& t)5787{5788to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});5789}57905791#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM5792template<typename BasicJsonType>5793inline void to_json(BasicJsonType& j, const std_fs::path& p)5794{5795j = p.string();5796}5797#endif57985799struct to_json_fn5800{5801template<typename BasicJsonType, typename T>5802auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))5803-> decltype(to_json(j, std::forward<T>(val)), void())5804{5805return to_json(j, std::forward<T>(val));5806}5807};5808} // namespace detail58095810#ifndef JSON_HAS_CPP_175811/// namespace to hold default `to_json` function5812/// to see why this is required:5813/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html5814namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)5815{5816#endif5817JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)5818detail::static_const<detail::to_json_fn>::value;5819#ifndef JSON_HAS_CPP_175820} // namespace5821#endif58225823NLOHMANN_JSON_NAMESPACE_END58245825// #include <nlohmann/detail/meta/identity_tag.hpp>582658275828NLOHMANN_JSON_NAMESPACE_BEGIN58295830/// @sa https://json.nlohmann.me/api/adl_serializer/5831template<typename ValueType, typename>5832struct adl_serializer5833{5834/// @brief convert a JSON value to any value type5835/// @sa https://json.nlohmann.me/api/adl_serializer/from_json/5836template<typename BasicJsonType, typename TargetType = ValueType>5837static auto from_json(BasicJsonType && j, TargetType& val) noexcept(5838noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))5839-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())5840{5841::nlohmann::from_json(std::forward<BasicJsonType>(j), val);5842}58435844/// @brief convert a JSON value to any value type5845/// @sa https://json.nlohmann.me/api/adl_serializer/from_json/5846template<typename BasicJsonType, typename TargetType = ValueType>5847static auto from_json(BasicJsonType && j) noexcept(5848noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))5849-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))5850{5851return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});5852}58535854/// @brief convert any value type to a JSON value5855/// @sa https://json.nlohmann.me/api/adl_serializer/to_json/5856template<typename BasicJsonType, typename TargetType = ValueType>5857static auto to_json(BasicJsonType& j, TargetType && val) noexcept(5858noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))5859-> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())5860{5861::nlohmann::to_json(j, std::forward<TargetType>(val));5862}5863};58645865NLOHMANN_JSON_NAMESPACE_END58665867// #include <nlohmann/byte_container_with_subtype.hpp>5868// __ _____ _____ _____5869// __| | __| | | | JSON for Modern C++5870// | | |__ | | | | | | version 3.11.35871// |_____|_____|_____|_|___| https://github.com/nlohmann/json5872//5873// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>5874// SPDX-License-Identifier: MIT5875587658775878#include <cstdint> // uint8_t, uint64_t5879#include <tuple> // tie5880#include <utility> // move58815882// #include <nlohmann/detail/abi_macros.hpp>588358845885NLOHMANN_JSON_NAMESPACE_BEGIN58865887/// @brief an internal type for a backed binary type5888/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/5889template<typename BinaryType>5890class byte_container_with_subtype : public BinaryType5891{5892public:5893using container_type = BinaryType;5894using subtype_type = std::uint64_t;58955896/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/5897byte_container_with_subtype() noexcept(noexcept(container_type()))5898: container_type()5899{}59005901/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/5902byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))5903: container_type(b)5904{}59055906/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/5907byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))5908: container_type(std::move(b))5909{}59105911/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/5912byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))5913: container_type(b)5914, m_subtype(subtype_)5915, m_has_subtype(true)5916{}59175918/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/5919byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))5920: container_type(std::move(b))5921, m_subtype(subtype_)5922, m_has_subtype(true)5923{}59245925bool operator==(const byte_container_with_subtype& rhs) const5926{5927return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==5928std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);5929}59305931bool operator!=(const byte_container_with_subtype& rhs) const5932{5933return !(rhs == *this);5934}59355936/// @brief sets the binary subtype5937/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/5938void set_subtype(subtype_type subtype_) noexcept5939{5940m_subtype = subtype_;5941m_has_subtype = true;5942}59435944/// @brief return the binary subtype5945/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/subtype/5946constexpr subtype_type subtype() const noexcept5947{5948return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);5949}59505951/// @brief return whether the value has a subtype5952/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/5953constexpr bool has_subtype() const noexcept5954{5955return m_has_subtype;5956}59575958/// @brief clears the binary subtype5959/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/5960void clear_subtype() noexcept5961{5962m_subtype = 0;5963m_has_subtype = false;5964}59655966private:5967subtype_type m_subtype = 0;5968bool m_has_subtype = false;5969};59705971NLOHMANN_JSON_NAMESPACE_END59725973// #include <nlohmann/detail/conversions/from_json.hpp>59745975// #include <nlohmann/detail/conversions/to_json.hpp>59765977// #include <nlohmann/detail/exceptions.hpp>59785979// #include <nlohmann/detail/hash.hpp>5980// __ _____ _____ _____5981// __| | __| | | | JSON for Modern C++5982// | | |__ | | | | | | version 3.11.35983// |_____|_____|_____|_|___| https://github.com/nlohmann/json5984//5985// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>5986// SPDX-License-Identifier: MIT5987598859895990#include <cstdint> // uint8_t5991#include <cstddef> // size_t5992#include <functional> // hash59935994// #include <nlohmann/detail/abi_macros.hpp>59955996// #include <nlohmann/detail/value_t.hpp>599759985999NLOHMANN_JSON_NAMESPACE_BEGIN6000namespace detail6001{60026003// boost::hash_combine6004inline std::size_t combine(std::size_t seed, std::size_t h) noexcept6005{6006seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);6007return seed;6008}60096010/*!6011@brief hash a JSON value60126013The hash function tries to rely on std::hash where possible. Furthermore, the6014type of the JSON value is taken into account to have different hash values for6015null, 0, 0U, and false, etc.60166017@tparam BasicJsonType basic_json specialization6018@param j JSON value to hash6019@return hash value of j6020*/6021template<typename BasicJsonType>6022std::size_t hash(const BasicJsonType& j)6023{6024using string_t = typename BasicJsonType::string_t;6025using number_integer_t = typename BasicJsonType::number_integer_t;6026using number_unsigned_t = typename BasicJsonType::number_unsigned_t;6027using number_float_t = typename BasicJsonType::number_float_t;60286029const auto type = static_cast<std::size_t>(j.type());6030switch (j.type())6031{6032case BasicJsonType::value_t::null:6033case BasicJsonType::value_t::discarded:6034{6035return combine(type, 0);6036}60376038case BasicJsonType::value_t::object:6039{6040auto seed = combine(type, j.size());6041for (const auto& element : j.items())6042{6043const auto h = std::hash<string_t> {}(element.key());6044seed = combine(seed, h);6045seed = combine(seed, hash(element.value()));6046}6047return seed;6048}60496050case BasicJsonType::value_t::array:6051{6052auto seed = combine(type, j.size());6053for (const auto& element : j)6054{6055seed = combine(seed, hash(element));6056}6057return seed;6058}60596060case BasicJsonType::value_t::string:6061{6062const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());6063return combine(type, h);6064}60656066case BasicJsonType::value_t::boolean:6067{6068const auto h = std::hash<bool> {}(j.template get<bool>());6069return combine(type, h);6070}60716072case BasicJsonType::value_t::number_integer:6073{6074const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());6075return combine(type, h);6076}60776078case BasicJsonType::value_t::number_unsigned:6079{6080const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());6081return combine(type, h);6082}60836084case BasicJsonType::value_t::number_float:6085{6086const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());6087return combine(type, h);6088}60896090case BasicJsonType::value_t::binary:6091{6092auto seed = combine(type, j.get_binary().size());6093const auto h = std::hash<bool> {}(j.get_binary().has_subtype());6094seed = combine(seed, h);6095seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));6096for (const auto byte : j.get_binary())6097{6098seed = combine(seed, std::hash<std::uint8_t> {}(byte));6099}6100return seed;6101}61026103default: // LCOV_EXCL_LINE6104JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE6105return 0; // LCOV_EXCL_LINE6106}6107}61086109} // namespace detail6110NLOHMANN_JSON_NAMESPACE_END61116112// #include <nlohmann/detail/input/binary_reader.hpp>6113// __ _____ _____ _____6114// __| | __| | | | JSON for Modern C++6115// | | |__ | | | | | | version 3.11.36116// |_____|_____|_____|_|___| https://github.com/nlohmann/json6117//6118// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>6119// SPDX-License-Identifier: MIT6120612161226123#include <algorithm> // generate_n6124#include <array> // array6125#include <cmath> // ldexp6126#include <cstddef> // size_t6127#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t6128#include <cstdio> // snprintf6129#include <cstring> // memcpy6130#include <iterator> // back_inserter6131#include <limits> // numeric_limits6132#include <string> // char_traits, string6133#include <utility> // make_pair, move6134#include <vector> // vector61356136// #include <nlohmann/detail/exceptions.hpp>61376138// #include <nlohmann/detail/input/input_adapters.hpp>6139// __ _____ _____ _____6140// __| | __| | | | JSON for Modern C++6141// | | |__ | | | | | | version 3.11.36142// |_____|_____|_____|_|___| https://github.com/nlohmann/json6143//6144// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>6145// SPDX-License-Identifier: MIT6146614761486149#include <array> // array6150#include <cstddef> // size_t6151#include <cstring> // strlen6152#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next6153#include <memory> // shared_ptr, make_shared, addressof6154#include <numeric> // accumulate6155#include <string> // string, char_traits6156#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer6157#include <utility> // pair, declval61586159#ifndef JSON_NO_IO6160#include <cstdio> // FILE *6161#include <istream> // istream6162#endif // JSON_NO_IO61636164// #include <nlohmann/detail/iterators/iterator_traits.hpp>61656166// #include <nlohmann/detail/macro_scope.hpp>61676168// #include <nlohmann/detail/meta/type_traits.hpp>616961706171NLOHMANN_JSON_NAMESPACE_BEGIN6172namespace detail6173{61746175/// the supported input formats6176enum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata };61776178////////////////////6179// input adapters //6180////////////////////61816182#ifndef JSON_NO_IO6183/*!6184Input adapter for stdio file access. This adapter read only 1 byte and do not use any6185buffer. This adapter is a very low level adapter.6186*/6187class file_input_adapter6188{6189public:6190using char_type = char;61916192JSON_HEDLEY_NON_NULL(2)6193explicit file_input_adapter(std::FILE* f) noexcept6194: m_file(f)6195{6196JSON_ASSERT(m_file != nullptr);6197}61986199// make class move-only6200file_input_adapter(const file_input_adapter&) = delete;6201file_input_adapter(file_input_adapter&&) noexcept = default;6202file_input_adapter& operator=(const file_input_adapter&) = delete;6203file_input_adapter& operator=(file_input_adapter&&) = delete;6204~file_input_adapter() = default;62056206std::char_traits<char>::int_type get_character() noexcept6207{6208return std::fgetc(m_file);6209}62106211private:6212/// the file pointer to read from6213std::FILE* m_file;6214};62156216/*!6217Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at6218beginning of input. Does not support changing the underlying std::streambuf6219in mid-input. Maintains underlying std::istream and std::streambuf to support6220subsequent use of standard std::istream operations to process any input6221characters following those used in parsing the JSON input. Clears the6222std::istream flags; any input errors (e.g., EOF) will be detected by the first6223subsequent call for input from the std::istream.6224*/6225class input_stream_adapter6226{6227public:6228using char_type = char;62296230~input_stream_adapter()6231{6232// clear stream flags; we use underlying streambuf I/O, do not6233// maintain ifstream flags, except eof6234if (is != nullptr)6235{6236is->clear(is->rdstate() & std::ios::eofbit);6237}6238}62396240explicit input_stream_adapter(std::istream& i)6241: is(&i), sb(i.rdbuf())6242{}62436244// delete because of pointer members6245input_stream_adapter(const input_stream_adapter&) = delete;6246input_stream_adapter& operator=(input_stream_adapter&) = delete;6247input_stream_adapter& operator=(input_stream_adapter&&) = delete;62486249input_stream_adapter(input_stream_adapter&& rhs) noexcept6250: is(rhs.is), sb(rhs.sb)6251{6252rhs.is = nullptr;6253rhs.sb = nullptr;6254}62556256// std::istream/std::streambuf use std::char_traits<char>::to_int_type, to6257// ensure that std::char_traits<char>::eof() and the character 0xFF do not6258// end up as the same value, e.g. 0xFFFFFFFF.6259std::char_traits<char>::int_type get_character()6260{6261auto res = sb->sbumpc();6262// set eof manually, as we don't use the istream interface.6263if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))6264{6265is->clear(is->rdstate() | std::ios::eofbit);6266}6267return res;6268}62696270private:6271/// the associated input stream6272std::istream* is = nullptr;6273std::streambuf* sb = nullptr;6274};6275#endif // JSON_NO_IO62766277// General-purpose iterator-based adapter. It might not be as fast as6278// theoretically possible for some containers, but it is extremely versatile.6279template<typename IteratorType>6280class iterator_input_adapter6281{6282public:6283using char_type = typename std::iterator_traits<IteratorType>::value_type;62846285iterator_input_adapter(IteratorType first, IteratorType last)6286: current(std::move(first)), end(std::move(last))6287{}62886289typename char_traits<char_type>::int_type get_character()6290{6291if (JSON_HEDLEY_LIKELY(current != end))6292{6293auto result = char_traits<char_type>::to_int_type(*current);6294std::advance(current, 1);6295return result;6296}62976298return char_traits<char_type>::eof();6299}63006301private:6302IteratorType current;6303IteratorType end;63046305template<typename BaseInputAdapter, size_t T>6306friend struct wide_string_input_helper;63076308bool empty() const6309{6310return current == end;6311}6312};63136314template<typename BaseInputAdapter, size_t T>6315struct wide_string_input_helper;63166317template<typename BaseInputAdapter>6318struct wide_string_input_helper<BaseInputAdapter, 4>6319{6320// UTF-326321static void fill_buffer(BaseInputAdapter& input,6322std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,6323size_t& utf8_bytes_index,6324size_t& utf8_bytes_filled)6325{6326utf8_bytes_index = 0;63276328if (JSON_HEDLEY_UNLIKELY(input.empty()))6329{6330utf8_bytes[0] = std::char_traits<char>::eof();6331utf8_bytes_filled = 1;6332}6333else6334{6335// get the current character6336const auto wc = input.get_character();63376338// UTF-32 to UTF-8 encoding6339if (wc < 0x80)6340{6341utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);6342utf8_bytes_filled = 1;6343}6344else if (wc <= 0x7FF)6345{6346utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));6347utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));6348utf8_bytes_filled = 2;6349}6350else if (wc <= 0xFFFF)6351{6352utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));6353utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));6354utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));6355utf8_bytes_filled = 3;6356}6357else if (wc <= 0x10FFFF)6358{6359utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));6360utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));6361utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));6362utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));6363utf8_bytes_filled = 4;6364}6365else6366{6367// unknown character6368utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);6369utf8_bytes_filled = 1;6370}6371}6372}6373};63746375template<typename BaseInputAdapter>6376struct wide_string_input_helper<BaseInputAdapter, 2>6377{6378// UTF-166379static void fill_buffer(BaseInputAdapter& input,6380std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,6381size_t& utf8_bytes_index,6382size_t& utf8_bytes_filled)6383{6384utf8_bytes_index = 0;63856386if (JSON_HEDLEY_UNLIKELY(input.empty()))6387{6388utf8_bytes[0] = std::char_traits<char>::eof();6389utf8_bytes_filled = 1;6390}6391else6392{6393// get the current character6394const auto wc = input.get_character();63956396// UTF-16 to UTF-8 encoding6397if (wc < 0x80)6398{6399utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);6400utf8_bytes_filled = 1;6401}6402else if (wc <= 0x7FF)6403{6404utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));6405utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));6406utf8_bytes_filled = 2;6407}6408else if (0xD800 > wc || wc >= 0xE000)6409{6410utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));6411utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));6412utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));6413utf8_bytes_filled = 3;6414}6415else6416{6417if (JSON_HEDLEY_UNLIKELY(!input.empty()))6418{6419const auto wc2 = static_cast<unsigned int>(input.get_character());6420const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));6421utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));6422utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));6423utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));6424utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));6425utf8_bytes_filled = 4;6426}6427else6428{6429utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);6430utf8_bytes_filled = 1;6431}6432}6433}6434}6435};64366437// Wraps another input adapter to convert wide character types into individual bytes.6438template<typename BaseInputAdapter, typename WideCharType>6439class wide_string_input_adapter6440{6441public:6442using char_type = char;64436444wide_string_input_adapter(BaseInputAdapter base)6445: base_adapter(base) {}64466447typename std::char_traits<char>::int_type get_character() noexcept6448{6449// check if buffer needs to be filled6450if (utf8_bytes_index == utf8_bytes_filled)6451{6452fill_buffer<sizeof(WideCharType)>();64536454JSON_ASSERT(utf8_bytes_filled > 0);6455JSON_ASSERT(utf8_bytes_index == 0);6456}64576458// use buffer6459JSON_ASSERT(utf8_bytes_filled > 0);6460JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);6461return utf8_bytes[utf8_bytes_index++];6462}64636464private:6465BaseInputAdapter base_adapter;64666467template<size_t T>6468void fill_buffer()6469{6470wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);6471}64726473/// a buffer for UTF-8 bytes6474std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};64756476/// index to the utf8_codes array for the next valid byte6477std::size_t utf8_bytes_index = 0;6478/// number of valid bytes in the utf8_codes array6479std::size_t utf8_bytes_filled = 0;6480};64816482template<typename IteratorType, typename Enable = void>6483struct iterator_input_adapter_factory6484{6485using iterator_type = IteratorType;6486using char_type = typename std::iterator_traits<iterator_type>::value_type;6487using adapter_type = iterator_input_adapter<iterator_type>;64886489static adapter_type create(IteratorType first, IteratorType last)6490{6491return adapter_type(std::move(first), std::move(last));6492}6493};64946495template<typename T>6496struct is_iterator_of_multibyte6497{6498using value_type = typename std::iterator_traits<T>::value_type;6499enum6500{6501value = sizeof(value_type) > 16502};6503};65046505template<typename IteratorType>6506struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>6507{6508using iterator_type = IteratorType;6509using char_type = typename std::iterator_traits<iterator_type>::value_type;6510using base_adapter_type = iterator_input_adapter<iterator_type>;6511using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;65126513static adapter_type create(IteratorType first, IteratorType last)6514{6515return adapter_type(base_adapter_type(std::move(first), std::move(last)));6516}6517};65186519// General purpose iterator-based input6520template<typename IteratorType>6521typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)6522{6523using factory_type = iterator_input_adapter_factory<IteratorType>;6524return factory_type::create(first, last);6525}65266527// Convenience shorthand from container to iterator6528// Enables ADL on begin(container) and end(container)6529// Encloses the using declarations in namespace for not to leak them to outside scope65306531namespace container_input_adapter_factory_impl6532{65336534using std::begin;6535using std::end;65366537template<typename ContainerType, typename Enable = void>6538struct container_input_adapter_factory {};65396540template<typename ContainerType>6541struct container_input_adapter_factory< ContainerType,6542void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>6543{6544using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));65456546static adapter_type create(const ContainerType& container)6547{6548return input_adapter(begin(container), end(container));6549}6550};65516552} // namespace container_input_adapter_factory_impl65536554template<typename ContainerType>6555typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)6556{6557return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);6558}65596560#ifndef JSON_NO_IO6561// Special cases with fast paths6562inline file_input_adapter input_adapter(std::FILE* file)6563{6564return file_input_adapter(file);6565}65666567inline input_stream_adapter input_adapter(std::istream& stream)6568{6569return input_stream_adapter(stream);6570}65716572inline input_stream_adapter input_adapter(std::istream&& stream)6573{6574return input_stream_adapter(stream);6575}6576#endif // JSON_NO_IO65776578using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));65796580// Null-delimited strings, and the like.6581template < typename CharT,6582typename std::enable_if <6583std::is_pointer<CharT>::value&&6584!std::is_array<CharT>::value&&6585std::is_integral<typename std::remove_pointer<CharT>::type>::value&&6586sizeof(typename std::remove_pointer<CharT>::type) == 1,6587int >::type = 0 >6588contiguous_bytes_input_adapter input_adapter(CharT b)6589{6590auto length = std::strlen(reinterpret_cast<const char*>(b));6591const auto* ptr = reinterpret_cast<const char*>(b);6592return input_adapter(ptr, ptr + length);6593}65946595template<typename T, std::size_t N>6596auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)6597{6598return input_adapter(array, array + N);6599}66006601// This class only handles inputs of input_buffer_adapter type.6602// It's required so that expressions like {ptr, len} can be implicitly cast6603// to the correct adapter.6604class span_input_adapter6605{6606public:6607template < typename CharT,6608typename std::enable_if <6609std::is_pointer<CharT>::value&&6610std::is_integral<typename std::remove_pointer<CharT>::type>::value&&6611sizeof(typename std::remove_pointer<CharT>::type) == 1,6612int >::type = 0 >6613span_input_adapter(CharT b, std::size_t l)6614: ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}66156616template<class IteratorType,6617typename std::enable_if<6618std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,6619int>::type = 0>6620span_input_adapter(IteratorType first, IteratorType last)6621: ia(input_adapter(first, last)) {}66226623contiguous_bytes_input_adapter&& get()6624{6625return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)6626}66276628private:6629contiguous_bytes_input_adapter ia;6630};66316632} // namespace detail6633NLOHMANN_JSON_NAMESPACE_END66346635// #include <nlohmann/detail/input/json_sax.hpp>6636// __ _____ _____ _____6637// __| | __| | | | JSON for Modern C++6638// | | |__ | | | | | | version 3.11.36639// |_____|_____|_____|_|___| https://github.com/nlohmann/json6640//6641// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>6642// SPDX-License-Identifier: MIT6643664466456646#include <cstddef>6647#include <string> // string6648#include <utility> // move6649#include <vector> // vector66506651// #include <nlohmann/detail/exceptions.hpp>66526653// #include <nlohmann/detail/macro_scope.hpp>66546655// #include <nlohmann/detail/string_concat.hpp>665666576658NLOHMANN_JSON_NAMESPACE_BEGIN66596660/*!6661@brief SAX interface66626663This class describes the SAX interface used by @ref nlohmann::json::sax_parse.6664Each function is called in different situations while the input is parsed. The6665boolean return value informs the parser whether to continue processing the6666input.6667*/6668template<typename BasicJsonType>6669struct json_sax6670{6671using number_integer_t = typename BasicJsonType::number_integer_t;6672using number_unsigned_t = typename BasicJsonType::number_unsigned_t;6673using number_float_t = typename BasicJsonType::number_float_t;6674using string_t = typename BasicJsonType::string_t;6675using binary_t = typename BasicJsonType::binary_t;66766677/*!6678@brief a null value was read6679@return whether parsing should proceed6680*/6681virtual bool null() = 0;66826683/*!6684@brief a boolean value was read6685@param[in] val boolean value6686@return whether parsing should proceed6687*/6688virtual bool boolean(bool val) = 0;66896690/*!6691@brief an integer number was read6692@param[in] val integer value6693@return whether parsing should proceed6694*/6695virtual bool number_integer(number_integer_t val) = 0;66966697/*!6698@brief an unsigned integer number was read6699@param[in] val unsigned integer value6700@return whether parsing should proceed6701*/6702virtual bool number_unsigned(number_unsigned_t val) = 0;67036704/*!6705@brief a floating-point number was read6706@param[in] val floating-point value6707@param[in] s raw token value6708@return whether parsing should proceed6709*/6710virtual bool number_float(number_float_t val, const string_t& s) = 0;67116712/*!6713@brief a string value was read6714@param[in] val string value6715@return whether parsing should proceed6716@note It is safe to move the passed string value.6717*/6718virtual bool string(string_t& val) = 0;67196720/*!6721@brief a binary value was read6722@param[in] val binary value6723@return whether parsing should proceed6724@note It is safe to move the passed binary value.6725*/6726virtual bool binary(binary_t& val) = 0;67276728/*!6729@brief the beginning of an object was read6730@param[in] elements number of object elements or -1 if unknown6731@return whether parsing should proceed6732@note binary formats may report the number of elements6733*/6734virtual bool start_object(std::size_t elements) = 0;67356736/*!6737@brief an object key was read6738@param[in] val object key6739@return whether parsing should proceed6740@note It is safe to move the passed string.6741*/6742virtual bool key(string_t& val) = 0;67436744/*!6745@brief the end of an object was read6746@return whether parsing should proceed6747*/6748virtual bool end_object() = 0;67496750/*!6751@brief the beginning of an array was read6752@param[in] elements number of array elements or -1 if unknown6753@return whether parsing should proceed6754@note binary formats may report the number of elements6755*/6756virtual bool start_array(std::size_t elements) = 0;67576758/*!6759@brief the end of an array was read6760@return whether parsing should proceed6761*/6762virtual bool end_array() = 0;67636764/*!6765@brief a parse error occurred6766@param[in] position the position in the input where the error occurs6767@param[in] last_token the last read token6768@param[in] ex an exception object describing the error6769@return whether parsing should proceed (must return false)6770*/6771virtual bool parse_error(std::size_t position,6772const std::string& last_token,6773const detail::exception& ex) = 0;67746775json_sax() = default;6776json_sax(const json_sax&) = default;6777json_sax(json_sax&&) noexcept = default;6778json_sax& operator=(const json_sax&) = default;6779json_sax& operator=(json_sax&&) noexcept = default;6780virtual ~json_sax() = default;6781};67826783namespace detail6784{6785/*!6786@brief SAX implementation to create a JSON value from SAX events67876788This class implements the @ref json_sax interface and processes the SAX events6789to create a JSON value which makes it basically a DOM parser. The structure or6790hierarchy of the JSON value is managed by the stack `ref_stack` which contains6791a pointer to the respective array or object for each recursion depth.67926793After successful parsing, the value that is passed by reference to the6794constructor contains the parsed value.67956796@tparam BasicJsonType the JSON type6797*/6798template<typename BasicJsonType>6799class json_sax_dom_parser6800{6801public:6802using number_integer_t = typename BasicJsonType::number_integer_t;6803using number_unsigned_t = typename BasicJsonType::number_unsigned_t;6804using number_float_t = typename BasicJsonType::number_float_t;6805using string_t = typename BasicJsonType::string_t;6806using binary_t = typename BasicJsonType::binary_t;68076808/*!6809@param[in,out] r reference to a JSON value that is manipulated while6810parsing6811@param[in] allow_exceptions_ whether parse errors yield exceptions6812*/6813explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)6814: root(r), allow_exceptions(allow_exceptions_)6815{}68166817// make class move-only6818json_sax_dom_parser(const json_sax_dom_parser&) = delete;6819json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)6820json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;6821json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)6822~json_sax_dom_parser() = default;68236824bool null()6825{6826handle_value(nullptr);6827return true;6828}68296830bool boolean(bool val)6831{6832handle_value(val);6833return true;6834}68356836bool number_integer(number_integer_t val)6837{6838handle_value(val);6839return true;6840}68416842bool number_unsigned(number_unsigned_t val)6843{6844handle_value(val);6845return true;6846}68476848bool number_float(number_float_t val, const string_t& /*unused*/)6849{6850handle_value(val);6851return true;6852}68536854bool string(string_t& val)6855{6856handle_value(val);6857return true;6858}68596860bool binary(binary_t& val)6861{6862handle_value(std::move(val));6863return true;6864}68656866bool start_object(std::size_t len)6867{6868ref_stack.push_back(handle_value(BasicJsonType::value_t::object));68696870if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))6871{6872JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));6873}68746875return true;6876}68776878bool key(string_t& val)6879{6880JSON_ASSERT(!ref_stack.empty());6881JSON_ASSERT(ref_stack.back()->is_object());68826883// add null at given key and store the reference for later6884object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val));6885return true;6886}68876888bool end_object()6889{6890JSON_ASSERT(!ref_stack.empty());6891JSON_ASSERT(ref_stack.back()->is_object());68926893ref_stack.back()->set_parents();6894ref_stack.pop_back();6895return true;6896}68976898bool start_array(std::size_t len)6899{6900ref_stack.push_back(handle_value(BasicJsonType::value_t::array));69016902if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))6903{6904JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));6905}69066907return true;6908}69096910bool end_array()6911{6912JSON_ASSERT(!ref_stack.empty());6913JSON_ASSERT(ref_stack.back()->is_array());69146915ref_stack.back()->set_parents();6916ref_stack.pop_back();6917return true;6918}69196920template<class Exception>6921bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,6922const Exception& ex)6923{6924errored = true;6925static_cast<void>(ex);6926if (allow_exceptions)6927{6928JSON_THROW(ex);6929}6930return false;6931}69326933constexpr bool is_errored() const6934{6935return errored;6936}69376938private:6939/*!6940@invariant If the ref stack is empty, then the passed value will be the new6941root.6942@invariant If the ref stack contains a value, then it is an array or an6943object to which we can add elements6944*/6945template<typename Value>6946JSON_HEDLEY_RETURNS_NON_NULL6947BasicJsonType* handle_value(Value&& v)6948{6949if (ref_stack.empty())6950{6951root = BasicJsonType(std::forward<Value>(v));6952return &root;6953}69546955JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());69566957if (ref_stack.back()->is_array())6958{6959ref_stack.back()->m_data.m_value.array->emplace_back(std::forward<Value>(v));6960return &(ref_stack.back()->m_data.m_value.array->back());6961}69626963JSON_ASSERT(ref_stack.back()->is_object());6964JSON_ASSERT(object_element);6965*object_element = BasicJsonType(std::forward<Value>(v));6966return object_element;6967}69686969/// the parsed JSON value6970BasicJsonType& root;6971/// stack to model hierarchy of values6972std::vector<BasicJsonType*> ref_stack {};6973/// helper to hold the reference for the next object element6974BasicJsonType* object_element = nullptr;6975/// whether a syntax error occurred6976bool errored = false;6977/// whether to throw exceptions in case of errors6978const bool allow_exceptions = true;6979};69806981template<typename BasicJsonType>6982class json_sax_dom_callback_parser6983{6984public:6985using number_integer_t = typename BasicJsonType::number_integer_t;6986using number_unsigned_t = typename BasicJsonType::number_unsigned_t;6987using number_float_t = typename BasicJsonType::number_float_t;6988using string_t = typename BasicJsonType::string_t;6989using binary_t = typename BasicJsonType::binary_t;6990using parser_callback_t = typename BasicJsonType::parser_callback_t;6991using parse_event_t = typename BasicJsonType::parse_event_t;69926993json_sax_dom_callback_parser(BasicJsonType& r,6994const parser_callback_t cb,6995const bool allow_exceptions_ = true)6996: root(r), callback(cb), allow_exceptions(allow_exceptions_)6997{6998keep_stack.push_back(true);6999}70007001// make class move-only7002json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;7003json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)7004json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;7005json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)7006~json_sax_dom_callback_parser() = default;70077008bool null()7009{7010handle_value(nullptr);7011return true;7012}70137014bool boolean(bool val)7015{7016handle_value(val);7017return true;7018}70197020bool number_integer(number_integer_t val)7021{7022handle_value(val);7023return true;7024}70257026bool number_unsigned(number_unsigned_t val)7027{7028handle_value(val);7029return true;7030}70317032bool number_float(number_float_t val, const string_t& /*unused*/)7033{7034handle_value(val);7035return true;7036}70377038bool string(string_t& val)7039{7040handle_value(val);7041return true;7042}70437044bool binary(binary_t& val)7045{7046handle_value(std::move(val));7047return true;7048}70497050bool start_object(std::size_t len)7051{7052// check callback for object start7053const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);7054keep_stack.push_back(keep);70557056auto val = handle_value(BasicJsonType::value_t::object, true);7057ref_stack.push_back(val.second);70587059// check object limit7060if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))7061{7062JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));7063}70647065return true;7066}70677068bool key(string_t& val)7069{7070BasicJsonType k = BasicJsonType(val);70717072// check callback for key7073const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);7074key_keep_stack.push_back(keep);70757076// add discarded value at given key and store the reference for later7077if (keep && ref_stack.back())7078{7079object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded);7080}70817082return true;7083}70847085bool end_object()7086{7087if (ref_stack.back())7088{7089if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))7090{7091// discard object7092*ref_stack.back() = discarded;7093}7094else7095{7096ref_stack.back()->set_parents();7097}7098}70997100JSON_ASSERT(!ref_stack.empty());7101JSON_ASSERT(!keep_stack.empty());7102ref_stack.pop_back();7103keep_stack.pop_back();71047105if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())7106{7107// remove discarded value7108for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)7109{7110if (it->is_discarded())7111{7112ref_stack.back()->erase(it);7113break;7114}7115}7116}71177118return true;7119}71207121bool start_array(std::size_t len)7122{7123const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);7124keep_stack.push_back(keep);71257126auto val = handle_value(BasicJsonType::value_t::array, true);7127ref_stack.push_back(val.second);71287129// check array limit7130if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))7131{7132JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));7133}71347135return true;7136}71377138bool end_array()7139{7140bool keep = true;71417142if (ref_stack.back())7143{7144keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());7145if (keep)7146{7147ref_stack.back()->set_parents();7148}7149else7150{7151// discard array7152*ref_stack.back() = discarded;7153}7154}71557156JSON_ASSERT(!ref_stack.empty());7157JSON_ASSERT(!keep_stack.empty());7158ref_stack.pop_back();7159keep_stack.pop_back();71607161// remove discarded value7162if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())7163{7164ref_stack.back()->m_data.m_value.array->pop_back();7165}71667167return true;7168}71697170template<class Exception>7171bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,7172const Exception& ex)7173{7174errored = true;7175static_cast<void>(ex);7176if (allow_exceptions)7177{7178JSON_THROW(ex);7179}7180return false;7181}71827183constexpr bool is_errored() const7184{7185return errored;7186}71877188private:7189/*!7190@param[in] v value to add to the JSON value we build during parsing7191@param[in] skip_callback whether we should skip calling the callback7192function; this is required after start_array() and7193start_object() SAX events, because otherwise we would call the7194callback function with an empty array or object, respectively.71957196@invariant If the ref stack is empty, then the passed value will be the new7197root.7198@invariant If the ref stack contains a value, then it is an array or an7199object to which we can add elements72007201@return pair of boolean (whether value should be kept) and pointer (to the7202passed value in the ref_stack hierarchy; nullptr if not kept)7203*/7204template<typename Value>7205std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)7206{7207JSON_ASSERT(!keep_stack.empty());72087209// do not handle this value if we know it would be added to a discarded7210// container7211if (!keep_stack.back())7212{7213return {false, nullptr};7214}72157216// create value7217auto value = BasicJsonType(std::forward<Value>(v));72187219// check callback7220const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);72217222// do not handle this value if we just learnt it shall be discarded7223if (!keep)7224{7225return {false, nullptr};7226}72277228if (ref_stack.empty())7229{7230root = std::move(value);7231return {true, & root};7232}72337234// skip this value if we already decided to skip the parent7235// (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)7236if (!ref_stack.back())7237{7238return {false, nullptr};7239}72407241// we now only expect arrays and objects7242JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());72437244// array7245if (ref_stack.back()->is_array())7246{7247ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));7248return {true, & (ref_stack.back()->m_data.m_value.array->back())};7249}72507251// object7252JSON_ASSERT(ref_stack.back()->is_object());7253// check if we should store an element for the current key7254JSON_ASSERT(!key_keep_stack.empty());7255const bool store_element = key_keep_stack.back();7256key_keep_stack.pop_back();72577258if (!store_element)7259{7260return {false, nullptr};7261}72627263JSON_ASSERT(object_element);7264*object_element = std::move(value);7265return {true, object_element};7266}72677268/// the parsed JSON value7269BasicJsonType& root;7270/// stack to model hierarchy of values7271std::vector<BasicJsonType*> ref_stack {};7272/// stack to manage which values to keep7273std::vector<bool> keep_stack {};7274/// stack to manage which object keys to keep7275std::vector<bool> key_keep_stack {};7276/// helper to hold the reference for the next object element7277BasicJsonType* object_element = nullptr;7278/// whether a syntax error occurred7279bool errored = false;7280/// callback function7281const parser_callback_t callback = nullptr;7282/// whether to throw exceptions in case of errors7283const bool allow_exceptions = true;7284/// a discarded value for the callback7285BasicJsonType discarded = BasicJsonType::value_t::discarded;7286};72877288template<typename BasicJsonType>7289class json_sax_acceptor7290{7291public:7292using number_integer_t = typename BasicJsonType::number_integer_t;7293using number_unsigned_t = typename BasicJsonType::number_unsigned_t;7294using number_float_t = typename BasicJsonType::number_float_t;7295using string_t = typename BasicJsonType::string_t;7296using binary_t = typename BasicJsonType::binary_t;72977298bool null()7299{7300return true;7301}73027303bool boolean(bool /*unused*/)7304{7305return true;7306}73077308bool number_integer(number_integer_t /*unused*/)7309{7310return true;7311}73127313bool number_unsigned(number_unsigned_t /*unused*/)7314{7315return true;7316}73177318bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)7319{7320return true;7321}73227323bool string(string_t& /*unused*/)7324{7325return true;7326}73277328bool binary(binary_t& /*unused*/)7329{7330return true;7331}73327333bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))7334{7335return true;7336}73377338bool key(string_t& /*unused*/)7339{7340return true;7341}73427343bool end_object()7344{7345return true;7346}73477348bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))7349{7350return true;7351}73527353bool end_array()7354{7355return true;7356}73577358bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)7359{7360return false;7361}7362};73637364} // namespace detail7365NLOHMANN_JSON_NAMESPACE_END73667367// #include <nlohmann/detail/input/lexer.hpp>7368// __ _____ _____ _____7369// __| | __| | | | JSON for Modern C++7370// | | |__ | | | | | | version 3.11.37371// |_____|_____|_____|_|___| https://github.com/nlohmann/json7372//7373// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>7374// SPDX-License-Identifier: MIT7375737673777378#include <array> // array7379#include <clocale> // localeconv7380#include <cstddef> // size_t7381#include <cstdio> // snprintf7382#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull7383#include <initializer_list> // initializer_list7384#include <string> // char_traits, string7385#include <utility> // move7386#include <vector> // vector73877388// #include <nlohmann/detail/input/input_adapters.hpp>73897390// #include <nlohmann/detail/input/position_t.hpp>73917392// #include <nlohmann/detail/macro_scope.hpp>73937394// #include <nlohmann/detail/meta/type_traits.hpp>739573967397NLOHMANN_JSON_NAMESPACE_BEGIN7398namespace detail7399{74007401///////////7402// lexer //7403///////////74047405template<typename BasicJsonType>7406class lexer_base7407{7408public:7409/// token types for the parser7410enum class token_type7411{7412uninitialized, ///< indicating the scanner is uninitialized7413literal_true, ///< the `true` literal7414literal_false, ///< the `false` literal7415literal_null, ///< the `null` literal7416value_string, ///< a string -- use get_string() for actual value7417value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value7418value_integer, ///< a signed integer -- use get_number_integer() for actual value7419value_float, ///< an floating point number -- use get_number_float() for actual value7420begin_array, ///< the character for array begin `[`7421begin_object, ///< the character for object begin `{`7422end_array, ///< the character for array end `]`7423end_object, ///< the character for object end `}`7424name_separator, ///< the name separator `:`7425value_separator, ///< the value separator `,`7426parse_error, ///< indicating a parse error7427end_of_input, ///< indicating the end of the input buffer7428literal_or_value ///< a literal or the begin of a value (only for diagnostics)7429};74307431/// return name of values of type token_type (only used for errors)7432JSON_HEDLEY_RETURNS_NON_NULL7433JSON_HEDLEY_CONST7434static const char* token_type_name(const token_type t) noexcept7435{7436switch (t)7437{7438case token_type::uninitialized:7439return "<uninitialized>";7440case token_type::literal_true:7441return "true literal";7442case token_type::literal_false:7443return "false literal";7444case token_type::literal_null:7445return "null literal";7446case token_type::value_string:7447return "string literal";7448case token_type::value_unsigned:7449case token_type::value_integer:7450case token_type::value_float:7451return "number literal";7452case token_type::begin_array:7453return "'['";7454case token_type::begin_object:7455return "'{'";7456case token_type::end_array:7457return "']'";7458case token_type::end_object:7459return "'}'";7460case token_type::name_separator:7461return "':'";7462case token_type::value_separator:7463return "','";7464case token_type::parse_error:7465return "<parse error>";7466case token_type::end_of_input:7467return "end of input";7468case token_type::literal_or_value:7469return "'[', '{', or a literal";7470// LCOV_EXCL_START7471default: // catch non-enum values7472return "unknown token";7473// LCOV_EXCL_STOP7474}7475}7476};7477/*!7478@brief lexical analysis74797480This class organizes the lexical analysis during JSON deserialization.7481*/7482template<typename BasicJsonType, typename InputAdapterType>7483class lexer : public lexer_base<BasicJsonType>7484{7485using number_integer_t = typename BasicJsonType::number_integer_t;7486using number_unsigned_t = typename BasicJsonType::number_unsigned_t;7487using number_float_t = typename BasicJsonType::number_float_t;7488using string_t = typename BasicJsonType::string_t;7489using char_type = typename InputAdapterType::char_type;7490using char_int_type = typename char_traits<char_type>::int_type;74917492public:7493using token_type = typename lexer_base<BasicJsonType>::token_type;74947495explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept7496: ia(std::move(adapter))7497, ignore_comments(ignore_comments_)7498, decimal_point_char(static_cast<char_int_type>(get_decimal_point()))7499{}75007501// delete because of pointer members7502lexer(const lexer&) = delete;7503lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)7504lexer& operator=(lexer&) = delete;7505lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)7506~lexer() = default;75077508private:7509/////////////////////7510// locales7511/////////////////////75127513/// return the locale-dependent decimal point7514JSON_HEDLEY_PURE7515static char get_decimal_point() noexcept7516{7517const auto* loc = localeconv();7518JSON_ASSERT(loc != nullptr);7519return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);7520}75217522/////////////////////7523// scan functions7524/////////////////////75257526/*!7527@brief get codepoint from 4 hex characters following `\u`75287529For input "\u c1 c2 c3 c4" the codepoint is:7530(c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c47531= (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)75327533Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'7534must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The7535conversion is done by subtracting the offset (0x30, 0x37, and 0x57)7536between the ASCII value of the character and the desired integer value.75377538@return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or7539non-hex character)7540*/7541int get_codepoint()7542{7543// this function only makes sense after reading `\u`7544JSON_ASSERT(current == 'u');7545int codepoint = 0;75467547const auto factors = { 12u, 8u, 4u, 0u };7548for (const auto factor : factors)7549{7550get();75517552if (current >= '0' && current <= '9')7553{7554codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);7555}7556else if (current >= 'A' && current <= 'F')7557{7558codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);7559}7560else if (current >= 'a' && current <= 'f')7561{7562codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);7563}7564else7565{7566return -1;7567}7568}75697570JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);7571return codepoint;7572}75737574/*!7575@brief check if the next byte(s) are inside a given range75767577Adds the current byte and, for each passed range, reads a new byte and7578checks if it is inside the range. If a violation was detected, set up an7579error message and return false. Otherwise, return true.75807581@param[in] ranges list of integers; interpreted as list of pairs of7582inclusive lower and upper bound, respectively75837584@pre The passed list @a ranges must have 2, 4, or 6 elements; that is,75851, 2, or 3 pairs. This precondition is enforced by an assertion.75867587@return true if and only if no range violation was detected7588*/7589bool next_byte_in_range(std::initializer_list<char_int_type> ranges)7590{7591JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);7592add(current);75937594for (auto range = ranges.begin(); range != ranges.end(); ++range)7595{7596get();7597if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) // NOLINT(bugprone-inc-dec-in-conditions)7598{7599add(current);7600}7601else7602{7603error_message = "invalid string: ill-formed UTF-8 byte";7604return false;7605}7606}76077608return true;7609}76107611/*!7612@brief scan a string literal76137614This function scans a string according to Sect. 7 of RFC 8259. While7615scanning, bytes are escaped and copied into buffer token_buffer. Then the7616function returns successfully, token_buffer is *not* null-terminated (as it7617may contain \0 bytes), and token_buffer.size() is the number of bytes in the7618string.76197620@return token_type::value_string if string could be successfully scanned,7621token_type::parse_error otherwise76227623@note In case of errors, variable error_message contains a textual7624description.7625*/7626token_type scan_string()7627{7628// reset token_buffer (ignore opening quote)7629reset();76307631// we entered the function by reading an open quote7632JSON_ASSERT(current == '\"');76337634while (true)7635{7636// get next character7637switch (get())7638{7639// end of file while parsing string7640case char_traits<char_type>::eof():7641{7642error_message = "invalid string: missing closing quote";7643return token_type::parse_error;7644}76457646// closing quote7647case '\"':7648{7649return token_type::value_string;7650}76517652// escapes7653case '\\':7654{7655switch (get())7656{7657// quotation mark7658case '\"':7659add('\"');7660break;7661// reverse solidus7662case '\\':7663add('\\');7664break;7665// solidus7666case '/':7667add('/');7668break;7669// backspace7670case 'b':7671add('\b');7672break;7673// form feed7674case 'f':7675add('\f');7676break;7677// line feed7678case 'n':7679add('\n');7680break;7681// carriage return7682case 'r':7683add('\r');7684break;7685// tab7686case 't':7687add('\t');7688break;76897690// unicode escapes7691case 'u':7692{7693const int codepoint1 = get_codepoint();7694int codepoint = codepoint1; // start with codepoint176957696if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))7697{7698error_message = "invalid string: '\\u' must be followed by 4 hex digits";7699return token_type::parse_error;7700}77017702// check if code point is a high surrogate7703if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)7704{7705// expect next \uxxxx entry7706if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))7707{7708const int codepoint2 = get_codepoint();77097710if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))7711{7712error_message = "invalid string: '\\u' must be followed by 4 hex digits";7713return token_type::parse_error;7714}77157716// check if codepoint2 is a low surrogate7717if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))7718{7719// overwrite codepoint7720codepoint = static_cast<int>(7721// high surrogate occupies the most significant 22 bits7722(static_cast<unsigned int>(codepoint1) << 10u)7723// low surrogate occupies the least significant 15 bits7724+ static_cast<unsigned int>(codepoint2)7725// there is still the 0xD800, 0xDC00 and 0x10000 noise7726// in the result, so we have to subtract with:7727// (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC007728- 0x35FDC00u);7729}7730else7731{7732error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";7733return token_type::parse_error;7734}7735}7736else7737{7738error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";7739return token_type::parse_error;7740}7741}7742else7743{7744if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))7745{7746error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";7747return token_type::parse_error;7748}7749}77507751// result of the above calculation yields a proper codepoint7752JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);77537754// translate codepoint into bytes7755if (codepoint < 0x80)7756{7757// 1-byte characters: 0xxxxxxx (ASCII)7758add(static_cast<char_int_type>(codepoint));7759}7760else if (codepoint <= 0x7FF)7761{7762// 2-byte characters: 110xxxxx 10xxxxxx7763add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));7764add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));7765}7766else if (codepoint <= 0xFFFF)7767{7768// 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx7769add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));7770add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));7771add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));7772}7773else7774{7775// 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx7776add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));7777add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));7778add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));7779add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));7780}77817782break;7783}77847785// other characters after escape7786default:7787error_message = "invalid string: forbidden character after backslash";7788return token_type::parse_error;7789}77907791break;7792}77937794// invalid control characters7795case 0x00:7796{7797error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";7798return token_type::parse_error;7799}78007801case 0x01:7802{7803error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";7804return token_type::parse_error;7805}78067807case 0x02:7808{7809error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";7810return token_type::parse_error;7811}78127813case 0x03:7814{7815error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";7816return token_type::parse_error;7817}78187819case 0x04:7820{7821error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";7822return token_type::parse_error;7823}78247825case 0x05:7826{7827error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";7828return token_type::parse_error;7829}78307831case 0x06:7832{7833error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";7834return token_type::parse_error;7835}78367837case 0x07:7838{7839error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";7840return token_type::parse_error;7841}78427843case 0x08:7844{7845error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";7846return token_type::parse_error;7847}78487849case 0x09:7850{7851error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";7852return token_type::parse_error;7853}78547855case 0x0A:7856{7857error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";7858return token_type::parse_error;7859}78607861case 0x0B:7862{7863error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";7864return token_type::parse_error;7865}78667867case 0x0C:7868{7869error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";7870return token_type::parse_error;7871}78727873case 0x0D:7874{7875error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";7876return token_type::parse_error;7877}78787879case 0x0E:7880{7881error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";7882return token_type::parse_error;7883}78847885case 0x0F:7886{7887error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";7888return token_type::parse_error;7889}78907891case 0x10:7892{7893error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";7894return token_type::parse_error;7895}78967897case 0x11:7898{7899error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";7900return token_type::parse_error;7901}79027903case 0x12:7904{7905error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";7906return token_type::parse_error;7907}79087909case 0x13:7910{7911error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";7912return token_type::parse_error;7913}79147915case 0x14:7916{7917error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";7918return token_type::parse_error;7919}79207921case 0x15:7922{7923error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";7924return token_type::parse_error;7925}79267927case 0x16:7928{7929error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";7930return token_type::parse_error;7931}79327933case 0x17:7934{7935error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";7936return token_type::parse_error;7937}79387939case 0x18:7940{7941error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";7942return token_type::parse_error;7943}79447945case 0x19:7946{7947error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";7948return token_type::parse_error;7949}79507951case 0x1A:7952{7953error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";7954return token_type::parse_error;7955}79567957case 0x1B:7958{7959error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";7960return token_type::parse_error;7961}79627963case 0x1C:7964{7965error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";7966return token_type::parse_error;7967}79687969case 0x1D:7970{7971error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";7972return token_type::parse_error;7973}79747975case 0x1E:7976{7977error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";7978return token_type::parse_error;7979}79807981case 0x1F:7982{7983error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";7984return token_type::parse_error;7985}79867987// U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))7988case 0x20:7989case 0x21:7990case 0x23:7991case 0x24:7992case 0x25:7993case 0x26:7994case 0x27:7995case 0x28:7996case 0x29:7997case 0x2A:7998case 0x2B:7999case 0x2C:8000case 0x2D:8001case 0x2E:8002case 0x2F:8003case 0x30:8004case 0x31:8005case 0x32:8006case 0x33:8007case 0x34:8008case 0x35:8009case 0x36:8010case 0x37:8011case 0x38:8012case 0x39:8013case 0x3A:8014case 0x3B:8015case 0x3C:8016case 0x3D:8017case 0x3E:8018case 0x3F:8019case 0x40:8020case 0x41:8021case 0x42:8022case 0x43:8023case 0x44:8024case 0x45:8025case 0x46:8026case 0x47:8027case 0x48:8028case 0x49:8029case 0x4A:8030case 0x4B:8031case 0x4C:8032case 0x4D:8033case 0x4E:8034case 0x4F:8035case 0x50:8036case 0x51:8037case 0x52:8038case 0x53:8039case 0x54:8040case 0x55:8041case 0x56:8042case 0x57:8043case 0x58:8044case 0x59:8045case 0x5A:8046case 0x5B:8047case 0x5D:8048case 0x5E:8049case 0x5F:8050case 0x60:8051case 0x61:8052case 0x62:8053case 0x63:8054case 0x64:8055case 0x65:8056case 0x66:8057case 0x67:8058case 0x68:8059case 0x69:8060case 0x6A:8061case 0x6B:8062case 0x6C:8063case 0x6D:8064case 0x6E:8065case 0x6F:8066case 0x70:8067case 0x71:8068case 0x72:8069case 0x73:8070case 0x74:8071case 0x75:8072case 0x76:8073case 0x77:8074case 0x78:8075case 0x79:8076case 0x7A:8077case 0x7B:8078case 0x7C:8079case 0x7D:8080case 0x7E:8081case 0x7F:8082{8083add(current);8084break;8085}80868087// U+0080..U+07FF: bytes C2..DF 80..BF8088case 0xC2:8089case 0xC3:8090case 0xC4:8091case 0xC5:8092case 0xC6:8093case 0xC7:8094case 0xC8:8095case 0xC9:8096case 0xCA:8097case 0xCB:8098case 0xCC:8099case 0xCD:8100case 0xCE:8101case 0xCF:8102case 0xD0:8103case 0xD1:8104case 0xD2:8105case 0xD3:8106case 0xD4:8107case 0xD5:8108case 0xD6:8109case 0xD7:8110case 0xD8:8111case 0xD9:8112case 0xDA:8113case 0xDB:8114case 0xDC:8115case 0xDD:8116case 0xDE:8117case 0xDF:8118{8119if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))8120{8121return token_type::parse_error;8122}8123break;8124}81258126// U+0800..U+0FFF: bytes E0 A0..BF 80..BF8127case 0xE0:8128{8129if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))8130{8131return token_type::parse_error;8132}8133break;8134}81358136// U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF8137// U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF8138case 0xE1:8139case 0xE2:8140case 0xE3:8141case 0xE4:8142case 0xE5:8143case 0xE6:8144case 0xE7:8145case 0xE8:8146case 0xE9:8147case 0xEA:8148case 0xEB:8149case 0xEC:8150case 0xEE:8151case 0xEF:8152{8153if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))8154{8155return token_type::parse_error;8156}8157break;8158}81598160// U+D000..U+D7FF: bytes ED 80..9F 80..BF8161case 0xED:8162{8163if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))8164{8165return token_type::parse_error;8166}8167break;8168}81698170// U+10000..U+3FFFF F0 90..BF 80..BF 80..BF8171case 0xF0:8172{8173if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))8174{8175return token_type::parse_error;8176}8177break;8178}81798180// U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF8181case 0xF1:8182case 0xF2:8183case 0xF3:8184{8185if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))8186{8187return token_type::parse_error;8188}8189break;8190}81918192// U+100000..U+10FFFF F4 80..8F 80..BF 80..BF8193case 0xF4:8194{8195if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))8196{8197return token_type::parse_error;8198}8199break;8200}82018202// remaining bytes (80..C1 and F5..FF) are ill-formed8203default:8204{8205error_message = "invalid string: ill-formed UTF-8 byte";8206return token_type::parse_error;8207}8208}8209}8210}82118212/*!8213* @brief scan a comment8214* @return whether comment could be scanned successfully8215*/8216bool scan_comment()8217{8218switch (get())8219{8220// single-line comments skip input until a newline or EOF is read8221case '/':8222{8223while (true)8224{8225switch (get())8226{8227case '\n':8228case '\r':8229case char_traits<char_type>::eof():8230case '\0':8231return true;82328233default:8234break;8235}8236}8237}82388239// multi-line comments skip input until */ is read8240case '*':8241{8242while (true)8243{8244switch (get())8245{8246case char_traits<char_type>::eof():8247case '\0':8248{8249error_message = "invalid comment; missing closing '*/'";8250return false;8251}82528253case '*':8254{8255switch (get())8256{8257case '/':8258return true;82598260default:8261{8262unget();8263continue;8264}8265}8266}82678268default:8269continue;8270}8271}8272}82738274// unexpected character after reading '/'8275default:8276{8277error_message = "invalid comment; expecting '/' or '*' after '/'";8278return false;8279}8280}8281}82828283JSON_HEDLEY_NON_NULL(2)8284static void strtof(float& f, const char* str, char** endptr) noexcept8285{8286f = std::strtof(str, endptr);8287}82888289JSON_HEDLEY_NON_NULL(2)8290static void strtof(double& f, const char* str, char** endptr) noexcept8291{8292f = std::strtod(str, endptr);8293}82948295JSON_HEDLEY_NON_NULL(2)8296static void strtof(long double& f, const char* str, char** endptr) noexcept8297{8298f = std::strtold(str, endptr);8299}83008301/*!8302@brief scan a number literal83038304This function scans a string according to Sect. 6 of RFC 8259.83058306The function is realized with a deterministic finite state machine derived8307from the grammar described in RFC 8259. Starting in state "init", the8308input is read and used to determined the next state. Only state "done"8309accepts the number. State "error" is a trap state to model errors. In the8310table below, "anything" means any character but the ones listed before.83118312state | 0 | 1-9 | e E | + | - | . | anything8313---------|----------|----------|----------|---------|---------|----------|-----------8314init | zero | any1 | [error] | [error] | minus | [error] | [error]8315minus | zero | any1 | [error] | [error] | [error] | [error] | [error]8316zero | done | done | exponent | done | done | decimal1 | done8317any1 | any1 | any1 | exponent | done | done | decimal1 | done8318decimal1 | decimal2 | decimal2 | [error] | [error] | [error] | [error] | [error]8319decimal2 | decimal2 | decimal2 | exponent | done | done | done | done8320exponent | any2 | any2 | [error] | sign | sign | [error] | [error]8321sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]8322any2 | any2 | any2 | done | done | done | done | done83238324The state machine is realized with one label per state (prefixed with8325"scan_number_") and `goto` statements between them. The state machine8326contains cycles, but any cycle can be left when EOF is read. Therefore,8327the function is guaranteed to terminate.83288329During scanning, the read bytes are stored in token_buffer. This string is8330then converted to a signed integer, an unsigned integer, or a8331floating-point number.83328333@return token_type::value_unsigned, token_type::value_integer, or8334token_type::value_float if number could be successfully scanned,8335token_type::parse_error otherwise83368337@note The scanner is independent of the current locale. Internally, the8338locale's decimal point is used instead of `.` to work with the8339locale-dependent converters.8340*/8341token_type scan_number() // lgtm [cpp/use-of-goto]8342{8343// reset token_buffer to store the number's bytes8344reset();83458346// the type of the parsed number; initially set to unsigned; will be8347// changed if minus sign, decimal point or exponent is read8348token_type number_type = token_type::value_unsigned;83498350// state (init): we just found out we need to scan a number8351switch (current)8352{8353case '-':8354{8355add(current);8356goto scan_number_minus;8357}83588359case '0':8360{8361add(current);8362goto scan_number_zero;8363}83648365case '1':8366case '2':8367case '3':8368case '4':8369case '5':8370case '6':8371case '7':8372case '8':8373case '9':8374{8375add(current);8376goto scan_number_any1;8377}83788379// all other characters are rejected outside scan_number()8380default: // LCOV_EXCL_LINE8381JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE8382}83838384scan_number_minus:8385// state: we just parsed a leading minus sign8386number_type = token_type::value_integer;8387switch (get())8388{8389case '0':8390{8391add(current);8392goto scan_number_zero;8393}83948395case '1':8396case '2':8397case '3':8398case '4':8399case '5':8400case '6':8401case '7':8402case '8':8403case '9':8404{8405add(current);8406goto scan_number_any1;8407}84088409default:8410{8411error_message = "invalid number; expected digit after '-'";8412return token_type::parse_error;8413}8414}84158416scan_number_zero:8417// state: we just parse a zero (maybe with a leading minus sign)8418switch (get())8419{8420case '.':8421{8422add(decimal_point_char);8423goto scan_number_decimal1;8424}84258426case 'e':8427case 'E':8428{8429add(current);8430goto scan_number_exponent;8431}84328433default:8434goto scan_number_done;8435}84368437scan_number_any1:8438// state: we just parsed a number 0-9 (maybe with a leading minus sign)8439switch (get())8440{8441case '0':8442case '1':8443case '2':8444case '3':8445case '4':8446case '5':8447case '6':8448case '7':8449case '8':8450case '9':8451{8452add(current);8453goto scan_number_any1;8454}84558456case '.':8457{8458add(decimal_point_char);8459goto scan_number_decimal1;8460}84618462case 'e':8463case 'E':8464{8465add(current);8466goto scan_number_exponent;8467}84688469default:8470goto scan_number_done;8471}84728473scan_number_decimal1:8474// state: we just parsed a decimal point8475number_type = token_type::value_float;8476switch (get())8477{8478case '0':8479case '1':8480case '2':8481case '3':8482case '4':8483case '5':8484case '6':8485case '7':8486case '8':8487case '9':8488{8489add(current);8490goto scan_number_decimal2;8491}84928493default:8494{8495error_message = "invalid number; expected digit after '.'";8496return token_type::parse_error;8497}8498}84998500scan_number_decimal2:8501// we just parsed at least one number after a decimal point8502switch (get())8503{8504case '0':8505case '1':8506case '2':8507case '3':8508case '4':8509case '5':8510case '6':8511case '7':8512case '8':8513case '9':8514{8515add(current);8516goto scan_number_decimal2;8517}85188519case 'e':8520case 'E':8521{8522add(current);8523goto scan_number_exponent;8524}85258526default:8527goto scan_number_done;8528}85298530scan_number_exponent:8531// we just parsed an exponent8532number_type = token_type::value_float;8533switch (get())8534{8535case '+':8536case '-':8537{8538add(current);8539goto scan_number_sign;8540}85418542case '0':8543case '1':8544case '2':8545case '3':8546case '4':8547case '5':8548case '6':8549case '7':8550case '8':8551case '9':8552{8553add(current);8554goto scan_number_any2;8555}85568557default:8558{8559error_message =8560"invalid number; expected '+', '-', or digit after exponent";8561return token_type::parse_error;8562}8563}85648565scan_number_sign:8566// we just parsed an exponent sign8567switch (get())8568{8569case '0':8570case '1':8571case '2':8572case '3':8573case '4':8574case '5':8575case '6':8576case '7':8577case '8':8578case '9':8579{8580add(current);8581goto scan_number_any2;8582}85838584default:8585{8586error_message = "invalid number; expected digit after exponent sign";8587return token_type::parse_error;8588}8589}85908591scan_number_any2:8592// we just parsed a number after the exponent or exponent sign8593switch (get())8594{8595case '0':8596case '1':8597case '2':8598case '3':8599case '4':8600case '5':8601case '6':8602case '7':8603case '8':8604case '9':8605{8606add(current);8607goto scan_number_any2;8608}86098610default:8611goto scan_number_done;8612}86138614scan_number_done:8615// unget the character after the number (we only read it to know that8616// we are done scanning a number)8617unget();86188619char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)8620errno = 0;86218622// try to parse integers first and fall back to floats8623if (number_type == token_type::value_unsigned)8624{8625const auto x = std::strtoull(token_buffer.data(), &endptr, 10);86268627// we checked the number format before8628JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());86298630if (errno == 0)8631{8632value_unsigned = static_cast<number_unsigned_t>(x);8633if (value_unsigned == x)8634{8635return token_type::value_unsigned;8636}8637}8638}8639else if (number_type == token_type::value_integer)8640{8641const auto x = std::strtoll(token_buffer.data(), &endptr, 10);86428643// we checked the number format before8644JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());86458646if (errno == 0)8647{8648value_integer = static_cast<number_integer_t>(x);8649if (value_integer == x)8650{8651return token_type::value_integer;8652}8653}8654}86558656// this code is reached if we parse a floating-point number or if an8657// integer conversion above failed8658strtof(value_float, token_buffer.data(), &endptr);86598660// we checked the number format before8661JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());86628663return token_type::value_float;8664}86658666/*!8667@param[in] literal_text the literal text to expect8668@param[in] length the length of the passed literal text8669@param[in] return_type the token type to return on success8670*/8671JSON_HEDLEY_NON_NULL(2)8672token_type scan_literal(const char_type* literal_text, const std::size_t length,8673token_type return_type)8674{8675JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);8676for (std::size_t i = 1; i < length; ++i)8677{8678if (JSON_HEDLEY_UNLIKELY(char_traits<char_type>::to_char_type(get()) != literal_text[i]))8679{8680error_message = "invalid literal";8681return token_type::parse_error;8682}8683}8684return return_type;8685}86868687/////////////////////8688// input management8689/////////////////////86908691/// reset token_buffer; current character is beginning of token8692void reset() noexcept8693{8694token_buffer.clear();8695token_string.clear();8696token_string.push_back(char_traits<char_type>::to_char_type(current));8697}86988699/*8700@brief get next character from the input87018702This function provides the interface to the used input adapter. It does8703not throw in case the input reached EOF, but returns a8704`char_traits<char>::eof()` in that case. Stores the scanned characters8705for use in error messages.87068707@return character read from the input8708*/8709char_int_type get()8710{8711++position.chars_read_total;8712++position.chars_read_current_line;87138714if (next_unget)8715{8716// just reset the next_unget variable and work with current8717next_unget = false;8718}8719else8720{8721current = ia.get_character();8722}87238724if (JSON_HEDLEY_LIKELY(current != char_traits<char_type>::eof()))8725{8726token_string.push_back(char_traits<char_type>::to_char_type(current));8727}87288729if (current == '\n')8730{8731++position.lines_read;8732position.chars_read_current_line = 0;8733}87348735return current;8736}87378738/*!8739@brief unget current character (read it again on next get)87408741We implement unget by setting variable next_unget to true. The input is not8742changed - we just simulate ungetting by modifying chars_read_total,8743chars_read_current_line, and token_string. The next call to get() will8744behave as if the unget character is read again.8745*/8746void unget()8747{8748next_unget = true;87498750--position.chars_read_total;87518752// in case we "unget" a newline, we have to also decrement the lines_read8753if (position.chars_read_current_line == 0)8754{8755if (position.lines_read > 0)8756{8757--position.lines_read;8758}8759}8760else8761{8762--position.chars_read_current_line;8763}87648765if (JSON_HEDLEY_LIKELY(current != char_traits<char_type>::eof()))8766{8767JSON_ASSERT(!token_string.empty());8768token_string.pop_back();8769}8770}87718772/// add a character to token_buffer8773void add(char_int_type c)8774{8775token_buffer.push_back(static_cast<typename string_t::value_type>(c));8776}87778778public:8779/////////////////////8780// value getters8781/////////////////////87828783/// return integer value8784constexpr number_integer_t get_number_integer() const noexcept8785{8786return value_integer;8787}87888789/// return unsigned integer value8790constexpr number_unsigned_t get_number_unsigned() const noexcept8791{8792return value_unsigned;8793}87948795/// return floating-point value8796constexpr number_float_t get_number_float() const noexcept8797{8798return value_float;8799}88008801/// return current string value (implicitly resets the token; useful only once)8802string_t& get_string()8803{8804return token_buffer;8805}88068807/////////////////////8808// diagnostics8809/////////////////////88108811/// return position of last read token8812constexpr position_t get_position() const noexcept8813{8814return position;8815}88168817/// return the last read token (for errors only). Will never contain EOF8818/// (an arbitrary value that is not a valid char value, often -1), because8819/// 255 may legitimately occur. May contain NUL, which should be escaped.8820std::string get_token_string() const8821{8822// escape control characters8823std::string result;8824for (const auto c : token_string)8825{8826if (static_cast<unsigned char>(c) <= '\x1F')8827{8828// escape control characters8829std::array<char, 9> cs{{}};8830static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)8831result += cs.data();8832}8833else8834{8835// add character as is8836result.push_back(static_cast<std::string::value_type>(c));8837}8838}88398840return result;8841}88428843/// return syntax error message8844JSON_HEDLEY_RETURNS_NON_NULL8845constexpr const char* get_error_message() const noexcept8846{8847return error_message;8848}88498850/////////////////////8851// actual scanner8852/////////////////////88538854/*!8855@brief skip the UTF-8 byte order mark8856@return true iff there is no BOM or the correct BOM has been skipped8857*/8858bool skip_bom()8859{8860if (get() == 0xEF)8861{8862// check if we completely parse the BOM8863return get() == 0xBB && get() == 0xBF;8864}88658866// the first character is not the beginning of the BOM; unget it to8867// process is later8868unget();8869return true;8870}88718872void skip_whitespace()8873{8874do8875{8876get();8877}8878while (current == ' ' || current == '\t' || current == '\n' || current == '\r');8879}88808881token_type scan()8882{8883// initially, skip the BOM8884if (position.chars_read_total == 0 && !skip_bom())8885{8886error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";8887return token_type::parse_error;8888}88898890// read next character and ignore whitespace8891skip_whitespace();88928893// ignore comments8894while (ignore_comments && current == '/')8895{8896if (!scan_comment())8897{8898return token_type::parse_error;8899}89008901// skip following whitespace8902skip_whitespace();8903}89048905switch (current)8906{8907// structural characters8908case '[':8909return token_type::begin_array;8910case ']':8911return token_type::end_array;8912case '{':8913return token_type::begin_object;8914case '}':8915return token_type::end_object;8916case ':':8917return token_type::name_separator;8918case ',':8919return token_type::value_separator;89208921// literals8922case 't':8923{8924std::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')}};8925return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);8926}8927case 'f':8928{8929std::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')}};8930return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);8931}8932case 'n':8933{8934std::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')}};8935return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);8936}89378938// string8939case '\"':8940return scan_string();89418942// number8943case '-':8944case '0':8945case '1':8946case '2':8947case '3':8948case '4':8949case '5':8950case '6':8951case '7':8952case '8':8953case '9':8954return scan_number();89558956// end of input (the null byte is needed when parsing from8957// string literals)8958case '\0':8959case char_traits<char_type>::eof():8960return token_type::end_of_input;89618962// error8963default:8964error_message = "invalid literal";8965return token_type::parse_error;8966}8967}89688969private:8970/// input adapter8971InputAdapterType ia;89728973/// whether comments should be ignored (true) or signaled as errors (false)8974const bool ignore_comments = false;89758976/// the current character8977char_int_type current = char_traits<char_type>::eof();89788979/// whether the next get() call should just return current8980bool next_unget = false;89818982/// the start position of the current token8983position_t position {};89848985/// raw input token string (for error messages)8986std::vector<char_type> token_string {};89878988/// buffer for variable-length tokens (numbers, strings)8989string_t token_buffer {};89908991/// a description of occurred lexer errors8992const char* error_message = "";89938994// number values8995number_integer_t value_integer = 0;8996number_unsigned_t value_unsigned = 0;8997number_float_t value_float = 0;89988999/// the decimal point9000const char_int_type decimal_point_char = '.';9001};90029003} // namespace detail9004NLOHMANN_JSON_NAMESPACE_END90059006// #include <nlohmann/detail/macro_scope.hpp>90079008// #include <nlohmann/detail/meta/is_sax.hpp>9009// __ _____ _____ _____9010// __| | __| | | | JSON for Modern C++9011// | | |__ | | | | | | version 3.11.39012// |_____|_____|_____|_|___| https://github.com/nlohmann/json9013//9014// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>9015// SPDX-License-Identifier: MIT9016901790189019#include <cstdint> // size_t9020#include <utility> // declval9021#include <string> // string90229023// #include <nlohmann/detail/abi_macros.hpp>90249025// #include <nlohmann/detail/meta/detected.hpp>90269027// #include <nlohmann/detail/meta/type_traits.hpp>902890299030NLOHMANN_JSON_NAMESPACE_BEGIN9031namespace detail9032{90339034template<typename T>9035using null_function_t = decltype(std::declval<T&>().null());90369037template<typename T>9038using boolean_function_t =9039decltype(std::declval<T&>().boolean(std::declval<bool>()));90409041template<typename T, typename Integer>9042using number_integer_function_t =9043decltype(std::declval<T&>().number_integer(std::declval<Integer>()));90449045template<typename T, typename Unsigned>9046using number_unsigned_function_t =9047decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));90489049template<typename T, typename Float, typename String>9050using number_float_function_t = decltype(std::declval<T&>().number_float(9051std::declval<Float>(), std::declval<const String&>()));90529053template<typename T, typename String>9054using string_function_t =9055decltype(std::declval<T&>().string(std::declval<String&>()));90569057template<typename T, typename Binary>9058using binary_function_t =9059decltype(std::declval<T&>().binary(std::declval<Binary&>()));90609061template<typename T>9062using start_object_function_t =9063decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));90649065template<typename T, typename String>9066using key_function_t =9067decltype(std::declval<T&>().key(std::declval<String&>()));90689069template<typename T>9070using end_object_function_t = decltype(std::declval<T&>().end_object());90719072template<typename T>9073using start_array_function_t =9074decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));90759076template<typename T>9077using end_array_function_t = decltype(std::declval<T&>().end_array());90789079template<typename T, typename Exception>9080using parse_error_function_t = decltype(std::declval<T&>().parse_error(9081std::declval<std::size_t>(), std::declval<const std::string&>(),9082std::declval<const Exception&>()));90839084template<typename SAX, typename BasicJsonType>9085struct is_sax9086{9087private:9088static_assert(is_basic_json<BasicJsonType>::value,9089"BasicJsonType must be of type basic_json<...>");90909091using number_integer_t = typename BasicJsonType::number_integer_t;9092using number_unsigned_t = typename BasicJsonType::number_unsigned_t;9093using number_float_t = typename BasicJsonType::number_float_t;9094using string_t = typename BasicJsonType::string_t;9095using binary_t = typename BasicJsonType::binary_t;9096using exception_t = typename BasicJsonType::exception;90979098public:9099static constexpr bool value =9100is_detected_exact<bool, null_function_t, SAX>::value &&9101is_detected_exact<bool, boolean_function_t, SAX>::value &&9102is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&9103is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&9104is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&9105is_detected_exact<bool, string_function_t, SAX, string_t>::value &&9106is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&9107is_detected_exact<bool, start_object_function_t, SAX>::value &&9108is_detected_exact<bool, key_function_t, SAX, string_t>::value &&9109is_detected_exact<bool, end_object_function_t, SAX>::value &&9110is_detected_exact<bool, start_array_function_t, SAX>::value &&9111is_detected_exact<bool, end_array_function_t, SAX>::value &&9112is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;9113};91149115template<typename SAX, typename BasicJsonType>9116struct is_sax_static_asserts9117{9118private:9119static_assert(is_basic_json<BasicJsonType>::value,9120"BasicJsonType must be of type basic_json<...>");91219122using number_integer_t = typename BasicJsonType::number_integer_t;9123using number_unsigned_t = typename BasicJsonType::number_unsigned_t;9124using number_float_t = typename BasicJsonType::number_float_t;9125using string_t = typename BasicJsonType::string_t;9126using binary_t = typename BasicJsonType::binary_t;9127using exception_t = typename BasicJsonType::exception;91289129public:9130static_assert(is_detected_exact<bool, null_function_t, SAX>::value,9131"Missing/invalid function: bool null()");9132static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,9133"Missing/invalid function: bool boolean(bool)");9134static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,9135"Missing/invalid function: bool boolean(bool)");9136static_assert(9137is_detected_exact<bool, number_integer_function_t, SAX,9138number_integer_t>::value,9139"Missing/invalid function: bool number_integer(number_integer_t)");9140static_assert(9141is_detected_exact<bool, number_unsigned_function_t, SAX,9142number_unsigned_t>::value,9143"Missing/invalid function: bool number_unsigned(number_unsigned_t)");9144static_assert(is_detected_exact<bool, number_float_function_t, SAX,9145number_float_t, string_t>::value,9146"Missing/invalid function: bool number_float(number_float_t, const string_t&)");9147static_assert(9148is_detected_exact<bool, string_function_t, SAX, string_t>::value,9149"Missing/invalid function: bool string(string_t&)");9150static_assert(9151is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,9152"Missing/invalid function: bool binary(binary_t&)");9153static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,9154"Missing/invalid function: bool start_object(std::size_t)");9155static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,9156"Missing/invalid function: bool key(string_t&)");9157static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,9158"Missing/invalid function: bool end_object()");9159static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,9160"Missing/invalid function: bool start_array(std::size_t)");9161static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,9162"Missing/invalid function: bool end_array()");9163static_assert(9164is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,9165"Missing/invalid function: bool parse_error(std::size_t, const "9166"std::string&, const exception&)");9167};91689169} // namespace detail9170NLOHMANN_JSON_NAMESPACE_END91719172// #include <nlohmann/detail/meta/type_traits.hpp>91739174// #include <nlohmann/detail/string_concat.hpp>91759176// #include <nlohmann/detail/value_t.hpp>917791789179NLOHMANN_JSON_NAMESPACE_BEGIN9180namespace detail9181{91829183/// how to treat CBOR tags9184enum class cbor_tag_handler_t9185{9186error, ///< throw a parse_error exception in case of a tag9187ignore, ///< ignore tags9188store ///< store tags as binary type9189};91909191/*!9192@brief determine system byte order91939194@return true if and only if system's byte order is little endian91959196@note from https://stackoverflow.com/a/1001328/2663789197*/9198static inline bool little_endianness(int num = 1) noexcept9199{9200return *reinterpret_cast<char*>(&num) == 1;9201}92029203///////////////////9204// binary reader //9205///////////////////92069207/*!9208@brief deserialization of CBOR, MessagePack, and UBJSON values9209*/9210template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>9211class binary_reader9212{9213using number_integer_t = typename BasicJsonType::number_integer_t;9214using number_unsigned_t = typename BasicJsonType::number_unsigned_t;9215using number_float_t = typename BasicJsonType::number_float_t;9216using string_t = typename BasicJsonType::string_t;9217using binary_t = typename BasicJsonType::binary_t;9218using json_sax_t = SAX;9219using char_type = typename InputAdapterType::char_type;9220using char_int_type = typename char_traits<char_type>::int_type;92219222public:9223/*!9224@brief create a binary reader92259226@param[in] adapter input adapter to read from9227*/9228explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)9229{9230(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};9231}92329233// make class move-only9234binary_reader(const binary_reader&) = delete;9235binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)9236binary_reader& operator=(const binary_reader&) = delete;9237binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)9238~binary_reader() = default;92399240/*!9241@param[in] format the binary format to parse9242@param[in] sax_ a SAX event processor9243@param[in] strict whether to expect the input to be consumed completed9244@param[in] tag_handler how to treat CBOR tags92459246@return whether parsing was successful9247*/9248JSON_HEDLEY_NON_NULL(3)9249bool sax_parse(const input_format_t format,9250json_sax_t* sax_,9251const bool strict = true,9252const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)9253{9254sax = sax_;9255bool result = false;92569257switch (format)9258{9259case input_format_t::bson:9260result = parse_bson_internal();9261break;92629263case input_format_t::cbor:9264result = parse_cbor_internal(true, tag_handler);9265break;92669267case input_format_t::msgpack:9268result = parse_msgpack_internal();9269break;92709271case input_format_t::ubjson:9272case input_format_t::bjdata:9273result = parse_ubjson_internal();9274break;92759276case input_format_t::json: // LCOV_EXCL_LINE9277default: // LCOV_EXCL_LINE9278JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE9279}92809281// strict mode: next byte must be EOF9282if (result && strict)9283{9284if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)9285{9286get_ignore_noop();9287}9288else9289{9290get();9291}92929293if (JSON_HEDLEY_UNLIKELY(current != char_traits<char_type>::eof()))9294{9295return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,9296exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));9297}9298}92999300return result;9301}93029303private:9304//////////9305// BSON //9306//////////93079308/*!9309@brief Reads in a BSON-object and passes it to the SAX-parser.9310@return whether a valid BSON-value was passed to the SAX parser9311*/9312bool parse_bson_internal()9313{9314std::int32_t document_size{};9315get_number<std::int32_t, true>(input_format_t::bson, document_size);93169317if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))9318{9319return false;9320}93219322if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))9323{9324return false;9325}93269327return sax->end_object();9328}93299330/*!9331@brief Parses a C-style string from the BSON input.9332@param[in,out] result A reference to the string variable where the read9333string is to be stored.9334@return `true` if the \x00-byte indicating the end of the string was9335encountered before the EOF; false` indicates an unexpected EOF.9336*/9337bool get_bson_cstr(string_t& result)9338{9339auto out = std::back_inserter(result);9340while (true)9341{9342get();9343if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))9344{9345return false;9346}9347if (current == 0x00)9348{9349return true;9350}9351*out++ = static_cast<typename string_t::value_type>(current);9352}9353}93549355/*!9356@brief Parses a zero-terminated string of length @a len from the BSON9357input.9358@param[in] len The length (including the zero-byte at the end) of the9359string to be read.9360@param[in,out] result A reference to the string variable where the read9361string is to be stored.9362@tparam NumberType The type of the length @a len9363@pre len >= 19364@return `true` if the string was successfully parsed9365*/9366template<typename NumberType>9367bool get_bson_string(const NumberType len, string_t& result)9368{9369if (JSON_HEDLEY_UNLIKELY(len < 1))9370{9371auto last_token = get_token_string();9372return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,9373exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));9374}93759376return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != char_traits<char_type>::eof();9377}93789379/*!9380@brief Parses a byte array input of length @a len from the BSON input.9381@param[in] len The length of the byte array to be read.9382@param[in,out] result A reference to the binary variable where the read9383array is to be stored.9384@tparam NumberType The type of the length @a len9385@pre len >= 09386@return `true` if the byte array was successfully parsed9387*/9388template<typename NumberType>9389bool get_bson_binary(const NumberType len, binary_t& result)9390{9391if (JSON_HEDLEY_UNLIKELY(len < 0))9392{9393auto last_token = get_token_string();9394return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,9395exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));9396}93979398// All BSON binary values have a subtype9399std::uint8_t subtype{};9400get_number<std::uint8_t>(input_format_t::bson, subtype);9401result.set_subtype(subtype);94029403return get_binary(input_format_t::bson, len, result);9404}94059406/*!9407@brief Read a BSON document element of the given @a element_type.9408@param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html9409@param[in] element_type_parse_position The position in the input stream,9410where the `element_type` was read.9411@warning Not all BSON element types are supported yet. An unsupported9412@a element_type will give rise to a parse_error.114:9413Unsupported BSON record type 0x...9414@return whether a valid BSON-object/array was passed to the SAX parser9415*/9416bool parse_bson_element_internal(const char_int_type element_type,9417const std::size_t element_type_parse_position)9418{9419switch (element_type)9420{9421case 0x01: // double9422{9423double number{};9424return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");9425}94269427case 0x02: // string9428{9429std::int32_t len{};9430string_t value;9431return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);9432}94339434case 0x03: // object9435{9436return parse_bson_internal();9437}94389439case 0x04: // array9440{9441return parse_bson_array();9442}94439444case 0x05: // binary9445{9446std::int32_t len{};9447binary_t value;9448return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);9449}94509451case 0x08: // boolean9452{9453return sax->boolean(get() != 0);9454}94559456case 0x0A: // null9457{9458return sax->null();9459}94609461case 0x10: // int329462{9463std::int32_t value{};9464return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);9465}94669467case 0x12: // int649468{9469std::int64_t value{};9470return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);9471}94729473default: // anything else not supported (yet)9474{9475std::array<char, 3> cr{{}};9476static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)9477const std::string cr_str{cr.data()};9478return sax->parse_error(element_type_parse_position, cr_str,9479parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));9480}9481}9482}94839484/*!9485@brief Read a BSON element list (as specified in the BSON-spec)94869487The same binary layout is used for objects and arrays, hence it must be9488indicated with the argument @a is_array which one is expected9489(true --> array, false --> object).94909491@param[in] is_array Determines if the element list being read is to be9492treated as an object (@a is_array == false), or as an9493array (@a is_array == true).9494@return whether a valid BSON-object/array was passed to the SAX parser9495*/9496bool parse_bson_element_list(const bool is_array)9497{9498string_t key;94999500while (auto element_type = get())9501{9502if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))9503{9504return false;9505}95069507const std::size_t element_type_parse_position = chars_read;9508if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))9509{9510return false;9511}95129513if (!is_array && !sax->key(key))9514{9515return false;9516}95179518if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))9519{9520return false;9521}95229523// get_bson_cstr only appends9524key.clear();9525}95269527return true;9528}95299530/*!9531@brief Reads an array from the BSON input and passes it to the SAX-parser.9532@return whether a valid BSON-array was passed to the SAX parser9533*/9534bool parse_bson_array()9535{9536std::int32_t document_size{};9537get_number<std::int32_t, true>(input_format_t::bson, document_size);95389539if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))9540{9541return false;9542}95439544if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))9545{9546return false;9547}95489549return sax->end_array();9550}95519552//////////9553// CBOR //9554//////////95559556/*!9557@param[in] get_char whether a new character should be retrieved from the9558input (true) or whether the last read character should9559be considered instead (false)9560@param[in] tag_handler how CBOR tags should be treated95619562@return whether a valid CBOR value was passed to the SAX parser9563*/9564bool parse_cbor_internal(const bool get_char,9565const cbor_tag_handler_t tag_handler)9566{9567switch (get_char ? get() : current)9568{9569// EOF9570case char_traits<char_type>::eof():9571return unexpect_eof(input_format_t::cbor, "value");95729573// Integer 0x00..0x17 (0..23)9574case 0x00:9575case 0x01:9576case 0x02:9577case 0x03:9578case 0x04:9579case 0x05:9580case 0x06:9581case 0x07:9582case 0x08:9583case 0x09:9584case 0x0A:9585case 0x0B:9586case 0x0C:9587case 0x0D:9588case 0x0E:9589case 0x0F:9590case 0x10:9591case 0x11:9592case 0x12:9593case 0x13:9594case 0x14:9595case 0x15:9596case 0x16:9597case 0x17:9598return sax->number_unsigned(static_cast<number_unsigned_t>(current));95999600case 0x18: // Unsigned integer (one-byte uint8_t follows)9601{9602std::uint8_t number{};9603return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);9604}96059606case 0x19: // Unsigned integer (two-byte uint16_t follows)9607{9608std::uint16_t number{};9609return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);9610}96119612case 0x1A: // Unsigned integer (four-byte uint32_t follows)9613{9614std::uint32_t number{};9615return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);9616}96179618case 0x1B: // Unsigned integer (eight-byte uint64_t follows)9619{9620std::uint64_t number{};9621return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);9622}96239624// Negative integer -1-0x00..-1-0x17 (-1..-24)9625case 0x20:9626case 0x21:9627case 0x22:9628case 0x23:9629case 0x24:9630case 0x25:9631case 0x26:9632case 0x27:9633case 0x28:9634case 0x29:9635case 0x2A:9636case 0x2B:9637case 0x2C:9638case 0x2D:9639case 0x2E:9640case 0x2F:9641case 0x30:9642case 0x31:9643case 0x32:9644case 0x33:9645case 0x34:9646case 0x35:9647case 0x36:9648case 0x37:9649return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));96509651case 0x38: // Negative integer (one-byte uint8_t follows)9652{9653std::uint8_t number{};9654return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);9655}96569657case 0x39: // Negative integer -1-n (two-byte uint16_t follows)9658{9659std::uint16_t number{};9660return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);9661}96629663case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)9664{9665std::uint32_t number{};9666return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);9667}96689669case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)9670{9671std::uint64_t number{};9672return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)9673- static_cast<number_integer_t>(number));9674}96759676// Binary data (0x00..0x17 bytes follow)9677case 0x40:9678case 0x41:9679case 0x42:9680case 0x43:9681case 0x44:9682case 0x45:9683case 0x46:9684case 0x47:9685case 0x48:9686case 0x49:9687case 0x4A:9688case 0x4B:9689case 0x4C:9690case 0x4D:9691case 0x4E:9692case 0x4F:9693case 0x50:9694case 0x51:9695case 0x52:9696case 0x53:9697case 0x54:9698case 0x55:9699case 0x56:9700case 0x57:9701case 0x58: // Binary data (one-byte uint8_t for n follows)9702case 0x59: // Binary data (two-byte uint16_t for n follow)9703case 0x5A: // Binary data (four-byte uint32_t for n follow)9704case 0x5B: // Binary data (eight-byte uint64_t for n follow)9705case 0x5F: // Binary data (indefinite length)9706{9707binary_t b;9708return get_cbor_binary(b) && sax->binary(b);9709}97109711// UTF-8 string (0x00..0x17 bytes follow)9712case 0x60:9713case 0x61:9714case 0x62:9715case 0x63:9716case 0x64:9717case 0x65:9718case 0x66:9719case 0x67:9720case 0x68:9721case 0x69:9722case 0x6A:9723case 0x6B:9724case 0x6C:9725case 0x6D:9726case 0x6E:9727case 0x6F:9728case 0x70:9729case 0x71:9730case 0x72:9731case 0x73:9732case 0x74:9733case 0x75:9734case 0x76:9735case 0x77:9736case 0x78: // UTF-8 string (one-byte uint8_t for n follows)9737case 0x79: // UTF-8 string (two-byte uint16_t for n follow)9738case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)9739case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)9740case 0x7F: // UTF-8 string (indefinite length)9741{9742string_t s;9743return get_cbor_string(s) && sax->string(s);9744}97459746// array (0x00..0x17 data items follow)9747case 0x80:9748case 0x81:9749case 0x82:9750case 0x83:9751case 0x84:9752case 0x85:9753case 0x86:9754case 0x87:9755case 0x88:9756case 0x89:9757case 0x8A:9758case 0x8B:9759case 0x8C:9760case 0x8D:9761case 0x8E:9762case 0x8F:9763case 0x90:9764case 0x91:9765case 0x92:9766case 0x93:9767case 0x94:9768case 0x95:9769case 0x96:9770case 0x97:9771return get_cbor_array(9772conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);97739774case 0x98: // array (one-byte uint8_t for n follows)9775{9776std::uint8_t len{};9777return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);9778}97799780case 0x99: // array (two-byte uint16_t for n follow)9781{9782std::uint16_t len{};9783return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);9784}97859786case 0x9A: // array (four-byte uint32_t for n follow)9787{9788std::uint32_t len{};9789return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);9790}97919792case 0x9B: // array (eight-byte uint64_t for n follow)9793{9794std::uint64_t len{};9795return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);9796}97979798case 0x9F: // array (indefinite length)9799return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);98009801// map (0x00..0x17 pairs of data items follow)9802case 0xA0:9803case 0xA1:9804case 0xA2:9805case 0xA3:9806case 0xA4:9807case 0xA5:9808case 0xA6:9809case 0xA7:9810case 0xA8:9811case 0xA9:9812case 0xAA:9813case 0xAB:9814case 0xAC:9815case 0xAD:9816case 0xAE:9817case 0xAF:9818case 0xB0:9819case 0xB1:9820case 0xB2:9821case 0xB3:9822case 0xB4:9823case 0xB5:9824case 0xB6:9825case 0xB7:9826return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);98279828case 0xB8: // map (one-byte uint8_t for n follows)9829{9830std::uint8_t len{};9831return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);9832}98339834case 0xB9: // map (two-byte uint16_t for n follow)9835{9836std::uint16_t len{};9837return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);9838}98399840case 0xBA: // map (four-byte uint32_t for n follow)9841{9842std::uint32_t len{};9843return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);9844}98459846case 0xBB: // map (eight-byte uint64_t for n follow)9847{9848std::uint64_t len{};9849return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);9850}98519852case 0xBF: // map (indefinite length)9853return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);98549855case 0xC6: // tagged item9856case 0xC7:9857case 0xC8:9858case 0xC9:9859case 0xCA:9860case 0xCB:9861case 0xCC:9862case 0xCD:9863case 0xCE:9864case 0xCF:9865case 0xD0:9866case 0xD1:9867case 0xD2:9868case 0xD3:9869case 0xD4:9870case 0xD8: // tagged item (1 bytes follow)9871case 0xD9: // tagged item (2 bytes follow)9872case 0xDA: // tagged item (4 bytes follow)9873case 0xDB: // tagged item (8 bytes follow)9874{9875switch (tag_handler)9876{9877case cbor_tag_handler_t::error:9878{9879auto last_token = get_token_string();9880return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,9881exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));9882}98839884case cbor_tag_handler_t::ignore:9885{9886// ignore binary subtype9887switch (current)9888{9889case 0xD8:9890{9891std::uint8_t subtype_to_ignore{};9892get_number(input_format_t::cbor, subtype_to_ignore);9893break;9894}9895case 0xD9:9896{9897std::uint16_t subtype_to_ignore{};9898get_number(input_format_t::cbor, subtype_to_ignore);9899break;9900}9901case 0xDA:9902{9903std::uint32_t subtype_to_ignore{};9904get_number(input_format_t::cbor, subtype_to_ignore);9905break;9906}9907case 0xDB:9908{9909std::uint64_t subtype_to_ignore{};9910get_number(input_format_t::cbor, subtype_to_ignore);9911break;9912}9913default:9914break;9915}9916return parse_cbor_internal(true, tag_handler);9917}99189919case cbor_tag_handler_t::store:9920{9921binary_t b;9922// use binary subtype and store in binary container9923switch (current)9924{9925case 0xD8:9926{9927std::uint8_t subtype{};9928get_number(input_format_t::cbor, subtype);9929b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));9930break;9931}9932case 0xD9:9933{9934std::uint16_t subtype{};9935get_number(input_format_t::cbor, subtype);9936b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));9937break;9938}9939case 0xDA:9940{9941std::uint32_t subtype{};9942get_number(input_format_t::cbor, subtype);9943b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));9944break;9945}9946case 0xDB:9947{9948std::uint64_t subtype{};9949get_number(input_format_t::cbor, subtype);9950b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));9951break;9952}9953default:9954return parse_cbor_internal(true, tag_handler);9955}9956get();9957return get_cbor_binary(b) && sax->binary(b);9958}99599960default: // LCOV_EXCL_LINE9961JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE9962return false; // LCOV_EXCL_LINE9963}9964}99659966case 0xF4: // false9967return sax->boolean(false);99689969case 0xF5: // true9970return sax->boolean(true);99719972case 0xF6: // null9973return sax->null();99749975case 0xF9: // Half-Precision Float (two-byte IEEE 754)9976{9977const auto byte1_raw = get();9978if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))9979{9980return false;9981}9982const auto byte2_raw = get();9983if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))9984{9985return false;9986}99879988const auto byte1 = static_cast<unsigned char>(byte1_raw);9989const auto byte2 = static_cast<unsigned char>(byte2_raw);99909991// code from RFC 7049, Appendix D, Figure 3:9992// As half-precision floating-point numbers were only added9993// to IEEE 754 in 2008, today's programming platforms often9994// still only have limited support for them. It is very9995// easy to include at least decoding support for them even9996// without such support. An example of a small decoder for9997// half-precision floating-point numbers in the C language9998// is shown in Fig. 3.9999const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);10000const double val = [&half]10001{10002const int exp = (half >> 10u) & 0x1Fu;10003const unsigned int mant = half & 0x3FFu;10004JSON_ASSERT(0 <= exp&& exp <= 32);10005JSON_ASSERT(mant <= 1024);10006switch (exp)10007{10008case 0:10009return std::ldexp(mant, -24);10010case 31:10011return (mant == 0)10012? std::numeric_limits<double>::infinity()10013: std::numeric_limits<double>::quiet_NaN();10014default:10015return std::ldexp(mant + 1024, exp - 25);10016}10017}();10018return sax->number_float((half & 0x8000u) != 010019? static_cast<number_float_t>(-val)10020: static_cast<number_float_t>(val), "");10021}1002210023case 0xFA: // Single-Precision Float (four-byte IEEE 754)10024{10025float number{};10026return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");10027}1002810029case 0xFB: // Double-Precision Float (eight-byte IEEE 754)10030{10031double number{};10032return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");10033}1003410035default: // anything else (0xFF is handled inside the other types)10036{10037auto last_token = get_token_string();10038return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,10039exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));10040}10041}10042}1004310044/*!10045@brief reads a CBOR string1004610047This function first reads starting bytes to determine the expected10048string length and then copies this number of bytes into a string.10049Additionally, CBOR's strings with indefinite lengths are supported.1005010051@param[out] result created string1005210053@return whether string creation completed10054*/10055bool get_cbor_string(string_t& result)10056{10057if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))10058{10059return false;10060}1006110062switch (current)10063{10064// UTF-8 string (0x00..0x17 bytes follow)10065case 0x60:10066case 0x61:10067case 0x62:10068case 0x63:10069case 0x64:10070case 0x65:10071case 0x66:10072case 0x67:10073case 0x68:10074case 0x69:10075case 0x6A:10076case 0x6B:10077case 0x6C:10078case 0x6D:10079case 0x6E:10080case 0x6F:10081case 0x70:10082case 0x71:10083case 0x72:10084case 0x73:10085case 0x74:10086case 0x75:10087case 0x76:10088case 0x77:10089{10090return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);10091}1009210093case 0x78: // UTF-8 string (one-byte uint8_t for n follows)10094{10095std::uint8_t len{};10096return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);10097}1009810099case 0x79: // UTF-8 string (two-byte uint16_t for n follow)10100{10101std::uint16_t len{};10102return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);10103}1010410105case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)10106{10107std::uint32_t len{};10108return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);10109}1011010111case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)10112{10113std::uint64_t len{};10114return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);10115}1011610117case 0x7F: // UTF-8 string (indefinite length)10118{10119while (get() != 0xFF)10120{10121string_t chunk;10122if (!get_cbor_string(chunk))10123{10124return false;10125}10126result.append(chunk);10127}10128return true;10129}1013010131default:10132{10133auto last_token = get_token_string();10134return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,10135exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));10136}10137}10138}1013910140/*!10141@brief reads a CBOR byte array1014210143This function first reads starting bytes to determine the expected10144byte array length and then copies this number of bytes into the byte array.10145Additionally, CBOR's byte arrays with indefinite lengths are supported.1014610147@param[out] result created byte array1014810149@return whether byte array creation completed10150*/10151bool get_cbor_binary(binary_t& result)10152{10153if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))10154{10155return false;10156}1015710158switch (current)10159{10160// Binary data (0x00..0x17 bytes follow)10161case 0x40:10162case 0x41:10163case 0x42:10164case 0x43:10165case 0x44:10166case 0x45:10167case 0x46:10168case 0x47:10169case 0x48:10170case 0x49:10171case 0x4A:10172case 0x4B:10173case 0x4C:10174case 0x4D:10175case 0x4E:10176case 0x4F:10177case 0x50:10178case 0x51:10179case 0x52:10180case 0x53:10181case 0x54:10182case 0x55:10183case 0x56:10184case 0x57:10185{10186return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);10187}1018810189case 0x58: // Binary data (one-byte uint8_t for n follows)10190{10191std::uint8_t len{};10192return get_number(input_format_t::cbor, len) &&10193get_binary(input_format_t::cbor, len, result);10194}1019510196case 0x59: // Binary data (two-byte uint16_t for n follow)10197{10198std::uint16_t len{};10199return get_number(input_format_t::cbor, len) &&10200get_binary(input_format_t::cbor, len, result);10201}1020210203case 0x5A: // Binary data (four-byte uint32_t for n follow)10204{10205std::uint32_t len{};10206return get_number(input_format_t::cbor, len) &&10207get_binary(input_format_t::cbor, len, result);10208}1020910210case 0x5B: // Binary data (eight-byte uint64_t for n follow)10211{10212std::uint64_t len{};10213return get_number(input_format_t::cbor, len) &&10214get_binary(input_format_t::cbor, len, result);10215}1021610217case 0x5F: // Binary data (indefinite length)10218{10219while (get() != 0xFF)10220{10221binary_t chunk;10222if (!get_cbor_binary(chunk))10223{10224return false;10225}10226result.insert(result.end(), chunk.begin(), chunk.end());10227}10228return true;10229}1023010231default:10232{10233auto last_token = get_token_string();10234return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,10235exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));10236}10237}10238}1023910240/*!10241@param[in] len the length of the array or static_cast<std::size_t>(-1) for an10242array of indefinite size10243@param[in] tag_handler how CBOR tags should be treated10244@return whether array creation completed10245*/10246bool get_cbor_array(const std::size_t len,10247const cbor_tag_handler_t tag_handler)10248{10249if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))10250{10251return false;10252}1025310254if (len != static_cast<std::size_t>(-1))10255{10256for (std::size_t i = 0; i < len; ++i)10257{10258if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))10259{10260return false;10261}10262}10263}10264else10265{10266while (get() != 0xFF)10267{10268if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))10269{10270return false;10271}10272}10273}1027410275return sax->end_array();10276}1027710278/*!10279@param[in] len the length of the object or static_cast<std::size_t>(-1) for an10280object of indefinite size10281@param[in] tag_handler how CBOR tags should be treated10282@return whether object creation completed10283*/10284bool get_cbor_object(const std::size_t len,10285const cbor_tag_handler_t tag_handler)10286{10287if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))10288{10289return false;10290}1029110292if (len != 0)10293{10294string_t key;10295if (len != static_cast<std::size_t>(-1))10296{10297for (std::size_t i = 0; i < len; ++i)10298{10299get();10300if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))10301{10302return false;10303}1030410305if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))10306{10307return false;10308}10309key.clear();10310}10311}10312else10313{10314while (get() != 0xFF)10315{10316if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))10317{10318return false;10319}1032010321if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))10322{10323return false;10324}10325key.clear();10326}10327}10328}1032910330return sax->end_object();10331}1033210333/////////////10334// MsgPack //10335/////////////1033610337/*!10338@return whether a valid MessagePack value was passed to the SAX parser10339*/10340bool parse_msgpack_internal()10341{10342switch (get())10343{10344// EOF10345case char_traits<char_type>::eof():10346return unexpect_eof(input_format_t::msgpack, "value");1034710348// positive fixint10349case 0x00:10350case 0x01:10351case 0x02:10352case 0x03:10353case 0x04:10354case 0x05:10355case 0x06:10356case 0x07:10357case 0x08:10358case 0x09:10359case 0x0A:10360case 0x0B:10361case 0x0C:10362case 0x0D:10363case 0x0E:10364case 0x0F:10365case 0x10:10366case 0x11:10367case 0x12:10368case 0x13:10369case 0x14:10370case 0x15:10371case 0x16:10372case 0x17:10373case 0x18:10374case 0x19:10375case 0x1A:10376case 0x1B:10377case 0x1C:10378case 0x1D:10379case 0x1E:10380case 0x1F:10381case 0x20:10382case 0x21:10383case 0x22:10384case 0x23:10385case 0x24:10386case 0x25:10387case 0x26:10388case 0x27:10389case 0x28:10390case 0x29:10391case 0x2A:10392case 0x2B:10393case 0x2C:10394case 0x2D:10395case 0x2E:10396case 0x2F:10397case 0x30:10398case 0x31:10399case 0x32:10400case 0x33:10401case 0x34:10402case 0x35:10403case 0x36:10404case 0x37:10405case 0x38:10406case 0x39:10407case 0x3A:10408case 0x3B:10409case 0x3C:10410case 0x3D:10411case 0x3E:10412case 0x3F:10413case 0x40:10414case 0x41:10415case 0x42:10416case 0x43:10417case 0x44:10418case 0x45:10419case 0x46:10420case 0x47:10421case 0x48:10422case 0x49:10423case 0x4A:10424case 0x4B:10425case 0x4C:10426case 0x4D:10427case 0x4E:10428case 0x4F:10429case 0x50:10430case 0x51:10431case 0x52:10432case 0x53:10433case 0x54:10434case 0x55:10435case 0x56:10436case 0x57:10437case 0x58:10438case 0x59:10439case 0x5A:10440case 0x5B:10441case 0x5C:10442case 0x5D:10443case 0x5E:10444case 0x5F:10445case 0x60:10446case 0x61:10447case 0x62:10448case 0x63:10449case 0x64:10450case 0x65:10451case 0x66:10452case 0x67:10453case 0x68:10454case 0x69:10455case 0x6A:10456case 0x6B:10457case 0x6C:10458case 0x6D:10459case 0x6E:10460case 0x6F:10461case 0x70:10462case 0x71:10463case 0x72:10464case 0x73:10465case 0x74:10466case 0x75:10467case 0x76:10468case 0x77:10469case 0x78:10470case 0x79:10471case 0x7A:10472case 0x7B:10473case 0x7C:10474case 0x7D:10475case 0x7E:10476case 0x7F:10477return sax->number_unsigned(static_cast<number_unsigned_t>(current));1047810479// fixmap10480case 0x80:10481case 0x81:10482case 0x82:10483case 0x83:10484case 0x84:10485case 0x85:10486case 0x86:10487case 0x87:10488case 0x88:10489case 0x89:10490case 0x8A:10491case 0x8B:10492case 0x8C:10493case 0x8D:10494case 0x8E:10495case 0x8F:10496return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));1049710498// fixarray10499case 0x90:10500case 0x91:10501case 0x92:10502case 0x93:10503case 0x94:10504case 0x95:10505case 0x96:10506case 0x97:10507case 0x98:10508case 0x99:10509case 0x9A:10510case 0x9B:10511case 0x9C:10512case 0x9D:10513case 0x9E:10514case 0x9F:10515return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));1051610517// fixstr10518case 0xA0:10519case 0xA1:10520case 0xA2:10521case 0xA3:10522case 0xA4:10523case 0xA5:10524case 0xA6:10525case 0xA7:10526case 0xA8:10527case 0xA9:10528case 0xAA:10529case 0xAB:10530case 0xAC:10531case 0xAD:10532case 0xAE:10533case 0xAF:10534case 0xB0:10535case 0xB1:10536case 0xB2:10537case 0xB3:10538case 0xB4:10539case 0xB5:10540case 0xB6:10541case 0xB7:10542case 0xB8:10543case 0xB9:10544case 0xBA:10545case 0xBB:10546case 0xBC:10547case 0xBD:10548case 0xBE:10549case 0xBF:10550case 0xD9: // str 810551case 0xDA: // str 1610552case 0xDB: // str 3210553{10554string_t s;10555return get_msgpack_string(s) && sax->string(s);10556}1055710558case 0xC0: // nil10559return sax->null();1056010561case 0xC2: // false10562return sax->boolean(false);1056310564case 0xC3: // true10565return sax->boolean(true);1056610567case 0xC4: // bin 810568case 0xC5: // bin 1610569case 0xC6: // bin 3210570case 0xC7: // ext 810571case 0xC8: // ext 1610572case 0xC9: // ext 3210573case 0xD4: // fixext 110574case 0xD5: // fixext 210575case 0xD6: // fixext 410576case 0xD7: // fixext 810577case 0xD8: // fixext 1610578{10579binary_t b;10580return get_msgpack_binary(b) && sax->binary(b);10581}1058210583case 0xCA: // float 3210584{10585float number{};10586return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");10587}1058810589case 0xCB: // float 6410590{10591double number{};10592return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");10593}1059410595case 0xCC: // uint 810596{10597std::uint8_t number{};10598return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);10599}1060010601case 0xCD: // uint 1610602{10603std::uint16_t number{};10604return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);10605}1060610607case 0xCE: // uint 3210608{10609std::uint32_t number{};10610return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);10611}1061210613case 0xCF: // uint 6410614{10615std::uint64_t number{};10616return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);10617}1061810619case 0xD0: // int 810620{10621std::int8_t number{};10622return get_number(input_format_t::msgpack, number) && sax->number_integer(number);10623}1062410625case 0xD1: // int 1610626{10627std::int16_t number{};10628return get_number(input_format_t::msgpack, number) && sax->number_integer(number);10629}1063010631case 0xD2: // int 3210632{10633std::int32_t number{};10634return get_number(input_format_t::msgpack, number) && sax->number_integer(number);10635}1063610637case 0xD3: // int 6410638{10639std::int64_t number{};10640return get_number(input_format_t::msgpack, number) && sax->number_integer(number);10641}1064210643case 0xDC: // array 1610644{10645std::uint16_t len{};10646return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));10647}1064810649case 0xDD: // array 3210650{10651std::uint32_t len{};10652return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));10653}1065410655case 0xDE: // map 1610656{10657std::uint16_t len{};10658return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));10659}1066010661case 0xDF: // map 3210662{10663std::uint32_t len{};10664return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));10665}1066610667// negative fixint10668case 0xE0:10669case 0xE1:10670case 0xE2:10671case 0xE3:10672case 0xE4:10673case 0xE5:10674case 0xE6:10675case 0xE7:10676case 0xE8:10677case 0xE9:10678case 0xEA:10679case 0xEB:10680case 0xEC:10681case 0xED:10682case 0xEE:10683case 0xEF:10684case 0xF0:10685case 0xF1:10686case 0xF2:10687case 0xF3:10688case 0xF4:10689case 0xF5:10690case 0xF6:10691case 0xF7:10692case 0xF8:10693case 0xF9:10694case 0xFA:10695case 0xFB:10696case 0xFC:10697case 0xFD:10698case 0xFE:10699case 0xFF:10700return sax->number_integer(static_cast<std::int8_t>(current));1070110702default: // anything else10703{10704auto last_token = get_token_string();10705return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,10706exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));10707}10708}10709}1071010711/*!10712@brief reads a MessagePack string1071310714This function first reads starting bytes to determine the expected10715string length and then copies this number of bytes into a string.1071610717@param[out] result created string1071810719@return whether string creation completed10720*/10721bool get_msgpack_string(string_t& result)10722{10723if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))10724{10725return false;10726}1072710728switch (current)10729{10730// fixstr10731case 0xA0:10732case 0xA1:10733case 0xA2:10734case 0xA3:10735case 0xA4:10736case 0xA5:10737case 0xA6:10738case 0xA7:10739case 0xA8:10740case 0xA9:10741case 0xAA:10742case 0xAB:10743case 0xAC:10744case 0xAD:10745case 0xAE:10746case 0xAF:10747case 0xB0:10748case 0xB1:10749case 0xB2:10750case 0xB3:10751case 0xB4:10752case 0xB5:10753case 0xB6:10754case 0xB7:10755case 0xB8:10756case 0xB9:10757case 0xBA:10758case 0xBB:10759case 0xBC:10760case 0xBD:10761case 0xBE:10762case 0xBF:10763{10764return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);10765}1076610767case 0xD9: // str 810768{10769std::uint8_t len{};10770return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);10771}1077210773case 0xDA: // str 1610774{10775std::uint16_t len{};10776return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);10777}1077810779case 0xDB: // str 3210780{10781std::uint32_t len{};10782return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);10783}1078410785default:10786{10787auto last_token = get_token_string();10788return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,10789exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));10790}10791}10792}1079310794/*!10795@brief reads a MessagePack byte array1079610797This function first reads starting bytes to determine the expected10798byte array length and then copies this number of bytes into a byte array.1079910800@param[out] result created byte array1080110802@return whether byte array creation completed10803*/10804bool get_msgpack_binary(binary_t& result)10805{10806// helper function to set the subtype10807auto assign_and_return_true = [&result](std::int8_t subtype)10808{10809result.set_subtype(static_cast<std::uint8_t>(subtype));10810return true;10811};1081210813switch (current)10814{10815case 0xC4: // bin 810816{10817std::uint8_t len{};10818return get_number(input_format_t::msgpack, len) &&10819get_binary(input_format_t::msgpack, len, result);10820}1082110822case 0xC5: // bin 1610823{10824std::uint16_t len{};10825return get_number(input_format_t::msgpack, len) &&10826get_binary(input_format_t::msgpack, len, result);10827}1082810829case 0xC6: // bin 3210830{10831std::uint32_t len{};10832return get_number(input_format_t::msgpack, len) &&10833get_binary(input_format_t::msgpack, len, result);10834}1083510836case 0xC7: // ext 810837{10838std::uint8_t len{};10839std::int8_t subtype{};10840return get_number(input_format_t::msgpack, len) &&10841get_number(input_format_t::msgpack, subtype) &&10842get_binary(input_format_t::msgpack, len, result) &&10843assign_and_return_true(subtype);10844}1084510846case 0xC8: // ext 1610847{10848std::uint16_t len{};10849std::int8_t subtype{};10850return get_number(input_format_t::msgpack, len) &&10851get_number(input_format_t::msgpack, subtype) &&10852get_binary(input_format_t::msgpack, len, result) &&10853assign_and_return_true(subtype);10854}1085510856case 0xC9: // ext 3210857{10858std::uint32_t len{};10859std::int8_t subtype{};10860return get_number(input_format_t::msgpack, len) &&10861get_number(input_format_t::msgpack, subtype) &&10862get_binary(input_format_t::msgpack, len, result) &&10863assign_and_return_true(subtype);10864}1086510866case 0xD4: // fixext 110867{10868std::int8_t subtype{};10869return get_number(input_format_t::msgpack, subtype) &&10870get_binary(input_format_t::msgpack, 1, result) &&10871assign_and_return_true(subtype);10872}1087310874case 0xD5: // fixext 210875{10876std::int8_t subtype{};10877return get_number(input_format_t::msgpack, subtype) &&10878get_binary(input_format_t::msgpack, 2, result) &&10879assign_and_return_true(subtype);10880}1088110882case 0xD6: // fixext 410883{10884std::int8_t subtype{};10885return get_number(input_format_t::msgpack, subtype) &&10886get_binary(input_format_t::msgpack, 4, result) &&10887assign_and_return_true(subtype);10888}1088910890case 0xD7: // fixext 810891{10892std::int8_t subtype{};10893return get_number(input_format_t::msgpack, subtype) &&10894get_binary(input_format_t::msgpack, 8, result) &&10895assign_and_return_true(subtype);10896}1089710898case 0xD8: // fixext 1610899{10900std::int8_t subtype{};10901return get_number(input_format_t::msgpack, subtype) &&10902get_binary(input_format_t::msgpack, 16, result) &&10903assign_and_return_true(subtype);10904}1090510906default: // LCOV_EXCL_LINE10907return false; // LCOV_EXCL_LINE10908}10909}1091010911/*!10912@param[in] len the length of the array10913@return whether array creation completed10914*/10915bool get_msgpack_array(const std::size_t len)10916{10917if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))10918{10919return false;10920}1092110922for (std::size_t i = 0; i < len; ++i)10923{10924if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))10925{10926return false;10927}10928}1092910930return sax->end_array();10931}1093210933/*!10934@param[in] len the length of the object10935@return whether object creation completed10936*/10937bool get_msgpack_object(const std::size_t len)10938{10939if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))10940{10941return false;10942}1094310944string_t key;10945for (std::size_t i = 0; i < len; ++i)10946{10947get();10948if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))10949{10950return false;10951}1095210953if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))10954{10955return false;10956}10957key.clear();10958}1095910960return sax->end_object();10961}1096210963////////////10964// UBJSON //10965////////////1096610967/*!10968@param[in] get_char whether a new character should be retrieved from the10969input (true, default) or whether the last read10970character should be considered instead1097110972@return whether a valid UBJSON value was passed to the SAX parser10973*/10974bool parse_ubjson_internal(const bool get_char = true)10975{10976return get_ubjson_value(get_char ? get_ignore_noop() : current);10977}1097810979/*!10980@brief reads a UBJSON string1098110982This function is either called after reading the 'S' byte explicitly10983indicating a string, or in case of an object key where the 'S' byte can be10984left out.1098510986@param[out] result created string10987@param[in] get_char whether a new character should be retrieved from the10988input (true, default) or whether the last read10989character should be considered instead1099010991@return whether string creation completed10992*/10993bool get_ubjson_string(string_t& result, const bool get_char = true)10994{10995if (get_char)10996{10997get(); // TODO(niels): may we ignore N here?10998}1099911000if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))11001{11002return false;11003}1100411005switch (current)11006{11007case 'U':11008{11009std::uint8_t len{};11010return get_number(input_format, len) && get_string(input_format, len, result);11011}1101211013case 'i':11014{11015std::int8_t len{};11016return get_number(input_format, len) && get_string(input_format, len, result);11017}1101811019case 'I':11020{11021std::int16_t len{};11022return get_number(input_format, len) && get_string(input_format, len, result);11023}1102411025case 'l':11026{11027std::int32_t len{};11028return get_number(input_format, len) && get_string(input_format, len, result);11029}1103011031case 'L':11032{11033std::int64_t len{};11034return get_number(input_format, len) && get_string(input_format, len, result);11035}1103611037case 'u':11038{11039if (input_format != input_format_t::bjdata)11040{11041break;11042}11043std::uint16_t len{};11044return get_number(input_format, len) && get_string(input_format, len, result);11045}1104611047case 'm':11048{11049if (input_format != input_format_t::bjdata)11050{11051break;11052}11053std::uint32_t len{};11054return get_number(input_format, len) && get_string(input_format, len, result);11055}1105611057case 'M':11058{11059if (input_format != input_format_t::bjdata)11060{11061break;11062}11063std::uint64_t len{};11064return get_number(input_format, len) && get_string(input_format, len, result);11065}1106611067default:11068break;11069}11070auto last_token = get_token_string();11071std::string message;1107211073if (input_format != input_format_t::bjdata)11074{11075message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;11076}11077else11078{11079message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;11080}11081return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));11082}1108311084/*!11085@param[out] dim an integer vector storing the ND array dimensions11086@return whether reading ND array size vector is successful11087*/11088bool get_ubjson_ndarray_size(std::vector<size_t>& dim)11089{11090std::pair<std::size_t, char_int_type> size_and_type;11091size_t dimlen = 0;11092bool no_ndarray = true;1109311094if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))11095{11096return false;11097}1109811099if (size_and_type.first != npos)11100{11101if (size_and_type.second != 0)11102{11103if (size_and_type.second != 'N')11104{11105for (std::size_t i = 0; i < size_and_type.first; ++i)11106{11107if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))11108{11109return false;11110}11111dim.push_back(dimlen);11112}11113}11114}11115else11116{11117for (std::size_t i = 0; i < size_and_type.first; ++i)11118{11119if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))11120{11121return false;11122}11123dim.push_back(dimlen);11124}11125}11126}11127else11128{11129while (current != ']')11130{11131if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))11132{11133return false;11134}11135dim.push_back(dimlen);11136get_ignore_noop();11137}11138}11139return true;11140}1114111142/*!11143@param[out] result determined size11144@param[in,out] is_ndarray for input, `true` means already inside an ndarray vector11145or ndarray dimension is not allowed; `false` means ndarray11146is allowed; for output, `true` means an ndarray is found;11147is_ndarray can only return `true` when its initial value11148is `false`11149@param[in] prefix type marker if already read, otherwise set to 01115011151@return whether size determination completed11152*/11153bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)11154{11155if (prefix == 0)11156{11157prefix = get_ignore_noop();11158}1115911160switch (prefix)11161{11162case 'U':11163{11164std::uint8_t number{};11165if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))11166{11167return false;11168}11169result = static_cast<std::size_t>(number);11170return true;11171}1117211173case 'i':11174{11175std::int8_t number{};11176if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))11177{11178return false;11179}11180if (number < 0)11181{11182return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,11183exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));11184}11185result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char11186return true;11187}1118811189case 'I':11190{11191std::int16_t number{};11192if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))11193{11194return false;11195}11196if (number < 0)11197{11198return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,11199exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));11200}11201result = static_cast<std::size_t>(number);11202return true;11203}1120411205case 'l':11206{11207std::int32_t number{};11208if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))11209{11210return false;11211}11212if (number < 0)11213{11214return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,11215exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));11216}11217result = static_cast<std::size_t>(number);11218return true;11219}1122011221case 'L':11222{11223std::int64_t number{};11224if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))11225{11226return false;11227}11228if (number < 0)11229{11230return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,11231exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));11232}11233if (!value_in_range_of<std::size_t>(number))11234{11235return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,11236exception_message(input_format, "integer value overflow", "size"), nullptr));11237}11238result = static_cast<std::size_t>(number);11239return true;11240}1124111242case 'u':11243{11244if (input_format != input_format_t::bjdata)11245{11246break;11247}11248std::uint16_t number{};11249if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))11250{11251return false;11252}11253result = static_cast<std::size_t>(number);11254return true;11255}1125611257case 'm':11258{11259if (input_format != input_format_t::bjdata)11260{11261break;11262}11263std::uint32_t number{};11264if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))11265{11266return false;11267}11268result = conditional_static_cast<std::size_t>(number);11269return true;11270}1127111272case 'M':11273{11274if (input_format != input_format_t::bjdata)11275{11276break;11277}11278std::uint64_t number{};11279if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))11280{11281return false;11282}11283if (!value_in_range_of<std::size_t>(number))11284{11285return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,11286exception_message(input_format, "integer value overflow", "size"), nullptr));11287}11288result = detail::conditional_static_cast<std::size_t>(number);11289return true;11290}1129111292case '[':11293{11294if (input_format != input_format_t::bjdata)11295{11296break;11297}11298if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array11299{11300return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimensional vector is not allowed", "size"), nullptr));11301}11302std::vector<size_t> dim;11303if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))11304{11305return false;11306}11307if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector11308{11309result = dim.at(dim.size() - 1);11310return true;11311}11312if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format11313{11314for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container11315{11316if ( i == 0 )11317{11318result = 0;11319return true;11320}11321}1132211323string_t key = "_ArraySize_";11324if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))11325{11326return false;11327}11328result = 1;11329for (auto i : dim)11330{11331result *= i;11332if (result == 0 || result == npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be npos as it is used to initialize size in get_ubjson_size_type()11333{11334return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr));11335}11336if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))11337{11338return false;11339}11340}11341is_ndarray = true;11342return sax->end_array();11343}11344result = 0;11345return true;11346}1134711348default:11349break;11350}11351auto last_token = get_token_string();11352std::string message;1135311354if (input_format != input_format_t::bjdata)11355{11356message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;11357}11358else11359{11360message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;11361}11362return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));11363}1136411365/*!11366@brief determine the type and size for a container1136711368In the optimized UBJSON format, a type and a size can be provided to allow11369for a more compact representation.1137011371@param[out] result pair of the size and the type11372@param[in] inside_ndarray whether the parser is parsing an ND array dimensional vector1137311374@return whether pair creation completed11375*/11376bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)11377{11378result.first = npos; // size11379result.second = 0; // type11380bool is_ndarray = false;1138111382get_ignore_noop();1138311384if (current == '$')11385{11386result.second = get(); // must not ignore 'N', because 'N' maybe the type11387if (input_format == input_format_t::bjdata11388&& JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))11389{11390auto last_token = get_token_string();11391return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,11392exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));11393}1139411395if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))11396{11397return false;11398}1139911400get_ignore_noop();11401if (JSON_HEDLEY_UNLIKELY(current != '#'))11402{11403if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))11404{11405return false;11406}11407auto last_token = get_token_string();11408return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,11409exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));11410}1141111412const bool is_error = get_ubjson_size_value(result.first, is_ndarray);11413if (input_format == input_format_t::bjdata && is_ndarray)11414{11415if (inside_ndarray)11416{11417return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,11418exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));11419}11420result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters11421}11422return is_error;11423}1142411425if (current == '#')11426{11427const bool is_error = get_ubjson_size_value(result.first, is_ndarray);11428if (input_format == input_format_t::bjdata && is_ndarray)11429{11430return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,11431exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));11432}11433return is_error;11434}1143511436return true;11437}1143811439/*!11440@param prefix the previously read or set type prefix11441@return whether value creation completed11442*/11443bool get_ubjson_value(const char_int_type prefix)11444{11445switch (prefix)11446{11447case char_traits<char_type>::eof(): // EOF11448return unexpect_eof(input_format, "value");1144911450case 'T': // true11451return sax->boolean(true);11452case 'F': // false11453return sax->boolean(false);1145411455case 'Z': // null11456return sax->null();1145711458case 'U':11459{11460std::uint8_t number{};11461return get_number(input_format, number) && sax->number_unsigned(number);11462}1146311464case 'i':11465{11466std::int8_t number{};11467return get_number(input_format, number) && sax->number_integer(number);11468}1146911470case 'I':11471{11472std::int16_t number{};11473return get_number(input_format, number) && sax->number_integer(number);11474}1147511476case 'l':11477{11478std::int32_t number{};11479return get_number(input_format, number) && sax->number_integer(number);11480}1148111482case 'L':11483{11484std::int64_t number{};11485return get_number(input_format, number) && sax->number_integer(number);11486}1148711488case 'u':11489{11490if (input_format != input_format_t::bjdata)11491{11492break;11493}11494std::uint16_t number{};11495return get_number(input_format, number) && sax->number_unsigned(number);11496}1149711498case 'm':11499{11500if (input_format != input_format_t::bjdata)11501{11502break;11503}11504std::uint32_t number{};11505return get_number(input_format, number) && sax->number_unsigned(number);11506}1150711508case 'M':11509{11510if (input_format != input_format_t::bjdata)11511{11512break;11513}11514std::uint64_t number{};11515return get_number(input_format, number) && sax->number_unsigned(number);11516}1151711518case 'h':11519{11520if (input_format != input_format_t::bjdata)11521{11522break;11523}11524const auto byte1_raw = get();11525if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))11526{11527return false;11528}11529const auto byte2_raw = get();11530if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))11531{11532return false;11533}1153411535const auto byte1 = static_cast<unsigned char>(byte1_raw);11536const auto byte2 = static_cast<unsigned char>(byte2_raw);1153711538// code from RFC 7049, Appendix D, Figure 3:11539// As half-precision floating-point numbers were only added11540// to IEEE 754 in 2008, today's programming platforms often11541// still only have limited support for them. It is very11542// easy to include at least decoding support for them even11543// without such support. An example of a small decoder for11544// half-precision floating-point numbers in the C language11545// is shown in Fig. 3.11546const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);11547const double val = [&half]11548{11549const int exp = (half >> 10u) & 0x1Fu;11550const unsigned int mant = half & 0x3FFu;11551JSON_ASSERT(0 <= exp&& exp <= 32);11552JSON_ASSERT(mant <= 1024);11553switch (exp)11554{11555case 0:11556return std::ldexp(mant, -24);11557case 31:11558return (mant == 0)11559? std::numeric_limits<double>::infinity()11560: std::numeric_limits<double>::quiet_NaN();11561default:11562return std::ldexp(mant + 1024, exp - 25);11563}11564}();11565return sax->number_float((half & 0x8000u) != 011566? static_cast<number_float_t>(-val)11567: static_cast<number_float_t>(val), "");11568}1156911570case 'd':11571{11572float number{};11573return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");11574}1157511576case 'D':11577{11578double number{};11579return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");11580}1158111582case 'H':11583{11584return get_ubjson_high_precision_number();11585}1158611587case 'C': // char11588{11589get();11590if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))11591{11592return false;11593}11594if (JSON_HEDLEY_UNLIKELY(current > 127))11595{11596auto last_token = get_token_string();11597return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,11598exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));11599}11600string_t s(1, static_cast<typename string_t::value_type>(current));11601return sax->string(s);11602}1160311604case 'S': // string11605{11606string_t s;11607return get_ubjson_string(s) && sax->string(s);11608}1160911610case '[': // array11611return get_ubjson_array();1161211613case '{': // object11614return get_ubjson_object();1161511616default: // anything else11617break;11618}11619auto last_token = get_token_string();11620return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));11621}1162211623/*!11624@return whether array creation completed11625*/11626bool get_ubjson_array()11627{11628std::pair<std::size_t, char_int_type> size_and_type;11629if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))11630{11631return false;11632}1163311634// if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata):11635// {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}1163611637if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)11638{11639size_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 marker11640auto it = std::lower_bound(bjd_types_map.begin(), bjd_types_map.end(), size_and_type.second, [](const bjd_type & p, char_int_type t)11641{11642return p.first < t;11643});11644string_t key = "_ArrayType_";11645if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))11646{11647auto last_token = get_token_string();11648return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,11649exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));11650}1165111652string_t type = it->second; // sax->string() takes a reference11653if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type)))11654{11655return false;11656}1165711658if (size_and_type.second == 'C')11659{11660size_and_type.second = 'U';11661}1166211663key = "_ArrayData_";11664if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) ))11665{11666return false;11667}1166811669for (std::size_t i = 0; i < size_and_type.first; ++i)11670{11671if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))11672{11673return false;11674}11675}1167611677return (sax->end_array() && sax->end_object());11678}1167911680if (size_and_type.first != npos)11681{11682if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))11683{11684return false;11685}1168611687if (size_and_type.second != 0)11688{11689if (size_and_type.second != 'N')11690{11691for (std::size_t i = 0; i < size_and_type.first; ++i)11692{11693if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))11694{11695return false;11696}11697}11698}11699}11700else11701{11702for (std::size_t i = 0; i < size_and_type.first; ++i)11703{11704if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))11705{11706return false;11707}11708}11709}11710}11711else11712{11713if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))11714{11715return false;11716}1171711718while (current != ']')11719{11720if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))11721{11722return false;11723}11724get_ignore_noop();11725}11726}1172711728return sax->end_array();11729}1173011731/*!11732@return whether object creation completed11733*/11734bool get_ubjson_object()11735{11736std::pair<std::size_t, char_int_type> size_and_type;11737if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))11738{11739return false;11740}1174111742// do not accept ND-array size in objects in BJData11743if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)11744{11745auto last_token = get_token_string();11746return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,11747exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));11748}1174911750string_t key;11751if (size_and_type.first != npos)11752{11753if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))11754{11755return false;11756}1175711758if (size_and_type.second != 0)11759{11760for (std::size_t i = 0; i < size_and_type.first; ++i)11761{11762if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))11763{11764return false;11765}11766if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))11767{11768return false;11769}11770key.clear();11771}11772}11773else11774{11775for (std::size_t i = 0; i < size_and_type.first; ++i)11776{11777if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))11778{11779return false;11780}11781if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))11782{11783return false;11784}11785key.clear();11786}11787}11788}11789else11790{11791if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))11792{11793return false;11794}1179511796while (current != '}')11797{11798if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))11799{11800return false;11801}11802if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))11803{11804return false;11805}11806get_ignore_noop();11807key.clear();11808}11809}1181011811return sax->end_object();11812}1181311814// Note, no reader for UBJSON binary types is implemented because they do11815// not exist1181611817bool get_ubjson_high_precision_number()11818{11819// get size of following number string11820std::size_t size{};11821bool no_ndarray = true;11822auto res = get_ubjson_size_value(size, no_ndarray);11823if (JSON_HEDLEY_UNLIKELY(!res))11824{11825return res;11826}1182711828// get number string11829std::vector<char> number_vector;11830for (std::size_t i = 0; i < size; ++i)11831{11832get();11833if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))11834{11835return false;11836}11837number_vector.push_back(static_cast<char>(current));11838}1183911840// parse number string11841using ia_type = decltype(detail::input_adapter(number_vector));11842auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);11843const auto result_number = number_lexer.scan();11844const auto number_string = number_lexer.get_token_string();11845const auto result_remainder = number_lexer.scan();1184611847using token_type = typename detail::lexer_base<BasicJsonType>::token_type;1184811849if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))11850{11851return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,11852exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));11853}1185411855switch (result_number)11856{11857case token_type::value_integer:11858return sax->number_integer(number_lexer.get_number_integer());11859case token_type::value_unsigned:11860return sax->number_unsigned(number_lexer.get_number_unsigned());11861case token_type::value_float:11862return sax->number_float(number_lexer.get_number_float(), std::move(number_string));11863case token_type::uninitialized:11864case token_type::literal_true:11865case token_type::literal_false:11866case token_type::literal_null:11867case token_type::value_string:11868case token_type::begin_array:11869case token_type::begin_object:11870case token_type::end_array:11871case token_type::end_object:11872case token_type::name_separator:11873case token_type::value_separator:11874case token_type::parse_error:11875case token_type::end_of_input:11876case token_type::literal_or_value:11877default:11878return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,11879exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));11880}11881}1188211883///////////////////////11884// Utility functions //11885///////////////////////1188611887/*!11888@brief get next character from the input1188911890This function provides the interface to the used input adapter. It does11891not throw in case the input reached EOF, but returns a -'ve valued11892`char_traits<char_type>::eof()` in that case.1189311894@return character read from the input11895*/11896char_int_type get()11897{11898++chars_read;11899return current = ia.get_character();11900}1190111902/*!11903@return character read from the input after ignoring all 'N' entries11904*/11905char_int_type get_ignore_noop()11906{11907do11908{11909get();11910}11911while (current == 'N');1191211913return current;11914}1191511916/*11917@brief read a number from the input1191811919@tparam NumberType the type of the number11920@param[in] format the current format (for diagnostics)11921@param[out] result number of type @a NumberType1192211923@return whether conversion completed1192411925@note This function needs to respect the system's endianness, because11926bytes in CBOR, MessagePack, and UBJSON are stored in network order11927(big endian) and therefore need reordering on little endian systems.11928On the other hand, BSON and BJData use little endian and should reorder11929on big endian systems.11930*/11931template<typename NumberType, bool InputIsLittleEndian = false>11932bool get_number(const input_format_t format, NumberType& result)11933{11934// step 1: read input into array with system's byte order11935std::array<std::uint8_t, sizeof(NumberType)> vec{};11936for (std::size_t i = 0; i < sizeof(NumberType); ++i)11937{11938get();11939if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))11940{11941return false;11942}1194311944// reverse byte order prior to conversion if necessary11945if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))11946{11947vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);11948}11949else11950{11951vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE11952}11953}1195411955// step 2: convert array into number of type T and return11956std::memcpy(&result, vec.data(), sizeof(NumberType));11957return true;11958}1195911960/*!11961@brief create a string by reading characters from the input1196211963@tparam NumberType the type of the number11964@param[in] format the current format (for diagnostics)11965@param[in] len number of characters to read11966@param[out] result string created by reading @a len bytes1196711968@return whether string creation completed1196911970@note We can not reserve @a len bytes for the result, because @a len11971may be too large. Usually, @ref unexpect_eof() detects the end of11972the input before we run out of string memory.11973*/11974template<typename NumberType>11975bool get_string(const input_format_t format,11976const NumberType len,11977string_t& result)11978{11979bool success = true;11980for (NumberType i = 0; i < len; i++)11981{11982get();11983if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))11984{11985success = false;11986break;11987}11988result.push_back(static_cast<typename string_t::value_type>(current));11989}11990return success;11991}1199211993/*!11994@brief create a byte array by reading bytes from the input1199511996@tparam NumberType the type of the number11997@param[in] format the current format (for diagnostics)11998@param[in] len number of bytes to read11999@param[out] result byte array created by reading @a len bytes1200012001@return whether byte array creation completed1200212003@note We can not reserve @a len bytes for the result, because @a len12004may be too large. Usually, @ref unexpect_eof() detects the end of12005the input before we run out of memory.12006*/12007template<typename NumberType>12008bool get_binary(const input_format_t format,12009const NumberType len,12010binary_t& result)12011{12012bool success = true;12013for (NumberType i = 0; i < len; i++)12014{12015get();12016if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))12017{12018success = false;12019break;12020}12021result.push_back(static_cast<std::uint8_t>(current));12022}12023return success;12024}1202512026/*!12027@param[in] format the current format (for diagnostics)12028@param[in] context further context information (for diagnostics)12029@return whether the last read character is not EOF12030*/12031JSON_HEDLEY_NON_NULL(3)12032bool unexpect_eof(const input_format_t format, const char* context) const12033{12034if (JSON_HEDLEY_UNLIKELY(current == char_traits<char_type>::eof()))12035{12036return sax->parse_error(chars_read, "<end of file>",12037parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));12038}12039return true;12040}1204112042/*!12043@return a string representation of the last read byte12044*/12045std::string get_token_string() const12046{12047std::array<char, 3> cr{{}};12048static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)12049return std::string{cr.data()};12050}1205112052/*!12053@param[in] format the current format12054@param[in] detail a detailed error message12055@param[in] context further context information12056@return a message string to use in the parse_error exceptions12057*/12058std::string exception_message(const input_format_t format,12059const std::string& detail,12060const std::string& context) const12061{12062std::string error_msg = "syntax error while parsing ";1206312064switch (format)12065{12066case input_format_t::cbor:12067error_msg += "CBOR";12068break;1206912070case input_format_t::msgpack:12071error_msg += "MessagePack";12072break;1207312074case input_format_t::ubjson:12075error_msg += "UBJSON";12076break;1207712078case input_format_t::bson:12079error_msg += "BSON";12080break;1208112082case input_format_t::bjdata:12083error_msg += "BJData";12084break;1208512086case input_format_t::json: // LCOV_EXCL_LINE12087default: // LCOV_EXCL_LINE12088JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE12089}1209012091return concat(error_msg, ' ', context, ": ", detail);12092}1209312094private:12095static JSON_INLINE_VARIABLE constexpr std::size_t npos = static_cast<std::size_t>(-1);1209612097/// input adapter12098InputAdapterType ia;1209912100/// the current character12101char_int_type current = char_traits<char_type>::eof();1210212103/// the number of characters read12104std::size_t chars_read = 0;1210512106/// whether we can assume little endianness12107const bool is_little_endian = little_endianness();1210812109/// input format12110const input_format_t input_format = input_format_t::json;1211112112/// the SAX parser12113json_sax_t* sax = nullptr;1211412115// excluded markers in bjdata optimized type12116#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \12117make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')1211812119#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \12120make_array<bjd_type>( \12121bjd_type{'C', "char"}, \12122bjd_type{'D', "double"}, \12123bjd_type{'I', "int16"}, \12124bjd_type{'L', "int64"}, \12125bjd_type{'M', "uint64"}, \12126bjd_type{'U', "uint8"}, \12127bjd_type{'d', "single"}, \12128bjd_type{'i', "int8"}, \12129bjd_type{'l', "int32"}, \12130bjd_type{'m', "uint32"}, \12131bjd_type{'u', "uint16"})1213212133JSON_PRIVATE_UNLESS_TESTED:12134// lookup tables12135// NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)12136const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =12137JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_;1213812139using bjd_type = std::pair<char_int_type, string_t>;12140// NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)12141const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map =12142JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_;1214312144#undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_12145#undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_12146};1214712148#ifndef JSON_HAS_CPP_1712149template<typename BasicJsonType, typename InputAdapterType, typename SAX>12150constexpr std::size_t binary_reader<BasicJsonType, InputAdapterType, SAX>::npos;12151#endif1215212153} // namespace detail12154NLOHMANN_JSON_NAMESPACE_END1215512156// #include <nlohmann/detail/input/input_adapters.hpp>1215712158// #include <nlohmann/detail/input/lexer.hpp>1215912160// #include <nlohmann/detail/input/parser.hpp>12161// __ _____ _____ _____12162// __| | __| | | | JSON for Modern C++12163// | | |__ | | | | | | version 3.11.312164// |_____|_____|_____|_|___| https://github.com/nlohmann/json12165//12166// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>12167// SPDX-License-Identifier: MIT12168121691217012171#include <cmath> // isfinite12172#include <cstdint> // uint8_t12173#include <functional> // function12174#include <string> // string12175#include <utility> // move12176#include <vector> // vector1217712178// #include <nlohmann/detail/exceptions.hpp>1217912180// #include <nlohmann/detail/input/input_adapters.hpp>1218112182// #include <nlohmann/detail/input/json_sax.hpp>1218312184// #include <nlohmann/detail/input/lexer.hpp>1218512186// #include <nlohmann/detail/macro_scope.hpp>1218712188// #include <nlohmann/detail/meta/is_sax.hpp>1218912190// #include <nlohmann/detail/string_concat.hpp>1219112192// #include <nlohmann/detail/value_t.hpp>121931219412195NLOHMANN_JSON_NAMESPACE_BEGIN12196namespace detail12197{12198////////////12199// parser //12200////////////1220112202enum class parse_event_t : std::uint8_t12203{12204/// the parser read `{` and started to process a JSON object12205object_start,12206/// the parser read `}` and finished processing a JSON object12207object_end,12208/// the parser read `[` and started to process a JSON array12209array_start,12210/// the parser read `]` and finished processing a JSON array12211array_end,12212/// the parser read a key of a value in an object12213key,12214/// the parser finished reading a JSON value12215value12216};1221712218template<typename BasicJsonType>12219using parser_callback_t =12220std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;1222112222/*!12223@brief syntax analysis1222412225This class implements a recursive descent parser.12226*/12227template<typename BasicJsonType, typename InputAdapterType>12228class parser12229{12230using number_integer_t = typename BasicJsonType::number_integer_t;12231using number_unsigned_t = typename BasicJsonType::number_unsigned_t;12232using number_float_t = typename BasicJsonType::number_float_t;12233using string_t = typename BasicJsonType::string_t;12234using lexer_t = lexer<BasicJsonType, InputAdapterType>;12235using token_type = typename lexer_t::token_type;1223612237public:12238/// a parser reading from an input adapter12239explicit parser(InputAdapterType&& adapter,12240const parser_callback_t<BasicJsonType> cb = nullptr,12241const bool allow_exceptions_ = true,12242const bool skip_comments = false)12243: callback(cb)12244, m_lexer(std::move(adapter), skip_comments)12245, allow_exceptions(allow_exceptions_)12246{12247// read first token12248get_token();12249}1225012251/*!12252@brief public parser interface1225312254@param[in] strict whether to expect the last token to be EOF12255@param[in,out] result parsed JSON value1225612257@throw parse_error.101 in case of an unexpected token12258@throw parse_error.102 if to_unicode fails or surrogate error12259@throw parse_error.103 if to_unicode fails12260*/12261void parse(const bool strict, BasicJsonType& result)12262{12263if (callback)12264{12265json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);12266sax_parse_internal(&sdp);1226712268// in strict mode, input must be completely read12269if (strict && (get_token() != token_type::end_of_input))12270{12271sdp.parse_error(m_lexer.get_position(),12272m_lexer.get_token_string(),12273parse_error::create(101, m_lexer.get_position(),12274exception_message(token_type::end_of_input, "value"), nullptr));12275}1227612277// in case of an error, return discarded value12278if (sdp.is_errored())12279{12280result = value_t::discarded;12281return;12282}1228312284// set top-level value to null if it was discarded by the callback12285// function12286if (result.is_discarded())12287{12288result = nullptr;12289}12290}12291else12292{12293json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);12294sax_parse_internal(&sdp);1229512296// in strict mode, input must be completely read12297if (strict && (get_token() != token_type::end_of_input))12298{12299sdp.parse_error(m_lexer.get_position(),12300m_lexer.get_token_string(),12301parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));12302}1230312304// in case of an error, return discarded value12305if (sdp.is_errored())12306{12307result = value_t::discarded;12308return;12309}12310}1231112312result.assert_invariant();12313}1231412315/*!12316@brief public accept interface1231712318@param[in] strict whether to expect the last token to be EOF12319@return whether the input is a proper JSON text12320*/12321bool accept(const bool strict = true)12322{12323json_sax_acceptor<BasicJsonType> sax_acceptor;12324return sax_parse(&sax_acceptor, strict);12325}1232612327template<typename SAX>12328JSON_HEDLEY_NON_NULL(2)12329bool sax_parse(SAX* sax, const bool strict = true)12330{12331(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};12332const bool result = sax_parse_internal(sax);1233312334// strict mode: next byte must be EOF12335if (result && strict && (get_token() != token_type::end_of_input))12336{12337return sax->parse_error(m_lexer.get_position(),12338m_lexer.get_token_string(),12339parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));12340}1234112342return result;12343}1234412345private:12346template<typename SAX>12347JSON_HEDLEY_NON_NULL(2)12348bool sax_parse_internal(SAX* sax)12349{12350// stack to remember the hierarchy of structured values we are parsing12351// true = array; false = object12352std::vector<bool> states;12353// value to avoid a goto (see comment where set to true)12354bool skip_to_state_evaluation = false;1235512356while (true)12357{12358if (!skip_to_state_evaluation)12359{12360// invariant: get_token() was called before each iteration12361switch (last_token)12362{12363case token_type::begin_object:12364{12365if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))12366{12367return false;12368}1236912370// closing } -> we are done12371if (get_token() == token_type::end_object)12372{12373if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))12374{12375return false;12376}12377break;12378}1237912380// parse key12381if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))12382{12383return sax->parse_error(m_lexer.get_position(),12384m_lexer.get_token_string(),12385parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));12386}12387if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))12388{12389return false;12390}1239112392// parse separator (:)12393if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))12394{12395return sax->parse_error(m_lexer.get_position(),12396m_lexer.get_token_string(),12397parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));12398}1239912400// remember we are now inside an object12401states.push_back(false);1240212403// parse values12404get_token();12405continue;12406}1240712408case token_type::begin_array:12409{12410if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))12411{12412return false;12413}1241412415// closing ] -> we are done12416if (get_token() == token_type::end_array)12417{12418if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))12419{12420return false;12421}12422break;12423}1242412425// remember we are now inside an array12426states.push_back(true);1242712428// parse values (no need to call get_token)12429continue;12430}1243112432case token_type::value_float:12433{12434const auto res = m_lexer.get_number_float();1243512436if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))12437{12438return sax->parse_error(m_lexer.get_position(),12439m_lexer.get_token_string(),12440out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));12441}1244212443if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))12444{12445return false;12446}1244712448break;12449}1245012451case token_type::literal_false:12452{12453if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))12454{12455return false;12456}12457break;12458}1245912460case token_type::literal_null:12461{12462if (JSON_HEDLEY_UNLIKELY(!sax->null()))12463{12464return false;12465}12466break;12467}1246812469case token_type::literal_true:12470{12471if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))12472{12473return false;12474}12475break;12476}1247712478case token_type::value_integer:12479{12480if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))12481{12482return false;12483}12484break;12485}1248612487case token_type::value_string:12488{12489if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))12490{12491return false;12492}12493break;12494}1249512496case token_type::value_unsigned:12497{12498if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))12499{12500return false;12501}12502break;12503}1250412505case token_type::parse_error:12506{12507// using "uninitialized" to avoid "expected" message12508return sax->parse_error(m_lexer.get_position(),12509m_lexer.get_token_string(),12510parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));12511}12512case token_type::end_of_input:12513{12514if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1))12515{12516return sax->parse_error(m_lexer.get_position(),12517m_lexer.get_token_string(),12518parse_error::create(101, m_lexer.get_position(),12519"attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));12520}1252112522return sax->parse_error(m_lexer.get_position(),12523m_lexer.get_token_string(),12524parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));12525}12526case token_type::uninitialized:12527case token_type::end_array:12528case token_type::end_object:12529case token_type::name_separator:12530case token_type::value_separator:12531case token_type::literal_or_value:12532default: // the last token was unexpected12533{12534return sax->parse_error(m_lexer.get_position(),12535m_lexer.get_token_string(),12536parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));12537}12538}12539}12540else12541{12542skip_to_state_evaluation = false;12543}1254412545// we reached this line after we successfully parsed a value12546if (states.empty())12547{12548// empty stack: we reached the end of the hierarchy: done12549return true;12550}1255112552if (states.back()) // array12553{12554// comma -> next value12555if (get_token() == token_type::value_separator)12556{12557// parse a new value12558get_token();12559continue;12560}1256112562// closing ]12563if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))12564{12565if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))12566{12567return false;12568}1256912570// We are done with this array. Before we can parse a12571// new value, we need to evaluate the new state first.12572// By setting skip_to_state_evaluation to false, we12573// are effectively jumping to the beginning of this if.12574JSON_ASSERT(!states.empty());12575states.pop_back();12576skip_to_state_evaluation = true;12577continue;12578}1257912580return sax->parse_error(m_lexer.get_position(),12581m_lexer.get_token_string(),12582parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));12583}1258412585// states.back() is false -> object1258612587// comma -> next value12588if (get_token() == token_type::value_separator)12589{12590// parse key12591if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))12592{12593return sax->parse_error(m_lexer.get_position(),12594m_lexer.get_token_string(),12595parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));12596}1259712598if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))12599{12600return false;12601}1260212603// parse separator (:)12604if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))12605{12606return sax->parse_error(m_lexer.get_position(),12607m_lexer.get_token_string(),12608parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));12609}1261012611// parse values12612get_token();12613continue;12614}1261512616// closing }12617if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))12618{12619if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))12620{12621return false;12622}1262312624// We are done with this object. Before we can parse a12625// new value, we need to evaluate the new state first.12626// By setting skip_to_state_evaluation to false, we12627// are effectively jumping to the beginning of this if.12628JSON_ASSERT(!states.empty());12629states.pop_back();12630skip_to_state_evaluation = true;12631continue;12632}1263312634return sax->parse_error(m_lexer.get_position(),12635m_lexer.get_token_string(),12636parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));12637}12638}1263912640/// get next token from lexer12641token_type get_token()12642{12643return last_token = m_lexer.scan();12644}1264512646std::string exception_message(const token_type expected, const std::string& context)12647{12648std::string error_msg = "syntax error ";1264912650if (!context.empty())12651{12652error_msg += concat("while parsing ", context, ' ');12653}1265412655error_msg += "- ";1265612657if (last_token == token_type::parse_error)12658{12659error_msg += concat(m_lexer.get_error_message(), "; last read: '",12660m_lexer.get_token_string(), '\'');12661}12662else12663{12664error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));12665}1266612667if (expected != token_type::uninitialized)12668{12669error_msg += concat("; expected ", lexer_t::token_type_name(expected));12670}1267112672return error_msg;12673}1267412675private:12676/// callback function12677const parser_callback_t<BasicJsonType> callback = nullptr;12678/// the type of the last read token12679token_type last_token = token_type::uninitialized;12680/// the lexer12681lexer_t m_lexer;12682/// whether to throw exceptions in case of errors12683const bool allow_exceptions = true;12684};1268512686} // namespace detail12687NLOHMANN_JSON_NAMESPACE_END1268812689// #include <nlohmann/detail/iterators/internal_iterator.hpp>12690// __ _____ _____ _____12691// __| | __| | | | JSON for Modern C++12692// | | |__ | | | | | | version 3.11.312693// |_____|_____|_____|_|___| https://github.com/nlohmann/json12694//12695// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>12696// SPDX-License-Identifier: MIT12697126981269912700// #include <nlohmann/detail/abi_macros.hpp>1270112702// #include <nlohmann/detail/iterators/primitive_iterator.hpp>12703// __ _____ _____ _____12704// __| | __| | | | JSON for Modern C++12705// | | |__ | | | | | | version 3.11.312706// |_____|_____|_____|_|___| https://github.com/nlohmann/json12707//12708// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>12709// SPDX-License-Identifier: MIT12710127111271212713#include <cstddef> // ptrdiff_t12714#include <limits> // numeric_limits1271512716// #include <nlohmann/detail/macro_scope.hpp>127171271812719NLOHMANN_JSON_NAMESPACE_BEGIN12720namespace detail12721{1272212723/*12724@brief an iterator for primitive JSON types1272512726This class models an iterator for primitive JSON types (boolean, number,12727string). It's only purpose is to allow the iterator/const_iterator classes12728to "iterate" over primitive values. Internally, the iterator is modeled by12729a `difference_type` variable. Value begin_value (`0`) models the begin,12730end_value (`1`) models past the end.12731*/12732class primitive_iterator_t12733{12734private:12735using difference_type = std::ptrdiff_t;12736static constexpr difference_type begin_value = 0;12737static constexpr difference_type end_value = begin_value + 1;1273812739JSON_PRIVATE_UNLESS_TESTED:12740/// iterator as signed integer type12741difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();1274212743public:12744constexpr difference_type get_value() const noexcept12745{12746return m_it;12747}1274812749/// set iterator to a defined beginning12750void set_begin() noexcept12751{12752m_it = begin_value;12753}1275412755/// set iterator to a defined past the end12756void set_end() noexcept12757{12758m_it = end_value;12759}1276012761/// return whether the iterator can be dereferenced12762constexpr bool is_begin() const noexcept12763{12764return m_it == begin_value;12765}1276612767/// return whether the iterator is at end12768constexpr bool is_end() const noexcept12769{12770return m_it == end_value;12771}1277212773friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept12774{12775return lhs.m_it == rhs.m_it;12776}1277712778friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept12779{12780return lhs.m_it < rhs.m_it;12781}1278212783primitive_iterator_t operator+(difference_type n) noexcept12784{12785auto result = *this;12786result += n;12787return result;12788}1278912790friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept12791{12792return lhs.m_it - rhs.m_it;12793}1279412795primitive_iterator_t& operator++() noexcept12796{12797++m_it;12798return *this;12799}1280012801primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)12802{12803auto result = *this;12804++m_it;12805return result;12806}1280712808primitive_iterator_t& operator--() noexcept12809{12810--m_it;12811return *this;12812}1281312814primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)12815{12816auto result = *this;12817--m_it;12818return result;12819}1282012821primitive_iterator_t& operator+=(difference_type n) noexcept12822{12823m_it += n;12824return *this;12825}1282612827primitive_iterator_t& operator-=(difference_type n) noexcept12828{12829m_it -= n;12830return *this;12831}12832};1283312834} // namespace detail12835NLOHMANN_JSON_NAMESPACE_END128361283712838NLOHMANN_JSON_NAMESPACE_BEGIN12839namespace detail12840{1284112842/*!12843@brief an iterator value1284412845@note This structure could easily be a union, but MSVC currently does not allow12846unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.12847*/12848template<typename BasicJsonType> struct internal_iterator12849{12850/// iterator for JSON objects12851typename BasicJsonType::object_t::iterator object_iterator {};12852/// iterator for JSON arrays12853typename BasicJsonType::array_t::iterator array_iterator {};12854/// generic iterator for all other types12855primitive_iterator_t primitive_iterator {};12856};1285712858} // namespace detail12859NLOHMANN_JSON_NAMESPACE_END1286012861// #include <nlohmann/detail/iterators/iter_impl.hpp>12862// __ _____ _____ _____12863// __| | __| | | | JSON for Modern C++12864// | | |__ | | | | | | version 3.11.312865// |_____|_____|_____|_|___| https://github.com/nlohmann/json12866//12867// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>12868// SPDX-License-Identifier: MIT12869128701287112872#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next12873#include <type_traits> // conditional, is_const, remove_const1287412875// #include <nlohmann/detail/exceptions.hpp>1287612877// #include <nlohmann/detail/iterators/internal_iterator.hpp>1287812879// #include <nlohmann/detail/iterators/primitive_iterator.hpp>1288012881// #include <nlohmann/detail/macro_scope.hpp>1288212883// #include <nlohmann/detail/meta/cpp_future.hpp>1288412885// #include <nlohmann/detail/meta/type_traits.hpp>1288612887// #include <nlohmann/detail/value_t.hpp>128881288912890NLOHMANN_JSON_NAMESPACE_BEGIN12891namespace detail12892{1289312894// forward declare, to be able to friend it later on12895template<typename IteratorType> class iteration_proxy;12896template<typename IteratorType> class iteration_proxy_value;1289712898/*!12899@brief a template for a bidirectional iterator for the @ref basic_json class12900This class implements a both iterators (iterator and const_iterator) for the12901@ref basic_json class.12902@note An iterator is called *initialized* when a pointer to a JSON value has12903been set (e.g., by a constructor or a copy assignment). If the iterator is12904default-constructed, it is *uninitialized* and most methods are undefined.12905**The library uses assertions to detect calls on uninitialized iterators.**12906@requirement The class satisfies the following concept requirements:12907-12908[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):12909The iterator that can be moved can be moved in both directions (i.e.12910incremented and decremented).12911@since version 1.0.0, simplified in version 2.0.9, change to bidirectional12912iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)12913*/12914template<typename BasicJsonType>12915class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)12916{12917/// the iterator with BasicJsonType of different const-ness12918using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;12919/// allow basic_json to access private members12920friend other_iter_impl;12921friend BasicJsonType;12922friend iteration_proxy<iter_impl>;12923friend iteration_proxy_value<iter_impl>;1292412925using object_t = typename BasicJsonType::object_t;12926using array_t = typename BasicJsonType::array_t;12927// make sure BasicJsonType is basic_json or const basic_json12928static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,12929"iter_impl only accepts (const) basic_json");12930// superficial check for the LegacyBidirectionalIterator named requirement12931static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value12932&& std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,12933"basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");1293412935public:12936/// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.12937/// The C++ Standard has never required user-defined iterators to derive from std::iterator.12938/// A user-defined iterator should provide publicly accessible typedefs named12939/// iterator_category, value_type, difference_type, pointer, and reference.12940/// Note that value_type is required to be non-const, even for constant iterators.12941using iterator_category = std::bidirectional_iterator_tag;1294212943/// the type of the values when the iterator is dereferenced12944using value_type = typename BasicJsonType::value_type;12945/// a type to represent differences between iterators12946using difference_type = typename BasicJsonType::difference_type;12947/// defines a pointer to the type iterated over (value_type)12948using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,12949typename BasicJsonType::const_pointer,12950typename BasicJsonType::pointer>::type;12951/// defines a reference to the type iterated over (value_type)12952using reference =12953typename std::conditional<std::is_const<BasicJsonType>::value,12954typename BasicJsonType::const_reference,12955typename BasicJsonType::reference>::type;1295612957iter_impl() = default;12958~iter_impl() = default;12959iter_impl(iter_impl&&) noexcept = default;12960iter_impl& operator=(iter_impl&&) noexcept = default;1296112962/*!12963@brief constructor for a given JSON instance12964@param[in] object pointer to a JSON object for this iterator12965@pre object != nullptr12966@post The iterator is initialized; i.e. `m_object != nullptr`.12967*/12968explicit iter_impl(pointer object) noexcept : m_object(object)12969{12970JSON_ASSERT(m_object != nullptr);1297112972switch (m_object->m_data.m_type)12973{12974case value_t::object:12975{12976m_it.object_iterator = typename object_t::iterator();12977break;12978}1297912980case value_t::array:12981{12982m_it.array_iterator = typename array_t::iterator();12983break;12984}1298512986case value_t::null:12987case value_t::string:12988case value_t::boolean:12989case value_t::number_integer:12990case value_t::number_unsigned:12991case value_t::number_float:12992case value_t::binary:12993case value_t::discarded:12994default:12995{12996m_it.primitive_iterator = primitive_iterator_t();12997break;12998}12999}13000}1300113002/*!13003@note The conventional copy constructor and copy assignment are implicitly13004defined. Combined with the following converting constructor and13005assignment, they support: (1) copy from iterator to iterator, (2)13006copy from const iterator to const iterator, and (3) conversion from13007iterator to const iterator. However conversion from const iterator13008to iterator is not defined.13009*/1301013011/*!13012@brief const copy constructor13013@param[in] other const iterator to copy from13014@note This copy constructor had to be defined explicitly to circumvent a bug13015occurring on msvc v19.0 compiler (VS 2015) debug build. For more13016information refer to: https://github.com/nlohmann/json/issues/160813017*/13018iter_impl(const iter_impl<const BasicJsonType>& other) noexcept13019: m_object(other.m_object), m_it(other.m_it)13020{}1302113022/*!13023@brief converting assignment13024@param[in] other const iterator to copy from13025@return const/non-const iterator13026@note It is not checked whether @a other is initialized.13027*/13028iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept13029{13030if (&other != this)13031{13032m_object = other.m_object;13033m_it = other.m_it;13034}13035return *this;13036}1303713038/*!13039@brief converting constructor13040@param[in] other non-const iterator to copy from13041@note It is not checked whether @a other is initialized.13042*/13043iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept13044: m_object(other.m_object), m_it(other.m_it)13045{}1304613047/*!13048@brief converting assignment13049@param[in] other non-const iterator to copy from13050@return const/non-const iterator13051@note It is not checked whether @a other is initialized.13052*/13053iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)13054{13055m_object = other.m_object;13056m_it = other.m_it;13057return *this;13058}1305913060JSON_PRIVATE_UNLESS_TESTED:13061/*!13062@brief set the iterator to the first value13063@pre The iterator is initialized; i.e. `m_object != nullptr`.13064*/13065void set_begin() noexcept13066{13067JSON_ASSERT(m_object != nullptr);1306813069switch (m_object->m_data.m_type)13070{13071case value_t::object:13072{13073m_it.object_iterator = m_object->m_data.m_value.object->begin();13074break;13075}1307613077case value_t::array:13078{13079m_it.array_iterator = m_object->m_data.m_value.array->begin();13080break;13081}1308213083case value_t::null:13084{13085// set to end so begin()==end() is true: null is empty13086m_it.primitive_iterator.set_end();13087break;13088}1308913090case value_t::string:13091case value_t::boolean:13092case value_t::number_integer:13093case value_t::number_unsigned:13094case value_t::number_float:13095case value_t::binary:13096case value_t::discarded:13097default:13098{13099m_it.primitive_iterator.set_begin();13100break;13101}13102}13103}1310413105/*!13106@brief set the iterator past the last value13107@pre The iterator is initialized; i.e. `m_object != nullptr`.13108*/13109void set_end() noexcept13110{13111JSON_ASSERT(m_object != nullptr);1311213113switch (m_object->m_data.m_type)13114{13115case value_t::object:13116{13117m_it.object_iterator = m_object->m_data.m_value.object->end();13118break;13119}1312013121case value_t::array:13122{13123m_it.array_iterator = m_object->m_data.m_value.array->end();13124break;13125}1312613127case value_t::null:13128case value_t::string:13129case value_t::boolean:13130case value_t::number_integer:13131case value_t::number_unsigned:13132case value_t::number_float:13133case value_t::binary:13134case value_t::discarded:13135default:13136{13137m_it.primitive_iterator.set_end();13138break;13139}13140}13141}1314213143public:13144/*!13145@brief return a reference to the value pointed to by the iterator13146@pre The iterator is initialized; i.e. `m_object != nullptr`.13147*/13148reference operator*() const13149{13150JSON_ASSERT(m_object != nullptr);1315113152switch (m_object->m_data.m_type)13153{13154case value_t::object:13155{13156JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());13157return m_it.object_iterator->second;13158}1315913160case value_t::array:13161{13162JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());13163return *m_it.array_iterator;13164}1316513166case value_t::null:13167JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));1316813169case value_t::string:13170case value_t::boolean:13171case value_t::number_integer:13172case value_t::number_unsigned:13173case value_t::number_float:13174case value_t::binary:13175case value_t::discarded:13176default:13177{13178if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))13179{13180return *m_object;13181}1318213183JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));13184}13185}13186}1318713188/*!13189@brief dereference the iterator13190@pre The iterator is initialized; i.e. `m_object != nullptr`.13191*/13192pointer operator->() const13193{13194JSON_ASSERT(m_object != nullptr);1319513196switch (m_object->m_data.m_type)13197{13198case value_t::object:13199{13200JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());13201return &(m_it.object_iterator->second);13202}1320313204case value_t::array:13205{13206JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());13207return &*m_it.array_iterator;13208}1320913210case value_t::null:13211case value_t::string:13212case value_t::boolean:13213case value_t::number_integer:13214case value_t::number_unsigned:13215case value_t::number_float:13216case value_t::binary:13217case value_t::discarded:13218default:13219{13220if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))13221{13222return m_object;13223}1322413225JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));13226}13227}13228}1322913230/*!13231@brief post-increment (it++)13232@pre The iterator is initialized; i.e. `m_object != nullptr`.13233*/13234iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)13235{13236auto result = *this;13237++(*this);13238return result;13239}1324013241/*!13242@brief pre-increment (++it)13243@pre The iterator is initialized; i.e. `m_object != nullptr`.13244*/13245iter_impl& operator++()13246{13247JSON_ASSERT(m_object != nullptr);1324813249switch (m_object->m_data.m_type)13250{13251case value_t::object:13252{13253std::advance(m_it.object_iterator, 1);13254break;13255}1325613257case value_t::array:13258{13259std::advance(m_it.array_iterator, 1);13260break;13261}1326213263case value_t::null:13264case value_t::string:13265case value_t::boolean:13266case value_t::number_integer:13267case value_t::number_unsigned:13268case value_t::number_float:13269case value_t::binary:13270case value_t::discarded:13271default:13272{13273++m_it.primitive_iterator;13274break;13275}13276}1327713278return *this;13279}1328013281/*!13282@brief post-decrement (it--)13283@pre The iterator is initialized; i.e. `m_object != nullptr`.13284*/13285iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)13286{13287auto result = *this;13288--(*this);13289return result;13290}1329113292/*!13293@brief pre-decrement (--it)13294@pre The iterator is initialized; i.e. `m_object != nullptr`.13295*/13296iter_impl& operator--()13297{13298JSON_ASSERT(m_object != nullptr);1329913300switch (m_object->m_data.m_type)13301{13302case value_t::object:13303{13304std::advance(m_it.object_iterator, -1);13305break;13306}1330713308case value_t::array:13309{13310std::advance(m_it.array_iterator, -1);13311break;13312}1331313314case value_t::null:13315case value_t::string:13316case value_t::boolean:13317case value_t::number_integer:13318case value_t::number_unsigned:13319case value_t::number_float:13320case value_t::binary:13321case value_t::discarded:13322default:13323{13324--m_it.primitive_iterator;13325break;13326}13327}1332813329return *this;13330}1333113332/*!13333@brief comparison: equal13334@pre The iterator is initialized; i.e. `m_object != nullptr`.13335*/13336template < 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 >13337bool operator==(const IterImpl& other) const13338{13339// if objects are not the same, the comparison is undefined13340if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))13341{13342JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));13343}1334413345JSON_ASSERT(m_object != nullptr);1334613347switch (m_object->m_data.m_type)13348{13349case value_t::object:13350return (m_it.object_iterator == other.m_it.object_iterator);1335113352case value_t::array:13353return (m_it.array_iterator == other.m_it.array_iterator);1335413355case value_t::null:13356case value_t::string:13357case value_t::boolean:13358case value_t::number_integer:13359case value_t::number_unsigned:13360case value_t::number_float:13361case value_t::binary:13362case value_t::discarded:13363default:13364return (m_it.primitive_iterator == other.m_it.primitive_iterator);13365}13366}1336713368/*!13369@brief comparison: not equal13370@pre The iterator is initialized; i.e. `m_object != nullptr`.13371*/13372template < 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 >13373bool operator!=(const IterImpl& other) const13374{13375return !operator==(other);13376}1337713378/*!13379@brief comparison: smaller13380@pre The iterator is initialized; i.e. `m_object != nullptr`.13381*/13382bool operator<(const iter_impl& other) const13383{13384// if objects are not the same, the comparison is undefined13385if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))13386{13387JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));13388}1338913390JSON_ASSERT(m_object != nullptr);1339113392switch (m_object->m_data.m_type)13393{13394case value_t::object:13395JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));1339613397case value_t::array:13398return (m_it.array_iterator < other.m_it.array_iterator);1339913400case value_t::null:13401case value_t::string:13402case value_t::boolean:13403case value_t::number_integer:13404case value_t::number_unsigned:13405case value_t::number_float:13406case value_t::binary:13407case value_t::discarded:13408default:13409return (m_it.primitive_iterator < other.m_it.primitive_iterator);13410}13411}1341213413/*!13414@brief comparison: less than or equal13415@pre The iterator is initialized; i.e. `m_object != nullptr`.13416*/13417bool operator<=(const iter_impl& other) const13418{13419return !other.operator < (*this);13420}1342113422/*!13423@brief comparison: greater than13424@pre The iterator is initialized; i.e. `m_object != nullptr`.13425*/13426bool operator>(const iter_impl& other) const13427{13428return !operator<=(other);13429}1343013431/*!13432@brief comparison: greater than or equal13433@pre The iterator is initialized; i.e. `m_object != nullptr`.13434*/13435bool operator>=(const iter_impl& other) const13436{13437return !operator<(other);13438}1343913440/*!13441@brief add to iterator13442@pre The iterator is initialized; i.e. `m_object != nullptr`.13443*/13444iter_impl& operator+=(difference_type i)13445{13446JSON_ASSERT(m_object != nullptr);1344713448switch (m_object->m_data.m_type)13449{13450case value_t::object:13451JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));1345213453case value_t::array:13454{13455std::advance(m_it.array_iterator, i);13456break;13457}1345813459case value_t::null:13460case value_t::string:13461case value_t::boolean:13462case value_t::number_integer:13463case value_t::number_unsigned:13464case value_t::number_float:13465case value_t::binary:13466case value_t::discarded:13467default:13468{13469m_it.primitive_iterator += i;13470break;13471}13472}1347313474return *this;13475}1347613477/*!13478@brief subtract from iterator13479@pre The iterator is initialized; i.e. `m_object != nullptr`.13480*/13481iter_impl& operator-=(difference_type i)13482{13483return operator+=(-i);13484}1348513486/*!13487@brief add to iterator13488@pre The iterator is initialized; i.e. `m_object != nullptr`.13489*/13490iter_impl operator+(difference_type i) const13491{13492auto result = *this;13493result += i;13494return result;13495}1349613497/*!13498@brief addition of distance and iterator13499@pre The iterator is initialized; i.e. `m_object != nullptr`.13500*/13501friend iter_impl operator+(difference_type i, const iter_impl& it)13502{13503auto result = it;13504result += i;13505return result;13506}1350713508/*!13509@brief subtract from iterator13510@pre The iterator is initialized; i.e. `m_object != nullptr`.13511*/13512iter_impl operator-(difference_type i) const13513{13514auto result = *this;13515result -= i;13516return result;13517}1351813519/*!13520@brief return difference13521@pre The iterator is initialized; i.e. `m_object != nullptr`.13522*/13523difference_type operator-(const iter_impl& other) const13524{13525JSON_ASSERT(m_object != nullptr);1352613527switch (m_object->m_data.m_type)13528{13529case value_t::object:13530JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));1353113532case value_t::array:13533return m_it.array_iterator - other.m_it.array_iterator;1353413535case value_t::null:13536case value_t::string:13537case value_t::boolean:13538case value_t::number_integer:13539case value_t::number_unsigned:13540case value_t::number_float:13541case value_t::binary:13542case value_t::discarded:13543default:13544return m_it.primitive_iterator - other.m_it.primitive_iterator;13545}13546}1354713548/*!13549@brief access to successor13550@pre The iterator is initialized; i.e. `m_object != nullptr`.13551*/13552reference operator[](difference_type n) const13553{13554JSON_ASSERT(m_object != nullptr);1355513556switch (m_object->m_data.m_type)13557{13558case value_t::object:13559JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));1356013561case value_t::array:13562return *std::next(m_it.array_iterator, n);1356313564case value_t::null:13565JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));1356613567case value_t::string:13568case value_t::boolean:13569case value_t::number_integer:13570case value_t::number_unsigned:13571case value_t::number_float:13572case value_t::binary:13573case value_t::discarded:13574default:13575{13576if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))13577{13578return *m_object;13579}1358013581JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));13582}13583}13584}1358513586/*!13587@brief return the key of an object iterator13588@pre The iterator is initialized; i.e. `m_object != nullptr`.13589*/13590const typename object_t::key_type& key() const13591{13592JSON_ASSERT(m_object != nullptr);1359313594if (JSON_HEDLEY_LIKELY(m_object->is_object()))13595{13596return m_it.object_iterator->first;13597}1359813599JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));13600}1360113602/*!13603@brief return the value of an iterator13604@pre The iterator is initialized; i.e. `m_object != nullptr`.13605*/13606reference value() const13607{13608return operator*();13609}1361013611JSON_PRIVATE_UNLESS_TESTED:13612/// associated JSON instance13613pointer m_object = nullptr;13614/// the actual iterator of the associated instance13615internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};13616};1361713618} // namespace detail13619NLOHMANN_JSON_NAMESPACE_END1362013621// #include <nlohmann/detail/iterators/iteration_proxy.hpp>1362213623// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>13624// __ _____ _____ _____13625// __| | __| | | | JSON for Modern C++13626// | | |__ | | | | | | version 3.11.313627// |_____|_____|_____|_|___| https://github.com/nlohmann/json13628//13629// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>13630// SPDX-License-Identifier: MIT13631136321363313634#include <cstddef> // ptrdiff_t13635#include <iterator> // reverse_iterator13636#include <utility> // declval1363713638// #include <nlohmann/detail/abi_macros.hpp>136391364013641NLOHMANN_JSON_NAMESPACE_BEGIN13642namespace detail13643{1364413645//////////////////////13646// reverse_iterator //13647//////////////////////1364813649/*!13650@brief a template for a reverse iterator class1365113652@tparam Base the base iterator type to reverse. Valid types are @ref13653iterator (to create @ref reverse_iterator) and @ref const_iterator (to13654create @ref const_reverse_iterator).1365513656@requirement The class satisfies the following concept requirements:13657-13658[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):13659The iterator that can be moved can be moved in both directions (i.e.13660incremented and decremented).13661- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):13662It is possible to write to the pointed-to element (only if @a Base is13663@ref iterator).1366413665@since version 1.0.013666*/13667template<typename Base>13668class json_reverse_iterator : public std::reverse_iterator<Base>13669{13670public:13671using difference_type = std::ptrdiff_t;13672/// shortcut to the reverse iterator adapter13673using base_iterator = std::reverse_iterator<Base>;13674/// the reference type for the pointed-to element13675using reference = typename Base::reference;1367613677/// create reverse iterator from iterator13678explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept13679: base_iterator(it) {}1368013681/// create reverse iterator from base class13682explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}1368313684/// post-increment (it++)13685json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)13686{13687return static_cast<json_reverse_iterator>(base_iterator::operator++(1));13688}1368913690/// pre-increment (++it)13691json_reverse_iterator& operator++()13692{13693return static_cast<json_reverse_iterator&>(base_iterator::operator++());13694}1369513696/// post-decrement (it--)13697json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)13698{13699return static_cast<json_reverse_iterator>(base_iterator::operator--(1));13700}1370113702/// pre-decrement (--it)13703json_reverse_iterator& operator--()13704{13705return static_cast<json_reverse_iterator&>(base_iterator::operator--());13706}1370713708/// add to iterator13709json_reverse_iterator& operator+=(difference_type i)13710{13711return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));13712}1371313714/// add to iterator13715json_reverse_iterator operator+(difference_type i) const13716{13717return static_cast<json_reverse_iterator>(base_iterator::operator+(i));13718}1371913720/// subtract from iterator13721json_reverse_iterator operator-(difference_type i) const13722{13723return static_cast<json_reverse_iterator>(base_iterator::operator-(i));13724}1372513726/// return difference13727difference_type operator-(const json_reverse_iterator& other) const13728{13729return base_iterator(*this) - base_iterator(other);13730}1373113732/// access to successor13733reference operator[](difference_type n) const13734{13735return *(this->operator+(n));13736}1373713738/// return the key of an object iterator13739auto key() const -> decltype(std::declval<Base>().key())13740{13741auto it = --this->base();13742return it.key();13743}1374413745/// return the value of an iterator13746reference value() const13747{13748auto it = --this->base();13749return it.operator * ();13750}13751};1375213753} // namespace detail13754NLOHMANN_JSON_NAMESPACE_END1375513756// #include <nlohmann/detail/iterators/primitive_iterator.hpp>1375713758// #include <nlohmann/detail/json_custom_base_class.hpp>13759// __ _____ _____ _____13760// __| | __| | | | JSON for Modern C++13761// | | |__ | | | | | | version 3.11.313762// |_____|_____|_____|_|___| https://github.com/nlohmann/json13763//13764// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>13765// SPDX-License-Identifier: MIT13766137671376813769#include <type_traits> // conditional, is_same1377013771// #include <nlohmann/detail/abi_macros.hpp>137721377313774NLOHMANN_JSON_NAMESPACE_BEGIN13775namespace detail13776{1377713778/*!13779@brief Default base class of the @ref basic_json class.1378013781So that the correct implementations of the copy / move ctors / assign operators13782of @ref basic_json do not require complex case distinctions13783(no base class / custom base class used as customization point),13784@ref basic_json always has a base class.13785By default, this class is used because it is empty and thus has no effect13786on the behavior of @ref basic_json.13787*/13788struct json_default_base {};1378913790template<class T>13791using json_base_class = typename std::conditional <13792std::is_same<T, void>::value,13793json_default_base,13794T13795>::type;1379613797} // namespace detail13798NLOHMANN_JSON_NAMESPACE_END1379913800// #include <nlohmann/detail/json_pointer.hpp>13801// __ _____ _____ _____13802// __| | __| | | | JSON for Modern C++13803// | | |__ | | | | | | version 3.11.313804// |_____|_____|_____|_|___| https://github.com/nlohmann/json13805//13806// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>13807// SPDX-License-Identifier: MIT13808138091381013811#include <algorithm> // all_of13812#include <cctype> // isdigit13813#include <cerrno> // errno, ERANGE13814#include <cstdlib> // strtoull13815#ifndef JSON_NO_IO13816#include <iosfwd> // ostream13817#endif // JSON_NO_IO13818#include <limits> // max13819#include <numeric> // accumulate13820#include <string> // string13821#include <utility> // move13822#include <vector> // vector1382313824// #include <nlohmann/detail/exceptions.hpp>1382513826// #include <nlohmann/detail/macro_scope.hpp>1382713828// #include <nlohmann/detail/string_concat.hpp>1382913830// #include <nlohmann/detail/string_escape.hpp>1383113832// #include <nlohmann/detail/value_t.hpp>138331383413835NLOHMANN_JSON_NAMESPACE_BEGIN1383613837/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document13838/// @sa https://json.nlohmann.me/api/json_pointer/13839template<typename RefStringType>13840class json_pointer13841{13842// allow basic_json to access private members13843NLOHMANN_BASIC_JSON_TPL_DECLARATION13844friend class basic_json;1384513846template<typename>13847friend class json_pointer;1384813849template<typename T>13850struct string_t_helper13851{13852using type = T;13853};1385413855NLOHMANN_BASIC_JSON_TPL_DECLARATION13856struct string_t_helper<NLOHMANN_BASIC_JSON_TPL>13857{13858using type = StringType;13859};1386013861public:13862// for backwards compatibility accept BasicJsonType13863using string_t = typename string_t_helper<RefStringType>::type;1386413865/// @brief create JSON pointer13866/// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/13867explicit json_pointer(const string_t& s = "")13868: reference_tokens(split(s))13869{}1387013871/// @brief return a string representation of the JSON pointer13872/// @sa https://json.nlohmann.me/api/json_pointer/to_string/13873string_t to_string() const13874{13875return std::accumulate(reference_tokens.begin(), reference_tokens.end(),13876string_t{},13877[](const string_t& a, const string_t& b)13878{13879return detail::concat(a, '/', detail::escape(b));13880});13881}1388213883/// @brief return a string representation of the JSON pointer13884/// @sa https://json.nlohmann.me/api/json_pointer/operator_string/13885JSON_HEDLEY_DEPRECATED_FOR(3.11.0, to_string())13886operator string_t() const13887{13888return to_string();13889}1389013891#ifndef JSON_NO_IO13892/// @brief write string representation of the JSON pointer to stream13893/// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/13894friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)13895{13896o << ptr.to_string();13897return o;13898}13899#endif1390013901/// @brief append another JSON pointer at the end of this JSON pointer13902/// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/13903json_pointer& operator/=(const json_pointer& ptr)13904{13905reference_tokens.insert(reference_tokens.end(),13906ptr.reference_tokens.begin(),13907ptr.reference_tokens.end());13908return *this;13909}1391013911/// @brief append an unescaped reference token at the end of this JSON pointer13912/// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/13913json_pointer& operator/=(string_t token)13914{13915push_back(std::move(token));13916return *this;13917}1391813919/// @brief append an array index at the end of this JSON pointer13920/// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/13921json_pointer& operator/=(std::size_t array_idx)13922{13923return *this /= std::to_string(array_idx);13924}1392513926/// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer13927/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/13928friend json_pointer operator/(const json_pointer& lhs,13929const json_pointer& rhs)13930{13931return json_pointer(lhs) /= rhs;13932}1393313934/// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer13935/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/13936friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)13937{13938return json_pointer(lhs) /= std::move(token);13939}1394013941/// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer13942/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/13943friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)13944{13945return json_pointer(lhs) /= array_idx;13946}1394713948/// @brief returns the parent of this JSON pointer13949/// @sa https://json.nlohmann.me/api/json_pointer/parent_pointer/13950json_pointer parent_pointer() const13951{13952if (empty())13953{13954return *this;13955}1395613957json_pointer res = *this;13958res.pop_back();13959return res;13960}1396113962/// @brief remove last reference token13963/// @sa https://json.nlohmann.me/api/json_pointer/pop_back/13964void pop_back()13965{13966if (JSON_HEDLEY_UNLIKELY(empty()))13967{13968JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));13969}1397013971reference_tokens.pop_back();13972}1397313974/// @brief return last reference token13975/// @sa https://json.nlohmann.me/api/json_pointer/back/13976const string_t& back() const13977{13978if (JSON_HEDLEY_UNLIKELY(empty()))13979{13980JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));13981}1398213983return reference_tokens.back();13984}1398513986/// @brief append an unescaped token at the end of the reference pointer13987/// @sa https://json.nlohmann.me/api/json_pointer/push_back/13988void push_back(const string_t& token)13989{13990reference_tokens.push_back(token);13991}1399213993/// @brief append an unescaped token at the end of the reference pointer13994/// @sa https://json.nlohmann.me/api/json_pointer/push_back/13995void push_back(string_t&& token)13996{13997reference_tokens.push_back(std::move(token));13998}1399914000/// @brief return whether pointer points to the root document14001/// @sa https://json.nlohmann.me/api/json_pointer/empty/14002bool empty() const noexcept14003{14004return reference_tokens.empty();14005}1400614007private:14008/*!14009@param[in] s reference token to be converted into an array index1401014011@return integer representation of @a s1401214013@throw parse_error.106 if an array index begins with '0'14014@throw parse_error.109 if an array index begins not with a digit14015@throw out_of_range.404 if string @a s could not be converted to an integer14016@throw out_of_range.410 if an array index exceeds size_type14017*/14018template<typename BasicJsonType>14019static typename BasicJsonType::size_type array_index(const string_t& s)14020{14021using size_type = typename BasicJsonType::size_type;1402214023// error condition (cf. RFC 6901, Sect. 4)14024if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))14025{14026JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));14027}1402814029// error condition (cf. RFC 6901, Sect. 4)14030if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))14031{14032JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));14033}1403414035const char* p = s.c_str();14036char* p_end = nullptr;14037errno = 0; // strtoull doesn't reset errno14038const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)14039if (p == p_end // invalid input or empty string14040|| errno == ERANGE // out of range14041|| JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read14042{14043JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));14044}1404514046// only triggered on special platforms (like 32bit), see also14047// https://github.com/nlohmann/json/pull/220314048if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)14049{14050JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE14051}1405214053return static_cast<size_type>(res);14054}1405514056JSON_PRIVATE_UNLESS_TESTED:14057json_pointer top() const14058{14059if (JSON_HEDLEY_UNLIKELY(empty()))14060{14061JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));14062}1406314064json_pointer result = *this;14065result.reference_tokens = {reference_tokens[0]};14066return result;14067}1406814069private:14070/*!14071@brief create and return a reference to the pointed to value1407214073@complexity Linear in the number of reference tokens.1407414075@throw parse_error.109 if array index is not a number14076@throw type_error.313 if value cannot be unflattened14077*/14078template<typename BasicJsonType>14079BasicJsonType& get_and_create(BasicJsonType& j) const14080{14081auto* result = &j;1408214083// in case no reference tokens exist, return a reference to the JSON value14084// j which will be overwritten by a primitive value14085for (const auto& reference_token : reference_tokens)14086{14087switch (result->type())14088{14089case detail::value_t::null:14090{14091if (reference_token == "0")14092{14093// start a new array if reference token is 014094result = &result->operator[](0);14095}14096else14097{14098// start a new object otherwise14099result = &result->operator[](reference_token);14100}14101break;14102}1410314104case detail::value_t::object:14105{14106// create an entry in the object14107result = &result->operator[](reference_token);14108break;14109}1411014111case detail::value_t::array:14112{14113// create an entry in the array14114result = &result->operator[](array_index<BasicJsonType>(reference_token));14115break;14116}1411714118/*14119The following code is only reached if there exists a reference14120token _and_ the current value is primitive. In this case, we have14121an error situation, because primitive values may only occur as14122single value; that is, with an empty list of reference tokens.14123*/14124case detail::value_t::string:14125case detail::value_t::boolean:14126case detail::value_t::number_integer:14127case detail::value_t::number_unsigned:14128case detail::value_t::number_float:14129case detail::value_t::binary:14130case detail::value_t::discarded:14131default:14132JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));14133}14134}1413514136return *result;14137}1413814139/*!14140@brief return a reference to the pointed to value1414114142@note This version does not throw if a value is not present, but tries to14143create nested values instead. For instance, calling this function14144with pointer `"/this/that"` on a null value is equivalent to calling14145`operator[]("this").operator[]("that")` on that value, effectively14146changing the null value to an object.1414714148@param[in] ptr a JSON value1414914150@return reference to the JSON value pointed to by the JSON pointer1415114152@complexity Linear in the length of the JSON pointer.1415314154@throw parse_error.106 if an array index begins with '0'14155@throw parse_error.109 if an array index was not a number14156@throw out_of_range.404 if the JSON pointer can not be resolved14157*/14158template<typename BasicJsonType>14159BasicJsonType& get_unchecked(BasicJsonType* ptr) const14160{14161for (const auto& reference_token : reference_tokens)14162{14163// convert null values to arrays or objects before continuing14164if (ptr->is_null())14165{14166// check if reference token is a number14167const bool nums =14168std::all_of(reference_token.begin(), reference_token.end(),14169[](const unsigned char x)14170{14171return std::isdigit(x);14172});1417314174// change value to array for numbers or "-" or to object otherwise14175*ptr = (nums || reference_token == "-")14176? detail::value_t::array14177: detail::value_t::object;14178}1417914180switch (ptr->type())14181{14182case detail::value_t::object:14183{14184// use unchecked object access14185ptr = &ptr->operator[](reference_token);14186break;14187}1418814189case detail::value_t::array:14190{14191if (reference_token == "-")14192{14193// explicitly treat "-" as index beyond the end14194ptr = &ptr->operator[](ptr->m_data.m_value.array->size());14195}14196else14197{14198// convert array index to number; unchecked access14199ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));14200}14201break;14202}1420314204case detail::value_t::null:14205case detail::value_t::string:14206case detail::value_t::boolean:14207case detail::value_t::number_integer:14208case detail::value_t::number_unsigned:14209case detail::value_t::number_float:14210case detail::value_t::binary:14211case detail::value_t::discarded:14212default:14213JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));14214}14215}1421614217return *ptr;14218}1421914220/*!14221@throw parse_error.106 if an array index begins with '0'14222@throw parse_error.109 if an array index was not a number14223@throw out_of_range.402 if the array index '-' is used14224@throw out_of_range.404 if the JSON pointer can not be resolved14225*/14226template<typename BasicJsonType>14227BasicJsonType& get_checked(BasicJsonType* ptr) const14228{14229for (const auto& reference_token : reference_tokens)14230{14231switch (ptr->type())14232{14233case detail::value_t::object:14234{14235// note: at performs range check14236ptr = &ptr->at(reference_token);14237break;14238}1423914240case detail::value_t::array:14241{14242if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))14243{14244// "-" always fails the range check14245JSON_THROW(detail::out_of_range::create(402, detail::concat(14246"array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),14247") is out of range"), ptr));14248}1424914250// note: at performs range check14251ptr = &ptr->at(array_index<BasicJsonType>(reference_token));14252break;14253}1425414255case detail::value_t::null:14256case detail::value_t::string:14257case detail::value_t::boolean:14258case detail::value_t::number_integer:14259case detail::value_t::number_unsigned:14260case detail::value_t::number_float:14261case detail::value_t::binary:14262case detail::value_t::discarded:14263default:14264JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));14265}14266}1426714268return *ptr;14269}1427014271/*!14272@brief return a const reference to the pointed to value1427314274@param[in] ptr a JSON value1427514276@return const reference to the JSON value pointed to by the JSON14277pointer1427814279@throw parse_error.106 if an array index begins with '0'14280@throw parse_error.109 if an array index was not a number14281@throw out_of_range.402 if the array index '-' is used14282@throw out_of_range.404 if the JSON pointer can not be resolved14283*/14284template<typename BasicJsonType>14285const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const14286{14287for (const auto& reference_token : reference_tokens)14288{14289switch (ptr->type())14290{14291case detail::value_t::object:14292{14293// use unchecked object access14294ptr = &ptr->operator[](reference_token);14295break;14296}1429714298case detail::value_t::array:14299{14300if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))14301{14302// "-" cannot be used for const access14303JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));14304}1430514306// use unchecked array access14307ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));14308break;14309}1431014311case detail::value_t::null:14312case detail::value_t::string:14313case detail::value_t::boolean:14314case detail::value_t::number_integer:14315case detail::value_t::number_unsigned:14316case detail::value_t::number_float:14317case detail::value_t::binary:14318case detail::value_t::discarded:14319default:14320JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));14321}14322}1432314324return *ptr;14325}1432614327/*!14328@throw parse_error.106 if an array index begins with '0'14329@throw parse_error.109 if an array index was not a number14330@throw out_of_range.402 if the array index '-' is used14331@throw out_of_range.404 if the JSON pointer can not be resolved14332*/14333template<typename BasicJsonType>14334const BasicJsonType& get_checked(const BasicJsonType* ptr) const14335{14336for (const auto& reference_token : reference_tokens)14337{14338switch (ptr->type())14339{14340case detail::value_t::object:14341{14342// note: at performs range check14343ptr = &ptr->at(reference_token);14344break;14345}1434614347case detail::value_t::array:14348{14349if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))14350{14351// "-" always fails the range check14352JSON_THROW(detail::out_of_range::create(402, detail::concat(14353"array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),14354") is out of range"), ptr));14355}1435614357// note: at performs range check14358ptr = &ptr->at(array_index<BasicJsonType>(reference_token));14359break;14360}1436114362case detail::value_t::null:14363case detail::value_t::string:14364case detail::value_t::boolean:14365case detail::value_t::number_integer:14366case detail::value_t::number_unsigned:14367case detail::value_t::number_float:14368case detail::value_t::binary:14369case detail::value_t::discarded:14370default:14371JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));14372}14373}1437414375return *ptr;14376}1437714378/*!14379@throw parse_error.106 if an array index begins with '0'14380@throw parse_error.109 if an array index was not a number14381*/14382template<typename BasicJsonType>14383bool contains(const BasicJsonType* ptr) const14384{14385for (const auto& reference_token : reference_tokens)14386{14387switch (ptr->type())14388{14389case detail::value_t::object:14390{14391if (!ptr->contains(reference_token))14392{14393// we did not find the key in the object14394return false;14395}1439614397ptr = &ptr->operator[](reference_token);14398break;14399}1440014401case detail::value_t::array:14402{14403if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))14404{14405// "-" always fails the range check14406return false;14407}14408if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))14409{14410// invalid char14411return false;14412}14413if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))14414{14415if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))14416{14417// first char should be between '1' and '9'14418return false;14419}14420for (std::size_t i = 1; i < reference_token.size(); i++)14421{14422if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))14423{14424// other char should be between '0' and '9'14425return false;14426}14427}14428}1442914430const auto idx = array_index<BasicJsonType>(reference_token);14431if (idx >= ptr->size())14432{14433// index out of range14434return false;14435}1443614437ptr = &ptr->operator[](idx);14438break;14439}1444014441case detail::value_t::null:14442case detail::value_t::string:14443case detail::value_t::boolean:14444case detail::value_t::number_integer:14445case detail::value_t::number_unsigned:14446case detail::value_t::number_float:14447case detail::value_t::binary:14448case detail::value_t::discarded:14449default:14450{14451// we do not expect primitive values if there is still a14452// reference token to process14453return false;14454}14455}14456}1445714458// no reference token left means we found a primitive value14459return true;14460}1446114462/*!14463@brief split the string input to reference tokens1446414465@note This function is only called by the json_pointer constructor.14466All exceptions below are documented there.1446714468@throw parse_error.107 if the pointer is not empty or begins with '/'14469@throw parse_error.108 if character '~' is not followed by '0' or '1'14470*/14471static std::vector<string_t> split(const string_t& reference_string)14472{14473std::vector<string_t> result;1447414475// special case: empty reference string -> no reference tokens14476if (reference_string.empty())14477{14478return result;14479}1448014481// check if nonempty reference string begins with slash14482if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))14483{14484JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));14485}1448614487// extract the reference tokens:14488// - slash: position of the last read slash (or end of string)14489// - start: position after the previous slash14490for (14491// search for the first slash after the first character14492std::size_t slash = reference_string.find_first_of('/', 1),14493// set the beginning of the first reference token14494start = 1;14495// we can stop if start == 0 (if slash == string_t::npos)14496start != 0;14497// set the beginning of the next reference token14498// (will eventually be 0 if slash == string_t::npos)14499start = (slash == string_t::npos) ? 0 : slash + 1,14500// find next slash14501slash = reference_string.find_first_of('/', start))14502{14503// use the text between the beginning of the reference token14504// (start) and the last slash (slash).14505auto reference_token = reference_string.substr(start, slash - start);1450614507// check reference tokens are properly escaped14508for (std::size_t pos = reference_token.find_first_of('~');14509pos != string_t::npos;14510pos = reference_token.find_first_of('~', pos + 1))14511{14512JSON_ASSERT(reference_token[pos] == '~');1451314514// ~ must be followed by 0 or 114515if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||14516(reference_token[pos + 1] != '0' &&14517reference_token[pos + 1] != '1')))14518{14519JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));14520}14521}1452214523// finally, store the reference token14524detail::unescape(reference_token);14525result.push_back(reference_token);14526}1452714528return result;14529}1453014531private:14532/*!14533@param[in] reference_string the reference string to the current value14534@param[in] value the value to consider14535@param[in,out] result the result object to insert values to1453614537@note Empty objects or arrays are flattened to `null`.14538*/14539template<typename BasicJsonType>14540static void flatten(const string_t& reference_string,14541const BasicJsonType& value,14542BasicJsonType& result)14543{14544switch (value.type())14545{14546case detail::value_t::array:14547{14548if (value.m_data.m_value.array->empty())14549{14550// flatten empty array as null14551result[reference_string] = nullptr;14552}14553else14554{14555// iterate array and use index as reference string14556for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)14557{14558flatten(detail::concat(reference_string, '/', std::to_string(i)),14559value.m_data.m_value.array->operator[](i), result);14560}14561}14562break;14563}1456414565case detail::value_t::object:14566{14567if (value.m_data.m_value.object->empty())14568{14569// flatten empty object as null14570result[reference_string] = nullptr;14571}14572else14573{14574// iterate object and use keys as reference string14575for (const auto& element : *value.m_data.m_value.object)14576{14577flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);14578}14579}14580break;14581}1458214583case detail::value_t::null:14584case detail::value_t::string:14585case detail::value_t::boolean:14586case detail::value_t::number_integer:14587case detail::value_t::number_unsigned:14588case detail::value_t::number_float:14589case detail::value_t::binary:14590case detail::value_t::discarded:14591default:14592{14593// add primitive value with its reference string14594result[reference_string] = value;14595break;14596}14597}14598}1459914600/*!14601@param[in] value flattened JSON1460214603@return unflattened JSON1460414605@throw parse_error.109 if array index is not a number14606@throw type_error.314 if value is not an object14607@throw type_error.315 if object values are not primitive14608@throw type_error.313 if value cannot be unflattened14609*/14610template<typename BasicJsonType>14611static BasicJsonType14612unflatten(const BasicJsonType& value)14613{14614if (JSON_HEDLEY_UNLIKELY(!value.is_object()))14615{14616JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));14617}1461814619BasicJsonType result;1462014621// iterate the JSON object values14622for (const auto& element : *value.m_data.m_value.object)14623{14624if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))14625{14626JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));14627}1462814629// assign value to reference pointed to by JSON pointer; Note that if14630// the JSON pointer is "" (i.e., points to the whole value), function14631// get_and_create returns a reference to result itself. An assignment14632// will then create a primitive value.14633json_pointer(element.first).get_and_create(result) = element.second;14634}1463514636return result;14637}1463814639// can't use conversion operator because of ambiguity14640json_pointer<string_t> convert() const&14641{14642json_pointer<string_t> result;14643result.reference_tokens = reference_tokens;14644return result;14645}1464614647json_pointer<string_t> convert()&&14648{14649json_pointer<string_t> result;14650result.reference_tokens = std::move(reference_tokens);14651return result;14652}1465314654public:14655#if JSON_HAS_THREE_WAY_COMPARISON14656/// @brief compares two JSON pointers for equality14657/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/14658template<typename RefStringTypeRhs>14659bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept14660{14661return reference_tokens == rhs.reference_tokens;14662}1466314664/// @brief compares JSON pointer and string for equality14665/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/14666JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))14667bool operator==(const string_t& rhs) const14668{14669return *this == json_pointer(rhs);14670}1467114672/// @brief 3-way compares two JSON pointers14673template<typename RefStringTypeRhs>14674std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*14675{14676return reference_tokens <=> rhs.reference_tokens; // *NOPAD*14677}14678#else14679/// @brief compares two JSON pointers for equality14680/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/14681template<typename RefStringTypeLhs, typename RefStringTypeRhs>14682// NOLINTNEXTLINE(readability-redundant-declaration)14683friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,14684const json_pointer<RefStringTypeRhs>& rhs) noexcept;1468514686/// @brief compares JSON pointer and string for equality14687/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/14688template<typename RefStringTypeLhs, typename StringType>14689// NOLINTNEXTLINE(readability-redundant-declaration)14690friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,14691const StringType& rhs);1469214693/// @brief compares string and JSON pointer for equality14694/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/14695template<typename RefStringTypeRhs, typename StringType>14696// NOLINTNEXTLINE(readability-redundant-declaration)14697friend bool operator==(const StringType& lhs,14698const json_pointer<RefStringTypeRhs>& rhs);1469914700/// @brief compares two JSON pointers for inequality14701/// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/14702template<typename RefStringTypeLhs, typename RefStringTypeRhs>14703// NOLINTNEXTLINE(readability-redundant-declaration)14704friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,14705const json_pointer<RefStringTypeRhs>& rhs) noexcept;1470614707/// @brief compares JSON pointer and string for inequality14708/// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/14709template<typename RefStringTypeLhs, typename StringType>14710// NOLINTNEXTLINE(readability-redundant-declaration)14711friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,14712const StringType& rhs);1471314714/// @brief compares string and JSON pointer for inequality14715/// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/14716template<typename RefStringTypeRhs, typename StringType>14717// NOLINTNEXTLINE(readability-redundant-declaration)14718friend bool operator!=(const StringType& lhs,14719const json_pointer<RefStringTypeRhs>& rhs);1472014721/// @brief compares two JSON pointer for less-than14722template<typename RefStringTypeLhs, typename RefStringTypeRhs>14723// NOLINTNEXTLINE(readability-redundant-declaration)14724friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs,14725const json_pointer<RefStringTypeRhs>& rhs) noexcept;14726#endif1472714728private:14729/// the reference tokens14730std::vector<string_t> reference_tokens;14731};1473214733#if !JSON_HAS_THREE_WAY_COMPARISON14734// functions cannot be defined inside class due to ODR violations14735template<typename RefStringTypeLhs, typename RefStringTypeRhs>14736inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,14737const json_pointer<RefStringTypeRhs>& rhs) noexcept14738{14739return lhs.reference_tokens == rhs.reference_tokens;14740}1474114742template<typename RefStringTypeLhs,14743typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>14744JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))14745inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,14746const StringType& rhs)14747{14748return lhs == json_pointer<RefStringTypeLhs>(rhs);14749}1475014751template<typename RefStringTypeRhs,14752typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>14753JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))14754inline bool operator==(const StringType& lhs,14755const json_pointer<RefStringTypeRhs>& rhs)14756{14757return json_pointer<RefStringTypeRhs>(lhs) == rhs;14758}1475914760template<typename RefStringTypeLhs, typename RefStringTypeRhs>14761inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,14762const json_pointer<RefStringTypeRhs>& rhs) noexcept14763{14764return !(lhs == rhs);14765}1476614767template<typename RefStringTypeLhs,14768typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>14769JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))14770inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,14771const StringType& rhs)14772{14773return !(lhs == rhs);14774}1477514776template<typename RefStringTypeRhs,14777typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>14778JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))14779inline bool operator!=(const StringType& lhs,14780const json_pointer<RefStringTypeRhs>& rhs)14781{14782return !(lhs == rhs);14783}1478414785template<typename RefStringTypeLhs, typename RefStringTypeRhs>14786inline bool operator<(const json_pointer<RefStringTypeLhs>& lhs,14787const json_pointer<RefStringTypeRhs>& rhs) noexcept14788{14789return lhs.reference_tokens < rhs.reference_tokens;14790}14791#endif1479214793NLOHMANN_JSON_NAMESPACE_END1479414795// #include <nlohmann/detail/json_ref.hpp>14796// __ _____ _____ _____14797// __| | __| | | | JSON for Modern C++14798// | | |__ | | | | | | version 3.11.314799// |_____|_____|_____|_|___| https://github.com/nlohmann/json14800//14801// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>14802// SPDX-License-Identifier: MIT14803148041480514806#include <initializer_list>14807#include <utility>1480814809// #include <nlohmann/detail/abi_macros.hpp>1481014811// #include <nlohmann/detail/meta/type_traits.hpp>148121481314814NLOHMANN_JSON_NAMESPACE_BEGIN14815namespace detail14816{1481714818template<typename BasicJsonType>14819class json_ref14820{14821public:14822using value_type = BasicJsonType;1482314824json_ref(value_type&& value)14825: owned_value(std::move(value))14826{}1482714828json_ref(const value_type& value)14829: value_ref(&value)14830{}1483114832json_ref(std::initializer_list<json_ref> init)14833: owned_value(init)14834{}1483514836template <14837class... Args,14838enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >14839json_ref(Args && ... args)14840: owned_value(std::forward<Args>(args)...)14841{}1484214843// class should be movable only14844json_ref(json_ref&&) noexcept = default;14845json_ref(const json_ref&) = delete;14846json_ref& operator=(const json_ref&) = delete;14847json_ref& operator=(json_ref&&) = delete;14848~json_ref() = default;1484914850value_type moved_or_copied() const14851{14852if (value_ref == nullptr)14853{14854return std::move(owned_value);14855}14856return *value_ref;14857}1485814859value_type const& operator*() const14860{14861return value_ref ? *value_ref : owned_value;14862}1486314864value_type const* operator->() const14865{14866return &** this;14867}1486814869private:14870mutable value_type owned_value = nullptr;14871value_type const* value_ref = nullptr;14872};1487314874} // namespace detail14875NLOHMANN_JSON_NAMESPACE_END1487614877// #include <nlohmann/detail/macro_scope.hpp>1487814879// #include <nlohmann/detail/string_concat.hpp>1488014881// #include <nlohmann/detail/string_escape.hpp>1488214883// #include <nlohmann/detail/meta/cpp_future.hpp>1488414885// #include <nlohmann/detail/meta/type_traits.hpp>1488614887// #include <nlohmann/detail/output/binary_writer.hpp>14888// __ _____ _____ _____14889// __| | __| | | | JSON for Modern C++14890// | | |__ | | | | | | version 3.11.314891// |_____|_____|_____|_|___| https://github.com/nlohmann/json14892//14893// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>14894// SPDX-License-Identifier: MIT14895148961489714898#include <algorithm> // reverse14899#include <array> // array14900#include <map> // map14901#include <cmath> // isnan, isinf14902#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t14903#include <cstring> // memcpy14904#include <limits> // numeric_limits14905#include <string> // string14906#include <utility> // move14907#include <vector> // vector1490814909// #include <nlohmann/detail/input/binary_reader.hpp>1491014911// #include <nlohmann/detail/macro_scope.hpp>1491214913// #include <nlohmann/detail/output/output_adapters.hpp>14914// __ _____ _____ _____14915// __| | __| | | | JSON for Modern C++14916// | | |__ | | | | | | version 3.11.314917// |_____|_____|_____|_|___| https://github.com/nlohmann/json14918//14919// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>14920// SPDX-License-Identifier: MIT14921149221492314924#include <algorithm> // copy14925#include <cstddef> // size_t14926#include <iterator> // back_inserter14927#include <memory> // shared_ptr, make_shared14928#include <string> // basic_string14929#include <vector> // vector1493014931#ifndef JSON_NO_IO14932#include <ios> // streamsize14933#include <ostream> // basic_ostream14934#endif // JSON_NO_IO1493514936// #include <nlohmann/detail/macro_scope.hpp>149371493814939NLOHMANN_JSON_NAMESPACE_BEGIN14940namespace detail14941{1494214943/// abstract output adapter interface14944template<typename CharType> struct output_adapter_protocol14945{14946virtual void write_character(CharType c) = 0;14947virtual void write_characters(const CharType* s, std::size_t length) = 0;14948virtual ~output_adapter_protocol() = default;1494914950output_adapter_protocol() = default;14951output_adapter_protocol(const output_adapter_protocol&) = default;14952output_adapter_protocol(output_adapter_protocol&&) noexcept = default;14953output_adapter_protocol& operator=(const output_adapter_protocol&) = default;14954output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;14955};1495614957/// a type to simplify interfaces14958template<typename CharType>14959using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;1496014961/// output adapter for byte vectors14962template<typename CharType, typename AllocatorType = std::allocator<CharType>>14963class output_vector_adapter : public output_adapter_protocol<CharType>14964{14965public:14966explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept14967: v(vec)14968{}1496914970void write_character(CharType c) override14971{14972v.push_back(c);14973}1497414975JSON_HEDLEY_NON_NULL(2)14976void write_characters(const CharType* s, std::size_t length) override14977{14978v.insert(v.end(), s, s + length);14979}1498014981private:14982std::vector<CharType, AllocatorType>& v;14983};1498414985#ifndef JSON_NO_IO14986/// output adapter for output streams14987template<typename CharType>14988class output_stream_adapter : public output_adapter_protocol<CharType>14989{14990public:14991explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept14992: stream(s)14993{}1499414995void write_character(CharType c) override14996{14997stream.put(c);14998}1499915000JSON_HEDLEY_NON_NULL(2)15001void write_characters(const CharType* s, std::size_t length) override15002{15003stream.write(s, static_cast<std::streamsize>(length));15004}1500515006private:15007std::basic_ostream<CharType>& stream;15008};15009#endif // JSON_NO_IO1501015011/// output adapter for basic_string15012template<typename CharType, typename StringType = std::basic_string<CharType>>15013class output_string_adapter : public output_adapter_protocol<CharType>15014{15015public:15016explicit output_string_adapter(StringType& s) noexcept15017: str(s)15018{}1501915020void write_character(CharType c) override15021{15022str.push_back(c);15023}1502415025JSON_HEDLEY_NON_NULL(2)15026void write_characters(const CharType* s, std::size_t length) override15027{15028str.append(s, length);15029}1503015031private:15032StringType& str;15033};1503415035template<typename CharType, typename StringType = std::basic_string<CharType>>15036class output_adapter15037{15038public:15039template<typename AllocatorType = std::allocator<CharType>>15040output_adapter(std::vector<CharType, AllocatorType>& vec)15041: oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}1504215043#ifndef JSON_NO_IO15044output_adapter(std::basic_ostream<CharType>& s)15045: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}15046#endif // JSON_NO_IO1504715048output_adapter(StringType& s)15049: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}1505015051operator output_adapter_t<CharType>()15052{15053return oa;15054}1505515056private:15057output_adapter_t<CharType> oa = nullptr;15058};1505915060} // namespace detail15061NLOHMANN_JSON_NAMESPACE_END1506215063// #include <nlohmann/detail/string_concat.hpp>150641506515066NLOHMANN_JSON_NAMESPACE_BEGIN15067namespace detail15068{1506915070///////////////////15071// binary writer //15072///////////////////1507315074/*!15075@brief serialization to CBOR and MessagePack values15076*/15077template<typename BasicJsonType, typename CharType>15078class binary_writer15079{15080using string_t = typename BasicJsonType::string_t;15081using binary_t = typename BasicJsonType::binary_t;15082using number_float_t = typename BasicJsonType::number_float_t;1508315084public:15085/*!15086@brief create a binary writer1508715088@param[in] adapter output adapter to write to15089*/15090explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))15091{15092JSON_ASSERT(oa);15093}1509415095/*!15096@param[in] j JSON value to serialize15097@pre j.type() == value_t::object15098*/15099void write_bson(const BasicJsonType& j)15100{15101switch (j.type())15102{15103case value_t::object:15104{15105write_bson_object(*j.m_data.m_value.object);15106break;15107}1510815109case value_t::null:15110case value_t::array:15111case value_t::string:15112case value_t::boolean:15113case value_t::number_integer:15114case value_t::number_unsigned:15115case value_t::number_float:15116case value_t::binary:15117case value_t::discarded:15118default:15119{15120JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));15121}15122}15123}1512415125/*!15126@param[in] j JSON value to serialize15127*/15128void write_cbor(const BasicJsonType& j)15129{15130switch (j.type())15131{15132case value_t::null:15133{15134oa->write_character(to_char_type(0xF6));15135break;15136}1513715138case value_t::boolean:15139{15140oa->write_character(j.m_data.m_value.boolean15141? to_char_type(0xF5)15142: to_char_type(0xF4));15143break;15144}1514515146case value_t::number_integer:15147{15148if (j.m_data.m_value.number_integer >= 0)15149{15150// CBOR does not differentiate between positive signed15151// integers and unsigned integers. Therefore, we used the15152// code from the value_t::number_unsigned case here.15153if (j.m_data.m_value.number_integer <= 0x17)15154{15155write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));15156}15157else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())15158{15159oa->write_character(to_char_type(0x18));15160write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));15161}15162else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())15163{15164oa->write_character(to_char_type(0x19));15165write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));15166}15167else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())15168{15169oa->write_character(to_char_type(0x1A));15170write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));15171}15172else15173{15174oa->write_character(to_char_type(0x1B));15175write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));15176}15177}15178else15179{15180// The conversions below encode the sign in the first15181// byte, and the value is converted to a positive number.15182const auto positive_number = -1 - j.m_data.m_value.number_integer;15183if (j.m_data.m_value.number_integer >= -24)15184{15185write_number(static_cast<std::uint8_t>(0x20 + positive_number));15186}15187else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())15188{15189oa->write_character(to_char_type(0x38));15190write_number(static_cast<std::uint8_t>(positive_number));15191}15192else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())15193{15194oa->write_character(to_char_type(0x39));15195write_number(static_cast<std::uint16_t>(positive_number));15196}15197else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())15198{15199oa->write_character(to_char_type(0x3A));15200write_number(static_cast<std::uint32_t>(positive_number));15201}15202else15203{15204oa->write_character(to_char_type(0x3B));15205write_number(static_cast<std::uint64_t>(positive_number));15206}15207}15208break;15209}1521015211case value_t::number_unsigned:15212{15213if (j.m_data.m_value.number_unsigned <= 0x17)15214{15215write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));15216}15217else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())15218{15219oa->write_character(to_char_type(0x18));15220write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));15221}15222else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())15223{15224oa->write_character(to_char_type(0x19));15225write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));15226}15227else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())15228{15229oa->write_character(to_char_type(0x1A));15230write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));15231}15232else15233{15234oa->write_character(to_char_type(0x1B));15235write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));15236}15237break;15238}1523915240case value_t::number_float:15241{15242if (std::isnan(j.m_data.m_value.number_float))15243{15244// NaN is 0xf97e00 in CBOR15245oa->write_character(to_char_type(0xF9));15246oa->write_character(to_char_type(0x7E));15247oa->write_character(to_char_type(0x00));15248}15249else if (std::isinf(j.m_data.m_value.number_float))15250{15251// Infinity is 0xf97c00, -Infinity is 0xf9fc0015252oa->write_character(to_char_type(0xf9));15253oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));15254oa->write_character(to_char_type(0x00));15255}15256else15257{15258write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::cbor);15259}15260break;15261}1526215263case value_t::string:15264{15265// step 1: write control byte and the string length15266const auto N = j.m_data.m_value.string->size();15267if (N <= 0x17)15268{15269write_number(static_cast<std::uint8_t>(0x60 + N));15270}15271else if (N <= (std::numeric_limits<std::uint8_t>::max)())15272{15273oa->write_character(to_char_type(0x78));15274write_number(static_cast<std::uint8_t>(N));15275}15276else if (N <= (std::numeric_limits<std::uint16_t>::max)())15277{15278oa->write_character(to_char_type(0x79));15279write_number(static_cast<std::uint16_t>(N));15280}15281else if (N <= (std::numeric_limits<std::uint32_t>::max)())15282{15283oa->write_character(to_char_type(0x7A));15284write_number(static_cast<std::uint32_t>(N));15285}15286// LCOV_EXCL_START15287else if (N <= (std::numeric_limits<std::uint64_t>::max)())15288{15289oa->write_character(to_char_type(0x7B));15290write_number(static_cast<std::uint64_t>(N));15291}15292// LCOV_EXCL_STOP1529315294// step 2: write the string15295oa->write_characters(15296reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),15297j.m_data.m_value.string->size());15298break;15299}1530015301case value_t::array:15302{15303// step 1: write control byte and the array size15304const auto N = j.m_data.m_value.array->size();15305if (N <= 0x17)15306{15307write_number(static_cast<std::uint8_t>(0x80 + N));15308}15309else if (N <= (std::numeric_limits<std::uint8_t>::max)())15310{15311oa->write_character(to_char_type(0x98));15312write_number(static_cast<std::uint8_t>(N));15313}15314else if (N <= (std::numeric_limits<std::uint16_t>::max)())15315{15316oa->write_character(to_char_type(0x99));15317write_number(static_cast<std::uint16_t>(N));15318}15319else if (N <= (std::numeric_limits<std::uint32_t>::max)())15320{15321oa->write_character(to_char_type(0x9A));15322write_number(static_cast<std::uint32_t>(N));15323}15324// LCOV_EXCL_START15325else if (N <= (std::numeric_limits<std::uint64_t>::max)())15326{15327oa->write_character(to_char_type(0x9B));15328write_number(static_cast<std::uint64_t>(N));15329}15330// LCOV_EXCL_STOP1533115332// step 2: write each element15333for (const auto& el : *j.m_data.m_value.array)15334{15335write_cbor(el);15336}15337break;15338}1533915340case value_t::binary:15341{15342if (j.m_data.m_value.binary->has_subtype())15343{15344if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())15345{15346write_number(static_cast<std::uint8_t>(0xd8));15347write_number(static_cast<std::uint8_t>(j.m_data.m_value.binary->subtype()));15348}15349else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())15350{15351write_number(static_cast<std::uint8_t>(0xd9));15352write_number(static_cast<std::uint16_t>(j.m_data.m_value.binary->subtype()));15353}15354else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())15355{15356write_number(static_cast<std::uint8_t>(0xda));15357write_number(static_cast<std::uint32_t>(j.m_data.m_value.binary->subtype()));15358}15359else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())15360{15361write_number(static_cast<std::uint8_t>(0xdb));15362write_number(static_cast<std::uint64_t>(j.m_data.m_value.binary->subtype()));15363}15364}1536515366// step 1: write control byte and the binary array size15367const auto N = j.m_data.m_value.binary->size();15368if (N <= 0x17)15369{15370write_number(static_cast<std::uint8_t>(0x40 + N));15371}15372else if (N <= (std::numeric_limits<std::uint8_t>::max)())15373{15374oa->write_character(to_char_type(0x58));15375write_number(static_cast<std::uint8_t>(N));15376}15377else if (N <= (std::numeric_limits<std::uint16_t>::max)())15378{15379oa->write_character(to_char_type(0x59));15380write_number(static_cast<std::uint16_t>(N));15381}15382else if (N <= (std::numeric_limits<std::uint32_t>::max)())15383{15384oa->write_character(to_char_type(0x5A));15385write_number(static_cast<std::uint32_t>(N));15386}15387// LCOV_EXCL_START15388else if (N <= (std::numeric_limits<std::uint64_t>::max)())15389{15390oa->write_character(to_char_type(0x5B));15391write_number(static_cast<std::uint64_t>(N));15392}15393// LCOV_EXCL_STOP1539415395// step 2: write each element15396oa->write_characters(15397reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),15398N);1539915400break;15401}1540215403case value_t::object:15404{15405// step 1: write control byte and the object size15406const auto N = j.m_data.m_value.object->size();15407if (N <= 0x17)15408{15409write_number(static_cast<std::uint8_t>(0xA0 + N));15410}15411else if (N <= (std::numeric_limits<std::uint8_t>::max)())15412{15413oa->write_character(to_char_type(0xB8));15414write_number(static_cast<std::uint8_t>(N));15415}15416else if (N <= (std::numeric_limits<std::uint16_t>::max)())15417{15418oa->write_character(to_char_type(0xB9));15419write_number(static_cast<std::uint16_t>(N));15420}15421else if (N <= (std::numeric_limits<std::uint32_t>::max)())15422{15423oa->write_character(to_char_type(0xBA));15424write_number(static_cast<std::uint32_t>(N));15425}15426// LCOV_EXCL_START15427else if (N <= (std::numeric_limits<std::uint64_t>::max)())15428{15429oa->write_character(to_char_type(0xBB));15430write_number(static_cast<std::uint64_t>(N));15431}15432// LCOV_EXCL_STOP1543315434// step 2: write each element15435for (const auto& el : *j.m_data.m_value.object)15436{15437write_cbor(el.first);15438write_cbor(el.second);15439}15440break;15441}1544215443case value_t::discarded:15444default:15445break;15446}15447}1544815449/*!15450@param[in] j JSON value to serialize15451*/15452void write_msgpack(const BasicJsonType& j)15453{15454switch (j.type())15455{15456case value_t::null: // nil15457{15458oa->write_character(to_char_type(0xC0));15459break;15460}1546115462case value_t::boolean: // true and false15463{15464oa->write_character(j.m_data.m_value.boolean15465? to_char_type(0xC3)15466: to_char_type(0xC2));15467break;15468}1546915470case value_t::number_integer:15471{15472if (j.m_data.m_value.number_integer >= 0)15473{15474// MessagePack does not differentiate between positive15475// signed integers and unsigned integers. Therefore, we used15476// the code from the value_t::number_unsigned case here.15477if (j.m_data.m_value.number_unsigned < 128)15478{15479// positive fixnum15480write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));15481}15482else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())15483{15484// uint 815485oa->write_character(to_char_type(0xCC));15486write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));15487}15488else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())15489{15490// uint 1615491oa->write_character(to_char_type(0xCD));15492write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));15493}15494else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())15495{15496// uint 3215497oa->write_character(to_char_type(0xCE));15498write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));15499}15500else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())15501{15502// uint 6415503oa->write_character(to_char_type(0xCF));15504write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));15505}15506}15507else15508{15509if (j.m_data.m_value.number_integer >= -32)15510{15511// negative fixnum15512write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));15513}15514else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&15515j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())15516{15517// int 815518oa->write_character(to_char_type(0xD0));15519write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));15520}15521else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&15522j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())15523{15524// int 1615525oa->write_character(to_char_type(0xD1));15526write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));15527}15528else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&15529j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())15530{15531// int 3215532oa->write_character(to_char_type(0xD2));15533write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));15534}15535else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&15536j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())15537{15538// int 6415539oa->write_character(to_char_type(0xD3));15540write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));15541}15542}15543break;15544}1554515546case value_t::number_unsigned:15547{15548if (j.m_data.m_value.number_unsigned < 128)15549{15550// positive fixnum15551write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));15552}15553else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())15554{15555// uint 815556oa->write_character(to_char_type(0xCC));15557write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));15558}15559else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())15560{15561// uint 1615562oa->write_character(to_char_type(0xCD));15563write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));15564}15565else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())15566{15567// uint 3215568oa->write_character(to_char_type(0xCE));15569write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));15570}15571else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())15572{15573// uint 6415574oa->write_character(to_char_type(0xCF));15575write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));15576}15577break;15578}1557915580case value_t::number_float:15581{15582write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::msgpack);15583break;15584}1558515586case value_t::string:15587{15588// step 1: write control byte and the string length15589const auto N = j.m_data.m_value.string->size();15590if (N <= 31)15591{15592// fixstr15593write_number(static_cast<std::uint8_t>(0xA0 | N));15594}15595else if (N <= (std::numeric_limits<std::uint8_t>::max)())15596{15597// str 815598oa->write_character(to_char_type(0xD9));15599write_number(static_cast<std::uint8_t>(N));15600}15601else if (N <= (std::numeric_limits<std::uint16_t>::max)())15602{15603// str 1615604oa->write_character(to_char_type(0xDA));15605write_number(static_cast<std::uint16_t>(N));15606}15607else if (N <= (std::numeric_limits<std::uint32_t>::max)())15608{15609// str 3215610oa->write_character(to_char_type(0xDB));15611write_number(static_cast<std::uint32_t>(N));15612}1561315614// step 2: write the string15615oa->write_characters(15616reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),15617j.m_data.m_value.string->size());15618break;15619}1562015621case value_t::array:15622{15623// step 1: write control byte and the array size15624const auto N = j.m_data.m_value.array->size();15625if (N <= 15)15626{15627// fixarray15628write_number(static_cast<std::uint8_t>(0x90 | N));15629}15630else if (N <= (std::numeric_limits<std::uint16_t>::max)())15631{15632// array 1615633oa->write_character(to_char_type(0xDC));15634write_number(static_cast<std::uint16_t>(N));15635}15636else if (N <= (std::numeric_limits<std::uint32_t>::max)())15637{15638// array 3215639oa->write_character(to_char_type(0xDD));15640write_number(static_cast<std::uint32_t>(N));15641}1564215643// step 2: write each element15644for (const auto& el : *j.m_data.m_value.array)15645{15646write_msgpack(el);15647}15648break;15649}1565015651case value_t::binary:15652{15653// step 0: determine if the binary type has a set subtype to15654// determine whether or not to use the ext or fixext types15655const bool use_ext = j.m_data.m_value.binary->has_subtype();1565615657// step 1: write control byte and the byte string length15658const auto N = j.m_data.m_value.binary->size();15659if (N <= (std::numeric_limits<std::uint8_t>::max)())15660{15661std::uint8_t output_type{};15662bool fixed = true;15663if (use_ext)15664{15665switch (N)15666{15667case 1:15668output_type = 0xD4; // fixext 115669break;15670case 2:15671output_type = 0xD5; // fixext 215672break;15673case 4:15674output_type = 0xD6; // fixext 415675break;15676case 8:15677output_type = 0xD7; // fixext 815678break;15679case 16:15680output_type = 0xD8; // fixext 1615681break;15682default:15683output_type = 0xC7; // ext 815684fixed = false;15685break;15686}1568715688}15689else15690{15691output_type = 0xC4; // bin 815692fixed = false;15693}1569415695oa->write_character(to_char_type(output_type));15696if (!fixed)15697{15698write_number(static_cast<std::uint8_t>(N));15699}15700}15701else if (N <= (std::numeric_limits<std::uint16_t>::max)())15702{15703const std::uint8_t output_type = use_ext15704? 0xC8 // ext 1615705: 0xC5; // bin 161570615707oa->write_character(to_char_type(output_type));15708write_number(static_cast<std::uint16_t>(N));15709}15710else if (N <= (std::numeric_limits<std::uint32_t>::max)())15711{15712const std::uint8_t output_type = use_ext15713? 0xC9 // ext 3215714: 0xC6; // bin 321571515716oa->write_character(to_char_type(output_type));15717write_number(static_cast<std::uint32_t>(N));15718}1571915720// step 1.5: if this is an ext type, write the subtype15721if (use_ext)15722{15723write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));15724}1572515726// step 2: write the byte string15727oa->write_characters(15728reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),15729N);1573015731break;15732}1573315734case value_t::object:15735{15736// step 1: write control byte and the object size15737const auto N = j.m_data.m_value.object->size();15738if (N <= 15)15739{15740// fixmap15741write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));15742}15743else if (N <= (std::numeric_limits<std::uint16_t>::max)())15744{15745// map 1615746oa->write_character(to_char_type(0xDE));15747write_number(static_cast<std::uint16_t>(N));15748}15749else if (N <= (std::numeric_limits<std::uint32_t>::max)())15750{15751// map 3215752oa->write_character(to_char_type(0xDF));15753write_number(static_cast<std::uint32_t>(N));15754}1575515756// step 2: write each element15757for (const auto& el : *j.m_data.m_value.object)15758{15759write_msgpack(el.first);15760write_msgpack(el.second);15761}15762break;15763}1576415765case value_t::discarded:15766default:15767break;15768}15769}1577015771/*!15772@param[in] j JSON value to serialize15773@param[in] use_count whether to use '#' prefixes (optimized format)15774@param[in] use_type whether to use '$' prefixes (optimized format)15775@param[in] add_prefix whether prefixes need to be used for this value15776@param[in] use_bjdata whether write in BJData format, default is false15777*/15778void write_ubjson(const BasicJsonType& j, const bool use_count,15779const bool use_type, const bool add_prefix = true,15780const bool use_bjdata = false)15781{15782switch (j.type())15783{15784case value_t::null:15785{15786if (add_prefix)15787{15788oa->write_character(to_char_type('Z'));15789}15790break;15791}1579215793case value_t::boolean:15794{15795if (add_prefix)15796{15797oa->write_character(j.m_data.m_value.boolean15798? to_char_type('T')15799: to_char_type('F'));15800}15801break;15802}1580315804case value_t::number_integer:15805{15806write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);15807break;15808}1580915810case value_t::number_unsigned:15811{15812write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);15813break;15814}1581515816case value_t::number_float:15817{15818write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);15819break;15820}1582115822case value_t::string:15823{15824if (add_prefix)15825{15826oa->write_character(to_char_type('S'));15827}15828write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);15829oa->write_characters(15830reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),15831j.m_data.m_value.string->size());15832break;15833}1583415835case value_t::array:15836{15837if (add_prefix)15838{15839oa->write_character(to_char_type('['));15840}1584115842bool prefix_required = true;15843if (use_type && !j.m_data.m_value.array->empty())15844{15845JSON_ASSERT(use_count);15846const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);15847const bool same_prefix = std::all_of(j.begin() + 1, j.end(),15848[this, first_prefix, use_bjdata](const BasicJsonType & v)15849{15850return ubjson_prefix(v, use_bjdata) == first_prefix;15851});1585215853std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type1585415855if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))15856{15857prefix_required = false;15858oa->write_character(to_char_type('$'));15859oa->write_character(first_prefix);15860}15861}1586215863if (use_count)15864{15865oa->write_character(to_char_type('#'));15866write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);15867}1586815869for (const auto& el : *j.m_data.m_value.array)15870{15871write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);15872}1587315874if (!use_count)15875{15876oa->write_character(to_char_type(']'));15877}1587815879break;15880}1588115882case value_t::binary:15883{15884if (add_prefix)15885{15886oa->write_character(to_char_type('['));15887}1588815889if (use_type && !j.m_data.m_value.binary->empty())15890{15891JSON_ASSERT(use_count);15892oa->write_character(to_char_type('$'));15893oa->write_character('U');15894}1589515896if (use_count)15897{15898oa->write_character(to_char_type('#'));15899write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);15900}1590115902if (use_type)15903{15904oa->write_characters(15905reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),15906j.m_data.m_value.binary->size());15907}15908else15909{15910for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)15911{15912oa->write_character(to_char_type('U'));15913oa->write_character(j.m_data.m_value.binary->data()[i]);15914}15915}1591615917if (!use_count)15918{15919oa->write_character(to_char_type(']'));15920}1592115922break;15923}1592415925case value_t::object:15926{15927if (use_bjdata && j.m_data.m_value.object->size() == 3 && j.m_data.m_value.object->find("_ArrayType_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArraySize_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArrayData_") != j.m_data.m_value.object->end())15928{15929if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)15930{15931break;15932}15933}1593415935if (add_prefix)15936{15937oa->write_character(to_char_type('{'));15938}1593915940bool prefix_required = true;15941if (use_type && !j.m_data.m_value.object->empty())15942{15943JSON_ASSERT(use_count);15944const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);15945const bool same_prefix = std::all_of(j.begin(), j.end(),15946[this, first_prefix, use_bjdata](const BasicJsonType & v)15947{15948return ubjson_prefix(v, use_bjdata) == first_prefix;15949});1595015951std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type1595215953if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))15954{15955prefix_required = false;15956oa->write_character(to_char_type('$'));15957oa->write_character(first_prefix);15958}15959}1596015961if (use_count)15962{15963oa->write_character(to_char_type('#'));15964write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);15965}1596615967for (const auto& el : *j.m_data.m_value.object)15968{15969write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);15970oa->write_characters(15971reinterpret_cast<const CharType*>(el.first.c_str()),15972el.first.size());15973write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);15974}1597515976if (!use_count)15977{15978oa->write_character(to_char_type('}'));15979}1598015981break;15982}1598315984case value_t::discarded:15985default:15986break;15987}15988}1598915990private:15991//////////15992// BSON //15993//////////1599415995/*!15996@return The size of a BSON document entry header, including the id marker15997and the entry name size (and its null-terminator).15998*/15999static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)16000{16001const auto it = name.find(static_cast<typename string_t::value_type>(0));16002if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))16003{16004JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));16005static_cast<void>(j);16006}1600716008return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;16009}1601016011/*!16012@brief Writes the given @a element_type and @a name to the output adapter16013*/16014void write_bson_entry_header(const string_t& name,16015const std::uint8_t element_type)16016{16017oa->write_character(to_char_type(element_type)); // boolean16018oa->write_characters(16019reinterpret_cast<const CharType*>(name.c_str()),16020name.size() + 1u);16021}1602216023/*!16024@brief Writes a BSON element with key @a name and boolean value @a value16025*/16026void write_bson_boolean(const string_t& name,16027const bool value)16028{16029write_bson_entry_header(name, 0x08);16030oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));16031}1603216033/*!16034@brief Writes a BSON element with key @a name and double value @a value16035*/16036void write_bson_double(const string_t& name,16037const double value)16038{16039write_bson_entry_header(name, 0x01);16040write_number<double>(value, true);16041}1604216043/*!16044@return The size of the BSON-encoded string in @a value16045*/16046static std::size_t calc_bson_string_size(const string_t& value)16047{16048return sizeof(std::int32_t) + value.size() + 1ul;16049}1605016051/*!16052@brief Writes a BSON element with key @a name and string value @a value16053*/16054void write_bson_string(const string_t& name,16055const string_t& value)16056{16057write_bson_entry_header(name, 0x02);1605816059write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);16060oa->write_characters(16061reinterpret_cast<const CharType*>(value.c_str()),16062value.size() + 1);16063}1606416065/*!16066@brief Writes a BSON element with key @a name and null value16067*/16068void write_bson_null(const string_t& name)16069{16070write_bson_entry_header(name, 0x0A);16071}1607216073/*!16074@return The size of the BSON-encoded integer @a value16075*/16076static std::size_t calc_bson_integer_size(const std::int64_t value)16077{16078return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()16079? sizeof(std::int32_t)16080: sizeof(std::int64_t);16081}1608216083/*!16084@brief Writes a BSON element with key @a name and integer @a value16085*/16086void write_bson_integer(const string_t& name,16087const std::int64_t value)16088{16089if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())16090{16091write_bson_entry_header(name, 0x10); // int3216092write_number<std::int32_t>(static_cast<std::int32_t>(value), true);16093}16094else16095{16096write_bson_entry_header(name, 0x12); // int6416097write_number<std::int64_t>(static_cast<std::int64_t>(value), true);16098}16099}1610016101/*!16102@return The size of the BSON-encoded unsigned integer in @a j16103*/16104static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept16105{16106return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))16107? sizeof(std::int32_t)16108: sizeof(std::int64_t);16109}1611016111/*!16112@brief Writes a BSON element with key @a name and unsigned @a value16113*/16114void write_bson_unsigned(const string_t& name,16115const BasicJsonType& j)16116{16117if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))16118{16119write_bson_entry_header(name, 0x10 /* int32 */);16120write_number<std::int32_t>(static_cast<std::int32_t>(j.m_data.m_value.number_unsigned), true);16121}16122else if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))16123{16124write_bson_entry_header(name, 0x12 /* int64 */);16125write_number<std::int64_t>(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned), true);16126}16127else16128{16129JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));16130}16131}1613216133/*!16134@brief Writes a BSON element with key @a name and object @a value16135*/16136void write_bson_object_entry(const string_t& name,16137const typename BasicJsonType::object_t& value)16138{16139write_bson_entry_header(name, 0x03); // object16140write_bson_object(value);16141}1614216143/*!16144@return The size of the BSON-encoded array @a value16145*/16146static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)16147{16148std::size_t array_index = 0ul;1614916150const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)16151{16152return result + calc_bson_element_size(std::to_string(array_index++), el);16153});1615416155return sizeof(std::int32_t) + embedded_document_size + 1ul;16156}1615716158/*!16159@return The size of the BSON-encoded binary array @a value16160*/16161static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)16162{16163return sizeof(std::int32_t) + value.size() + 1ul;16164}1616516166/*!16167@brief Writes a BSON element with key @a name and array @a value16168*/16169void write_bson_array(const string_t& name,16170const typename BasicJsonType::array_t& value)16171{16172write_bson_entry_header(name, 0x04); // array16173write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);1617416175std::size_t array_index = 0ul;1617616177for (const auto& el : value)16178{16179write_bson_element(std::to_string(array_index++), el);16180}1618116182oa->write_character(to_char_type(0x00));16183}1618416185/*!16186@brief Writes a BSON element with key @a name and binary value @a value16187*/16188void write_bson_binary(const string_t& name,16189const binary_t& value)16190{16191write_bson_entry_header(name, 0x05);1619216193write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);16194write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));1619516196oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());16197}1619816199/*!16200@brief Calculates the size necessary to serialize the JSON value @a j with its @a name16201@return The calculated size for the BSON document entry for @a j with the given @a name.16202*/16203static std::size_t calc_bson_element_size(const string_t& name,16204const BasicJsonType& j)16205{16206const auto header_size = calc_bson_entry_header_size(name, j);16207switch (j.type())16208{16209case value_t::object:16210return header_size + calc_bson_object_size(*j.m_data.m_value.object);1621116212case value_t::array:16213return header_size + calc_bson_array_size(*j.m_data.m_value.array);1621416215case value_t::binary:16216return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);1621716218case value_t::boolean:16219return header_size + 1ul;1622016221case value_t::number_float:16222return header_size + 8ul;1622316224case value_t::number_integer:16225return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);1622616227case value_t::number_unsigned:16228return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);1622916230case value_t::string:16231return header_size + calc_bson_string_size(*j.m_data.m_value.string);1623216233case value_t::null:16234return header_size + 0ul;1623516236// LCOV_EXCL_START16237case value_t::discarded:16238default:16239JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)16240return 0ul;16241// LCOV_EXCL_STOP16242}16243}1624416245/*!16246@brief Serializes the JSON value @a j to BSON and associates it with the16247key @a name.16248@param name The name to associate with the JSON entity @a j within the16249current BSON document16250*/16251void write_bson_element(const string_t& name,16252const BasicJsonType& j)16253{16254switch (j.type())16255{16256case value_t::object:16257return write_bson_object_entry(name, *j.m_data.m_value.object);1625816259case value_t::array:16260return write_bson_array(name, *j.m_data.m_value.array);1626116262case value_t::binary:16263return write_bson_binary(name, *j.m_data.m_value.binary);1626416265case value_t::boolean:16266return write_bson_boolean(name, j.m_data.m_value.boolean);1626716268case value_t::number_float:16269return write_bson_double(name, j.m_data.m_value.number_float);1627016271case value_t::number_integer:16272return write_bson_integer(name, j.m_data.m_value.number_integer);1627316274case value_t::number_unsigned:16275return write_bson_unsigned(name, j);1627616277case value_t::string:16278return write_bson_string(name, *j.m_data.m_value.string);1627916280case value_t::null:16281return write_bson_null(name);1628216283// LCOV_EXCL_START16284case value_t::discarded:16285default:16286JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)16287return;16288// LCOV_EXCL_STOP16289}16290}1629116292/*!16293@brief Calculates the size of the BSON serialization of the given16294JSON-object @a j.16295@param[in] value JSON value to serialize16296@pre value.type() == value_t::object16297*/16298static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)16299{16300const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),16301[](size_t result, const typename BasicJsonType::object_t::value_type & el)16302{16303return result += calc_bson_element_size(el.first, el.second);16304});1630516306return sizeof(std::int32_t) + document_size + 1ul;16307}1630816309/*!16310@param[in] value JSON value to serialize16311@pre value.type() == value_t::object16312*/16313void write_bson_object(const typename BasicJsonType::object_t& value)16314{16315write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);1631616317for (const auto& el : value)16318{16319write_bson_element(el.first, el.second);16320}1632116322oa->write_character(to_char_type(0x00));16323}1632416325//////////16326// CBOR //16327//////////1632816329static constexpr CharType get_cbor_float_prefix(float /*unused*/)16330{16331return to_char_type(0xFA); // Single-Precision Float16332}1633316334static constexpr CharType get_cbor_float_prefix(double /*unused*/)16335{16336return to_char_type(0xFB); // Double-Precision Float16337}1633816339/////////////16340// MsgPack //16341/////////////1634216343static constexpr CharType get_msgpack_float_prefix(float /*unused*/)16344{16345return to_char_type(0xCA); // float 3216346}1634716348static constexpr CharType get_msgpack_float_prefix(double /*unused*/)16349{16350return to_char_type(0xCB); // float 6416351}1635216353////////////16354// UBJSON //16355////////////1635616357// UBJSON: write number (floating point)16358template<typename NumberType, typename std::enable_if<16359std::is_floating_point<NumberType>::value, int>::type = 0>16360void write_number_with_ubjson_prefix(const NumberType n,16361const bool add_prefix,16362const bool use_bjdata)16363{16364if (add_prefix)16365{16366oa->write_character(get_ubjson_float_prefix(n));16367}16368write_number(n, use_bjdata);16369}1637016371// UBJSON: write number (unsigned integer)16372template<typename NumberType, typename std::enable_if<16373std::is_unsigned<NumberType>::value, int>::type = 0>16374void write_number_with_ubjson_prefix(const NumberType n,16375const bool add_prefix,16376const bool use_bjdata)16377{16378if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))16379{16380if (add_prefix)16381{16382oa->write_character(to_char_type('i')); // int816383}16384write_number(static_cast<std::uint8_t>(n), use_bjdata);16385}16386else if (n <= (std::numeric_limits<std::uint8_t>::max)())16387{16388if (add_prefix)16389{16390oa->write_character(to_char_type('U')); // uint816391}16392write_number(static_cast<std::uint8_t>(n), use_bjdata);16393}16394else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))16395{16396if (add_prefix)16397{16398oa->write_character(to_char_type('I')); // int1616399}16400write_number(static_cast<std::int16_t>(n), use_bjdata);16401}16402else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))16403{16404if (add_prefix)16405{16406oa->write_character(to_char_type('u')); // uint16 - bjdata only16407}16408write_number(static_cast<std::uint16_t>(n), use_bjdata);16409}16410else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))16411{16412if (add_prefix)16413{16414oa->write_character(to_char_type('l')); // int3216415}16416write_number(static_cast<std::int32_t>(n), use_bjdata);16417}16418else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))16419{16420if (add_prefix)16421{16422oa->write_character(to_char_type('m')); // uint32 - bjdata only16423}16424write_number(static_cast<std::uint32_t>(n), use_bjdata);16425}16426else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))16427{16428if (add_prefix)16429{16430oa->write_character(to_char_type('L')); // int6416431}16432write_number(static_cast<std::int64_t>(n), use_bjdata);16433}16434else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())16435{16436if (add_prefix)16437{16438oa->write_character(to_char_type('M')); // uint64 - bjdata only16439}16440write_number(static_cast<std::uint64_t>(n), use_bjdata);16441}16442else16443{16444if (add_prefix)16445{16446oa->write_character(to_char_type('H')); // high-precision number16447}1644816449const auto number = BasicJsonType(n).dump();16450write_number_with_ubjson_prefix(number.size(), true, use_bjdata);16451for (std::size_t i = 0; i < number.size(); ++i)16452{16453oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));16454}16455}16456}1645716458// UBJSON: write number (signed integer)16459template < typename NumberType, typename std::enable_if <16460std::is_signed<NumberType>::value&&16461!std::is_floating_point<NumberType>::value, int >::type = 0 >16462void write_number_with_ubjson_prefix(const NumberType n,16463const bool add_prefix,16464const bool use_bjdata)16465{16466if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())16467{16468if (add_prefix)16469{16470oa->write_character(to_char_type('i')); // int816471}16472write_number(static_cast<std::int8_t>(n), use_bjdata);16473}16474else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))16475{16476if (add_prefix)16477{16478oa->write_character(to_char_type('U')); // uint816479}16480write_number(static_cast<std::uint8_t>(n), use_bjdata);16481}16482else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())16483{16484if (add_prefix)16485{16486oa->write_character(to_char_type('I')); // int1616487}16488write_number(static_cast<std::int16_t>(n), use_bjdata);16489}16490else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))16491{16492if (add_prefix)16493{16494oa->write_character(to_char_type('u')); // uint16 - bjdata only16495}16496write_number(static_cast<uint16_t>(n), use_bjdata);16497}16498else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())16499{16500if (add_prefix)16501{16502oa->write_character(to_char_type('l')); // int3216503}16504write_number(static_cast<std::int32_t>(n), use_bjdata);16505}16506else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))16507{16508if (add_prefix)16509{16510oa->write_character(to_char_type('m')); // uint32 - bjdata only16511}16512write_number(static_cast<uint32_t>(n), use_bjdata);16513}16514else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())16515{16516if (add_prefix)16517{16518oa->write_character(to_char_type('L')); // int6416519}16520write_number(static_cast<std::int64_t>(n), use_bjdata);16521}16522// LCOV_EXCL_START16523else16524{16525if (add_prefix)16526{16527oa->write_character(to_char_type('H')); // high-precision number16528}1652916530const auto number = BasicJsonType(n).dump();16531write_number_with_ubjson_prefix(number.size(), true, use_bjdata);16532for (std::size_t i = 0; i < number.size(); ++i)16533{16534oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));16535}16536}16537// LCOV_EXCL_STOP16538}1653916540/*!16541@brief determine the type prefix of container values16542*/16543CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept16544{16545switch (j.type())16546{16547case value_t::null:16548return 'Z';1654916550case value_t::boolean:16551return j.m_data.m_value.boolean ? 'T' : 'F';1655216553case value_t::number_integer:16554{16555if ((std::numeric_limits<std::int8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())16556{16557return 'i';16558}16559if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())16560{16561return 'U';16562}16563if ((std::numeric_limits<std::int16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())16564{16565return 'I';16566}16567if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))16568{16569return 'u';16570}16571if ((std::numeric_limits<std::int32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())16572{16573return 'l';16574}16575if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))16576{16577return 'm';16578}16579if ((std::numeric_limits<std::int64_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())16580{16581return 'L';16582}16583// anything else is treated as high-precision number16584return 'H'; // LCOV_EXCL_LINE16585}1658616587case value_t::number_unsigned:16588{16589if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))16590{16591return 'i';16592}16593if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))16594{16595return 'U';16596}16597if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))16598{16599return 'I';16600}16601if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))16602{16603return 'u';16604}16605if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))16606{16607return 'l';16608}16609if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))16610{16611return 'm';16612}16613if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))16614{16615return 'L';16616}16617if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())16618{16619return 'M';16620}16621// anything else is treated as high-precision number16622return 'H'; // LCOV_EXCL_LINE16623}1662416625case value_t::number_float:16626return get_ubjson_float_prefix(j.m_data.m_value.number_float);1662716628case value_t::string:16629return 'S';1663016631case value_t::array: // fallthrough16632case value_t::binary:16633return '[';1663416635case value_t::object:16636return '{';1663716638case value_t::discarded:16639default: // discarded values16640return 'N';16641}16642}1664316644static constexpr CharType get_ubjson_float_prefix(float /*unused*/)16645{16646return 'd'; // float 3216647}1664816649static constexpr CharType get_ubjson_float_prefix(double /*unused*/)16650{16651return 'D'; // float 6416652}1665316654/*!16655@return false if the object is successfully converted to a bjdata ndarray, true if the type or size is invalid16656*/16657bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)16658{16659std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},16660{"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}16661};1666216663string_t key = "_ArrayType_";16664auto it = bjdtype.find(static_cast<string_t>(value.at(key)));16665if (it == bjdtype.end())16666{16667return true;16668}16669CharType dtype = it->second;1667016671key = "_ArraySize_";16672std::size_t len = (value.at(key).empty() ? 0 : 1);16673for (const auto& el : value.at(key))16674{16675len *= static_cast<std::size_t>(el.m_data.m_value.number_unsigned);16676}1667716678key = "_ArrayData_";16679if (value.at(key).size() != len)16680{16681return true;16682}1668316684oa->write_character('[');16685oa->write_character('$');16686oa->write_character(dtype);16687oa->write_character('#');1668816689key = "_ArraySize_";16690write_ubjson(value.at(key), use_count, use_type, true, true);1669116692key = "_ArrayData_";16693if (dtype == 'U' || dtype == 'C')16694{16695for (const auto& el : value.at(key))16696{16697write_number(static_cast<std::uint8_t>(el.m_data.m_value.number_unsigned), true);16698}16699}16700else if (dtype == 'i')16701{16702for (const auto& el : value.at(key))16703{16704write_number(static_cast<std::int8_t>(el.m_data.m_value.number_integer), true);16705}16706}16707else if (dtype == 'u')16708{16709for (const auto& el : value.at(key))16710{16711write_number(static_cast<std::uint16_t>(el.m_data.m_value.number_unsigned), true);16712}16713}16714else if (dtype == 'I')16715{16716for (const auto& el : value.at(key))16717{16718write_number(static_cast<std::int16_t>(el.m_data.m_value.number_integer), true);16719}16720}16721else if (dtype == 'm')16722{16723for (const auto& el : value.at(key))16724{16725write_number(static_cast<std::uint32_t>(el.m_data.m_value.number_unsigned), true);16726}16727}16728else if (dtype == 'l')16729{16730for (const auto& el : value.at(key))16731{16732write_number(static_cast<std::int32_t>(el.m_data.m_value.number_integer), true);16733}16734}16735else if (dtype == 'M')16736{16737for (const auto& el : value.at(key))16738{16739write_number(static_cast<std::uint64_t>(el.m_data.m_value.number_unsigned), true);16740}16741}16742else if (dtype == 'L')16743{16744for (const auto& el : value.at(key))16745{16746write_number(static_cast<std::int64_t>(el.m_data.m_value.number_integer), true);16747}16748}16749else if (dtype == 'd')16750{16751for (const auto& el : value.at(key))16752{16753write_number(static_cast<float>(el.m_data.m_value.number_float), true);16754}16755}16756else if (dtype == 'D')16757{16758for (const auto& el : value.at(key))16759{16760write_number(static_cast<double>(el.m_data.m_value.number_float), true);16761}16762}16763return false;16764}1676516766///////////////////////16767// Utility functions //16768///////////////////////1676916770/*16771@brief write a number to output input16772@param[in] n number of type @a NumberType16773@param[in] OutputIsLittleEndian Set to true if output data is16774required to be little endian16775@tparam NumberType the type of the number1677616777@note This function needs to respect the system's endianness, because bytes16778in CBOR, MessagePack, and UBJSON are stored in network order (big16779endian) and therefore need reordering on little endian systems.16780On the other hand, BSON and BJData use little endian and should reorder16781on big endian systems.16782*/16783template<typename NumberType>16784void write_number(const NumberType n, const bool OutputIsLittleEndian = false)16785{16786// step 1: write number to array of length NumberType16787std::array<CharType, sizeof(NumberType)> vec{};16788std::memcpy(vec.data(), &n, sizeof(NumberType));1678916790// step 2: write array to output (with possible reordering)16791if (is_little_endian != OutputIsLittleEndian)16792{16793// reverse byte order prior to conversion if necessary16794std::reverse(vec.begin(), vec.end());16795}1679616797oa->write_characters(vec.data(), sizeof(NumberType));16798}1679916800void write_compact_float(const number_float_t n, detail::input_format_t format)16801{16802#ifdef __GNUC__16803#pragma GCC diagnostic push16804#pragma GCC diagnostic ignored "-Wfloat-equal"16805#endif16806if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&16807static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&16808static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))16809{16810oa->write_character(format == detail::input_format_t::cbor16811? get_cbor_float_prefix(static_cast<float>(n))16812: get_msgpack_float_prefix(static_cast<float>(n)));16813write_number(static_cast<float>(n));16814}16815else16816{16817oa->write_character(format == detail::input_format_t::cbor16818? get_cbor_float_prefix(n)16819: get_msgpack_float_prefix(n));16820write_number(n);16821}16822#ifdef __GNUC__16823#pragma GCC diagnostic pop16824#endif16825}1682616827public:16828// The following to_char_type functions are implement the conversion16829// between uint8_t and CharType. In case CharType is not unsigned,16830// such a conversion is required to allow values greater than 128.16831// See <https://github.com/nlohmann/json/issues/1286> for a discussion.16832template < typename C = CharType,16833enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >16834static constexpr CharType to_char_type(std::uint8_t x) noexcept16835{16836return *reinterpret_cast<char*>(&x);16837}1683816839template < typename C = CharType,16840enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >16841static CharType to_char_type(std::uint8_t x) noexcept16842{16843static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");16844static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");16845CharType result;16846std::memcpy(&result, &x, sizeof(x));16847return result;16848}1684916850template<typename C = CharType,16851enable_if_t<std::is_unsigned<C>::value>* = nullptr>16852static constexpr CharType to_char_type(std::uint8_t x) noexcept16853{16854return x;16855}1685616857template < typename InputCharType, typename C = CharType,16858enable_if_t <16859std::is_signed<C>::value &&16860std::is_signed<char>::value &&16861std::is_same<char, typename std::remove_cv<InputCharType>::type>::value16862> * = nullptr >16863static constexpr CharType to_char_type(InputCharType x) noexcept16864{16865return x;16866}1686716868private:16869/// whether we can assume little endianness16870const bool is_little_endian = little_endianness();1687116872/// the output16873output_adapter_t<CharType> oa = nullptr;16874};1687516876} // namespace detail16877NLOHMANN_JSON_NAMESPACE_END1687816879// #include <nlohmann/detail/output/output_adapters.hpp>1688016881// #include <nlohmann/detail/output/serializer.hpp>16882// __ _____ _____ _____16883// __| | __| | | | JSON for Modern C++16884// | | |__ | | | | | | version 3.11.316885// |_____|_____|_____|_|___| https://github.com/nlohmann/json16886//16887// SPDX-FileCopyrightText: 2008-2009 Björn Hoehrmann <[email protected]>16888// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>16889// SPDX-License-Identifier: MIT16890168911689216893#include <algorithm> // reverse, remove, fill, find, none_of16894#include <array> // array16895#include <clocale> // localeconv, lconv16896#include <cmath> // labs, isfinite, isnan, signbit16897#include <cstddef> // size_t, ptrdiff_t16898#include <cstdint> // uint8_t16899#include <cstdio> // snprintf16900#include <limits> // numeric_limits16901#include <string> // string, char_traits16902#include <iomanip> // setfill, setw16903#include <type_traits> // is_same16904#include <utility> // move1690516906// #include <nlohmann/detail/conversions/to_chars.hpp>16907// __ _____ _____ _____16908// __| | __| | | | JSON for Modern C++16909// | | |__ | | | | | | version 3.11.316910// |_____|_____|_____|_|___| https://github.com/nlohmann/json16911//16912// SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>16913// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>16914// SPDX-License-Identifier: MIT16915169161691716918#include <array> // array16919#include <cmath> // signbit, isfinite16920#include <cstdint> // intN_t, uintN_t16921#include <cstring> // memcpy, memmove16922#include <limits> // numeric_limits16923#include <type_traits> // conditional1692416925// #include <nlohmann/detail/macro_scope.hpp>169261692716928NLOHMANN_JSON_NAMESPACE_BEGIN16929namespace detail16930{1693116932/*!16933@brief implements the Grisu2 algorithm for binary to decimal floating-point16934conversion.1693516936This implementation is a slightly modified version of the reference16937implementation which may be obtained from16938http://florian.loitsch.com/publications (bench.tar.gz).1693916940The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.1694116942For a detailed description of the algorithm see:1694316944[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with16945Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming16946Language Design and Implementation, PLDI 201016947[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",16948Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language16949Design and Implementation, PLDI 199616950*/16951namespace dtoa_impl16952{1695316954template<typename Target, typename Source>16955Target reinterpret_bits(const Source source)16956{16957static_assert(sizeof(Target) == sizeof(Source), "size mismatch");1695816959Target target;16960std::memcpy(&target, &source, sizeof(Source));16961return target;16962}1696316964struct diyfp // f * 2^e16965{16966static constexpr int kPrecision = 64; // = q1696716968std::uint64_t f = 0;16969int e = 0;1697016971constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}1697216973/*!16974@brief returns x - y16975@pre x.e == y.e and x.f >= y.f16976*/16977static diyfp sub(const diyfp& x, const diyfp& y) noexcept16978{16979JSON_ASSERT(x.e == y.e);16980JSON_ASSERT(x.f >= y.f);1698116982return {x.f - y.f, x.e};16983}1698416985/*!16986@brief returns x * y16987@note The result is rounded. (Only the upper q bits are returned.)16988*/16989static diyfp mul(const diyfp& x, const diyfp& y) noexcept16990{16991static_assert(kPrecision == 64, "internal error");1699216993// Computes:16994// f = round((x.f * y.f) / 2^q)16995// e = x.e + y.e + q1699616997// Emulate the 64-bit * 64-bit multiplication:16998//16999// p = u * v17000// = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)17001// = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )17002// = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )17003// = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )17004// = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)17005// = (p0_lo ) + 2^32 (Q ) + 2^64 (H )17006// = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )17007//17008// (Since Q might be larger than 2^32 - 1)17009//17010// = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)17011//17012// (Q_hi + H does not overflow a 64-bit int)17013//17014// = p_lo + 2^64 p_hi1701517016const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;17017const std::uint64_t u_hi = x.f >> 32u;17018const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;17019const std::uint64_t v_hi = y.f >> 32u;1702017021const std::uint64_t p0 = u_lo * v_lo;17022const std::uint64_t p1 = u_lo * v_hi;17023const std::uint64_t p2 = u_hi * v_lo;17024const std::uint64_t p3 = u_hi * v_hi;1702517026const std::uint64_t p0_hi = p0 >> 32u;17027const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;17028const std::uint64_t p1_hi = p1 >> 32u;17029const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;17030const std::uint64_t p2_hi = p2 >> 32u;1703117032std::uint64_t Q = p0_hi + p1_lo + p2_lo;1703317034// The full product might now be computed as17035//17036// p_hi = p3 + p2_hi + p1_hi + (Q >> 32)17037// p_lo = p0_lo + (Q << 32)17038//17039// But in this particular case here, the full p_lo is not required.17040// Effectively we only need to add the highest bit in p_lo to p_hi (and17041// Q_hi + 1 does not overflow).1704217043Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up1704417045const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);1704617047return {h, x.e + y.e + 64};17048}1704917050/*!17051@brief normalize x such that the significand is >= 2^(q-1)17052@pre x.f != 017053*/17054static diyfp normalize(diyfp x) noexcept17055{17056JSON_ASSERT(x.f != 0);1705717058while ((x.f >> 63u) == 0)17059{17060x.f <<= 1u;17061x.e--;17062}1706317064return x;17065}1706617067/*!17068@brief normalize x such that the result has the exponent E17069@pre e >= x.e and the upper e - x.e bits of x.f must be zero.17070*/17071static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept17072{17073const int delta = x.e - target_exponent;1707417075JSON_ASSERT(delta >= 0);17076JSON_ASSERT(((x.f << delta) >> delta) == x.f);1707717078return {x.f << delta, target_exponent};17079}17080};1708117082struct boundaries17083{17084diyfp w;17085diyfp minus;17086diyfp plus;17087};1708817089/*!17090Compute the (normalized) diyfp representing the input number 'value' and its17091boundaries.1709217093@pre value must be finite and positive17094*/17095template<typename FloatType>17096boundaries compute_boundaries(FloatType value)17097{17098JSON_ASSERT(std::isfinite(value));17099JSON_ASSERT(value > 0);1710017101// Convert the IEEE representation into a diyfp.17102//17103// If v is denormal:17104// value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))17105// If v is normalized:17106// value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))1710717108static_assert(std::numeric_limits<FloatType>::is_iec559,17109"internal error: dtoa_short requires an IEEE-754 floating-point implementation");1711017111constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)17112constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);17113constexpr int kMinExp = 1 - kBias;17114constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)1711517116using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;1711717118const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));17119const std::uint64_t E = bits >> (kPrecision - 1);17120const std::uint64_t F = bits & (kHiddenBit - 1);1712117122const bool is_denormal = E == 0;17123const diyfp v = is_denormal17124? diyfp(F, kMinExp)17125: diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);1712617127// Compute the boundaries m- and m+ of the floating-point value17128// v = f * 2^e.17129//17130// Determine v- and v+, the floating-point predecessor and successor if v,17131// respectively.17132//17133// v- = v - 2^e if f != 2^(p-1) or e == e_min (A)17134// = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)17135//17136// v+ = v + 2^e17137//17138// Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_17139// between m- and m+ round to v, regardless of how the input rounding17140// algorithm breaks ties.17141//17142// ---+-------------+-------------+-------------+-------------+--- (A)17143// v- m- v m+ v+17144//17145// -----------------+------+------+-------------+-------------+--- (B)17146// v- m- v m+ v+1714717148const bool lower_boundary_is_closer = F == 0 && E > 1;17149const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);17150const diyfp m_minus = lower_boundary_is_closer17151? diyfp(4 * v.f - 1, v.e - 2) // (B)17152: diyfp(2 * v.f - 1, v.e - 1); // (A)1715317154// Determine the normalized w+ = m+.17155const diyfp w_plus = diyfp::normalize(m_plus);1715617157// Determine w- = m- such that e_(w-) = e_(w+).17158const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);1715917160return {diyfp::normalize(v), w_minus, w_plus};17161}1716217163// Given normalized diyfp w, Grisu needs to find a (normalized) cached17164// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies17165// within a certain range [alpha, gamma] (Definition 3.2 from [1])17166//17167// alpha <= e = e_c + e_w + q <= gamma17168//17169// or17170//17171// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q17172// <= f_c * f_w * 2^gamma17173//17174// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies17175//17176// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma17177//17178// or17179//17180// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)17181//17182// The choice of (alpha,gamma) determines the size of the table and the form of17183// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well17184// in practice:17185//17186// The idea is to cut the number c * w = f * 2^e into two parts, which can be17187// processed independently: An integral part p1, and a fractional part p2:17188//17189// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e17190// = (f div 2^-e) + (f mod 2^-e) * 2^e17191// = p1 + p2 * 2^e17192//17193// The conversion of p1 into decimal form requires a series of divisions and17194// modulos by (a power of) 10. These operations are faster for 32-bit than for17195// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be17196// achieved by choosing17197//17198// -e >= 32 or e <= -32 := gamma17199//17200// In order to convert the fractional part17201//17202// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...17203//17204// into decimal form, the fraction is repeatedly multiplied by 10 and the digits17205// d[-i] are extracted in order:17206//17207// (10 * p2) div 2^-e = d[-1]17208// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...17209//17210// The multiplication by 10 must not overflow. It is sufficient to choose17211//17212// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.17213//17214// Since p2 = f mod 2^-e < 2^-e,17215//17216// -e <= 60 or e >= -60 := alpha1721717218constexpr int kAlpha = -60;17219constexpr int kGamma = -32;1722017221struct cached_power // c = f * 2^e ~= 10^k17222{17223std::uint64_t f;17224int e;17225int k;17226};1722717228/*!17229For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached17230power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c17231satisfies (Definition 3.2 from [1])1723217233alpha <= e_c + e + q <= gamma.17234*/17235inline cached_power get_cached_power_for_binary_exponent(int e)17236{17237// Now17238//17239// alpha <= e_c + e + q <= gamma (1)17240// ==> f_c * 2^alpha <= c * 2^e * 2^q17241//17242// and since the c's are normalized, 2^(q-1) <= f_c,17243//17244// ==> 2^(q - 1 + alpha) <= c * 2^(e + q)17245// ==> 2^(alpha - e - 1) <= c17246//17247// If c were an exact power of ten, i.e. c = 10^k, one may determine k as17248//17249// k = ceil( log_10( 2^(alpha - e - 1) ) )17250// = ceil( (alpha - e - 1) * log_10(2) )17251//17252// From the paper:17253// "In theory the result of the procedure could be wrong since c is rounded,17254// and the computation itself is approximated [...]. In practice, however,17255// this simple function is sufficient."17256//17257// For IEEE double precision floating-point numbers converted into17258// normalized diyfp's w = f * 2^e, with q = 64,17259//17260// e >= -1022 (min IEEE exponent)17261// -52 (p - 1)17262// -52 (p - 1, possibly normalize denormal IEEE numbers)17263// -11 (normalize the diyfp)17264// = -113717265//17266// and17267//17268// e <= +1023 (max IEEE exponent)17269// -52 (p - 1)17270// -11 (normalize the diyfp)17271// = 96017272//17273// This binary exponent range [-1137,960] results in a decimal exponent17274// range [-307,324]. One does not need to store a cached power for each17275// k in this range. For each such k it suffices to find a cached power17276// such that the exponent of the product lies in [alpha,gamma].17277// This implies that the difference of the decimal exponents of adjacent17278// table entries must be less than or equal to17279//17280// floor( (gamma - alpha) * log_10(2) ) = 8.17281//17282// (A smaller distance gamma-alpha would require a larger table.)1728317284// NB:17285// Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.1728617287constexpr int kCachedPowersMinDecExp = -300;17288constexpr int kCachedPowersDecStep = 8;1728917290static constexpr std::array<cached_power, 79> kCachedPowers =17291{17292{17293{ 0xAB70FE17C79AC6CA, -1060, -300 },17294{ 0xFF77B1FCBEBCDC4F, -1034, -292 },17295{ 0xBE5691EF416BD60C, -1007, -284 },17296{ 0x8DD01FAD907FFC3C, -980, -276 },17297{ 0xD3515C2831559A83, -954, -268 },17298{ 0x9D71AC8FADA6C9B5, -927, -260 },17299{ 0xEA9C227723EE8BCB, -901, -252 },17300{ 0xAECC49914078536D, -874, -244 },17301{ 0x823C12795DB6CE57, -847, -236 },17302{ 0xC21094364DFB5637, -821, -228 },17303{ 0x9096EA6F3848984F, -794, -220 },17304{ 0xD77485CB25823AC7, -768, -212 },17305{ 0xA086CFCD97BF97F4, -741, -204 },17306{ 0xEF340A98172AACE5, -715, -196 },17307{ 0xB23867FB2A35B28E, -688, -188 },17308{ 0x84C8D4DFD2C63F3B, -661, -180 },17309{ 0xC5DD44271AD3CDBA, -635, -172 },17310{ 0x936B9FCEBB25C996, -608, -164 },17311{ 0xDBAC6C247D62A584, -582, -156 },17312{ 0xA3AB66580D5FDAF6, -555, -148 },17313{ 0xF3E2F893DEC3F126, -529, -140 },17314{ 0xB5B5ADA8AAFF80B8, -502, -132 },17315{ 0x87625F056C7C4A8B, -475, -124 },17316{ 0xC9BCFF6034C13053, -449, -116 },17317{ 0x964E858C91BA2655, -422, -108 },17318{ 0xDFF9772470297EBD, -396, -100 },17319{ 0xA6DFBD9FB8E5B88F, -369, -92 },17320{ 0xF8A95FCF88747D94, -343, -84 },17321{ 0xB94470938FA89BCF, -316, -76 },17322{ 0x8A08F0F8BF0F156B, -289, -68 },17323{ 0xCDB02555653131B6, -263, -60 },17324{ 0x993FE2C6D07B7FAC, -236, -52 },17325{ 0xE45C10C42A2B3B06, -210, -44 },17326{ 0xAA242499697392D3, -183, -36 },17327{ 0xFD87B5F28300CA0E, -157, -28 },17328{ 0xBCE5086492111AEB, -130, -20 },17329{ 0x8CBCCC096F5088CC, -103, -12 },17330{ 0xD1B71758E219652C, -77, -4 },17331{ 0x9C40000000000000, -50, 4 },17332{ 0xE8D4A51000000000, -24, 12 },17333{ 0xAD78EBC5AC620000, 3, 20 },17334{ 0x813F3978F8940984, 30, 28 },17335{ 0xC097CE7BC90715B3, 56, 36 },17336{ 0x8F7E32CE7BEA5C70, 83, 44 },17337{ 0xD5D238A4ABE98068, 109, 52 },17338{ 0x9F4F2726179A2245, 136, 60 },17339{ 0xED63A231D4C4FB27, 162, 68 },17340{ 0xB0DE65388CC8ADA8, 189, 76 },17341{ 0x83C7088E1AAB65DB, 216, 84 },17342{ 0xC45D1DF942711D9A, 242, 92 },17343{ 0x924D692CA61BE758, 269, 100 },17344{ 0xDA01EE641A708DEA, 295, 108 },17345{ 0xA26DA3999AEF774A, 322, 116 },17346{ 0xF209787BB47D6B85, 348, 124 },17347{ 0xB454E4A179DD1877, 375, 132 },17348{ 0x865B86925B9BC5C2, 402, 140 },17349{ 0xC83553C5C8965D3D, 428, 148 },17350{ 0x952AB45CFA97A0B3, 455, 156 },17351{ 0xDE469FBD99A05FE3, 481, 164 },17352{ 0xA59BC234DB398C25, 508, 172 },17353{ 0xF6C69A72A3989F5C, 534, 180 },17354{ 0xB7DCBF5354E9BECE, 561, 188 },17355{ 0x88FCF317F22241E2, 588, 196 },17356{ 0xCC20CE9BD35C78A5, 614, 204 },17357{ 0x98165AF37B2153DF, 641, 212 },17358{ 0xE2A0B5DC971F303A, 667, 220 },17359{ 0xA8D9D1535CE3B396, 694, 228 },17360{ 0xFB9B7CD9A4A7443C, 720, 236 },17361{ 0xBB764C4CA7A44410, 747, 244 },17362{ 0x8BAB8EEFB6409C1A, 774, 252 },17363{ 0xD01FEF10A657842C, 800, 260 },17364{ 0x9B10A4E5E9913129, 827, 268 },17365{ 0xE7109BFBA19C0C9D, 853, 276 },17366{ 0xAC2820D9623BF429, 880, 284 },17367{ 0x80444B5E7AA7CF85, 907, 292 },17368{ 0xBF21E44003ACDD2D, 933, 300 },17369{ 0x8E679C2F5E44FF8F, 960, 308 },17370{ 0xD433179D9C8CB841, 986, 316 },17371{ 0x9E19DB92B4E31BA9, 1013, 324 },17372}17373};1737417375// This computation gives exactly the same results for k as17376// k = ceil((kAlpha - e - 1) * 0.30102999566398114)17377// for |e| <= 1500, but doesn't require floating-point operations.17378// NB: log_10(2) ~= 78913 / 2^1817379JSON_ASSERT(e >= -1500);17380JSON_ASSERT(e <= 1500);17381const int f = kAlpha - e - 1;17382const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);1738317384const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;17385JSON_ASSERT(index >= 0);17386JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());1738717388const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];17389JSON_ASSERT(kAlpha <= cached.e + e + 64);17390JSON_ASSERT(kGamma >= cached.e + e + 64);1739117392return cached;17393}1739417395/*!17396For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.17397For n == 0, returns 1 and sets pow10 := 1.17398*/17399inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)17400{17401// LCOV_EXCL_START17402if (n >= 1000000000)17403{17404pow10 = 1000000000;17405return 10;17406}17407// LCOV_EXCL_STOP17408if (n >= 100000000)17409{17410pow10 = 100000000;17411return 9;17412}17413if (n >= 10000000)17414{17415pow10 = 10000000;17416return 8;17417}17418if (n >= 1000000)17419{17420pow10 = 1000000;17421return 7;17422}17423if (n >= 100000)17424{17425pow10 = 100000;17426return 6;17427}17428if (n >= 10000)17429{17430pow10 = 10000;17431return 5;17432}17433if (n >= 1000)17434{17435pow10 = 1000;17436return 4;17437}17438if (n >= 100)17439{17440pow10 = 100;17441return 3;17442}17443if (n >= 10)17444{17445pow10 = 10;17446return 2;17447}1744817449pow10 = 1;17450return 1;17451}1745217453inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,17454std::uint64_t rest, std::uint64_t ten_k)17455{17456JSON_ASSERT(len >= 1);17457JSON_ASSERT(dist <= delta);17458JSON_ASSERT(rest <= delta);17459JSON_ASSERT(ten_k > 0);1746017461// <--------------------------- delta ---->17462// <---- dist --------->17463// --------------[------------------+-------------------]--------------17464// M- w M+17465//17466// ten_k17467// <------>17468// <---- rest ---->17469// --------------[------------------+----+--------------]--------------17470// w V17471// = buf * 10^k17472//17473// ten_k represents a unit-in-the-last-place in the decimal representation17474// stored in buf.17475// Decrement buf by ten_k while this takes buf closer to w.1747617477// The tests are written in this order to avoid overflow in unsigned17478// integer arithmetic.1747917480while (rest < dist17481&& delta - rest >= ten_k17482&& (rest + ten_k < dist || dist - rest > rest + ten_k - dist))17483{17484JSON_ASSERT(buf[len - 1] != '0');17485buf[len - 1]--;17486rest += ten_k;17487}17488}1748917490/*!17491Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.17492M- and M+ must be normalized and share the same exponent -60 <= e <= -32.17493*/17494inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,17495diyfp M_minus, diyfp w, diyfp M_plus)17496{17497static_assert(kAlpha >= -60, "internal error");17498static_assert(kGamma <= -32, "internal error");1749917500// Generates the digits (and the exponent) of a decimal floating-point17501// number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's17502// w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.17503//17504// <--------------------------- delta ---->17505// <---- dist --------->17506// --------------[------------------+-------------------]--------------17507// M- w M+17508//17509// Grisu2 generates the digits of M+ from left to right and stops as soon as17510// V is in [M-,M+].1751117512JSON_ASSERT(M_plus.e >= kAlpha);17513JSON_ASSERT(M_plus.e <= kGamma);1751417515std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)17516std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)1751717518// Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):17519//17520// M+ = f * 2^e17521// = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e17522// = ((p1 ) * 2^-e + (p2 )) * 2^e17523// = p1 + p2 * 2^e1752417525const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);1752617527auto 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.)17528std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e1752917530// 1)17531//17532// Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]1753317534JSON_ASSERT(p1 > 0);1753517536std::uint32_t pow10{};17537const int k = find_largest_pow10(p1, pow10);1753817539// 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)17540//17541// p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))17542// = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))17543//17544// M+ = p1 + p2 * 2^e17545// = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e17546// = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e17547// = d[k-1] * 10^(k-1) + ( rest) * 2^e17548//17549// Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)17550//17551// p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]17552//17553// but stop as soon as17554//17555// rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e1755617557int n = k;17558while (n > 0)17559{17560// Invariants:17561// M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)17562// pow10 = 10^(n-1) <= p1 < 10^n17563//17564const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)17565const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)17566//17567// M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e17568// = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)17569//17570JSON_ASSERT(d <= 9);17571buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d17572//17573// M+ = buffer * 10^(n-1) + (r + p2 * 2^e)17574//17575p1 = r;17576n--;17577//17578// M+ = buffer * 10^n + (p1 + p2 * 2^e)17579// pow10 = 10^n17580//1758117582// Now check if enough digits have been generated.17583// Compute17584//17585// p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e17586//17587// Note:17588// Since rest and delta share the same exponent e, it suffices to17589// compare the significands.17590const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;17591if (rest <= delta)17592{17593// V = buffer * 10^n, with M- <= V <= M+.1759417595decimal_exponent += n;1759617597// We may now just stop. But instead look if the buffer could be17598// decremented to bring V closer to w.17599//17600// pow10 = 10^n is now 1 ulp in the decimal representation V.17601// The rounding procedure works with diyfp's with an implicit17602// exponent of e.17603//17604// 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e17605//17606const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;17607grisu2_round(buffer, length, dist, delta, rest, ten_n);1760817609return;17610}1761117612pow10 /= 10;17613//17614// pow10 = 10^(n-1) <= p1 < 10^n17615// Invariants restored.17616}1761717618// 2)17619//17620// The digits of the integral part have been generated:17621//17622// M+ = d[k-1]...d[1]d[0] + p2 * 2^e17623// = buffer + p2 * 2^e17624//17625// Now generate the digits of the fractional part p2 * 2^e.17626//17627// Note:17628// No decimal point is generated: the exponent is adjusted instead.17629//17630// p2 actually represents the fraction17631//17632// p2 * 2^e17633// = p2 / 2^-e17634// = d[-1] / 10^1 + d[-2] / 10^2 + ...17635//17636// Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)17637//17638// p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m17639// + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)17640//17641// using17642//17643// 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)17644// = ( d) * 2^-e + ( r)17645//17646// or17647// 10^m * p2 * 2^e = d + r * 2^e17648//17649// i.e.17650//17651// M+ = buffer + p2 * 2^e17652// = buffer + 10^-m * (d + r * 2^e)17653// = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e17654//17655// and stop as soon as 10^-m * r * 2^e <= delta * 2^e1765617657JSON_ASSERT(p2 > delta);1765817659int m = 0;17660for (;;)17661{17662// Invariant:17663// M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e17664// = buffer * 10^-m + 10^-m * (p2 ) * 2^e17665// = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e17666// = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e17667//17668JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);17669p2 *= 10;17670const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e17671const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e17672//17673// M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e17674// = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))17675// = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e17676//17677JSON_ASSERT(d <= 9);17678buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d17679//17680// M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e17681//17682p2 = r;17683m++;17684//17685// M+ = buffer * 10^-m + 10^-m * p2 * 2^e17686// Invariant restored.1768717688// Check if enough digits have been generated.17689//17690// 10^-m * p2 * 2^e <= delta * 2^e17691// p2 * 2^e <= 10^m * delta * 2^e17692// p2 <= 10^m * delta17693delta *= 10;17694dist *= 10;17695if (p2 <= delta)17696{17697break;17698}17699}1770017701// V = buffer * 10^-m, with M- <= V <= M+.1770217703decimal_exponent -= m;1770417705// 1 ulp in the decimal representation is now 10^-m.17706// Since delta and dist are now scaled by 10^m, we need to do the17707// same with ulp in order to keep the units in sync.17708//17709// 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e17710//17711const std::uint64_t ten_m = one.f;17712grisu2_round(buffer, length, dist, delta, p2, ten_m);1771317714// By construction this algorithm generates the shortest possible decimal17715// number (Loitsch, Theorem 6.2) which rounds back to w.17716// For an input number of precision p, at least17717//17718// N = 1 + ceil(p * log_10(2))17719//17720// decimal digits are sufficient to identify all binary floating-point17721// numbers (Matula, "In-and-Out conversions").17722// This implies that the algorithm does not produce more than N decimal17723// digits.17724//17725// N = 17 for p = 53 (IEEE double precision)17726// N = 9 for p = 24 (IEEE single precision)17727}1772817729/*!17730v = buf * 10^decimal_exponent17731len is the length of the buffer (number of decimal digits)17732The buffer must be large enough, i.e. >= max_digits10.17733*/17734JSON_HEDLEY_NON_NULL(1)17735inline void grisu2(char* buf, int& len, int& decimal_exponent,17736diyfp m_minus, diyfp v, diyfp m_plus)17737{17738JSON_ASSERT(m_plus.e == m_minus.e);17739JSON_ASSERT(m_plus.e == v.e);1774017741// --------(-----------------------+-----------------------)-------- (A)17742// m- v m+17743//17744// --------------------(-----------+-----------------------)-------- (B)17745// m- v m+17746//17747// First scale v (and m- and m+) such that the exponent is in the range17748// [alpha, gamma].1774917750const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);1775117752const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k1775317754// The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]17755const diyfp w = diyfp::mul(v, c_minus_k);17756const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);17757const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);1775817759// ----(---+---)---------------(---+---)---------------(---+---)----17760// w- w w+17761// = c*m- = c*v = c*m+17762//17763// diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and17764// w+ are now off by a small amount.17765// In fact:17766//17767// w - v * 10^k < 1 ulp17768//17769// To account for this inaccuracy, add resp. subtract 1 ulp.17770//17771// --------+---[---------------(---+---)---------------]---+--------17772// w- M- w M+ w+17773//17774// Now any number in [M-, M+] (bounds included) will round to w when input,17775// regardless of how the input rounding algorithm breaks ties.17776//17777// And digit_gen generates the shortest possible such number in [M-, M+].17778// Note that this does not mean that Grisu2 always generates the shortest17779// possible number in the interval (m-, m+).17780const diyfp M_minus(w_minus.f + 1, w_minus.e);17781const diyfp M_plus (w_plus.f - 1, w_plus.e );1778217783decimal_exponent = -cached.k; // = -(-k) = k1778417785grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);17786}1778717788/*!17789v = buf * 10^decimal_exponent17790len is the length of the buffer (number of decimal digits)17791The buffer must be large enough, i.e. >= max_digits10.17792*/17793template<typename FloatType>17794JSON_HEDLEY_NON_NULL(1)17795void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)17796{17797static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,17798"internal error: not enough precision");1779917800JSON_ASSERT(std::isfinite(value));17801JSON_ASSERT(value > 0);1780217803// If the neighbors (and boundaries) of 'value' are always computed for double-precision17804// numbers, all float's can be recovered using strtod (and strtof). However, the resulting17805// decimal representations are not exactly "short".17806//17807// The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)17808// says "value is converted to a string as if by std::sprintf in the default ("C") locale"17809// and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'17810// does.17811// On the other hand, the documentation for 'std::to_chars' requires that "parsing the17812// representation using the corresponding std::from_chars function recovers value exactly". That17813// indicates that single precision floating-point numbers should be recovered using17814// 'std::strtof'.17815//17816// NB: If the neighbors are computed for single-precision numbers, there is a single float17817// (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision17818// value is off by 1 ulp.17819#if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)17820const boundaries w = compute_boundaries(static_cast<double>(value));17821#else17822const boundaries w = compute_boundaries(value);17823#endif1782417825grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);17826}1782717828/*!17829@brief appends a decimal representation of e to buf17830@return a pointer to the element following the exponent.17831@pre -1000 < e < 100017832*/17833JSON_HEDLEY_NON_NULL(1)17834JSON_HEDLEY_RETURNS_NON_NULL17835inline char* append_exponent(char* buf, int e)17836{17837JSON_ASSERT(e > -1000);17838JSON_ASSERT(e < 1000);1783917840if (e < 0)17841{17842e = -e;17843*buf++ = '-';17844}17845else17846{17847*buf++ = '+';17848}1784917850auto k = static_cast<std::uint32_t>(e);17851if (k < 10)17852{17853// Always print at least two digits in the exponent.17854// This is for compatibility with printf("%g").17855*buf++ = '0';17856*buf++ = static_cast<char>('0' + k);17857}17858else if (k < 100)17859{17860*buf++ = static_cast<char>('0' + k / 10);17861k %= 10;17862*buf++ = static_cast<char>('0' + k);17863}17864else17865{17866*buf++ = static_cast<char>('0' + k / 100);17867k %= 100;17868*buf++ = static_cast<char>('0' + k / 10);17869k %= 10;17870*buf++ = static_cast<char>('0' + k);17871}1787217873return buf;17874}1787517876/*!17877@brief prettify v = buf * 10^decimal_exponent1787817879If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point17880notation. Otherwise it will be printed in exponential notation.1788117882@pre min_exp < 017883@pre max_exp > 017884*/17885JSON_HEDLEY_NON_NULL(1)17886JSON_HEDLEY_RETURNS_NON_NULL17887inline char* format_buffer(char* buf, int len, int decimal_exponent,17888int min_exp, int max_exp)17889{17890JSON_ASSERT(min_exp < 0);17891JSON_ASSERT(max_exp > 0);1789217893const int k = len;17894const int n = len + decimal_exponent;1789517896// v = buf * 10^(n-k)17897// k is the length of the buffer (number of decimal digits)17898// n is the position of the decimal point relative to the start of the buffer.1789917900if (k <= n && n <= max_exp)17901{17902// digits[000]17903// len <= max_exp + 21790417905std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));17906// Make it look like a floating-point number (#362, #378)17907buf[n + 0] = '.';17908buf[n + 1] = '0';17909return buf + (static_cast<size_t>(n) + 2);17910}1791117912if (0 < n && n <= max_exp)17913{17914// dig.its17915// len <= max_digits10 + 11791617917JSON_ASSERT(k > n);1791817919std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));17920buf[n] = '.';17921return buf + (static_cast<size_t>(k) + 1U);17922}1792317924if (min_exp < n && n <= 0)17925{17926// 0.[000]digits17927// len <= 2 + (-min_exp - 1) + max_digits101792817929std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));17930buf[0] = '0';17931buf[1] = '.';17932std::memset(buf + 2, '0', static_cast<size_t>(-n));17933return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));17934}1793517936if (k == 1)17937{17938// dE+12317939// len <= 1 + 51794017941buf += 1;17942}17943else17944{17945// d.igitsE+12317946// len <= max_digits10 + 1 + 51794717948std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);17949buf[1] = '.';17950buf += 1 + static_cast<size_t>(k);17951}1795217953*buf++ = 'e';17954return append_exponent(buf, n - 1);17955}1795617957} // namespace dtoa_impl1795817959/*!17960@brief generates a decimal representation of the floating-point number value in [first, last).1796117962The format of the resulting decimal representation is similar to printf's %g17963format. Returns an iterator pointing past-the-end of the decimal representation.1796417965@note The input number must be finite, i.e. NaN's and Inf's are not supported.17966@note The buffer must be large enough.17967@note The result is NOT null-terminated.17968*/17969template<typename FloatType>17970JSON_HEDLEY_NON_NULL(1, 2)17971JSON_HEDLEY_RETURNS_NON_NULL17972char* to_chars(char* first, const char* last, FloatType value)17973{17974static_cast<void>(last); // maybe unused - fix warning17975JSON_ASSERT(std::isfinite(value));1797617977// Use signbit(value) instead of (value < 0) since signbit works for -0.17978if (std::signbit(value))17979{17980value = -value;17981*first++ = '-';17982}1798317984#ifdef __GNUC__17985#pragma GCC diagnostic push17986#pragma GCC diagnostic ignored "-Wfloat-equal"17987#endif17988if (value == 0) // +-017989{17990*first++ = '0';17991// Make it look like a floating-point number (#362, #378)17992*first++ = '.';17993*first++ = '0';17994return first;17995}17996#ifdef __GNUC__17997#pragma GCC diagnostic pop17998#endif1799918000JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);1800118002// Compute v = buffer * 10^decimal_exponent.18003// The decimal digits are stored in the buffer, which needs to be interpreted18004// as an unsigned decimal integer.18005// len is the length of the buffer, i.e. the number of decimal digits.18006int len = 0;18007int decimal_exponent = 0;18008dtoa_impl::grisu2(first, len, decimal_exponent, value);1800918010JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);1801118012// Format the buffer like printf("%.*g", prec, value)18013constexpr int kMinExp = -4;18014// Use digits10 here to increase compatibility with version 2.18015constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;1801618017JSON_ASSERT(last - first >= kMaxExp + 2);18018JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);18019JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);1802018021return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);18022}1802318024} // namespace detail18025NLOHMANN_JSON_NAMESPACE_END1802618027// #include <nlohmann/detail/exceptions.hpp>1802818029// #include <nlohmann/detail/macro_scope.hpp>1803018031// #include <nlohmann/detail/meta/cpp_future.hpp>1803218033// #include <nlohmann/detail/output/binary_writer.hpp>1803418035// #include <nlohmann/detail/output/output_adapters.hpp>1803618037// #include <nlohmann/detail/string_concat.hpp>1803818039// #include <nlohmann/detail/value_t.hpp>180401804118042NLOHMANN_JSON_NAMESPACE_BEGIN18043namespace detail18044{1804518046///////////////////18047// serialization //18048///////////////////1804918050/// how to treat decoding errors18051enum class error_handler_t18052{18053strict, ///< throw a type_error exception in case of invalid UTF-818054replace, ///< replace invalid UTF-8 sequences with U+FFFD18055ignore ///< ignore invalid UTF-8 sequences18056};1805718058template<typename BasicJsonType>18059class serializer18060{18061using string_t = typename BasicJsonType::string_t;18062using number_float_t = typename BasicJsonType::number_float_t;18063using number_integer_t = typename BasicJsonType::number_integer_t;18064using number_unsigned_t = typename BasicJsonType::number_unsigned_t;18065using binary_char_t = typename BasicJsonType::binary_t::value_type;18066static constexpr std::uint8_t UTF8_ACCEPT = 0;18067static constexpr std::uint8_t UTF8_REJECT = 1;1806818069public:18070/*!18071@param[in] s output stream to serialize to18072@param[in] ichar indentation character to use18073@param[in] error_handler_ how to react on decoding errors18074*/18075serializer(output_adapter_t<char> s, const char ichar,18076error_handler_t error_handler_ = error_handler_t::strict)18077: o(std::move(s))18078, loc(std::localeconv())18079, thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))18080, decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))18081, indent_char(ichar)18082, indent_string(512, indent_char)18083, error_handler(error_handler_)18084{}1808518086// delete because of pointer members18087serializer(const serializer&) = delete;18088serializer& operator=(const serializer&) = delete;18089serializer(serializer&&) = delete;18090serializer& operator=(serializer&&) = delete;18091~serializer() = default;1809218093/*!18094@brief internal implementation of the serialization function1809518096This function is called by the public member function dump and organizes18097the serialization internally. The indentation level is propagated as18098additional parameter. In case of arrays and objects, the function is18099called recursively.1810018101- strings and object keys are escaped using `escape_string()`18102- integer numbers are converted implicitly via `operator<<`18103- floating-point numbers are converted to a string using `"%g"` format18104- binary values are serialized as objects containing the subtype and the18105byte array1810618107@param[in] val value to serialize18108@param[in] pretty_print whether the output shall be pretty-printed18109@param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters18110in the output are escaped with `\uXXXX` sequences, and the result consists18111of ASCII characters only.18112@param[in] indent_step the indent level18113@param[in] current_indent the current indent level (only used internally)18114*/18115void dump(const BasicJsonType& val,18116const bool pretty_print,18117const bool ensure_ascii,18118const unsigned int indent_step,18119const unsigned int current_indent = 0)18120{18121switch (val.m_data.m_type)18122{18123case value_t::object:18124{18125if (val.m_data.m_value.object->empty())18126{18127o->write_characters("{}", 2);18128return;18129}1813018131if (pretty_print)18132{18133o->write_characters("{\n", 2);1813418135// variable to hold indentation for recursive calls18136const auto new_indent = current_indent + indent_step;18137if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))18138{18139indent_string.resize(indent_string.size() * 2, ' ');18140}1814118142// first n-1 elements18143auto i = val.m_data.m_value.object->cbegin();18144for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)18145{18146o->write_characters(indent_string.c_str(), new_indent);18147o->write_character('\"');18148dump_escaped(i->first, ensure_ascii);18149o->write_characters("\": ", 3);18150dump(i->second, true, ensure_ascii, indent_step, new_indent);18151o->write_characters(",\n", 2);18152}1815318154// last element18155JSON_ASSERT(i != val.m_data.m_value.object->cend());18156JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());18157o->write_characters(indent_string.c_str(), new_indent);18158o->write_character('\"');18159dump_escaped(i->first, ensure_ascii);18160o->write_characters("\": ", 3);18161dump(i->second, true, ensure_ascii, indent_step, new_indent);1816218163o->write_character('\n');18164o->write_characters(indent_string.c_str(), current_indent);18165o->write_character('}');18166}18167else18168{18169o->write_character('{');1817018171// first n-1 elements18172auto i = val.m_data.m_value.object->cbegin();18173for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)18174{18175o->write_character('\"');18176dump_escaped(i->first, ensure_ascii);18177o->write_characters("\":", 2);18178dump(i->second, false, ensure_ascii, indent_step, current_indent);18179o->write_character(',');18180}1818118182// last element18183JSON_ASSERT(i != val.m_data.m_value.object->cend());18184JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());18185o->write_character('\"');18186dump_escaped(i->first, ensure_ascii);18187o->write_characters("\":", 2);18188dump(i->second, false, ensure_ascii, indent_step, current_indent);1818918190o->write_character('}');18191}1819218193return;18194}1819518196case value_t::array:18197{18198if (val.m_data.m_value.array->empty())18199{18200o->write_characters("[]", 2);18201return;18202}1820318204if (pretty_print)18205{18206o->write_characters("[\n", 2);1820718208// variable to hold indentation for recursive calls18209const auto new_indent = current_indent + indent_step;18210if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))18211{18212indent_string.resize(indent_string.size() * 2, ' ');18213}1821418215// first n-1 elements18216for (auto i = val.m_data.m_value.array->cbegin();18217i != val.m_data.m_value.array->cend() - 1; ++i)18218{18219o->write_characters(indent_string.c_str(), new_indent);18220dump(*i, true, ensure_ascii, indent_step, new_indent);18221o->write_characters(",\n", 2);18222}1822318224// last element18225JSON_ASSERT(!val.m_data.m_value.array->empty());18226o->write_characters(indent_string.c_str(), new_indent);18227dump(val.m_data.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);1822818229o->write_character('\n');18230o->write_characters(indent_string.c_str(), current_indent);18231o->write_character(']');18232}18233else18234{18235o->write_character('[');1823618237// first n-1 elements18238for (auto i = val.m_data.m_value.array->cbegin();18239i != val.m_data.m_value.array->cend() - 1; ++i)18240{18241dump(*i, false, ensure_ascii, indent_step, current_indent);18242o->write_character(',');18243}1824418245// last element18246JSON_ASSERT(!val.m_data.m_value.array->empty());18247dump(val.m_data.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);1824818249o->write_character(']');18250}1825118252return;18253}1825418255case value_t::string:18256{18257o->write_character('\"');18258dump_escaped(*val.m_data.m_value.string, ensure_ascii);18259o->write_character('\"');18260return;18261}1826218263case value_t::binary:18264{18265if (pretty_print)18266{18267o->write_characters("{\n", 2);1826818269// variable to hold indentation for recursive calls18270const auto new_indent = current_indent + indent_step;18271if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))18272{18273indent_string.resize(indent_string.size() * 2, ' ');18274}1827518276o->write_characters(indent_string.c_str(), new_indent);1827718278o->write_characters("\"bytes\": [", 10);1827918280if (!val.m_data.m_value.binary->empty())18281{18282for (auto i = val.m_data.m_value.binary->cbegin();18283i != val.m_data.m_value.binary->cend() - 1; ++i)18284{18285dump_integer(*i);18286o->write_characters(", ", 2);18287}18288dump_integer(val.m_data.m_value.binary->back());18289}1829018291o->write_characters("],\n", 3);18292o->write_characters(indent_string.c_str(), new_indent);1829318294o->write_characters("\"subtype\": ", 11);18295if (val.m_data.m_value.binary->has_subtype())18296{18297dump_integer(val.m_data.m_value.binary->subtype());18298}18299else18300{18301o->write_characters("null", 4);18302}18303o->write_character('\n');18304o->write_characters(indent_string.c_str(), current_indent);18305o->write_character('}');18306}18307else18308{18309o->write_characters("{\"bytes\":[", 10);1831018311if (!val.m_data.m_value.binary->empty())18312{18313for (auto i = val.m_data.m_value.binary->cbegin();18314i != val.m_data.m_value.binary->cend() - 1; ++i)18315{18316dump_integer(*i);18317o->write_character(',');18318}18319dump_integer(val.m_data.m_value.binary->back());18320}1832118322o->write_characters("],\"subtype\":", 12);18323if (val.m_data.m_value.binary->has_subtype())18324{18325dump_integer(val.m_data.m_value.binary->subtype());18326o->write_character('}');18327}18328else18329{18330o->write_characters("null}", 5);18331}18332}18333return;18334}1833518336case value_t::boolean:18337{18338if (val.m_data.m_value.boolean)18339{18340o->write_characters("true", 4);18341}18342else18343{18344o->write_characters("false", 5);18345}18346return;18347}1834818349case value_t::number_integer:18350{18351dump_integer(val.m_data.m_value.number_integer);18352return;18353}1835418355case value_t::number_unsigned:18356{18357dump_integer(val.m_data.m_value.number_unsigned);18358return;18359}1836018361case value_t::number_float:18362{18363dump_float(val.m_data.m_value.number_float);18364return;18365}1836618367case value_t::discarded:18368{18369o->write_characters("<discarded>", 11);18370return;18371}1837218373case value_t::null:18374{18375o->write_characters("null", 4);18376return;18377}1837818379default: // LCOV_EXCL_LINE18380JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE18381}18382}1838318384JSON_PRIVATE_UNLESS_TESTED:18385/*!18386@brief dump escaped string1838718388Escape a string by replacing certain special characters by a sequence of an18389escape character (backslash) and another character and other control18390characters by a sequence of "\u" followed by a four-digit hex18391representation. The escaped string is written to output stream @a o.1839218393@param[in] s the string to escape18394@param[in] ensure_ascii whether to escape non-ASCII characters with18395\uXXXX sequences1839618397@complexity Linear in the length of string @a s.18398*/18399void dump_escaped(const string_t& s, const bool ensure_ascii)18400{18401std::uint32_t codepoint{};18402std::uint8_t state = UTF8_ACCEPT;18403std::size_t bytes = 0; // number of bytes written to string_buffer1840418405// number of bytes written at the point of the last valid byte18406std::size_t bytes_after_last_accept = 0;18407std::size_t undumped_chars = 0;1840818409for (std::size_t i = 0; i < s.size(); ++i)18410{18411const auto byte = static_cast<std::uint8_t>(s[i]);1841218413switch (decode(state, codepoint, byte))18414{18415case UTF8_ACCEPT: // decode found a new code point18416{18417switch (codepoint)18418{18419case 0x08: // backspace18420{18421string_buffer[bytes++] = '\\';18422string_buffer[bytes++] = 'b';18423break;18424}1842518426case 0x09: // horizontal tab18427{18428string_buffer[bytes++] = '\\';18429string_buffer[bytes++] = 't';18430break;18431}1843218433case 0x0A: // newline18434{18435string_buffer[bytes++] = '\\';18436string_buffer[bytes++] = 'n';18437break;18438}1843918440case 0x0C: // formfeed18441{18442string_buffer[bytes++] = '\\';18443string_buffer[bytes++] = 'f';18444break;18445}1844618447case 0x0D: // carriage return18448{18449string_buffer[bytes++] = '\\';18450string_buffer[bytes++] = 'r';18451break;18452}1845318454case 0x22: // quotation mark18455{18456string_buffer[bytes++] = '\\';18457string_buffer[bytes++] = '\"';18458break;18459}1846018461case 0x5C: // reverse solidus18462{18463string_buffer[bytes++] = '\\';18464string_buffer[bytes++] = '\\';18465break;18466}1846718468default:18469{18470// escape control characters (0x00..0x1F) or, if18471// ensure_ascii parameter is used, non-ASCII characters18472if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))18473{18474if (codepoint <= 0xFFFF)18475{18476// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)18477static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",18478static_cast<std::uint16_t>(codepoint)));18479bytes += 6;18480}18481else18482{18483// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)18484static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",18485static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),18486static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));18487bytes += 12;18488}18489}18490else18491{18492// copy byte to buffer (all previous bytes18493// been copied have in default case above)18494string_buffer[bytes++] = s[i];18495}18496break;18497}18498}1849918500// write buffer and reset index; there must be 13 bytes18501// left, as this is the maximal number of bytes to be18502// written ("\uxxxx\uxxxx\0") for one code point18503if (string_buffer.size() - bytes < 13)18504{18505o->write_characters(string_buffer.data(), bytes);18506bytes = 0;18507}1850818509// remember the byte position of this accept18510bytes_after_last_accept = bytes;18511undumped_chars = 0;18512break;18513}1851418515case UTF8_REJECT: // decode found invalid UTF-8 byte18516{18517switch (error_handler)18518{18519case error_handler_t::strict:18520{18521JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));18522}1852318524case error_handler_t::ignore:18525case error_handler_t::replace:18526{18527// in case we saw this character the first time, we18528// would like to read it again, because the byte18529// may be OK for itself, but just not OK for the18530// previous sequence18531if (undumped_chars > 0)18532{18533--i;18534}1853518536// reset length buffer to the last accepted index;18537// thus removing/ignoring the invalid characters18538bytes = bytes_after_last_accept;1853918540if (error_handler == error_handler_t::replace)18541{18542// add a replacement character18543if (ensure_ascii)18544{18545string_buffer[bytes++] = '\\';18546string_buffer[bytes++] = 'u';18547string_buffer[bytes++] = 'f';18548string_buffer[bytes++] = 'f';18549string_buffer[bytes++] = 'f';18550string_buffer[bytes++] = 'd';18551}18552else18553{18554string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');18555string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');18556string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');18557}1855818559// write buffer and reset index; there must be 13 bytes18560// left, as this is the maximal number of bytes to be18561// written ("\uxxxx\uxxxx\0") for one code point18562if (string_buffer.size() - bytes < 13)18563{18564o->write_characters(string_buffer.data(), bytes);18565bytes = 0;18566}1856718568bytes_after_last_accept = bytes;18569}1857018571undumped_chars = 0;1857218573// continue processing the string18574state = UTF8_ACCEPT;18575break;18576}1857718578default: // LCOV_EXCL_LINE18579JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE18580}18581break;18582}1858318584default: // decode found yet incomplete multi-byte code point18585{18586if (!ensure_ascii)18587{18588// code point will not be escaped - copy byte to buffer18589string_buffer[bytes++] = s[i];18590}18591++undumped_chars;18592break;18593}18594}18595}1859618597// we finished processing the string18598if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))18599{18600// write buffer18601if (bytes > 0)18602{18603o->write_characters(string_buffer.data(), bytes);18604}18605}18606else18607{18608// we finish reading, but do not accept: string was incomplete18609switch (error_handler)18610{18611case error_handler_t::strict:18612{18613JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));18614}1861518616case error_handler_t::ignore:18617{18618// write all accepted bytes18619o->write_characters(string_buffer.data(), bytes_after_last_accept);18620break;18621}1862218623case error_handler_t::replace:18624{18625// write all accepted bytes18626o->write_characters(string_buffer.data(), bytes_after_last_accept);18627// add a replacement character18628if (ensure_ascii)18629{18630o->write_characters("\\ufffd", 6);18631}18632else18633{18634o->write_characters("\xEF\xBF\xBD", 3);18635}18636break;18637}1863818639default: // LCOV_EXCL_LINE18640JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE18641}18642}18643}1864418645private:18646/*!18647@brief count digits1864818649Count the number of decimal (base 10) digits for an input unsigned integer.1865018651@param[in] x unsigned integer number to count its digits18652@return number of decimal digits18653*/18654inline unsigned int count_digits(number_unsigned_t x) noexcept18655{18656unsigned int n_digits = 1;18657for (;;)18658{18659if (x < 10)18660{18661return n_digits;18662}18663if (x < 100)18664{18665return n_digits + 1;18666}18667if (x < 1000)18668{18669return n_digits + 2;18670}18671if (x < 10000)18672{18673return n_digits + 3;18674}18675x = x / 10000u;18676n_digits += 4;18677}18678}1867918680/*!18681* @brief convert a byte to a uppercase hex representation18682* @param[in] byte byte to represent18683* @return representation ("00".."FF")18684*/18685static std::string hex_bytes(std::uint8_t byte)18686{18687std::string result = "FF";18688constexpr const char* nibble_to_hex = "0123456789ABCDEF";18689result[0] = nibble_to_hex[byte / 16];18690result[1] = nibble_to_hex[byte % 16];18691return result;18692}1869318694// templates to avoid warnings about useless casts18695template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>18696bool is_negative_number(NumberType x)18697{18698return x < 0;18699}1870018701template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >18702bool is_negative_number(NumberType /*unused*/)18703{18704return false;18705}1870618707/*!18708@brief dump an integer1870918710Dump a given integer to output stream @a o. Works internally with18711@a number_buffer.1871218713@param[in] x integer number (signed or unsigned) to dump18714@tparam NumberType either @a number_integer_t or @a number_unsigned_t18715*/18716template < typename NumberType, detail::enable_if_t <18717std::is_integral<NumberType>::value ||18718std::is_same<NumberType, number_unsigned_t>::value ||18719std::is_same<NumberType, number_integer_t>::value ||18720std::is_same<NumberType, binary_char_t>::value,18721int > = 0 >18722void dump_integer(NumberType x)18723{18724static constexpr std::array<std::array<char, 2>, 100> digits_to_9918725{18726{18727{{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},18728{{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},18729{{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},18730{{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},18731{{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},18732{{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},18733{{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},18734{{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},18735{{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},18736{{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},18737}18738};1873918740// special case for "0"18741if (x == 0)18742{18743o->write_character('0');18744return;18745}1874618747// use a pointer to fill the buffer18748auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)1874918750number_unsigned_t abs_value;1875118752unsigned int n_chars{};1875318754if (is_negative_number(x))18755{18756*buffer_ptr = '-';18757abs_value = remove_sign(static_cast<number_integer_t>(x));1875818759// account one more byte for the minus sign18760n_chars = 1 + count_digits(abs_value);18761}18762else18763{18764abs_value = static_cast<number_unsigned_t>(x);18765n_chars = count_digits(abs_value);18766}1876718768// spare 1 byte for '\0'18769JSON_ASSERT(n_chars < number_buffer.size() - 1);1877018771// jump to the end to generate the string from backward,18772// so we later avoid reversing the result18773buffer_ptr += n_chars;1877418775// Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu18776// See: https://www.youtube.com/watch?v=o4-CwDo2zpg18777while (abs_value >= 100)18778{18779const auto digits_index = static_cast<unsigned>((abs_value % 100));18780abs_value /= 100;18781*(--buffer_ptr) = digits_to_99[digits_index][1];18782*(--buffer_ptr) = digits_to_99[digits_index][0];18783}1878418785if (abs_value >= 10)18786{18787const auto digits_index = static_cast<unsigned>(abs_value);18788*(--buffer_ptr) = digits_to_99[digits_index][1];18789*(--buffer_ptr) = digits_to_99[digits_index][0];18790}18791else18792{18793*(--buffer_ptr) = static_cast<char>('0' + abs_value);18794}1879518796o->write_characters(number_buffer.data(), n_chars);18797}1879818799/*!18800@brief dump a floating-point number1880118802Dump a given floating-point number to output stream @a o. Works internally18803with @a number_buffer.1880418805@param[in] x floating-point number to dump18806*/18807void dump_float(number_float_t x)18808{18809// NaN / inf18810if (!std::isfinite(x))18811{18812o->write_characters("null", 4);18813return;18814}1881518816// If number_float_t is an IEEE-754 single or double precision number,18817// use the Grisu2 algorithm to produce short numbers which are18818// guaranteed to round-trip, using strtof and strtod, resp.18819//18820// NB: The test below works if <long double> == <double>.18821static constexpr bool is_ieee_single_or_double18822= (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||18823(std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);1882418825dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());18826}1882718828void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)18829{18830auto* begin = number_buffer.data();18831auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);1883218833o->write_characters(begin, static_cast<size_t>(end - begin));18834}1883518836void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)18837{18838// get number of digits for a float -> text -> float round-trip18839static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;1884018841// the actual conversion18842// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)18843std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);1884418845// negative value indicates an error18846JSON_ASSERT(len > 0);18847// check if buffer was large enough18848JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());1884918850// erase thousands separator18851if (thousands_sep != '\0')18852{18853// NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/308118854const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);18855std::fill(end, number_buffer.end(), '\0');18856JSON_ASSERT((end - number_buffer.begin()) <= len);18857len = (end - number_buffer.begin());18858}1885918860// convert decimal point to '.'18861if (decimal_point != '\0' && decimal_point != '.')18862{18863// NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/308118864const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);18865if (dec_pos != number_buffer.end())18866{18867*dec_pos = '.';18868}18869}1887018871o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));1887218873// determine if we need to append ".0"18874const bool value_is_int_like =18875std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,18876[](char c)18877{18878return c == '.' || c == 'e';18879});1888018881if (value_is_int_like)18882{18883o->write_characters(".0", 2);18884}18885}1888618887/*!18888@brief check whether a string is UTF-8 encoded1888918890The function checks each byte of a string whether it is UTF-8 encoded. The18891result of the check is stored in the @a state parameter. The function must18892be called initially with state 0 (accept). State 1 means the string must18893be rejected, because the current byte is not allowed. If the string is18894completely processed, but the state is non-zero, the string ended18895prematurely; that is, the last byte indicated more bytes should have18896followed.1889718898@param[in,out] state the state of the decoding18899@param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)18900@param[in] byte next byte to decode18901@return new state1890218903@note The function has been edited: a std::array is used.1890418905@copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <[email protected]>18906@sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/18907*/18908static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept18909{18910static const std::array<std::uint8_t, 400> utf8d =18911{18912{189130, 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..1F189140, 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..3F189150, 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..5F189160, 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..7F189171, 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..9F189187, 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..BF189198, 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..DF189200xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF189210xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF189220x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0189231, 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..s2189241, 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..s4189251, 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..s6189261, 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..s818927}18928};1892918930JSON_ASSERT(byte < utf8d.size());18931const std::uint8_t type = utf8d[byte];1893218933codep = (state != UTF8_ACCEPT)18934? (byte & 0x3fu) | (codep << 6u)18935: (0xFFu >> type) & (byte);1893618937const std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);18938JSON_ASSERT(index < utf8d.size());18939state = utf8d[index];18940return state;18941}1894218943/*18944* Overload to make the compiler happy while it is instantiating18945* dump_integer for number_unsigned_t.18946* Must never be called.18947*/18948number_unsigned_t remove_sign(number_unsigned_t x)18949{18950JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE18951return x; // LCOV_EXCL_LINE18952}1895318954/*18955* Helper function for dump_integer18956*18957* This function takes a negative signed integer and returns its absolute18958* value as unsigned integer. The plus/minus shuffling is necessary as we can18959* not directly remove the sign of an arbitrary signed integer as the18960* absolute values of INT_MIN and INT_MAX are usually not the same. See18961* #1708 for details.18962*/18963inline number_unsigned_t remove_sign(number_integer_t x) noexcept18964{18965JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)18966return static_cast<number_unsigned_t>(-(x + 1)) + 1;18967}1896818969private:18970/// the output of the serializer18971output_adapter_t<char> o = nullptr;1897218973/// a (hopefully) large enough character buffer18974std::array<char, 64> number_buffer{{}};1897518976/// the locale18977const std::lconv* loc = nullptr;18978/// the locale's thousand separator character18979const char thousands_sep = '\0';18980/// the locale's decimal point character18981const char decimal_point = '\0';1898218983/// string buffer18984std::array<char, 512> string_buffer{{}};1898518986/// the indentation character18987const char indent_char;18988/// the indentation string18989string_t indent_string;1899018991/// error_handler how to react on decoding errors18992const error_handler_t error_handler;18993};1899418995} // namespace detail18996NLOHMANN_JSON_NAMESPACE_END1899718998// #include <nlohmann/detail/value_t.hpp>1899919000// #include <nlohmann/json_fwd.hpp>1900119002// #include <nlohmann/ordered_map.hpp>19003// __ _____ _____ _____19004// __| | __| | | | JSON for Modern C++19005// | | |__ | | | | | | version 3.11.319006// |_____|_____|_____|_|___| https://github.com/nlohmann/json19007//19008// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>19009// SPDX-License-Identifier: MIT19010190111901219013#include <functional> // equal_to, less19014#include <initializer_list> // initializer_list19015#include <iterator> // input_iterator_tag, iterator_traits19016#include <memory> // allocator19017#include <stdexcept> // for out_of_range19018#include <type_traits> // enable_if, is_convertible19019#include <utility> // pair19020#include <vector> // vector1902119022// #include <nlohmann/detail/macro_scope.hpp>1902319024// #include <nlohmann/detail/meta/type_traits.hpp>190251902619027NLOHMANN_JSON_NAMESPACE_BEGIN1902819029/// ordered_map: a minimal map-like container that preserves insertion order19030/// for use within nlohmann::basic_json<ordered_map>19031template <class Key, class T, class IgnoredLess = std::less<Key>,19032class Allocator = std::allocator<std::pair<const Key, T>>>19033struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>19034{19035using key_type = Key;19036using mapped_type = T;19037using Container = std::vector<std::pair<const Key, T>, Allocator>;19038using iterator = typename Container::iterator;19039using const_iterator = typename Container::const_iterator;19040using size_type = typename Container::size_type;19041using value_type = typename Container::value_type;19042#ifdef JSON_HAS_CPP_1419043using key_compare = std::equal_to<>;19044#else19045using key_compare = std::equal_to<Key>;19046#endif1904719048// Explicit constructors instead of `using Container::Container`19049// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)19050ordered_map() noexcept(noexcept(Container())) : Container{} {}19051explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}19052template <class It>19053ordered_map(It first, It last, const Allocator& alloc = Allocator())19054: Container{first, last, alloc} {}19055ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )19056: Container{init, alloc} {}1905719058std::pair<iterator, bool> emplace(const key_type& key, T&& t)19059{19060for (auto it = this->begin(); it != this->end(); ++it)19061{19062if (m_compare(it->first, key))19063{19064return {it, false};19065}19066}19067Container::emplace_back(key, std::forward<T>(t));19068return {std::prev(this->end()), true};19069}1907019071template<class KeyType, detail::enable_if_t<19072detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>19073std::pair<iterator, bool> emplace(KeyType && key, T && t)19074{19075for (auto it = this->begin(); it != this->end(); ++it)19076{19077if (m_compare(it->first, key))19078{19079return {it, false};19080}19081}19082Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));19083return {std::prev(this->end()), true};19084}1908519086T& operator[](const key_type& key)19087{19088return emplace(key, T{}).first->second;19089}1909019091template<class KeyType, detail::enable_if_t<19092detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>19093T & operator[](KeyType && key)19094{19095return emplace(std::forward<KeyType>(key), T{}).first->second;19096}1909719098const T& operator[](const key_type& key) const19099{19100return at(key);19101}1910219103template<class KeyType, detail::enable_if_t<19104detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>19105const T & operator[](KeyType && key) const19106{19107return at(std::forward<KeyType>(key));19108}1910919110T& at(const key_type& key)19111{19112for (auto it = this->begin(); it != this->end(); ++it)19113{19114if (m_compare(it->first, key))19115{19116return it->second;19117}19118}1911919120JSON_THROW(std::out_of_range("key not found"));19121}1912219123template<class KeyType, detail::enable_if_t<19124detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>19125T & at(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)19126{19127for (auto it = this->begin(); it != this->end(); ++it)19128{19129if (m_compare(it->first, key))19130{19131return it->second;19132}19133}1913419135JSON_THROW(std::out_of_range("key not found"));19136}1913719138const T& at(const key_type& key) const19139{19140for (auto it = this->begin(); it != this->end(); ++it)19141{19142if (m_compare(it->first, key))19143{19144return it->second;19145}19146}1914719148JSON_THROW(std::out_of_range("key not found"));19149}1915019151template<class KeyType, detail::enable_if_t<19152detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>19153const T & at(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)19154{19155for (auto it = this->begin(); it != this->end(); ++it)19156{19157if (m_compare(it->first, key))19158{19159return it->second;19160}19161}1916219163JSON_THROW(std::out_of_range("key not found"));19164}1916519166size_type erase(const key_type& key)19167{19168for (auto it = this->begin(); it != this->end(); ++it)19169{19170if (m_compare(it->first, key))19171{19172// Since we cannot move const Keys, re-construct them in place19173for (auto next = it; ++next != this->end(); ++it)19174{19175it->~value_type(); // Destroy but keep allocation19176new (&*it) value_type{std::move(*next)};19177}19178Container::pop_back();19179return 1;19180}19181}19182return 0;19183}1918419185template<class KeyType, detail::enable_if_t<19186detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>19187size_type erase(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)19188{19189for (auto it = this->begin(); it != this->end(); ++it)19190{19191if (m_compare(it->first, key))19192{19193// Since we cannot move const Keys, re-construct them in place19194for (auto next = it; ++next != this->end(); ++it)19195{19196it->~value_type(); // Destroy but keep allocation19197new (&*it) value_type{std::move(*next)};19198}19199Container::pop_back();19200return 1;19201}19202}19203return 0;19204}1920519206iterator erase(iterator pos)19207{19208return erase(pos, std::next(pos));19209}1921019211iterator erase(iterator first, iterator last)19212{19213if (first == last)19214{19215return first;19216}1921719218const auto elements_affected = std::distance(first, last);19219const auto offset = std::distance(Container::begin(), first);1922019221// This is the start situation. We need to delete elements_affected19222// elements (3 in this example: e, f, g), and need to return an19223// iterator past the last deleted element (h in this example).19224// Note that offset is the distance from the start of the vector19225// to first. We will need this later.1922619227// [ a, b, c, d, e, f, g, h, i, j ]19228// ^ ^19229// first last1923019231// Since we cannot move const Keys, we re-construct them in place.19232// We start at first and re-construct (viz. copy) the elements from19233// the back of the vector. Example for first iteration:1923419235// ,--------.19236// v | destroy e and re-construct with h19237// [ a, b, c, d, e, f, g, h, i, j ]19238// ^ ^19239// it it + elements_affected1924019241for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)19242{19243it->~value_type(); // destroy but keep allocation19244new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it19245}1924619247// [ a, b, c, d, h, i, j, h, i, j ]19248// ^ ^19249// first last1925019251// remove the unneeded elements at the end of the vector19252Container::resize(this->size() - static_cast<size_type>(elements_affected));1925319254// [ a, b, c, d, h, i, j ]19255// ^ ^19256// first last1925719258// first is now pointing past the last deleted element, but we cannot19259// use this iterator, because it may have been invalidated by the19260// resize call. Instead, we can return begin() + offset.19261return Container::begin() + offset;19262}1926319264size_type count(const key_type& key) const19265{19266for (auto it = this->begin(); it != this->end(); ++it)19267{19268if (m_compare(it->first, key))19269{19270return 1;19271}19272}19273return 0;19274}1927519276template<class KeyType, detail::enable_if_t<19277detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>19278size_type count(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)19279{19280for (auto it = this->begin(); it != this->end(); ++it)19281{19282if (m_compare(it->first, key))19283{19284return 1;19285}19286}19287return 0;19288}1928919290iterator find(const key_type& key)19291{19292for (auto it = this->begin(); it != this->end(); ++it)19293{19294if (m_compare(it->first, key))19295{19296return it;19297}19298}19299return Container::end();19300}1930119302template<class KeyType, detail::enable_if_t<19303detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>19304iterator find(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)19305{19306for (auto it = this->begin(); it != this->end(); ++it)19307{19308if (m_compare(it->first, key))19309{19310return it;19311}19312}19313return Container::end();19314}1931519316const_iterator find(const key_type& key) const19317{19318for (auto it = this->begin(); it != this->end(); ++it)19319{19320if (m_compare(it->first, key))19321{19322return it;19323}19324}19325return Container::end();19326}1932719328std::pair<iterator, bool> insert( value_type&& value )19329{19330return emplace(value.first, std::move(value.second));19331}1933219333std::pair<iterator, bool> insert( const value_type& value )19334{19335for (auto it = this->begin(); it != this->end(); ++it)19336{19337if (m_compare(it->first, value.first))19338{19339return {it, false};19340}19341}19342Container::push_back(value);19343return {--this->end(), true};19344}1934519346template<typename InputIt>19347using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,19348std::input_iterator_tag>::value>::type;1934919350template<typename InputIt, typename = require_input_iter<InputIt>>19351void insert(InputIt first, InputIt last)19352{19353for (auto it = first; it != last; ++it)19354{19355insert(*it);19356}19357}1935819359private:19360JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();19361};1936219363NLOHMANN_JSON_NAMESPACE_END193641936519366#if defined(JSON_HAS_CPP_17)19367#if JSON_HAS_STATIC_RTTI19368#include <any>19369#endif19370#include <string_view>19371#endif1937219373/*!19374@brief namespace for Niels Lohmann19375@see https://github.com/nlohmann19376@since version 1.0.019377*/19378NLOHMANN_JSON_NAMESPACE_BEGIN1937919380/*!19381@brief a class to store JSON values1938219383@internal19384@invariant The member variables @a m_value and @a m_type have the following19385relationship:19386- If `m_type == value_t::object`, then `m_value.object != nullptr`.19387- If `m_type == value_t::array`, then `m_value.array != nullptr`.19388- If `m_type == value_t::string`, then `m_value.string != nullptr`.19389The invariants are checked by member function assert_invariant().1939019391@note ObjectType trick from https://stackoverflow.com/a/986091119392@endinternal1939319394@since version 1.0.01939519396@nosubgrouping19397*/19398NLOHMANN_BASIC_JSON_TPL_DECLARATION19399class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)19400: public ::nlohmann::detail::json_base_class<CustomBaseClass>19401{19402private:19403template<detail::value_t> friend struct detail::external_constructor;1940419405template<typename>19406friend class ::nlohmann::json_pointer;19407// can be restored when json_pointer backwards compatibility is removed19408// friend ::nlohmann::json_pointer<StringType>;1940919410template<typename BasicJsonType, typename InputType>19411friend class ::nlohmann::detail::parser;19412friend ::nlohmann::detail::serializer<basic_json>;19413template<typename BasicJsonType>19414friend class ::nlohmann::detail::iter_impl;19415template<typename BasicJsonType, typename CharType>19416friend class ::nlohmann::detail::binary_writer;19417template<typename BasicJsonType, typename InputType, typename SAX>19418friend class ::nlohmann::detail::binary_reader;19419template<typename BasicJsonType>19420friend class ::nlohmann::detail::json_sax_dom_parser;19421template<typename BasicJsonType>19422friend class ::nlohmann::detail::json_sax_dom_callback_parser;19423friend class ::nlohmann::detail::exception;1942419425/// workaround type for MSVC19426using basic_json_t = NLOHMANN_BASIC_JSON_TPL;19427using json_base_class_t = ::nlohmann::detail::json_base_class<CustomBaseClass>;1942819429JSON_PRIVATE_UNLESS_TESTED:19430// convenience aliases for types residing in namespace detail;19431using lexer = ::nlohmann::detail::lexer_base<basic_json>;1943219433template<typename InputAdapterType>19434static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(19435InputAdapterType adapter,19436detail::parser_callback_t<basic_json>cb = nullptr,19437const bool allow_exceptions = true,19438const bool ignore_comments = false19439)19440{19441return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),19442std::move(cb), allow_exceptions, ignore_comments);19443}1944419445private:19446using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;19447template<typename BasicJsonType>19448using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;19449template<typename BasicJsonType>19450using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;19451template<typename Iterator>19452using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;19453template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;1945419455template<typename CharType>19456using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;1945719458template<typename InputType>19459using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;19460template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;1946119462JSON_PRIVATE_UNLESS_TESTED:19463using serializer = ::nlohmann::detail::serializer<basic_json>;1946419465public:19466using value_t = detail::value_t;19467/// JSON Pointer, see @ref nlohmann::json_pointer19468using json_pointer = ::nlohmann::json_pointer<StringType>;19469template<typename T, typename SFINAE>19470using json_serializer = JSONSerializer<T, SFINAE>;19471/// how to treat decoding errors19472using error_handler_t = detail::error_handler_t;19473/// how to treat CBOR tags19474using cbor_tag_handler_t = detail::cbor_tag_handler_t;19475/// helper type for initializer lists of basic_json values19476using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;1947719478using input_format_t = detail::input_format_t;19479/// SAX interface type, see @ref nlohmann::json_sax19480using json_sax_t = json_sax<basic_json>;1948119482////////////////19483// exceptions //19484////////////////1948519486/// @name exceptions19487/// Classes to implement user-defined exceptions.19488/// @{1948919490using exception = detail::exception;19491using parse_error = detail::parse_error;19492using invalid_iterator = detail::invalid_iterator;19493using type_error = detail::type_error;19494using out_of_range = detail::out_of_range;19495using other_error = detail::other_error;1949619497/// @}1949819499/////////////////////19500// container types //19501/////////////////////1950219503/// @name container types19504/// The canonic container types to use @ref basic_json like any other STL19505/// container.19506/// @{1950719508/// the type of elements in a basic_json container19509using value_type = basic_json;1951019511/// the type of an element reference19512using reference = value_type&;19513/// the type of an element const reference19514using const_reference = const value_type&;1951519516/// a type to represent differences between iterators19517using difference_type = std::ptrdiff_t;19518/// a type to represent container sizes19519using size_type = std::size_t;1952019521/// the allocator type19522using allocator_type = AllocatorType<basic_json>;1952319524/// the type of an element pointer19525using pointer = typename std::allocator_traits<allocator_type>::pointer;19526/// the type of an element const pointer19527using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;1952819529/// an iterator for a basic_json container19530using iterator = iter_impl<basic_json>;19531/// a const iterator for a basic_json container19532using const_iterator = iter_impl<const basic_json>;19533/// a reverse iterator for a basic_json container19534using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;19535/// a const reverse iterator for a basic_json container19536using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;1953719538/// @}1953919540/// @brief returns the allocator associated with the container19541/// @sa https://json.nlohmann.me/api/basic_json/get_allocator/19542static allocator_type get_allocator()19543{19544return allocator_type();19545}1954619547/// @brief returns version information on the library19548/// @sa https://json.nlohmann.me/api/basic_json/meta/19549JSON_HEDLEY_WARN_UNUSED_RESULT19550static basic_json meta()19551{19552basic_json result;1955319554result["copyright"] = "(C) 2013-2023 Niels Lohmann";19555result["name"] = "JSON for Modern C++";19556result["url"] = "https://github.com/nlohmann/json";19557result["version"]["string"] =19558detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR), '.',19559std::to_string(NLOHMANN_JSON_VERSION_MINOR), '.',19560std::to_string(NLOHMANN_JSON_VERSION_PATCH));19561result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;19562result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;19563result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;1956419565#ifdef _WIN3219566result["platform"] = "win32";19567#elif defined __linux__19568result["platform"] = "linux";19569#elif defined __APPLE__19570result["platform"] = "apple";19571#elif defined __unix__19572result["platform"] = "unix";19573#else19574result["platform"] = "unknown";19575#endif1957619577#if defined(__ICC) || defined(__INTEL_COMPILER)19578result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};19579#elif defined(__clang__)19580result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};19581#elif defined(__GNUC__) || defined(__GNUG__)19582result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(19583std::to_string(__GNUC__), '.',19584std::to_string(__GNUC_MINOR__), '.',19585std::to_string(__GNUC_PATCHLEVEL__))19586}19587};19588#elif defined(__HP_cc) || defined(__HP_aCC)19589result["compiler"] = "hp"19590#elif defined(__IBMCPP__)19591result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};19592#elif defined(_MSC_VER)19593result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};19594#elif defined(__PGI)19595result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};19596#elif defined(__SUNPRO_CC)19597result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};19598#else19599result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};19600#endif1960119602#if defined(_MSVC_LANG)19603result["compiler"]["c++"] = std::to_string(_MSVC_LANG);19604#elif defined(__cplusplus)19605result["compiler"]["c++"] = std::to_string(__cplusplus);19606#else19607result["compiler"]["c++"] = "unknown";19608#endif19609return result;19610}1961119612///////////////////////////19613// JSON value data types //19614///////////////////////////1961519616/// @name JSON value data types19617/// The data types to store a JSON value. These types are derived from19618/// the template arguments passed to class @ref basic_json.19619/// @{1962019621/// @brief default object key comparator type19622/// The actual object key comparator type (@ref object_comparator_t) may be19623/// different.19624/// @sa https://json.nlohmann.me/api/basic_json/default_object_comparator_t/19625#if defined(JSON_HAS_CPP_14)19626// use of transparent comparator avoids unnecessary repeated construction of temporaries19627// in functions involving lookup by key with types other than object_t::key_type (aka. StringType)19628using default_object_comparator_t = std::less<>;19629#else19630using default_object_comparator_t = std::less<StringType>;19631#endif1963219633/// @brief a type for an object19634/// @sa https://json.nlohmann.me/api/basic_json/object_t/19635using object_t = ObjectType<StringType,19636basic_json,19637default_object_comparator_t,19638AllocatorType<std::pair<const StringType,19639basic_json>>>;1964019641/// @brief a type for an array19642/// @sa https://json.nlohmann.me/api/basic_json/array_t/19643using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;1964419645/// @brief a type for a string19646/// @sa https://json.nlohmann.me/api/basic_json/string_t/19647using string_t = StringType;1964819649/// @brief a type for a boolean19650/// @sa https://json.nlohmann.me/api/basic_json/boolean_t/19651using boolean_t = BooleanType;1965219653/// @brief a type for a number (integer)19654/// @sa https://json.nlohmann.me/api/basic_json/number_integer_t/19655using number_integer_t = NumberIntegerType;1965619657/// @brief a type for a number (unsigned)19658/// @sa https://json.nlohmann.me/api/basic_json/number_unsigned_t/19659using number_unsigned_t = NumberUnsignedType;1966019661/// @brief a type for a number (floating-point)19662/// @sa https://json.nlohmann.me/api/basic_json/number_float_t/19663using number_float_t = NumberFloatType;1966419665/// @brief a type for a packed binary type19666/// @sa https://json.nlohmann.me/api/basic_json/binary_t/19667using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;1966819669/// @brief object key comparator type19670/// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/19671using object_comparator_t = detail::actual_object_comparator_t<basic_json>;1967219673/// @}1967419675private:1967619677/// helper for exception-safe object creation19678template<typename T, typename... Args>19679JSON_HEDLEY_RETURNS_NON_NULL19680static T* create(Args&& ... args)19681{19682AllocatorType<T> alloc;19683using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;1968419685auto deleter = [&](T * obj)19686{19687AllocatorTraits::deallocate(alloc, obj, 1);19688};19689std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);19690AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);19691JSON_ASSERT(obj != nullptr);19692return obj.release();19693}1969419695////////////////////////19696// JSON value storage //19697////////////////////////1969819699JSON_PRIVATE_UNLESS_TESTED:19700/*!19701@brief a JSON value1970219703The actual storage for a JSON value of the @ref basic_json class. This19704union combines the different storage types for the JSON value types19705defined in @ref value_t.1970619707JSON type | value_t type | used type19708--------- | --------------- | ------------------------19709object | object | pointer to @ref object_t19710array | array | pointer to @ref array_t19711string | string | pointer to @ref string_t19712boolean | boolean | @ref boolean_t19713number | number_integer | @ref number_integer_t19714number | number_unsigned | @ref number_unsigned_t19715number | number_float | @ref number_float_t19716binary | binary | pointer to @ref binary_t19717null | null | *no value is stored*1971819719@note Variable-length types (objects, arrays, and strings) are stored as19720pointers. The size of the union should not exceed 64 bits if the default19721value types are used.1972219723@since version 1.0.019724*/19725union json_value19726{19727/// object (stored with pointer to save storage)19728object_t* object;19729/// array (stored with pointer to save storage)19730array_t* array;19731/// string (stored with pointer to save storage)19732string_t* string;19733/// binary (stored with pointer to save storage)19734binary_t* binary;19735/// boolean19736boolean_t boolean;19737/// number (integer)19738number_integer_t number_integer;19739/// number (unsigned integer)19740number_unsigned_t number_unsigned;19741/// number (floating-point)19742number_float_t number_float;1974319744/// default constructor (for null values)19745json_value() = default;19746/// constructor for booleans19747json_value(boolean_t v) noexcept : boolean(v) {}19748/// constructor for numbers (integer)19749json_value(number_integer_t v) noexcept : number_integer(v) {}19750/// constructor for numbers (unsigned)19751json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}19752/// constructor for numbers (floating-point)19753json_value(number_float_t v) noexcept : number_float(v) {}19754/// constructor for empty values of a given type19755json_value(value_t t)19756{19757switch (t)19758{19759case value_t::object:19760{19761object = create<object_t>();19762break;19763}1976419765case value_t::array:19766{19767array = create<array_t>();19768break;19769}1977019771case value_t::string:19772{19773string = create<string_t>("");19774break;19775}1977619777case value_t::binary:19778{19779binary = create<binary_t>();19780break;19781}1978219783case value_t::boolean:19784{19785boolean = static_cast<boolean_t>(false);19786break;19787}1978819789case value_t::number_integer:19790{19791number_integer = static_cast<number_integer_t>(0);19792break;19793}1979419795case value_t::number_unsigned:19796{19797number_unsigned = static_cast<number_unsigned_t>(0);19798break;19799}1980019801case value_t::number_float:19802{19803number_float = static_cast<number_float_t>(0.0);19804break;19805}1980619807case value_t::null:19808{19809object = nullptr; // silence warning, see #82119810break;19811}1981219813case value_t::discarded:19814default:19815{19816object = nullptr; // silence warning, see #82119817if (JSON_HEDLEY_UNLIKELY(t == value_t::null))19818{19819JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.3", nullptr)); // LCOV_EXCL_LINE19820}19821break;19822}19823}19824}1982519826/// constructor for strings19827json_value(const string_t& value) : string(create<string_t>(value)) {}1982819829/// constructor for rvalue strings19830json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}1983119832/// constructor for objects19833json_value(const object_t& value) : object(create<object_t>(value)) {}1983419835/// constructor for rvalue objects19836json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}1983719838/// constructor for arrays19839json_value(const array_t& value) : array(create<array_t>(value)) {}1984019841/// constructor for rvalue arrays19842json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}1984319844/// constructor for binary arrays19845json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}1984619847/// constructor for rvalue binary arrays19848json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}1984919850/// constructor for binary arrays (internal type)19851json_value(const binary_t& value) : binary(create<binary_t>(value)) {}1985219853/// constructor for rvalue binary arrays (internal type)19854json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}1985519856void destroy(value_t t)19857{19858if (19859(t == value_t::object && object == nullptr) ||19860(t == value_t::array && array == nullptr) ||19861(t == value_t::string && string == nullptr) ||19862(t == value_t::binary && binary == nullptr)19863)19864{19865//not initialized (e.g. due to exception in the ctor)19866return;19867}19868if (t == value_t::array || t == value_t::object)19869{19870// flatten the current json_value to a heap-allocated stack19871std::vector<basic_json> stack;1987219873// move the top-level items to stack19874if (t == value_t::array)19875{19876stack.reserve(array->size());19877std::move(array->begin(), array->end(), std::back_inserter(stack));19878}19879else19880{19881stack.reserve(object->size());19882for (auto&& it : *object)19883{19884stack.push_back(std::move(it.second));19885}19886}1988719888while (!stack.empty())19889{19890// move the last item to local variable to be processed19891basic_json current_item(std::move(stack.back()));19892stack.pop_back();1989319894// if current_item is array/object, move19895// its children to the stack to be processed later19896if (current_item.is_array())19897{19898std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));1989919900current_item.m_data.m_value.array->clear();19901}19902else if (current_item.is_object())19903{19904for (auto&& it : *current_item.m_data.m_value.object)19905{19906stack.push_back(std::move(it.second));19907}1990819909current_item.m_data.m_value.object->clear();19910}1991119912// it's now safe that current_item get destructed19913// since it doesn't have any children19914}19915}1991619917switch (t)19918{19919case value_t::object:19920{19921AllocatorType<object_t> alloc;19922std::allocator_traits<decltype(alloc)>::destroy(alloc, object);19923std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);19924break;19925}1992619927case value_t::array:19928{19929AllocatorType<array_t> alloc;19930std::allocator_traits<decltype(alloc)>::destroy(alloc, array);19931std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);19932break;19933}1993419935case value_t::string:19936{19937AllocatorType<string_t> alloc;19938std::allocator_traits<decltype(alloc)>::destroy(alloc, string);19939std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);19940break;19941}1994219943case value_t::binary:19944{19945AllocatorType<binary_t> alloc;19946std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);19947std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);19948break;19949}1995019951case value_t::null:19952case value_t::boolean:19953case value_t::number_integer:19954case value_t::number_unsigned:19955case value_t::number_float:19956case value_t::discarded:19957default:19958{19959break;19960}19961}19962}19963};1996419965private:19966/*!19967@brief checks the class invariants1996819969This function asserts the class invariants. It needs to be called at the19970end of every constructor to make sure that created objects respect the19971invariant. Furthermore, it has to be called each time the type of a JSON19972value is changed, because the invariant expresses a relationship between19973@a m_type and @a m_value.1997419975Furthermore, the parent relation is checked for arrays and objects: If19976@a check_parents true and the value is an array or object, then the19977container's elements must have the current value as parent.1997819979@param[in] check_parents whether the parent relation should be checked.19980The value is true by default and should only be set to false19981during destruction of objects when the invariant does not19982need to hold.19983*/19984void assert_invariant(bool check_parents = true) const noexcept19985{19986JSON_ASSERT(m_data.m_type != value_t::object || m_data.m_value.object != nullptr);19987JSON_ASSERT(m_data.m_type != value_t::array || m_data.m_value.array != nullptr);19988JSON_ASSERT(m_data.m_type != value_t::string || m_data.m_value.string != nullptr);19989JSON_ASSERT(m_data.m_type != value_t::binary || m_data.m_value.binary != nullptr);1999019991#if JSON_DIAGNOSTICS19992JSON_TRY19993{19994// cppcheck-suppress assertWithSideEffect19995JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)19996{19997return j.m_parent == this;19998}));19999}20000JSON_CATCH(...) {} // LCOV_EXCL_LINE20001#endif20002static_cast<void>(check_parents);20003}2000420005void set_parents()20006{20007#if JSON_DIAGNOSTICS20008switch (m_data.m_type)20009{20010case value_t::array:20011{20012for (auto& element : *m_data.m_value.array)20013{20014element.m_parent = this;20015}20016break;20017}2001820019case value_t::object:20020{20021for (auto& element : *m_data.m_value.object)20022{20023element.second.m_parent = this;20024}20025break;20026}2002720028case value_t::null:20029case value_t::string:20030case value_t::boolean:20031case value_t::number_integer:20032case value_t::number_unsigned:20033case value_t::number_float:20034case value_t::binary:20035case value_t::discarded:20036default:20037break;20038}20039#endif20040}2004120042iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)20043{20044#if JSON_DIAGNOSTICS20045for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)20046{20047(it + i)->m_parent = this;20048}20049#else20050static_cast<void>(count_set_parents);20051#endif20052return it;20053}2005420055reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))20056{20057#if JSON_DIAGNOSTICS20058if (old_capacity != static_cast<std::size_t>(-1))20059{20060// see https://github.com/nlohmann/json/issues/283820061JSON_ASSERT(type() == value_t::array);20062if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))20063{20064// capacity has changed: update all parents20065set_parents();20066return j;20067}20068}2006920070// ordered_json uses a vector internally, so pointers could have20071// been invalidated; see https://github.com/nlohmann/json/issues/296220072#ifdef JSON_HEDLEY_MSVC_VERSION20073#pragma warning(push )20074#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr20075#endif20076if (detail::is_ordered_map<object_t>::value)20077{20078set_parents();20079return j;20080}20081#ifdef JSON_HEDLEY_MSVC_VERSION20082#pragma warning( pop )20083#endif2008420085j.m_parent = this;20086#else20087static_cast<void>(j);20088static_cast<void>(old_capacity);20089#endif20090return j;20091}2009220093public:20094//////////////////////////20095// JSON parser callback //20096//////////////////////////2009720098/// @brief parser event types20099/// @sa https://json.nlohmann.me/api/basic_json/parse_event_t/20100using parse_event_t = detail::parse_event_t;2010120102/// @brief per-element parser callback type20103/// @sa https://json.nlohmann.me/api/basic_json/parser_callback_t/20104using parser_callback_t = detail::parser_callback_t<basic_json>;2010520106//////////////////20107// constructors //20108//////////////////2010920110/// @name constructors and destructors20111/// Constructors of class @ref basic_json, copy/move constructor, copy20112/// assignment, static functions creating objects, and the destructor.20113/// @{2011420115/// @brief create an empty value with a given type20116/// @sa https://json.nlohmann.me/api/basic_json/basic_json/20117basic_json(const value_t v)20118: m_data(v)20119{20120assert_invariant();20121}2012220123/// @brief create a null object20124/// @sa https://json.nlohmann.me/api/basic_json/basic_json/20125basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)20126: basic_json(value_t::null)20127{20128assert_invariant();20129}2013020131/// @brief create a JSON value from compatible types20132/// @sa https://json.nlohmann.me/api/basic_json/basic_json/20133template < typename CompatibleType,20134typename U = detail::uncvref_t<CompatibleType>,20135detail::enable_if_t <20136!detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >20137basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)20138JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),20139std::forward<CompatibleType>(val))))20140{20141JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));20142set_parents();20143assert_invariant();20144}2014520146/// @brief create a JSON value from an existing one20147/// @sa https://json.nlohmann.me/api/basic_json/basic_json/20148template < typename BasicJsonType,20149detail::enable_if_t <20150detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >20151basic_json(const BasicJsonType& val)20152{20153using other_boolean_t = typename BasicJsonType::boolean_t;20154using other_number_float_t = typename BasicJsonType::number_float_t;20155using other_number_integer_t = typename BasicJsonType::number_integer_t;20156using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;20157using other_string_t = typename BasicJsonType::string_t;20158using other_object_t = typename BasicJsonType::object_t;20159using other_array_t = typename BasicJsonType::array_t;20160using other_binary_t = typename BasicJsonType::binary_t;2016120162switch (val.type())20163{20164case value_t::boolean:20165JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());20166break;20167case value_t::number_float:20168JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());20169break;20170case value_t::number_integer:20171JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());20172break;20173case value_t::number_unsigned:20174JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());20175break;20176case value_t::string:20177JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());20178break;20179case value_t::object:20180JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());20181break;20182case value_t::array:20183JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());20184break;20185case value_t::binary:20186JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());20187break;20188case value_t::null:20189*this = nullptr;20190break;20191case value_t::discarded:20192m_data.m_type = value_t::discarded;20193break;20194default: // LCOV_EXCL_LINE20195JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE20196}20197JSON_ASSERT(m_data.m_type == val.type());20198set_parents();20199assert_invariant();20200}2020120202/// @brief create a container (array or object) from an initializer list20203/// @sa https://json.nlohmann.me/api/basic_json/basic_json/20204basic_json(initializer_list_t init,20205bool type_deduction = true,20206value_t manual_type = value_t::array)20207{20208// check if each element is an array with two elements whose first20209// element is a string20210bool is_an_object = std::all_of(init.begin(), init.end(),20211[](const detail::json_ref<basic_json>& element_ref)20212{20213// The cast is to ensure op[size_type] is called, bearing in mind size_type may not be int;20214// (many string types can be constructed from 0 via its null-pointer guise, so we get a20215// broken call to op[key_type], the wrong semantics and a 4804 warning on Windows)20216return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[static_cast<size_type>(0)].is_string();20217});2021820219// adjust type if type deduction is not wanted20220if (!type_deduction)20221{20222// if array is wanted, do not create an object though possible20223if (manual_type == value_t::array)20224{20225is_an_object = false;20226}2022720228// if object is wanted but impossible, throw an exception20229if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))20230{20231JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));20232}20233}2023420235if (is_an_object)20236{20237// the initializer list is a list of pairs -> create object20238m_data.m_type = value_t::object;20239m_data.m_value = value_t::object;2024020241for (auto& element_ref : init)20242{20243auto element = element_ref.moved_or_copied();20244m_data.m_value.object->emplace(20245std::move(*((*element.m_data.m_value.array)[0].m_data.m_value.string)),20246std::move((*element.m_data.m_value.array)[1]));20247}20248}20249else20250{20251// the initializer list describes an array -> create array20252m_data.m_type = value_t::array;20253m_data.m_value.array = create<array_t>(init.begin(), init.end());20254}2025520256set_parents();20257assert_invariant();20258}2025920260/// @brief explicitly create a binary array (without subtype)20261/// @sa https://json.nlohmann.me/api/basic_json/binary/20262JSON_HEDLEY_WARN_UNUSED_RESULT20263static basic_json binary(const typename binary_t::container_type& init)20264{20265auto res = basic_json();20266res.m_data.m_type = value_t::binary;20267res.m_data.m_value = init;20268return res;20269}2027020271/// @brief explicitly create a binary array (with subtype)20272/// @sa https://json.nlohmann.me/api/basic_json/binary/20273JSON_HEDLEY_WARN_UNUSED_RESULT20274static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)20275{20276auto res = basic_json();20277res.m_data.m_type = value_t::binary;20278res.m_data.m_value = binary_t(init, subtype);20279return res;20280}2028120282/// @brief explicitly create a binary array20283/// @sa https://json.nlohmann.me/api/basic_json/binary/20284JSON_HEDLEY_WARN_UNUSED_RESULT20285static basic_json binary(typename binary_t::container_type&& init)20286{20287auto res = basic_json();20288res.m_data.m_type = value_t::binary;20289res.m_data.m_value = std::move(init);20290return res;20291}2029220293/// @brief explicitly create a binary array (with subtype)20294/// @sa https://json.nlohmann.me/api/basic_json/binary/20295JSON_HEDLEY_WARN_UNUSED_RESULT20296static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)20297{20298auto res = basic_json();20299res.m_data.m_type = value_t::binary;20300res.m_data.m_value = binary_t(std::move(init), subtype);20301return res;20302}2030320304/// @brief explicitly create an array from an initializer list20305/// @sa https://json.nlohmann.me/api/basic_json/array/20306JSON_HEDLEY_WARN_UNUSED_RESULT20307static basic_json array(initializer_list_t init = {})20308{20309return basic_json(init, false, value_t::array);20310}2031120312/// @brief explicitly create an object from an initializer list20313/// @sa https://json.nlohmann.me/api/basic_json/object/20314JSON_HEDLEY_WARN_UNUSED_RESULT20315static basic_json object(initializer_list_t init = {})20316{20317return basic_json(init, false, value_t::object);20318}2031920320/// @brief construct an array with count copies of given value20321/// @sa https://json.nlohmann.me/api/basic_json/basic_json/20322basic_json(size_type cnt, const basic_json& val):20323m_data{cnt, val}20324{20325set_parents();20326assert_invariant();20327}2032820329/// @brief construct a JSON container given an iterator range20330/// @sa https://json.nlohmann.me/api/basic_json/basic_json/20331template < class InputIT, typename std::enable_if <20332std::is_same<InputIT, typename basic_json_t::iterator>::value ||20333std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >20334basic_json(InputIT first, InputIT last)20335{20336JSON_ASSERT(first.m_object != nullptr);20337JSON_ASSERT(last.m_object != nullptr);2033820339// make sure iterator fits the current value20340if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))20341{20342JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));20343}2034420345// copy type from first iterator20346m_data.m_type = first.m_object->m_data.m_type;2034720348// check if iterator range is complete for primitive values20349switch (m_data.m_type)20350{20351case value_t::boolean:20352case value_t::number_float:20353case value_t::number_integer:20354case value_t::number_unsigned:20355case value_t::string:20356{20357if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()20358|| !last.m_it.primitive_iterator.is_end()))20359{20360JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));20361}20362break;20363}2036420365case value_t::null:20366case value_t::object:20367case value_t::array:20368case value_t::binary:20369case value_t::discarded:20370default:20371break;20372}2037320374switch (m_data.m_type)20375{20376case value_t::number_integer:20377{20378m_data.m_value.number_integer = first.m_object->m_data.m_value.number_integer;20379break;20380}2038120382case value_t::number_unsigned:20383{20384m_data.m_value.number_unsigned = first.m_object->m_data.m_value.number_unsigned;20385break;20386}2038720388case value_t::number_float:20389{20390m_data.m_value.number_float = first.m_object->m_data.m_value.number_float;20391break;20392}2039320394case value_t::boolean:20395{20396m_data.m_value.boolean = first.m_object->m_data.m_value.boolean;20397break;20398}2039920400case value_t::string:20401{20402m_data.m_value = *first.m_object->m_data.m_value.string;20403break;20404}2040520406case value_t::object:20407{20408m_data.m_value.object = create<object_t>(first.m_it.object_iterator,20409last.m_it.object_iterator);20410break;20411}2041220413case value_t::array:20414{20415m_data.m_value.array = create<array_t>(first.m_it.array_iterator,20416last.m_it.array_iterator);20417break;20418}2041920420case value_t::binary:20421{20422m_data.m_value = *first.m_object->m_data.m_value.binary;20423break;20424}2042520426case value_t::null:20427case value_t::discarded:20428default:20429JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));20430}2043120432set_parents();20433assert_invariant();20434}2043520436///////////////////////////////////////20437// other constructors and destructor //20438///////////////////////////////////////2043920440template<typename JsonRef,20441detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,20442std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >20443basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}2044420445/// @brief copy constructor20446/// @sa https://json.nlohmann.me/api/basic_json/basic_json/20447basic_json(const basic_json& other)20448: json_base_class_t(other)20449{20450m_data.m_type = other.m_data.m_type;20451// check of passed value is valid20452other.assert_invariant();2045320454switch (m_data.m_type)20455{20456case value_t::object:20457{20458m_data.m_value = *other.m_data.m_value.object;20459break;20460}2046120462case value_t::array:20463{20464m_data.m_value = *other.m_data.m_value.array;20465break;20466}2046720468case value_t::string:20469{20470m_data.m_value = *other.m_data.m_value.string;20471break;20472}2047320474case value_t::boolean:20475{20476m_data.m_value = other.m_data.m_value.boolean;20477break;20478}2047920480case value_t::number_integer:20481{20482m_data.m_value = other.m_data.m_value.number_integer;20483break;20484}2048520486case value_t::number_unsigned:20487{20488m_data.m_value = other.m_data.m_value.number_unsigned;20489break;20490}2049120492case value_t::number_float:20493{20494m_data.m_value = other.m_data.m_value.number_float;20495break;20496}2049720498case value_t::binary:20499{20500m_data.m_value = *other.m_data.m_value.binary;20501break;20502}2050320504case value_t::null:20505case value_t::discarded:20506default:20507break;20508}2050920510set_parents();20511assert_invariant();20512}2051320514/// @brief move constructor20515/// @sa https://json.nlohmann.me/api/basic_json/basic_json/20516basic_json(basic_json&& other) noexcept20517: json_base_class_t(std::forward<json_base_class_t>(other)),20518m_data(std::move(other.m_data))20519{20520// check that passed value is valid20521other.assert_invariant(false);2052220523// invalidate payload20524other.m_data.m_type = value_t::null;20525other.m_data.m_value = {};2052620527set_parents();20528assert_invariant();20529}2053020531/// @brief copy assignment20532/// @sa https://json.nlohmann.me/api/basic_json/operator=/20533basic_json& operator=(basic_json other) noexcept (20534std::is_nothrow_move_constructible<value_t>::value&&20535std::is_nothrow_move_assignable<value_t>::value&&20536std::is_nothrow_move_constructible<json_value>::value&&20537std::is_nothrow_move_assignable<json_value>::value&&20538std::is_nothrow_move_assignable<json_base_class_t>::value20539)20540{20541// check that passed value is valid20542other.assert_invariant();2054320544using std::swap;20545swap(m_data.m_type, other.m_data.m_type);20546swap(m_data.m_value, other.m_data.m_value);20547json_base_class_t::operator=(std::move(other));2054820549set_parents();20550assert_invariant();20551return *this;20552}2055320554/// @brief destructor20555/// @sa https://json.nlohmann.me/api/basic_json/~basic_json/20556~basic_json() noexcept20557{20558assert_invariant(false);20559}2056020561/// @}2056220563public:20564///////////////////////20565// object inspection //20566///////////////////////2056720568/// @name object inspection20569/// Functions to inspect the type of a JSON value.20570/// @{2057120572/// @brief serialization20573/// @sa https://json.nlohmann.me/api/basic_json/dump/20574string_t dump(const int indent = -1,20575const char indent_char = ' ',20576const bool ensure_ascii = false,20577const error_handler_t error_handler = error_handler_t::strict) const20578{20579string_t result;20580serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);2058120582if (indent >= 0)20583{20584s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));20585}20586else20587{20588s.dump(*this, false, ensure_ascii, 0);20589}2059020591return result;20592}2059320594/// @brief return the type of the JSON value (explicit)20595/// @sa https://json.nlohmann.me/api/basic_json/type/20596constexpr value_t type() const noexcept20597{20598return m_data.m_type;20599}2060020601/// @brief return whether type is primitive20602/// @sa https://json.nlohmann.me/api/basic_json/is_primitive/20603constexpr bool is_primitive() const noexcept20604{20605return is_null() || is_string() || is_boolean() || is_number() || is_binary();20606}2060720608/// @brief return whether type is structured20609/// @sa https://json.nlohmann.me/api/basic_json/is_structured/20610constexpr bool is_structured() const noexcept20611{20612return is_array() || is_object();20613}2061420615/// @brief return whether value is null20616/// @sa https://json.nlohmann.me/api/basic_json/is_null/20617constexpr bool is_null() const noexcept20618{20619return m_data.m_type == value_t::null;20620}2062120622/// @brief return whether value is a boolean20623/// @sa https://json.nlohmann.me/api/basic_json/is_boolean/20624constexpr bool is_boolean() const noexcept20625{20626return m_data.m_type == value_t::boolean;20627}2062820629/// @brief return whether value is a number20630/// @sa https://json.nlohmann.me/api/basic_json/is_number/20631constexpr bool is_number() const noexcept20632{20633return is_number_integer() || is_number_float();20634}2063520636/// @brief return whether value is an integer number20637/// @sa https://json.nlohmann.me/api/basic_json/is_number_integer/20638constexpr bool is_number_integer() const noexcept20639{20640return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;20641}2064220643/// @brief return whether value is an unsigned integer number20644/// @sa https://json.nlohmann.me/api/basic_json/is_number_unsigned/20645constexpr bool is_number_unsigned() const noexcept20646{20647return m_data.m_type == value_t::number_unsigned;20648}2064920650/// @brief return whether value is a floating-point number20651/// @sa https://json.nlohmann.me/api/basic_json/is_number_float/20652constexpr bool is_number_float() const noexcept20653{20654return m_data.m_type == value_t::number_float;20655}2065620657/// @brief return whether value is an object20658/// @sa https://json.nlohmann.me/api/basic_json/is_object/20659constexpr bool is_object() const noexcept20660{20661return m_data.m_type == value_t::object;20662}2066320664/// @brief return whether value is an array20665/// @sa https://json.nlohmann.me/api/basic_json/is_array/20666constexpr bool is_array() const noexcept20667{20668return m_data.m_type == value_t::array;20669}2067020671/// @brief return whether value is a string20672/// @sa https://json.nlohmann.me/api/basic_json/is_string/20673constexpr bool is_string() const noexcept20674{20675return m_data.m_type == value_t::string;20676}2067720678/// @brief return whether value is a binary array20679/// @sa https://json.nlohmann.me/api/basic_json/is_binary/20680constexpr bool is_binary() const noexcept20681{20682return m_data.m_type == value_t::binary;20683}2068420685/// @brief return whether value is discarded20686/// @sa https://json.nlohmann.me/api/basic_json/is_discarded/20687constexpr bool is_discarded() const noexcept20688{20689return m_data.m_type == value_t::discarded;20690}2069120692/// @brief return the type of the JSON value (implicit)20693/// @sa https://json.nlohmann.me/api/basic_json/operator_value_t/20694constexpr operator value_t() const noexcept20695{20696return m_data.m_type;20697}2069820699/// @}2070020701private:20702//////////////////20703// value access //20704//////////////////2070520706/// get a boolean (explicit)20707boolean_t get_impl(boolean_t* /*unused*/) const20708{20709if (JSON_HEDLEY_LIKELY(is_boolean()))20710{20711return m_data.m_value.boolean;20712}2071320714JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));20715}2071620717/// get a pointer to the value (object)20718object_t* get_impl_ptr(object_t* /*unused*/) noexcept20719{20720return is_object() ? m_data.m_value.object : nullptr;20721}2072220723/// get a pointer to the value (object)20724constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept20725{20726return is_object() ? m_data.m_value.object : nullptr;20727}2072820729/// get a pointer to the value (array)20730array_t* get_impl_ptr(array_t* /*unused*/) noexcept20731{20732return is_array() ? m_data.m_value.array : nullptr;20733}2073420735/// get a pointer to the value (array)20736constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept20737{20738return is_array() ? m_data.m_value.array : nullptr;20739}2074020741/// get a pointer to the value (string)20742string_t* get_impl_ptr(string_t* /*unused*/) noexcept20743{20744return is_string() ? m_data.m_value.string : nullptr;20745}2074620747/// get a pointer to the value (string)20748constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept20749{20750return is_string() ? m_data.m_value.string : nullptr;20751}2075220753/// get a pointer to the value (boolean)20754boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept20755{20756return is_boolean() ? &m_data.m_value.boolean : nullptr;20757}2075820759/// get a pointer to the value (boolean)20760constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept20761{20762return is_boolean() ? &m_data.m_value.boolean : nullptr;20763}2076420765/// get a pointer to the value (integer number)20766number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept20767{20768return is_number_integer() ? &m_data.m_value.number_integer : nullptr;20769}2077020771/// get a pointer to the value (integer number)20772constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept20773{20774return is_number_integer() ? &m_data.m_value.number_integer : nullptr;20775}2077620777/// get a pointer to the value (unsigned number)20778number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept20779{20780return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;20781}2078220783/// get a pointer to the value (unsigned number)20784constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept20785{20786return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;20787}2078820789/// get a pointer to the value (floating-point number)20790number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept20791{20792return is_number_float() ? &m_data.m_value.number_float : nullptr;20793}2079420795/// get a pointer to the value (floating-point number)20796constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept20797{20798return is_number_float() ? &m_data.m_value.number_float : nullptr;20799}2080020801/// get a pointer to the value (binary)20802binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept20803{20804return is_binary() ? m_data.m_value.binary : nullptr;20805}2080620807/// get a pointer to the value (binary)20808constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept20809{20810return is_binary() ? m_data.m_value.binary : nullptr;20811}2081220813/*!20814@brief helper function to implement get_ref()2081520816This function helps to implement get_ref() without code duplication for20817const and non-const overloads2081820819@tparam ThisType will be deduced as `basic_json` or `const basic_json`2082020821@throw type_error.303 if ReferenceType does not match underlying value20822type of the current JSON20823*/20824template<typename ReferenceType, typename ThisType>20825static ReferenceType get_ref_impl(ThisType& obj)20826{20827// delegate the call to get_ptr<>()20828auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();2082920830if (JSON_HEDLEY_LIKELY(ptr != nullptr))20831{20832return *ptr;20833}2083420835JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));20836}2083720838public:20839/// @name value access20840/// Direct access to the stored value of a JSON value.20841/// @{2084220843/// @brief get a pointer value (implicit)20844/// @sa https://json.nlohmann.me/api/basic_json/get_ptr/20845template<typename PointerType, typename std::enable_if<20846std::is_pointer<PointerType>::value, int>::type = 0>20847auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))20848{20849// delegate the call to get_impl_ptr<>()20850return get_impl_ptr(static_cast<PointerType>(nullptr));20851}2085220853/// @brief get a pointer value (implicit)20854/// @sa https://json.nlohmann.me/api/basic_json/get_ptr/20855template < typename PointerType, typename std::enable_if <20856std::is_pointer<PointerType>::value&&20857std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >20858constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))20859{20860// delegate the call to get_impl_ptr<>() const20861return get_impl_ptr(static_cast<PointerType>(nullptr));20862}2086320864private:20865/*!20866@brief get a value (explicit)2086720868Explicit type conversion between the JSON value and a compatible value20869which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)20870and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).20871The value is converted by calling the @ref json_serializer<ValueType>20872`from_json()` method.2087320874The function is equivalent to executing20875@code {.cpp}20876ValueType ret;20877JSONSerializer<ValueType>::from_json(*this, ret);20878return ret;20879@endcode2088020881This overloads is chosen if:20882- @a ValueType is not @ref basic_json,20883- @ref json_serializer<ValueType> has a `from_json()` method of the form20884`void from_json(const basic_json&, ValueType&)`, and20885- @ref json_serializer<ValueType> does not have a `from_json()` method of20886the form `ValueType from_json(const basic_json&)`2088720888@tparam ValueType the returned value type2088920890@return copy of the JSON value, converted to @a ValueType2089120892@throw what @ref json_serializer<ValueType> `from_json()` method throws2089320894@liveexample{The example below shows several conversions from JSON values20895to other types. There a few things to note: (1) Floating-point numbers can20896be converted to integers\, (2) A JSON array can be converted to a standard20897`std::vector<short>`\, (3) A JSON object can be converted to C++20898associative containers such as `std::unordered_map<std::string\,20899json>`.,get__ValueType_const}2090020901@since version 2.1.020902*/20903template < typename ValueType,20904detail::enable_if_t <20905detail::is_default_constructible<ValueType>::value&&20906detail::has_from_json<basic_json_t, ValueType>::value,20907int > = 0 >20908ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(20909JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))20910{20911auto ret = ValueType();20912JSONSerializer<ValueType>::from_json(*this, ret);20913return ret;20914}2091520916/*!20917@brief get a value (explicit); special case2091820919Explicit type conversion between the JSON value and a compatible value20920which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)20921and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).20922The value is converted by calling the @ref json_serializer<ValueType>20923`from_json()` method.2092420925The function is equivalent to executing20926@code {.cpp}20927return JSONSerializer<ValueType>::from_json(*this);20928@endcode2092920930This overloads is chosen if:20931- @a ValueType is not @ref basic_json and20932- @ref json_serializer<ValueType> has a `from_json()` method of the form20933`ValueType from_json(const basic_json&)`2093420935@note If @ref json_serializer<ValueType> has both overloads of20936`from_json()`, this one is chosen.2093720938@tparam ValueType the returned value type2093920940@return copy of the JSON value, converted to @a ValueType2094120942@throw what @ref json_serializer<ValueType> `from_json()` method throws2094320944@since version 2.1.020945*/20946template < typename ValueType,20947detail::enable_if_t <20948detail::has_non_default_from_json<basic_json_t, ValueType>::value,20949int > = 0 >20950ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(20951JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))20952{20953return JSONSerializer<ValueType>::from_json(*this);20954}2095520956/*!20957@brief get special-case overload2095820959This overloads converts the current @ref basic_json in a different20960@ref basic_json type2096120962@tparam BasicJsonType == @ref basic_json2096320964@return a copy of *this, converted into @a BasicJsonType2096520966@complexity Depending on the implementation of the called `from_json()`20967method.2096820969@since version 3.2.020970*/20971template < typename BasicJsonType,20972detail::enable_if_t <20973detail::is_basic_json<BasicJsonType>::value,20974int > = 0 >20975BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const20976{20977return *this;20978}2097920980/*!20981@brief get special-case overload2098220983This overloads avoids a lot of template boilerplate, it can be seen as the20984identity method2098520986@tparam BasicJsonType == @ref basic_json2098720988@return a copy of *this2098920990@complexity Constant.2099120992@since version 2.1.020993*/20994template<typename BasicJsonType,20995detail::enable_if_t<20996std::is_same<BasicJsonType, basic_json_t>::value,20997int> = 0>20998basic_json get_impl(detail::priority_tag<3> /*unused*/) const20999{21000return *this;21001}2100221003/*!21004@brief get a pointer value (explicit)21005@copydoc get()21006*/21007template<typename PointerType,21008detail::enable_if_t<21009std::is_pointer<PointerType>::value,21010int> = 0>21011constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept21012-> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())21013{21014// delegate the call to get_ptr21015return get_ptr<PointerType>();21016}2101721018public:21019/*!21020@brief get a (pointer) value (explicit)2102121022Performs explicit type conversion between the JSON value and a compatible value if required.2102321024- If the requested type is a pointer to the internally stored JSON value that pointer is returned.21025No copies are made.2102621027- If the requested type is the current @ref basic_json, or a different @ref basic_json convertible21028from the current @ref basic_json.2102921030- Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`21031method.2103221033@tparam ValueTypeCV the provided value type21034@tparam ValueType the returned value type2103521036@return copy of the JSON value, converted to @tparam ValueType if necessary2103721038@throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required2103921040@since version 2.1.021041*/21042template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>21043#if defined(JSON_HAS_CPP_14)21044constexpr21045#endif21046auto get() const noexcept(21047noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))21048-> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))21049{21050// we cannot static_assert on ValueTypeCV being non-const, because21051// there is support for get<const basic_json_t>(), which is why we21052// still need the uncvref21053static_assert(!std::is_reference<ValueTypeCV>::value,21054"get() cannot be used with reference types, you might want to use get_ref()");21055return get_impl<ValueType>(detail::priority_tag<4> {});21056}2105721058/*!21059@brief get a pointer value (explicit)2106021061Explicit pointer access to the internally stored JSON value. No copies are21062made.2106321064@warning The pointer becomes invalid if the underlying JSON object21065changes.2106621067@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref21068object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,21069@ref number_unsigned_t, or @ref number_float_t.2107021071@return pointer to the internally stored JSON value if the requested21072pointer type @a PointerType fits to the JSON value; `nullptr` otherwise2107321074@complexity Constant.2107521076@liveexample{The example below shows how pointers to internal values of a21077JSON value can be requested. Note that no type conversions are made and a21078`nullptr` is returned if the value and the requested pointer type does not21079match.,get__PointerType}2108021081@sa see @ref get_ptr() for explicit pointer-member access2108221083@since version 1.0.021084*/21085template<typename PointerType, typename std::enable_if<21086std::is_pointer<PointerType>::value, int>::type = 0>21087auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())21088{21089// delegate the call to get_ptr21090return get_ptr<PointerType>();21091}2109221093/// @brief get a value (explicit)21094/// @sa https://json.nlohmann.me/api/basic_json/get_to/21095template < typename ValueType,21096detail::enable_if_t <21097!detail::is_basic_json<ValueType>::value&&21098detail::has_from_json<basic_json_t, ValueType>::value,21099int > = 0 >21100ValueType & get_to(ValueType& v) const noexcept(noexcept(21101JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))21102{21103JSONSerializer<ValueType>::from_json(*this, v);21104return v;21105}2110621107// specialization to allow calling get_to with a basic_json value21108// see https://github.com/nlohmann/json/issues/217521109template<typename ValueType,21110detail::enable_if_t <21111detail::is_basic_json<ValueType>::value,21112int> = 0>21113ValueType & get_to(ValueType& v) const21114{21115v = *this;21116return v;21117}2111821119template <21120typename T, std::size_t N,21121typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)21122detail::enable_if_t <21123detail::has_from_json<basic_json_t, Array>::value, int > = 0 >21124Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)21125noexcept(noexcept(JSONSerializer<Array>::from_json(21126std::declval<const basic_json_t&>(), v)))21127{21128JSONSerializer<Array>::from_json(*this, v);21129return v;21130}2113121132/// @brief get a reference value (implicit)21133/// @sa https://json.nlohmann.me/api/basic_json/get_ref/21134template<typename ReferenceType, typename std::enable_if<21135std::is_reference<ReferenceType>::value, int>::type = 0>21136ReferenceType get_ref()21137{21138// delegate call to get_ref_impl21139return get_ref_impl<ReferenceType>(*this);21140}2114121142/// @brief get a reference value (implicit)21143/// @sa https://json.nlohmann.me/api/basic_json/get_ref/21144template < typename ReferenceType, typename std::enable_if <21145std::is_reference<ReferenceType>::value&&21146std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >21147ReferenceType get_ref() const21148{21149// delegate call to get_ref_impl21150return get_ref_impl<ReferenceType>(*this);21151}2115221153/*!21154@brief get a value (implicit)2115521156Implicit type conversion between the JSON value and a compatible value.21157The call is realized by calling @ref get() const.2115821159@tparam ValueType non-pointer type compatible to the JSON value, for21160instance `int` for JSON integer numbers, `bool` for JSON booleans, or21161`std::vector` types for JSON arrays. The character type of @ref string_t21162as well as an initializer list of this type is excluded to avoid21163ambiguities as these types implicitly convert to `std::string`.2116421165@return copy of the JSON value, converted to type @a ValueType2116621167@throw type_error.302 in case passed type @a ValueType is incompatible21168to the JSON value type (e.g., the JSON value is of type boolean, but a21169string is requested); see example below2117021171@complexity Linear in the size of the JSON value.2117221173@liveexample{The example below shows several conversions from JSON values21174to other types. There a few things to note: (1) Floating-point numbers can21175be converted to integers\, (2) A JSON array can be converted to a standard21176`std::vector<short>`\, (3) A JSON object can be converted to C++21177associative containers such as `std::unordered_map<std::string\,21178json>`.,operator__ValueType}2117921180@since version 1.0.021181*/21182template < typename ValueType, typename std::enable_if <21183detail::conjunction <21184detail::negation<std::is_pointer<ValueType>>,21185detail::negation<std::is_same<ValueType, std::nullptr_t>>,21186detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,21187detail::negation<std::is_same<ValueType, typename string_t::value_type>>,21188detail::negation<detail::is_basic_json<ValueType>>,21189detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,21190#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))21191detail::negation<std::is_same<ValueType, std::string_view>>,21192#endif21193#if defined(JSON_HAS_CPP_17) && JSON_HAS_STATIC_RTTI21194detail::negation<std::is_same<ValueType, std::any>>,21195#endif21196detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>21197>::value, int >::type = 0 >21198JSON_EXPLICIT operator ValueType() const21199{21200// delegate the call to get<>() const21201return get<ValueType>();21202}2120321204/// @brief get a binary value21205/// @sa https://json.nlohmann.me/api/basic_json/get_binary/21206binary_t& get_binary()21207{21208if (!is_binary())21209{21210JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));21211}2121221213return *get_ptr<binary_t*>();21214}2121521216/// @brief get a binary value21217/// @sa https://json.nlohmann.me/api/basic_json/get_binary/21218const binary_t& get_binary() const21219{21220if (!is_binary())21221{21222JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));21223}2122421225return *get_ptr<const binary_t*>();21226}2122721228/// @}2122921230////////////////////21231// element access //21232////////////////////2123321234/// @name element access21235/// Access to the JSON value.21236/// @{2123721238/// @brief access specified array element with bounds checking21239/// @sa https://json.nlohmann.me/api/basic_json/at/21240reference at(size_type idx)21241{21242// at only works for arrays21243if (JSON_HEDLEY_LIKELY(is_array()))21244{21245JSON_TRY21246{21247return set_parent(m_data.m_value.array->at(idx));21248}21249JSON_CATCH (std::out_of_range&)21250{21251// create better exception explanation21252JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));21253}21254}21255else21256{21257JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));21258}21259}2126021261/// @brief access specified array element with bounds checking21262/// @sa https://json.nlohmann.me/api/basic_json/at/21263const_reference at(size_type idx) const21264{21265// at only works for arrays21266if (JSON_HEDLEY_LIKELY(is_array()))21267{21268JSON_TRY21269{21270return m_data.m_value.array->at(idx);21271}21272JSON_CATCH (std::out_of_range&)21273{21274// create better exception explanation21275JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));21276}21277}21278else21279{21280JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));21281}21282}2128321284/// @brief access specified object element with bounds checking21285/// @sa https://json.nlohmann.me/api/basic_json/at/21286reference at(const typename object_t::key_type& key)21287{21288// at only works for objects21289if (JSON_HEDLEY_UNLIKELY(!is_object()))21290{21291JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));21292}2129321294auto it = m_data.m_value.object->find(key);21295if (it == m_data.m_value.object->end())21296{21297JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));21298}21299return set_parent(it->second);21300}2130121302/// @brief access specified object element with bounds checking21303/// @sa https://json.nlohmann.me/api/basic_json/at/21304template<class KeyType, detail::enable_if_t<21305detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>21306reference at(KeyType && key)21307{21308// at only works for objects21309if (JSON_HEDLEY_UNLIKELY(!is_object()))21310{21311JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));21312}2131321314auto it = m_data.m_value.object->find(std::forward<KeyType>(key));21315if (it == m_data.m_value.object->end())21316{21317JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));21318}21319return set_parent(it->second);21320}2132121322/// @brief access specified object element with bounds checking21323/// @sa https://json.nlohmann.me/api/basic_json/at/21324const_reference at(const typename object_t::key_type& key) const21325{21326// at only works for objects21327if (JSON_HEDLEY_UNLIKELY(!is_object()))21328{21329JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));21330}2133121332auto it = m_data.m_value.object->find(key);21333if (it == m_data.m_value.object->end())21334{21335JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));21336}21337return it->second;21338}2133921340/// @brief access specified object element with bounds checking21341/// @sa https://json.nlohmann.me/api/basic_json/at/21342template<class KeyType, detail::enable_if_t<21343detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>21344const_reference at(KeyType && key) const21345{21346// at only works for objects21347if (JSON_HEDLEY_UNLIKELY(!is_object()))21348{21349JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));21350}2135121352auto it = m_data.m_value.object->find(std::forward<KeyType>(key));21353if (it == m_data.m_value.object->end())21354{21355JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));21356}21357return it->second;21358}2135921360/// @brief access specified array element21361/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/21362reference operator[](size_type idx)21363{21364// implicitly convert null value to an empty array21365if (is_null())21366{21367m_data.m_type = value_t::array;21368m_data.m_value.array = create<array_t>();21369assert_invariant();21370}2137121372// operator[] only works for arrays21373if (JSON_HEDLEY_LIKELY(is_array()))21374{21375// fill up array with null values if given idx is outside range21376if (idx >= m_data.m_value.array->size())21377{21378#if JSON_DIAGNOSTICS21379// remember array size & capacity before resizing21380const auto old_size = m_data.m_value.array->size();21381const auto old_capacity = m_data.m_value.array->capacity();21382#endif21383m_data.m_value.array->resize(idx + 1);2138421385#if JSON_DIAGNOSTICS21386if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))21387{21388// capacity has changed: update all parents21389set_parents();21390}21391else21392{21393// set parent for values added above21394set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));21395}21396#endif21397assert_invariant();21398}2139921400return m_data.m_value.array->operator[](idx);21401}2140221403JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));21404}2140521406/// @brief access specified array element21407/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/21408const_reference operator[](size_type idx) const21409{21410// const operator[] only works for arrays21411if (JSON_HEDLEY_LIKELY(is_array()))21412{21413return m_data.m_value.array->operator[](idx);21414}2141521416JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));21417}2141821419/// @brief access specified object element21420/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/21421reference operator[](typename object_t::key_type key)21422{21423// implicitly convert null value to an empty object21424if (is_null())21425{21426m_data.m_type = value_t::object;21427m_data.m_value.object = create<object_t>();21428assert_invariant();21429}2143021431// operator[] only works for objects21432if (JSON_HEDLEY_LIKELY(is_object()))21433{21434auto result = m_data.m_value.object->emplace(std::move(key), nullptr);21435return set_parent(result.first->second);21436}2143721438JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));21439}2144021441/// @brief access specified object element21442/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/21443const_reference operator[](const typename object_t::key_type& key) const21444{21445// const operator[] only works for objects21446if (JSON_HEDLEY_LIKELY(is_object()))21447{21448auto it = m_data.m_value.object->find(key);21449JSON_ASSERT(it != m_data.m_value.object->end());21450return it->second;21451}2145221453JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));21454}2145521456// these two functions resolve a (const) char * ambiguity affecting Clang and MSVC21457// (they seemingly cannot be constrained to resolve the ambiguity)21458template<typename T>21459reference operator[](T* key)21460{21461return operator[](typename object_t::key_type(key));21462}2146321464template<typename T>21465const_reference operator[](T* key) const21466{21467return operator[](typename object_t::key_type(key));21468}2146921470/// @brief access specified object element21471/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/21472template<class KeyType, detail::enable_if_t<21473detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int > = 0 >21474reference operator[](KeyType && key)21475{21476// implicitly convert null value to an empty object21477if (is_null())21478{21479m_data.m_type = value_t::object;21480m_data.m_value.object = create<object_t>();21481assert_invariant();21482}2148321484// operator[] only works for objects21485if (JSON_HEDLEY_LIKELY(is_object()))21486{21487auto result = m_data.m_value.object->emplace(std::forward<KeyType>(key), nullptr);21488return set_parent(result.first->second);21489}2149021491JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));21492}2149321494/// @brief access specified object element21495/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/21496template<class KeyType, detail::enable_if_t<21497detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int > = 0 >21498const_reference operator[](KeyType && key) const21499{21500// const operator[] only works for objects21501if (JSON_HEDLEY_LIKELY(is_object()))21502{21503auto it = m_data.m_value.object->find(std::forward<KeyType>(key));21504JSON_ASSERT(it != m_data.m_value.object->end());21505return it->second;21506}2150721508JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));21509}2151021511private:21512template<typename KeyType>21513using is_comparable_with_object_key = detail::is_comparable <21514object_comparator_t, const typename object_t::key_type&, KeyType >;2151521516template<typename ValueType>21517using value_return_type = std::conditional <21518detail::is_c_string_uncvref<ValueType>::value,21519string_t, typename std::decay<ValueType>::type >;2152021521public:21522/// @brief access specified object element with default value21523/// @sa https://json.nlohmann.me/api/basic_json/value/21524template < class ValueType, detail::enable_if_t <21525!detail::is_transparent<object_comparator_t>::value21526&& detail::is_getable<basic_json_t, ValueType>::value21527&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >21528ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const21529{21530// value only works for objects21531if (JSON_HEDLEY_LIKELY(is_object()))21532{21533// if key is found, return value and given default value otherwise21534const auto it = find(key);21535if (it != end())21536{21537return it->template get<ValueType>();21538}2153921540return default_value;21541}2154221543JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));21544}2154521546/// @brief access specified object element with default value21547/// @sa https://json.nlohmann.me/api/basic_json/value/21548template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,21549detail::enable_if_t <21550!detail::is_transparent<object_comparator_t>::value21551&& detail::is_getable<basic_json_t, ReturnType>::value21552&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >21553ReturnType value(const typename object_t::key_type& key, ValueType && default_value) const21554{21555// value only works for objects21556if (JSON_HEDLEY_LIKELY(is_object()))21557{21558// if key is found, return value and given default value otherwise21559const auto it = find(key);21560if (it != end())21561{21562return it->template get<ReturnType>();21563}2156421565return std::forward<ValueType>(default_value);21566}2156721568JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));21569}2157021571/// @brief access specified object element with default value21572/// @sa https://json.nlohmann.me/api/basic_json/value/21573template < class ValueType, class KeyType, detail::enable_if_t <21574detail::is_transparent<object_comparator_t>::value21575&& !detail::is_json_pointer<KeyType>::value21576&& is_comparable_with_object_key<KeyType>::value21577&& detail::is_getable<basic_json_t, ValueType>::value21578&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >21579ValueType value(KeyType && key, const ValueType& default_value) const21580{21581// value only works for objects21582if (JSON_HEDLEY_LIKELY(is_object()))21583{21584// if key is found, return value and given default value otherwise21585const auto it = find(std::forward<KeyType>(key));21586if (it != end())21587{21588return it->template get<ValueType>();21589}2159021591return default_value;21592}2159321594JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));21595}2159621597/// @brief access specified object element via JSON Pointer with default value21598/// @sa https://json.nlohmann.me/api/basic_json/value/21599template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,21600detail::enable_if_t <21601detail::is_transparent<object_comparator_t>::value21602&& !detail::is_json_pointer<KeyType>::value21603&& is_comparable_with_object_key<KeyType>::value21604&& detail::is_getable<basic_json_t, ReturnType>::value21605&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >21606ReturnType value(KeyType && key, ValueType && default_value) const21607{21608// value only works for objects21609if (JSON_HEDLEY_LIKELY(is_object()))21610{21611// if key is found, return value and given default value otherwise21612const auto it = find(std::forward<KeyType>(key));21613if (it != end())21614{21615return it->template get<ReturnType>();21616}2161721618return std::forward<ValueType>(default_value);21619}2162021621JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));21622}2162321624/// @brief access specified object element via JSON Pointer with default value21625/// @sa https://json.nlohmann.me/api/basic_json/value/21626template < class ValueType, detail::enable_if_t <21627detail::is_getable<basic_json_t, ValueType>::value21628&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >21629ValueType value(const json_pointer& ptr, const ValueType& default_value) const21630{21631// value only works for objects21632if (JSON_HEDLEY_LIKELY(is_object()))21633{21634// if pointer resolves a value, return it or use default value21635JSON_TRY21636{21637return ptr.get_checked(this).template get<ValueType>();21638}21639JSON_INTERNAL_CATCH (out_of_range&)21640{21641return default_value;21642}21643}2164421645JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));21646}2164721648/// @brief access specified object element via JSON Pointer with default value21649/// @sa https://json.nlohmann.me/api/basic_json/value/21650template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,21651detail::enable_if_t <21652detail::is_getable<basic_json_t, ReturnType>::value21653&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >21654ReturnType value(const json_pointer& ptr, ValueType && default_value) const21655{21656// value only works for objects21657if (JSON_HEDLEY_LIKELY(is_object()))21658{21659// if pointer resolves a value, return it or use default value21660JSON_TRY21661{21662return ptr.get_checked(this).template get<ReturnType>();21663}21664JSON_INTERNAL_CATCH (out_of_range&)21665{21666return std::forward<ValueType>(default_value);21667}21668}2166921670JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));21671}2167221673template < class ValueType, class BasicJsonType, detail::enable_if_t <21674detail::is_basic_json<BasicJsonType>::value21675&& detail::is_getable<basic_json_t, ValueType>::value21676&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >21677JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)21678ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const21679{21680return value(ptr.convert(), default_value);21681}2168221683template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,21684detail::enable_if_t <21685detail::is_basic_json<BasicJsonType>::value21686&& detail::is_getable<basic_json_t, ReturnType>::value21687&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >21688JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)21689ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const21690{21691return value(ptr.convert(), std::forward<ValueType>(default_value));21692}2169321694/// @brief access the first element21695/// @sa https://json.nlohmann.me/api/basic_json/front/21696reference front()21697{21698return *begin();21699}2170021701/// @brief access the first element21702/// @sa https://json.nlohmann.me/api/basic_json/front/21703const_reference front() const21704{21705return *cbegin();21706}2170721708/// @brief access the last element21709/// @sa https://json.nlohmann.me/api/basic_json/back/21710reference back()21711{21712auto tmp = end();21713--tmp;21714return *tmp;21715}2171621717/// @brief access the last element21718/// @sa https://json.nlohmann.me/api/basic_json/back/21719const_reference back() const21720{21721auto tmp = cend();21722--tmp;21723return *tmp;21724}2172521726/// @brief remove element given an iterator21727/// @sa https://json.nlohmann.me/api/basic_json/erase/21728template < class IteratorType, detail::enable_if_t <21729std::is_same<IteratorType, typename basic_json_t::iterator>::value ||21730std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >21731IteratorType erase(IteratorType pos)21732{21733// make sure iterator fits the current value21734if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))21735{21736JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));21737}2173821739IteratorType result = end();2174021741switch (m_data.m_type)21742{21743case value_t::boolean:21744case value_t::number_float:21745case value_t::number_integer:21746case value_t::number_unsigned:21747case value_t::string:21748case value_t::binary:21749{21750if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))21751{21752JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));21753}2175421755if (is_string())21756{21757AllocatorType<string_t> alloc;21758std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);21759std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);21760m_data.m_value.string = nullptr;21761}21762else if (is_binary())21763{21764AllocatorType<binary_t> alloc;21765std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);21766std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);21767m_data.m_value.binary = nullptr;21768}2176921770m_data.m_type = value_t::null;21771assert_invariant();21772break;21773}2177421775case value_t::object:21776{21777result.m_it.object_iterator = m_data.m_value.object->erase(pos.m_it.object_iterator);21778break;21779}2178021781case value_t::array:21782{21783result.m_it.array_iterator = m_data.m_value.array->erase(pos.m_it.array_iterator);21784break;21785}2178621787case value_t::null:21788case value_t::discarded:21789default:21790JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));21791}2179221793return result;21794}2179521796/// @brief remove elements given an iterator range21797/// @sa https://json.nlohmann.me/api/basic_json/erase/21798template < class IteratorType, detail::enable_if_t <21799std::is_same<IteratorType, typename basic_json_t::iterator>::value ||21800std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >21801IteratorType erase(IteratorType first, IteratorType last)21802{21803// make sure iterator fits the current value21804if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))21805{21806JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));21807}2180821809IteratorType result = end();2181021811switch (m_data.m_type)21812{21813case value_t::boolean:21814case value_t::number_float:21815case value_t::number_integer:21816case value_t::number_unsigned:21817case value_t::string:21818case value_t::binary:21819{21820if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()21821|| !last.m_it.primitive_iterator.is_end()))21822{21823JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));21824}2182521826if (is_string())21827{21828AllocatorType<string_t> alloc;21829std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);21830std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);21831m_data.m_value.string = nullptr;21832}21833else if (is_binary())21834{21835AllocatorType<binary_t> alloc;21836std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);21837std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);21838m_data.m_value.binary = nullptr;21839}2184021841m_data.m_type = value_t::null;21842assert_invariant();21843break;21844}2184521846case value_t::object:21847{21848result.m_it.object_iterator = m_data.m_value.object->erase(first.m_it.object_iterator,21849last.m_it.object_iterator);21850break;21851}2185221853case value_t::array:21854{21855result.m_it.array_iterator = m_data.m_value.array->erase(first.m_it.array_iterator,21856last.m_it.array_iterator);21857break;21858}2185921860case value_t::null:21861case value_t::discarded:21862default:21863JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));21864}2186521866return result;21867}2186821869private:21870template < typename KeyType, detail::enable_if_t <21871detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >21872size_type erase_internal(KeyType && key)21873{21874// this erase only works for objects21875if (JSON_HEDLEY_UNLIKELY(!is_object()))21876{21877JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));21878}2187921880return m_data.m_value.object->erase(std::forward<KeyType>(key));21881}2188221883template < typename KeyType, detail::enable_if_t <21884!detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >21885size_type erase_internal(KeyType && key)21886{21887// this erase only works for objects21888if (JSON_HEDLEY_UNLIKELY(!is_object()))21889{21890JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));21891}2189221893const auto it = m_data.m_value.object->find(std::forward<KeyType>(key));21894if (it != m_data.m_value.object->end())21895{21896m_data.m_value.object->erase(it);21897return 1;21898}21899return 0;21900}2190121902public:2190321904/// @brief remove element from a JSON object given a key21905/// @sa https://json.nlohmann.me/api/basic_json/erase/21906size_type erase(const typename object_t::key_type& key)21907{21908// the indirection via erase_internal() is added to avoid making this21909// function a template and thus de-rank it during overload resolution21910return erase_internal(key);21911}2191221913/// @brief remove element from a JSON object given a key21914/// @sa https://json.nlohmann.me/api/basic_json/erase/21915template<class KeyType, detail::enable_if_t<21916detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>21917size_type erase(KeyType && key)21918{21919return erase_internal(std::forward<KeyType>(key));21920}2192121922/// @brief remove element from a JSON array given an index21923/// @sa https://json.nlohmann.me/api/basic_json/erase/21924void erase(const size_type idx)21925{21926// this erase only works for arrays21927if (JSON_HEDLEY_LIKELY(is_array()))21928{21929if (JSON_HEDLEY_UNLIKELY(idx >= size()))21930{21931JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));21932}2193321934m_data.m_value.array->erase(m_data.m_value.array->begin() + static_cast<difference_type>(idx));21935}21936else21937{21938JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));21939}21940}2194121942/// @}2194321944////////////21945// lookup //21946////////////2194721948/// @name lookup21949/// @{2195021951/// @brief find an element in a JSON object21952/// @sa https://json.nlohmann.me/api/basic_json/find/21953iterator find(const typename object_t::key_type& key)21954{21955auto result = end();2195621957if (is_object())21958{21959result.m_it.object_iterator = m_data.m_value.object->find(key);21960}2196121962return result;21963}2196421965/// @brief find an element in a JSON object21966/// @sa https://json.nlohmann.me/api/basic_json/find/21967const_iterator find(const typename object_t::key_type& key) const21968{21969auto result = cend();2197021971if (is_object())21972{21973result.m_it.object_iterator = m_data.m_value.object->find(key);21974}2197521976return result;21977}2197821979/// @brief find an element in a JSON object21980/// @sa https://json.nlohmann.me/api/basic_json/find/21981template<class KeyType, detail::enable_if_t<21982detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>21983iterator find(KeyType && key)21984{21985auto result = end();2198621987if (is_object())21988{21989result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));21990}2199121992return result;21993}2199421995/// @brief find an element in a JSON object21996/// @sa https://json.nlohmann.me/api/basic_json/find/21997template<class KeyType, detail::enable_if_t<21998detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>21999const_iterator find(KeyType && key) const22000{22001auto result = cend();2200222003if (is_object())22004{22005result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));22006}2200722008return result;22009}2201022011/// @brief returns the number of occurrences of a key in a JSON object22012/// @sa https://json.nlohmann.me/api/basic_json/count/22013size_type count(const typename object_t::key_type& key) const22014{22015// return 0 for all nonobject types22016return is_object() ? m_data.m_value.object->count(key) : 0;22017}2201822019/// @brief returns the number of occurrences of a key in a JSON object22020/// @sa https://json.nlohmann.me/api/basic_json/count/22021template<class KeyType, detail::enable_if_t<22022detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>22023size_type count(KeyType && key) const22024{22025// return 0 for all nonobject types22026return is_object() ? m_data.m_value.object->count(std::forward<KeyType>(key)) : 0;22027}2202822029/// @brief check the existence of an element in a JSON object22030/// @sa https://json.nlohmann.me/api/basic_json/contains/22031bool contains(const typename object_t::key_type& key) const22032{22033return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();22034}2203522036/// @brief check the existence of an element in a JSON object22037/// @sa https://json.nlohmann.me/api/basic_json/contains/22038template<class KeyType, detail::enable_if_t<22039detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>22040bool contains(KeyType && key) const22041{22042return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();22043}2204422045/// @brief check the existence of an element in a JSON object given a JSON pointer22046/// @sa https://json.nlohmann.me/api/basic_json/contains/22047bool contains(const json_pointer& ptr) const22048{22049return ptr.contains(this);22050}2205122052template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>22053JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)22054bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const22055{22056return ptr.contains(this);22057}2205822059/// @}2206022061///////////////22062// iterators //22063///////////////2206422065/// @name iterators22066/// @{2206722068/// @brief returns an iterator to the first element22069/// @sa https://json.nlohmann.me/api/basic_json/begin/22070iterator begin() noexcept22071{22072iterator result(this);22073result.set_begin();22074return result;22075}2207622077/// @brief returns an iterator to the first element22078/// @sa https://json.nlohmann.me/api/basic_json/begin/22079const_iterator begin() const noexcept22080{22081return cbegin();22082}2208322084/// @brief returns a const iterator to the first element22085/// @sa https://json.nlohmann.me/api/basic_json/cbegin/22086const_iterator cbegin() const noexcept22087{22088const_iterator result(this);22089result.set_begin();22090return result;22091}2209222093/// @brief returns an iterator to one past the last element22094/// @sa https://json.nlohmann.me/api/basic_json/end/22095iterator end() noexcept22096{22097iterator result(this);22098result.set_end();22099return result;22100}2210122102/// @brief returns an iterator to one past the last element22103/// @sa https://json.nlohmann.me/api/basic_json/end/22104const_iterator end() const noexcept22105{22106return cend();22107}2210822109/// @brief returns an iterator to one past the last element22110/// @sa https://json.nlohmann.me/api/basic_json/cend/22111const_iterator cend() const noexcept22112{22113const_iterator result(this);22114result.set_end();22115return result;22116}2211722118/// @brief returns an iterator to the reverse-beginning22119/// @sa https://json.nlohmann.me/api/basic_json/rbegin/22120reverse_iterator rbegin() noexcept22121{22122return reverse_iterator(end());22123}2212422125/// @brief returns an iterator to the reverse-beginning22126/// @sa https://json.nlohmann.me/api/basic_json/rbegin/22127const_reverse_iterator rbegin() const noexcept22128{22129return crbegin();22130}2213122132/// @brief returns an iterator to the reverse-end22133/// @sa https://json.nlohmann.me/api/basic_json/rend/22134reverse_iterator rend() noexcept22135{22136return reverse_iterator(begin());22137}2213822139/// @brief returns an iterator to the reverse-end22140/// @sa https://json.nlohmann.me/api/basic_json/rend/22141const_reverse_iterator rend() const noexcept22142{22143return crend();22144}2214522146/// @brief returns a const reverse iterator to the last element22147/// @sa https://json.nlohmann.me/api/basic_json/crbegin/22148const_reverse_iterator crbegin() const noexcept22149{22150return const_reverse_iterator(cend());22151}2215222153/// @brief returns a const reverse iterator to one before the first22154/// @sa https://json.nlohmann.me/api/basic_json/crend/22155const_reverse_iterator crend() const noexcept22156{22157return const_reverse_iterator(cbegin());22158}2215922160public:22161/// @brief wrapper to access iterator member functions in range-based for22162/// @sa https://json.nlohmann.me/api/basic_json/items/22163/// @deprecated This function is deprecated since 3.1.0 and will be removed in22164/// version 4.0.0 of the library. Please use @ref items() instead;22165/// that is, replace `json::iterator_wrapper(j)` with `j.items()`.22166JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())22167static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept22168{22169return ref.items();22170}2217122172/// @brief wrapper to access iterator member functions in range-based for22173/// @sa https://json.nlohmann.me/api/basic_json/items/22174/// @deprecated This function is deprecated since 3.1.0 and will be removed in22175/// version 4.0.0 of the library. Please use @ref items() instead;22176/// that is, replace `json::iterator_wrapper(j)` with `j.items()`.22177JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())22178static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept22179{22180return ref.items();22181}2218222183/// @brief helper to access iterator member functions in range-based for22184/// @sa https://json.nlohmann.me/api/basic_json/items/22185iteration_proxy<iterator> items() noexcept22186{22187return iteration_proxy<iterator>(*this);22188}2218922190/// @brief helper to access iterator member functions in range-based for22191/// @sa https://json.nlohmann.me/api/basic_json/items/22192iteration_proxy<const_iterator> items() const noexcept22193{22194return iteration_proxy<const_iterator>(*this);22195}2219622197/// @}2219822199//////////////22200// capacity //22201//////////////2220222203/// @name capacity22204/// @{2220522206/// @brief checks whether the container is empty.22207/// @sa https://json.nlohmann.me/api/basic_json/empty/22208bool empty() const noexcept22209{22210switch (m_data.m_type)22211{22212case value_t::null:22213{22214// null values are empty22215return true;22216}2221722218case value_t::array:22219{22220// delegate call to array_t::empty()22221return m_data.m_value.array->empty();22222}2222322224case value_t::object:22225{22226// delegate call to object_t::empty()22227return m_data.m_value.object->empty();22228}2222922230case value_t::string:22231case value_t::boolean:22232case value_t::number_integer:22233case value_t::number_unsigned:22234case value_t::number_float:22235case value_t::binary:22236case value_t::discarded:22237default:22238{22239// all other types are nonempty22240return false;22241}22242}22243}2224422245/// @brief returns the number of elements22246/// @sa https://json.nlohmann.me/api/basic_json/size/22247size_type size() const noexcept22248{22249switch (m_data.m_type)22250{22251case value_t::null:22252{22253// null values are empty22254return 0;22255}2225622257case value_t::array:22258{22259// delegate call to array_t::size()22260return m_data.m_value.array->size();22261}2226222263case value_t::object:22264{22265// delegate call to object_t::size()22266return m_data.m_value.object->size();22267}2226822269case value_t::string:22270case value_t::boolean:22271case value_t::number_integer:22272case value_t::number_unsigned:22273case value_t::number_float:22274case value_t::binary:22275case value_t::discarded:22276default:22277{22278// all other types have size 122279return 1;22280}22281}22282}2228322284/// @brief returns the maximum possible number of elements22285/// @sa https://json.nlohmann.me/api/basic_json/max_size/22286size_type max_size() const noexcept22287{22288switch (m_data.m_type)22289{22290case value_t::array:22291{22292// delegate call to array_t::max_size()22293return m_data.m_value.array->max_size();22294}2229522296case value_t::object:22297{22298// delegate call to object_t::max_size()22299return m_data.m_value.object->max_size();22300}2230122302case value_t::null:22303case value_t::string:22304case value_t::boolean:22305case value_t::number_integer:22306case value_t::number_unsigned:22307case value_t::number_float:22308case value_t::binary:22309case value_t::discarded:22310default:22311{22312// all other types have max_size() == size()22313return size();22314}22315}22316}2231722318/// @}2231922320///////////////22321// modifiers //22322///////////////2232322324/// @name modifiers22325/// @{2232622327/// @brief clears the contents22328/// @sa https://json.nlohmann.me/api/basic_json/clear/22329void clear() noexcept22330{22331switch (m_data.m_type)22332{22333case value_t::number_integer:22334{22335m_data.m_value.number_integer = 0;22336break;22337}2233822339case value_t::number_unsigned:22340{22341m_data.m_value.number_unsigned = 0;22342break;22343}2234422345case value_t::number_float:22346{22347m_data.m_value.number_float = 0.0;22348break;22349}2235022351case value_t::boolean:22352{22353m_data.m_value.boolean = false;22354break;22355}2235622357case value_t::string:22358{22359m_data.m_value.string->clear();22360break;22361}2236222363case value_t::binary:22364{22365m_data.m_value.binary->clear();22366break;22367}2236822369case value_t::array:22370{22371m_data.m_value.array->clear();22372break;22373}2237422375case value_t::object:22376{22377m_data.m_value.object->clear();22378break;22379}2238022381case value_t::null:22382case value_t::discarded:22383default:22384break;22385}22386}2238722388/// @brief add an object to an array22389/// @sa https://json.nlohmann.me/api/basic_json/push_back/22390void push_back(basic_json&& val)22391{22392// push_back only works for null objects or arrays22393if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))22394{22395JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));22396}2239722398// transform null object into an array22399if (is_null())22400{22401m_data.m_type = value_t::array;22402m_data.m_value = value_t::array;22403assert_invariant();22404}2240522406// add element to array (move semantics)22407const auto old_capacity = m_data.m_value.array->capacity();22408m_data.m_value.array->push_back(std::move(val));22409set_parent(m_data.m_value.array->back(), old_capacity);22410// if val is moved from, basic_json move constructor marks it null, so we do not call the destructor22411}2241222413/// @brief add an object to an array22414/// @sa https://json.nlohmann.me/api/basic_json/operator+=/22415reference operator+=(basic_json&& val)22416{22417push_back(std::move(val));22418return *this;22419}2242022421/// @brief add an object to an array22422/// @sa https://json.nlohmann.me/api/basic_json/push_back/22423void push_back(const basic_json& val)22424{22425// push_back only works for null objects or arrays22426if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))22427{22428JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));22429}2243022431// transform null object into an array22432if (is_null())22433{22434m_data.m_type = value_t::array;22435m_data.m_value = value_t::array;22436assert_invariant();22437}2243822439// add element to array22440const auto old_capacity = m_data.m_value.array->capacity();22441m_data.m_value.array->push_back(val);22442set_parent(m_data.m_value.array->back(), old_capacity);22443}2244422445/// @brief add an object to an array22446/// @sa https://json.nlohmann.me/api/basic_json/operator+=/22447reference operator+=(const basic_json& val)22448{22449push_back(val);22450return *this;22451}2245222453/// @brief add an object to an object22454/// @sa https://json.nlohmann.me/api/basic_json/push_back/22455void push_back(const typename object_t::value_type& val)22456{22457// push_back only works for null objects or objects22458if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))22459{22460JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));22461}2246222463// transform null object into an object22464if (is_null())22465{22466m_data.m_type = value_t::object;22467m_data.m_value = value_t::object;22468assert_invariant();22469}2247022471// add element to object22472auto res = m_data.m_value.object->insert(val);22473set_parent(res.first->second);22474}2247522476/// @brief add an object to an object22477/// @sa https://json.nlohmann.me/api/basic_json/operator+=/22478reference operator+=(const typename object_t::value_type& val)22479{22480push_back(val);22481return *this;22482}2248322484/// @brief add an object to an object22485/// @sa https://json.nlohmann.me/api/basic_json/push_back/22486void push_back(initializer_list_t init)22487{22488if (is_object() && init.size() == 2 && (*init.begin())->is_string())22489{22490basic_json&& key = init.begin()->moved_or_copied();22491push_back(typename object_t::value_type(22492std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));22493}22494else22495{22496push_back(basic_json(init));22497}22498}2249922500/// @brief add an object to an object22501/// @sa https://json.nlohmann.me/api/basic_json/operator+=/22502reference operator+=(initializer_list_t init)22503{22504push_back(init);22505return *this;22506}2250722508/// @brief add an object to an array22509/// @sa https://json.nlohmann.me/api/basic_json/emplace_back/22510template<class... Args>22511reference emplace_back(Args&& ... args)22512{22513// emplace_back only works for null objects or arrays22514if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))22515{22516JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));22517}2251822519// transform null object into an array22520if (is_null())22521{22522m_data.m_type = value_t::array;22523m_data.m_value = value_t::array;22524assert_invariant();22525}2252622527// add element to array (perfect forwarding)22528const auto old_capacity = m_data.m_value.array->capacity();22529m_data.m_value.array->emplace_back(std::forward<Args>(args)...);22530return set_parent(m_data.m_value.array->back(), old_capacity);22531}2253222533/// @brief add an object to an object if key does not exist22534/// @sa https://json.nlohmann.me/api/basic_json/emplace/22535template<class... Args>22536std::pair<iterator, bool> emplace(Args&& ... args)22537{22538// emplace only works for null objects or arrays22539if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))22540{22541JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));22542}2254322544// transform null object into an object22545if (is_null())22546{22547m_data.m_type = value_t::object;22548m_data.m_value = value_t::object;22549assert_invariant();22550}2255122552// add element to array (perfect forwarding)22553auto res = m_data.m_value.object->emplace(std::forward<Args>(args)...);22554set_parent(res.first->second);2255522556// create result iterator and set iterator to the result of emplace22557auto it = begin();22558it.m_it.object_iterator = res.first;2255922560// return pair of iterator and boolean22561return {it, res.second};22562}2256322564/// Helper for insertion of an iterator22565/// @note: This uses std::distance to support GCC 4.8,22566/// see https://github.com/nlohmann/json/pull/125722567template<typename... Args>22568iterator insert_iterator(const_iterator pos, Args&& ... args)22569{22570iterator result(this);22571JSON_ASSERT(m_data.m_value.array != nullptr);2257222573auto insert_pos = std::distance(m_data.m_value.array->begin(), pos.m_it.array_iterator);22574m_data.m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);22575result.m_it.array_iterator = m_data.m_value.array->begin() + insert_pos;2257622577// This could have been written as:22578// result.m_it.array_iterator = m_data.m_value.array->insert(pos.m_it.array_iterator, cnt, val);22579// but the return value of insert is missing in GCC 4.8, so it is written this way instead.2258022581set_parents();22582return result;22583}2258422585/// @brief inserts element into array22586/// @sa https://json.nlohmann.me/api/basic_json/insert/22587iterator insert(const_iterator pos, const basic_json& val)22588{22589// insert only works for arrays22590if (JSON_HEDLEY_LIKELY(is_array()))22591{22592// check if iterator pos fits to this JSON value22593if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))22594{22595JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));22596}2259722598// insert to array and return iterator22599return insert_iterator(pos, val);22600}2260122602JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));22603}2260422605/// @brief inserts element into array22606/// @sa https://json.nlohmann.me/api/basic_json/insert/22607iterator insert(const_iterator pos, basic_json&& val)22608{22609return insert(pos, val);22610}2261122612/// @brief inserts copies of element into array22613/// @sa https://json.nlohmann.me/api/basic_json/insert/22614iterator insert(const_iterator pos, size_type cnt, const basic_json& val)22615{22616// insert only works for arrays22617if (JSON_HEDLEY_LIKELY(is_array()))22618{22619// check if iterator pos fits to this JSON value22620if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))22621{22622JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));22623}2262422625// insert to array and return iterator22626return insert_iterator(pos, cnt, val);22627}2262822629JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));22630}2263122632/// @brief inserts range of elements into array22633/// @sa https://json.nlohmann.me/api/basic_json/insert/22634iterator insert(const_iterator pos, const_iterator first, const_iterator last)22635{22636// insert only works for arrays22637if (JSON_HEDLEY_UNLIKELY(!is_array()))22638{22639JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));22640}2264122642// check if iterator pos fits to this JSON value22643if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))22644{22645JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));22646}2264722648// check if range iterators belong to the same JSON object22649if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))22650{22651JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));22652}2265322654if (JSON_HEDLEY_UNLIKELY(first.m_object == this))22655{22656JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));22657}2265822659// insert to array and return iterator22660return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);22661}2266222663/// @brief inserts elements from initializer list into array22664/// @sa https://json.nlohmann.me/api/basic_json/insert/22665iterator insert(const_iterator pos, initializer_list_t ilist)22666{22667// insert only works for arrays22668if (JSON_HEDLEY_UNLIKELY(!is_array()))22669{22670JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));22671}2267222673// check if iterator pos fits to this JSON value22674if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))22675{22676JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));22677}2267822679// insert to array and return iterator22680return insert_iterator(pos, ilist.begin(), ilist.end());22681}2268222683/// @brief inserts range of elements into object22684/// @sa https://json.nlohmann.me/api/basic_json/insert/22685void insert(const_iterator first, const_iterator last)22686{22687// insert only works for objects22688if (JSON_HEDLEY_UNLIKELY(!is_object()))22689{22690JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));22691}2269222693// check if range iterators belong to the same JSON object22694if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))22695{22696JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));22697}2269822699// passed iterators must belong to objects22700if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))22701{22702JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));22703}2270422705m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);22706}2270722708/// @brief updates a JSON object from another object, overwriting existing keys22709/// @sa https://json.nlohmann.me/api/basic_json/update/22710void update(const_reference j, bool merge_objects = false)22711{22712update(j.begin(), j.end(), merge_objects);22713}2271422715/// @brief updates a JSON object from another object, overwriting existing keys22716/// @sa https://json.nlohmann.me/api/basic_json/update/22717void update(const_iterator first, const_iterator last, bool merge_objects = false)22718{22719// implicitly convert null value to an empty object22720if (is_null())22721{22722m_data.m_type = value_t::object;22723m_data.m_value.object = create<object_t>();22724assert_invariant();22725}2272622727if (JSON_HEDLEY_UNLIKELY(!is_object()))22728{22729JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));22730}2273122732// check if range iterators belong to the same JSON object22733if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))22734{22735JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));22736}2273722738// passed iterators must belong to objects22739if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))22740{22741JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));22742}2274322744for (auto it = first; it != last; ++it)22745{22746if (merge_objects && it.value().is_object())22747{22748auto it2 = m_data.m_value.object->find(it.key());22749if (it2 != m_data.m_value.object->end())22750{22751it2->second.update(it.value(), true);22752continue;22753}22754}22755m_data.m_value.object->operator[](it.key()) = it.value();22756#if JSON_DIAGNOSTICS22757m_data.m_value.object->operator[](it.key()).m_parent = this;22758#endif22759}22760}2276122762/// @brief exchanges the values22763/// @sa https://json.nlohmann.me/api/basic_json/swap/22764void swap(reference other) noexcept (22765std::is_nothrow_move_constructible<value_t>::value&&22766std::is_nothrow_move_assignable<value_t>::value&&22767std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)22768std::is_nothrow_move_assignable<json_value>::value22769)22770{22771std::swap(m_data.m_type, other.m_data.m_type);22772std::swap(m_data.m_value, other.m_data.m_value);2277322774set_parents();22775other.set_parents();22776assert_invariant();22777}2277822779/// @brief exchanges the values22780/// @sa https://json.nlohmann.me/api/basic_json/swap/22781friend void swap(reference left, reference right) noexcept (22782std::is_nothrow_move_constructible<value_t>::value&&22783std::is_nothrow_move_assignable<value_t>::value&&22784std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)22785std::is_nothrow_move_assignable<json_value>::value22786)22787{22788left.swap(right);22789}2279022791/// @brief exchanges the values22792/// @sa https://json.nlohmann.me/api/basic_json/swap/22793void swap(array_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)22794{22795// swap only works for arrays22796if (JSON_HEDLEY_LIKELY(is_array()))22797{22798using std::swap;22799swap(*(m_data.m_value.array), other);22800}22801else22802{22803JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));22804}22805}2280622807/// @brief exchanges the values22808/// @sa https://json.nlohmann.me/api/basic_json/swap/22809void swap(object_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)22810{22811// swap only works for objects22812if (JSON_HEDLEY_LIKELY(is_object()))22813{22814using std::swap;22815swap(*(m_data.m_value.object), other);22816}22817else22818{22819JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));22820}22821}2282222823/// @brief exchanges the values22824/// @sa https://json.nlohmann.me/api/basic_json/swap/22825void swap(string_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)22826{22827// swap only works for strings22828if (JSON_HEDLEY_LIKELY(is_string()))22829{22830using std::swap;22831swap(*(m_data.m_value.string), other);22832}22833else22834{22835JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));22836}22837}2283822839/// @brief exchanges the values22840/// @sa https://json.nlohmann.me/api/basic_json/swap/22841void swap(binary_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)22842{22843// swap only works for strings22844if (JSON_HEDLEY_LIKELY(is_binary()))22845{22846using std::swap;22847swap(*(m_data.m_value.binary), other);22848}22849else22850{22851JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));22852}22853}2285422855/// @brief exchanges the values22856/// @sa https://json.nlohmann.me/api/basic_json/swap/22857void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)22858{22859// swap only works for strings22860if (JSON_HEDLEY_LIKELY(is_binary()))22861{22862using std::swap;22863swap(*(m_data.m_value.binary), other);22864}22865else22866{22867JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));22868}22869}2287022871/// @}2287222873//////////////////////////////////////////22874// lexicographical comparison operators //22875//////////////////////////////////////////2287622877/// @name lexicographical comparison operators22878/// @{2287922880// note parentheses around operands are necessary; see22881// https://github.com/nlohmann/json/issues/153022882#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \22883const auto lhs_type = lhs.type(); \22884const auto rhs_type = rhs.type(); \22885\22886if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \22887{ \22888switch (lhs_type) \22889{ \22890case value_t::array: \22891return (*lhs.m_data.m_value.array) op (*rhs.m_data.m_value.array); \22892\22893case value_t::object: \22894return (*lhs.m_data.m_value.object) op (*rhs.m_data.m_value.object); \22895\22896case value_t::null: \22897return (null_result); \22898\22899case value_t::string: \22900return (*lhs.m_data.m_value.string) op (*rhs.m_data.m_value.string); \22901\22902case value_t::boolean: \22903return (lhs.m_data.m_value.boolean) op (rhs.m_data.m_value.boolean); \22904\22905case value_t::number_integer: \22906return (lhs.m_data.m_value.number_integer) op (rhs.m_data.m_value.number_integer); \22907\22908case value_t::number_unsigned: \22909return (lhs.m_data.m_value.number_unsigned) op (rhs.m_data.m_value.number_unsigned); \22910\22911case value_t::number_float: \22912return (lhs.m_data.m_value.number_float) op (rhs.m_data.m_value.number_float); \22913\22914case value_t::binary: \22915return (*lhs.m_data.m_value.binary) op (*rhs.m_data.m_value.binary); \22916\22917case value_t::discarded: \22918default: \22919return (unordered_result); \22920} \22921} \22922else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \22923{ \22924return static_cast<number_float_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_float; \22925} \22926else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \22927{ \22928return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_integer); \22929} \22930else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \22931{ \22932return static_cast<number_float_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_float; \22933} \22934else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \22935{ \22936return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_unsigned); \22937} \22938else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \22939{ \22940return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \22941} \22942else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \22943{ \22944return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \22945} \22946else if(compares_unordered(lhs, rhs))\22947{\22948return (unordered_result);\22949}\22950\22951return (default_result);2295222953JSON_PRIVATE_UNLESS_TESTED:22954// returns true if:22955// - any operand is NaN and the other operand is of number type22956// - any operand is discarded22957// in legacy mode, discarded values are considered ordered if22958// an operation is computed as an odd number of inverses of others22959static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept22960{22961if ((lhs.is_number_float() && std::isnan(lhs.m_data.m_value.number_float) && rhs.is_number())22962|| (rhs.is_number_float() && std::isnan(rhs.m_data.m_value.number_float) && lhs.is_number()))22963{22964return true;22965}22966#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON22967return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;22968#else22969static_cast<void>(inverse);22970return lhs.is_discarded() || rhs.is_discarded();22971#endif22972}2297322974private:22975bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept22976{22977return compares_unordered(*this, rhs, inverse);22978}2297922980public:22981#if JSON_HAS_THREE_WAY_COMPARISON22982/// @brief comparison: equal22983/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/22984bool operator==(const_reference rhs) const noexcept22985{22986#ifdef __GNUC__22987#pragma GCC diagnostic push22988#pragma GCC diagnostic ignored "-Wfloat-equal"22989#endif22990const_reference lhs = *this;22991JSON_IMPLEMENT_OPERATOR( ==, true, false, false)22992#ifdef __GNUC__22993#pragma GCC diagnostic pop22994#endif22995}2299622997/// @brief comparison: equal22998/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/22999template<typename ScalarType>23000requires std::is_scalar_v<ScalarType>23001bool operator==(ScalarType rhs) const noexcept23002{23003return *this == basic_json(rhs);23004}2300523006/// @brief comparison: not equal23007/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/23008bool operator!=(const_reference rhs) const noexcept23009{23010if (compares_unordered(rhs, true))23011{23012return false;23013}23014return !operator==(rhs);23015}2301623017/// @brief comparison: 3-way23018/// @sa https://json.nlohmann.me/api/basic_json/operator_spaceship/23019std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*23020{23021const_reference lhs = *this;23022// default_result is used if we cannot compare values. In that case,23023// we compare types.23024JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD*23025std::partial_ordering::equivalent,23026std::partial_ordering::unordered,23027lhs_type <=> rhs_type) // *NOPAD*23028}2302923030/// @brief comparison: 3-way23031/// @sa https://json.nlohmann.me/api/basic_json/operator_spaceship/23032template<typename ScalarType>23033requires std::is_scalar_v<ScalarType>23034std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*23035{23036return *this <=> basic_json(rhs); // *NOPAD*23037}2303823039#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON23040// all operators that are computed as an odd number of inverses of others23041// need to be overloaded to emulate the legacy comparison behavior2304223043/// @brief comparison: less than or equal23044/// @sa https://json.nlohmann.me/api/basic_json/operator_le/23045JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)23046bool operator<=(const_reference rhs) const noexcept23047{23048if (compares_unordered(rhs, true))23049{23050return false;23051}23052return !(rhs < *this);23053}2305423055/// @brief comparison: less than or equal23056/// @sa https://json.nlohmann.me/api/basic_json/operator_le/23057template<typename ScalarType>23058requires std::is_scalar_v<ScalarType>23059bool operator<=(ScalarType rhs) const noexcept23060{23061return *this <= basic_json(rhs);23062}2306323064/// @brief comparison: greater than or equal23065/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/23066JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)23067bool operator>=(const_reference rhs) const noexcept23068{23069if (compares_unordered(rhs, true))23070{23071return false;23072}23073return !(*this < rhs);23074}2307523076/// @brief comparison: greater than or equal23077/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/23078template<typename ScalarType>23079requires std::is_scalar_v<ScalarType>23080bool operator>=(ScalarType rhs) const noexcept23081{23082return *this >= basic_json(rhs);23083}23084#endif23085#else23086/// @brief comparison: equal23087/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/23088friend bool operator==(const_reference lhs, const_reference rhs) noexcept23089{23090#ifdef __GNUC__23091#pragma GCC diagnostic push23092#pragma GCC diagnostic ignored "-Wfloat-equal"23093#endif23094JSON_IMPLEMENT_OPERATOR( ==, true, false, false)23095#ifdef __GNUC__23096#pragma GCC diagnostic pop23097#endif23098}2309923100/// @brief comparison: equal23101/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/23102template<typename ScalarType, typename std::enable_if<23103std::is_scalar<ScalarType>::value, int>::type = 0>23104friend bool operator==(const_reference lhs, ScalarType rhs) noexcept23105{23106return lhs == basic_json(rhs);23107}2310823109/// @brief comparison: equal23110/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/23111template<typename ScalarType, typename std::enable_if<23112std::is_scalar<ScalarType>::value, int>::type = 0>23113friend bool operator==(ScalarType lhs, const_reference rhs) noexcept23114{23115return basic_json(lhs) == rhs;23116}2311723118/// @brief comparison: not equal23119/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/23120friend bool operator!=(const_reference lhs, const_reference rhs) noexcept23121{23122if (compares_unordered(lhs, rhs, true))23123{23124return false;23125}23126return !(lhs == rhs);23127}2312823129/// @brief comparison: not equal23130/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/23131template<typename ScalarType, typename std::enable_if<23132std::is_scalar<ScalarType>::value, int>::type = 0>23133friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept23134{23135return lhs != basic_json(rhs);23136}2313723138/// @brief comparison: not equal23139/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/23140template<typename ScalarType, typename std::enable_if<23141std::is_scalar<ScalarType>::value, int>::type = 0>23142friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept23143{23144return basic_json(lhs) != rhs;23145}2314623147/// @brief comparison: less than23148/// @sa https://json.nlohmann.me/api/basic_json/operator_lt/23149friend bool operator<(const_reference lhs, const_reference rhs) noexcept23150{23151// default_result is used if we cannot compare values. In that case,23152// we compare types. Note we have to call the operator explicitly,23153// because MSVC has problems otherwise.23154JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))23155}2315623157/// @brief comparison: less than23158/// @sa https://json.nlohmann.me/api/basic_json/operator_lt/23159template<typename ScalarType, typename std::enable_if<23160std::is_scalar<ScalarType>::value, int>::type = 0>23161friend bool operator<(const_reference lhs, ScalarType rhs) noexcept23162{23163return lhs < basic_json(rhs);23164}2316523166/// @brief comparison: less than23167/// @sa https://json.nlohmann.me/api/basic_json/operator_lt/23168template<typename ScalarType, typename std::enable_if<23169std::is_scalar<ScalarType>::value, int>::type = 0>23170friend bool operator<(ScalarType lhs, const_reference rhs) noexcept23171{23172return basic_json(lhs) < rhs;23173}2317423175/// @brief comparison: less than or equal23176/// @sa https://json.nlohmann.me/api/basic_json/operator_le/23177friend bool operator<=(const_reference lhs, const_reference rhs) noexcept23178{23179if (compares_unordered(lhs, rhs, true))23180{23181return false;23182}23183return !(rhs < lhs);23184}2318523186/// @brief comparison: less than or equal23187/// @sa https://json.nlohmann.me/api/basic_json/operator_le/23188template<typename ScalarType, typename std::enable_if<23189std::is_scalar<ScalarType>::value, int>::type = 0>23190friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept23191{23192return lhs <= basic_json(rhs);23193}2319423195/// @brief comparison: less than or equal23196/// @sa https://json.nlohmann.me/api/basic_json/operator_le/23197template<typename ScalarType, typename std::enable_if<23198std::is_scalar<ScalarType>::value, int>::type = 0>23199friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept23200{23201return basic_json(lhs) <= rhs;23202}2320323204/// @brief comparison: greater than23205/// @sa https://json.nlohmann.me/api/basic_json/operator_gt/23206friend bool operator>(const_reference lhs, const_reference rhs) noexcept23207{23208// double inverse23209if (compares_unordered(lhs, rhs))23210{23211return false;23212}23213return !(lhs <= rhs);23214}2321523216/// @brief comparison: greater than23217/// @sa https://json.nlohmann.me/api/basic_json/operator_gt/23218template<typename ScalarType, typename std::enable_if<23219std::is_scalar<ScalarType>::value, int>::type = 0>23220friend bool operator>(const_reference lhs, ScalarType rhs) noexcept23221{23222return lhs > basic_json(rhs);23223}2322423225/// @brief comparison: greater than23226/// @sa https://json.nlohmann.me/api/basic_json/operator_gt/23227template<typename ScalarType, typename std::enable_if<23228std::is_scalar<ScalarType>::value, int>::type = 0>23229friend bool operator>(ScalarType lhs, const_reference rhs) noexcept23230{23231return basic_json(lhs) > rhs;23232}2323323234/// @brief comparison: greater than or equal23235/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/23236friend bool operator>=(const_reference lhs, const_reference rhs) noexcept23237{23238if (compares_unordered(lhs, rhs, true))23239{23240return false;23241}23242return !(lhs < rhs);23243}2324423245/// @brief comparison: greater than or equal23246/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/23247template<typename ScalarType, typename std::enable_if<23248std::is_scalar<ScalarType>::value, int>::type = 0>23249friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept23250{23251return lhs >= basic_json(rhs);23252}2325323254/// @brief comparison: greater than or equal23255/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/23256template<typename ScalarType, typename std::enable_if<23257std::is_scalar<ScalarType>::value, int>::type = 0>23258friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept23259{23260return basic_json(lhs) >= rhs;23261}23262#endif2326323264#undef JSON_IMPLEMENT_OPERATOR2326523266/// @}2326723268///////////////////23269// serialization //23270///////////////////2327123272/// @name serialization23273/// @{23274#ifndef JSON_NO_IO23275/// @brief serialize to stream23276/// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/23277friend std::ostream& operator<<(std::ostream& o, const basic_json& j)23278{23279// read width member and use it as indentation parameter if nonzero23280const bool pretty_print = o.width() > 0;23281const auto indentation = pretty_print ? o.width() : 0;2328223283// reset width to 0 for subsequent calls to this stream23284o.width(0);2328523286// do the actual serialization23287serializer s(detail::output_adapter<char>(o), o.fill());23288s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));23289return o;23290}2329123292/// @brief serialize to stream23293/// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/23294/// @deprecated This function is deprecated since 3.0.0 and will be removed in23295/// version 4.0.0 of the library. Please use23296/// operator<<(std::ostream&, const basic_json&) instead; that is,23297/// replace calls like `j >> o;` with `o << j;`.23298JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))23299friend std::ostream& operator>>(const basic_json& j, std::ostream& o)23300{23301return o << j;23302}23303#endif // JSON_NO_IO23304/// @}2330523306/////////////////////23307// deserialization //23308/////////////////////2330923310/// @name deserialization23311/// @{2331223313/// @brief deserialize from a compatible input23314/// @sa https://json.nlohmann.me/api/basic_json/parse/23315template<typename InputType>23316JSON_HEDLEY_WARN_UNUSED_RESULT23317static basic_json parse(InputType&& i,23318const parser_callback_t cb = nullptr,23319const bool allow_exceptions = true,23320const bool ignore_comments = false)23321{23322basic_json result;23323parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);23324return result;23325}2332623327/// @brief deserialize from a pair of character iterators23328/// @sa https://json.nlohmann.me/api/basic_json/parse/23329template<typename IteratorType>23330JSON_HEDLEY_WARN_UNUSED_RESULT23331static basic_json parse(IteratorType first,23332IteratorType last,23333const parser_callback_t cb = nullptr,23334const bool allow_exceptions = true,23335const bool ignore_comments = false)23336{23337basic_json result;23338parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);23339return result;23340}2334123342JSON_HEDLEY_WARN_UNUSED_RESULT23343JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))23344static basic_json parse(detail::span_input_adapter&& i,23345const parser_callback_t cb = nullptr,23346const bool allow_exceptions = true,23347const bool ignore_comments = false)23348{23349basic_json result;23350parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);23351return result;23352}2335323354/// @brief check if the input is valid JSON23355/// @sa https://json.nlohmann.me/api/basic_json/accept/23356template<typename InputType>23357static bool accept(InputType&& i,23358const bool ignore_comments = false)23359{23360return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);23361}2336223363/// @brief check if the input is valid JSON23364/// @sa https://json.nlohmann.me/api/basic_json/accept/23365template<typename IteratorType>23366static bool accept(IteratorType first, IteratorType last,23367const bool ignore_comments = false)23368{23369return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);23370}2337123372JSON_HEDLEY_WARN_UNUSED_RESULT23373JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))23374static bool accept(detail::span_input_adapter&& i,23375const bool ignore_comments = false)23376{23377return parser(i.get(), nullptr, false, ignore_comments).accept(true);23378}2337923380/// @brief generate SAX events23381/// @sa https://json.nlohmann.me/api/basic_json/sax_parse/23382template <typename InputType, typename SAX>23383JSON_HEDLEY_NON_NULL(2)23384static bool sax_parse(InputType&& i, SAX* sax,23385input_format_t format = input_format_t::json,23386const bool strict = true,23387const bool ignore_comments = false)23388{23389auto ia = detail::input_adapter(std::forward<InputType>(i));23390return format == input_format_t::json23391? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)23392: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);23393}2339423395/// @brief generate SAX events23396/// @sa https://json.nlohmann.me/api/basic_json/sax_parse/23397template<class IteratorType, class SAX>23398JSON_HEDLEY_NON_NULL(3)23399static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,23400input_format_t format = input_format_t::json,23401const bool strict = true,23402const bool ignore_comments = false)23403{23404auto ia = detail::input_adapter(std::move(first), std::move(last));23405return format == input_format_t::json23406? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)23407: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);23408}2340923410/// @brief generate SAX events23411/// @sa https://json.nlohmann.me/api/basic_json/sax_parse/23412/// @deprecated This function is deprecated since 3.8.0 and will be removed in23413/// version 4.0.0 of the library. Please use23414/// sax_parse(ptr, ptr + len) instead.23415template <typename SAX>23416JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))23417JSON_HEDLEY_NON_NULL(2)23418static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,23419input_format_t format = input_format_t::json,23420const bool strict = true,23421const bool ignore_comments = false)23422{23423auto ia = i.get();23424return format == input_format_t::json23425// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)23426? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)23427// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)23428: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);23429}23430#ifndef JSON_NO_IO23431/// @brief deserialize from stream23432/// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/23433/// @deprecated This stream operator is deprecated since 3.0.0 and will be removed in23434/// version 4.0.0 of the library. Please use23435/// operator>>(std::istream&, basic_json&) instead; that is,23436/// replace calls like `j << i;` with `i >> j;`.23437JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))23438friend std::istream& operator<<(basic_json& j, std::istream& i)23439{23440return operator>>(i, j);23441}2344223443/// @brief deserialize from stream23444/// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/23445friend std::istream& operator>>(std::istream& i, basic_json& j)23446{23447parser(detail::input_adapter(i)).parse(false, j);23448return i;23449}23450#endif // JSON_NO_IO23451/// @}2345223453///////////////////////////23454// convenience functions //23455///////////////////////////2345623457/// @brief return the type as string23458/// @sa https://json.nlohmann.me/api/basic_json/type_name/23459JSON_HEDLEY_RETURNS_NON_NULL23460const char* type_name() const noexcept23461{23462switch (m_data.m_type)23463{23464case value_t::null:23465return "null";23466case value_t::object:23467return "object";23468case value_t::array:23469return "array";23470case value_t::string:23471return "string";23472case value_t::boolean:23473return "boolean";23474case value_t::binary:23475return "binary";23476case value_t::discarded:23477return "discarded";23478case value_t::number_integer:23479case value_t::number_unsigned:23480case value_t::number_float:23481default:23482return "number";23483}23484}2348523486JSON_PRIVATE_UNLESS_TESTED:23487//////////////////////23488// member variables //23489//////////////////////2349023491struct data23492{23493/// the type of the current element23494value_t m_type = value_t::null;2349523496/// the value of the current element23497json_value m_value = {};2349823499data(const value_t v)23500: m_type(v), m_value(v)23501{23502}2350323504data(size_type cnt, const basic_json& val)23505: m_type(value_t::array)23506{23507m_value.array = create<array_t>(cnt, val);23508}2350923510data() noexcept = default;23511data(data&&) noexcept = default;23512data(const data&) noexcept = delete;23513data& operator=(data&&) noexcept = delete;23514data& operator=(const data&) noexcept = delete;2351523516~data() noexcept23517{23518m_value.destroy(m_type);23519}23520};2352123522data m_data = {};2352323524#if JSON_DIAGNOSTICS23525/// a pointer to a parent value (for debugging purposes)23526basic_json* m_parent = nullptr;23527#endif2352823529//////////////////////////////////////////23530// binary serialization/deserialization //23531//////////////////////////////////////////2353223533/// @name binary serialization/deserialization support23534/// @{2353523536public:23537/// @brief create a CBOR serialization of a given JSON value23538/// @sa https://json.nlohmann.me/api/basic_json/to_cbor/23539static std::vector<std::uint8_t> to_cbor(const basic_json& j)23540{23541std::vector<std::uint8_t> result;23542to_cbor(j, result);23543return result;23544}2354523546/// @brief create a CBOR serialization of a given JSON value23547/// @sa https://json.nlohmann.me/api/basic_json/to_cbor/23548static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)23549{23550binary_writer<std::uint8_t>(o).write_cbor(j);23551}2355223553/// @brief create a CBOR serialization of a given JSON value23554/// @sa https://json.nlohmann.me/api/basic_json/to_cbor/23555static void to_cbor(const basic_json& j, detail::output_adapter<char> o)23556{23557binary_writer<char>(o).write_cbor(j);23558}2355923560/// @brief create a MessagePack serialization of a given JSON value23561/// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/23562static std::vector<std::uint8_t> to_msgpack(const basic_json& j)23563{23564std::vector<std::uint8_t> result;23565to_msgpack(j, result);23566return result;23567}2356823569/// @brief create a MessagePack serialization of a given JSON value23570/// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/23571static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)23572{23573binary_writer<std::uint8_t>(o).write_msgpack(j);23574}2357523576/// @brief create a MessagePack serialization of a given JSON value23577/// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/23578static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)23579{23580binary_writer<char>(o).write_msgpack(j);23581}2358223583/// @brief create a UBJSON serialization of a given JSON value23584/// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/23585static std::vector<std::uint8_t> to_ubjson(const basic_json& j,23586const bool use_size = false,23587const bool use_type = false)23588{23589std::vector<std::uint8_t> result;23590to_ubjson(j, result, use_size, use_type);23591return result;23592}2359323594/// @brief create a UBJSON serialization of a given JSON value23595/// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/23596static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,23597const bool use_size = false, const bool use_type = false)23598{23599binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);23600}2360123602/// @brief create a UBJSON serialization of a given JSON value23603/// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/23604static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,23605const bool use_size = false, const bool use_type = false)23606{23607binary_writer<char>(o).write_ubjson(j, use_size, use_type);23608}2360923610/// @brief create a BJData serialization of a given JSON value23611/// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/23612static std::vector<std::uint8_t> to_bjdata(const basic_json& j,23613const bool use_size = false,23614const bool use_type = false)23615{23616std::vector<std::uint8_t> result;23617to_bjdata(j, result, use_size, use_type);23618return result;23619}2362023621/// @brief create a BJData serialization of a given JSON value23622/// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/23623static void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o,23624const bool use_size = false, const bool use_type = false)23625{23626binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);23627}2362823629/// @brief create a BJData serialization of a given JSON value23630/// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/23631static void to_bjdata(const basic_json& j, detail::output_adapter<char> o,23632const bool use_size = false, const bool use_type = false)23633{23634binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);23635}2363623637/// @brief create a BSON serialization of a given JSON value23638/// @sa https://json.nlohmann.me/api/basic_json/to_bson/23639static std::vector<std::uint8_t> to_bson(const basic_json& j)23640{23641std::vector<std::uint8_t> result;23642to_bson(j, result);23643return result;23644}2364523646/// @brief create a BSON serialization of a given JSON value23647/// @sa https://json.nlohmann.me/api/basic_json/to_bson/23648static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)23649{23650binary_writer<std::uint8_t>(o).write_bson(j);23651}2365223653/// @brief create a BSON serialization of a given JSON value23654/// @sa https://json.nlohmann.me/api/basic_json/to_bson/23655static void to_bson(const basic_json& j, detail::output_adapter<char> o)23656{23657binary_writer<char>(o).write_bson(j);23658}2365923660/// @brief create a JSON value from an input in CBOR format23661/// @sa https://json.nlohmann.me/api/basic_json/from_cbor/23662template<typename InputType>23663JSON_HEDLEY_WARN_UNUSED_RESULT23664static basic_json from_cbor(InputType&& i,23665const bool strict = true,23666const bool allow_exceptions = true,23667const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)23668{23669basic_json result;23670detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23671auto ia = detail::input_adapter(std::forward<InputType>(i));23672const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);23673return res ? result : basic_json(value_t::discarded);23674}2367523676/// @brief create a JSON value from an input in CBOR format23677/// @sa https://json.nlohmann.me/api/basic_json/from_cbor/23678template<typename IteratorType>23679JSON_HEDLEY_WARN_UNUSED_RESULT23680static basic_json from_cbor(IteratorType first, IteratorType last,23681const bool strict = true,23682const bool allow_exceptions = true,23683const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)23684{23685basic_json result;23686detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23687auto ia = detail::input_adapter(std::move(first), std::move(last));23688const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);23689return res ? result : basic_json(value_t::discarded);23690}2369123692template<typename T>23693JSON_HEDLEY_WARN_UNUSED_RESULT23694JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))23695static basic_json from_cbor(const T* ptr, std::size_t len,23696const bool strict = true,23697const bool allow_exceptions = true,23698const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)23699{23700return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);23701}2370223703JSON_HEDLEY_WARN_UNUSED_RESULT23704JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))23705static basic_json from_cbor(detail::span_input_adapter&& i,23706const bool strict = true,23707const bool allow_exceptions = true,23708const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)23709{23710basic_json result;23711detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23712auto ia = i.get();23713// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)23714const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);23715return res ? result : basic_json(value_t::discarded);23716}2371723718/// @brief create a JSON value from an input in MessagePack format23719/// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/23720template<typename InputType>23721JSON_HEDLEY_WARN_UNUSED_RESULT23722static basic_json from_msgpack(InputType&& i,23723const bool strict = true,23724const bool allow_exceptions = true)23725{23726basic_json result;23727detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23728auto ia = detail::input_adapter(std::forward<InputType>(i));23729const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);23730return res ? result : basic_json(value_t::discarded);23731}2373223733/// @brief create a JSON value from an input in MessagePack format23734/// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/23735template<typename IteratorType>23736JSON_HEDLEY_WARN_UNUSED_RESULT23737static basic_json from_msgpack(IteratorType first, IteratorType last,23738const bool strict = true,23739const bool allow_exceptions = true)23740{23741basic_json result;23742detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23743auto ia = detail::input_adapter(std::move(first), std::move(last));23744const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);23745return res ? result : basic_json(value_t::discarded);23746}2374723748template<typename T>23749JSON_HEDLEY_WARN_UNUSED_RESULT23750JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))23751static basic_json from_msgpack(const T* ptr, std::size_t len,23752const bool strict = true,23753const bool allow_exceptions = true)23754{23755return from_msgpack(ptr, ptr + len, strict, allow_exceptions);23756}2375723758JSON_HEDLEY_WARN_UNUSED_RESULT23759JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))23760static basic_json from_msgpack(detail::span_input_adapter&& i,23761const bool strict = true,23762const bool allow_exceptions = true)23763{23764basic_json result;23765detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23766auto ia = i.get();23767// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)23768const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);23769return res ? result : basic_json(value_t::discarded);23770}2377123772/// @brief create a JSON value from an input in UBJSON format23773/// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/23774template<typename InputType>23775JSON_HEDLEY_WARN_UNUSED_RESULT23776static basic_json from_ubjson(InputType&& i,23777const bool strict = true,23778const bool allow_exceptions = true)23779{23780basic_json result;23781detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23782auto ia = detail::input_adapter(std::forward<InputType>(i));23783const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);23784return res ? result : basic_json(value_t::discarded);23785}2378623787/// @brief create a JSON value from an input in UBJSON format23788/// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/23789template<typename IteratorType>23790JSON_HEDLEY_WARN_UNUSED_RESULT23791static basic_json from_ubjson(IteratorType first, IteratorType last,23792const bool strict = true,23793const bool allow_exceptions = true)23794{23795basic_json result;23796detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23797auto ia = detail::input_adapter(std::move(first), std::move(last));23798const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);23799return res ? result : basic_json(value_t::discarded);23800}2380123802template<typename T>23803JSON_HEDLEY_WARN_UNUSED_RESULT23804JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))23805static basic_json from_ubjson(const T* ptr, std::size_t len,23806const bool strict = true,23807const bool allow_exceptions = true)23808{23809return from_ubjson(ptr, ptr + len, strict, allow_exceptions);23810}2381123812JSON_HEDLEY_WARN_UNUSED_RESULT23813JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))23814static basic_json from_ubjson(detail::span_input_adapter&& i,23815const bool strict = true,23816const bool allow_exceptions = true)23817{23818basic_json result;23819detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23820auto ia = i.get();23821// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)23822const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);23823return res ? result : basic_json(value_t::discarded);23824}2382523826/// @brief create a JSON value from an input in BJData format23827/// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/23828template<typename InputType>23829JSON_HEDLEY_WARN_UNUSED_RESULT23830static basic_json from_bjdata(InputType&& i,23831const bool strict = true,23832const bool allow_exceptions = true)23833{23834basic_json result;23835detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23836auto ia = detail::input_adapter(std::forward<InputType>(i));23837const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);23838return res ? result : basic_json(value_t::discarded);23839}2384023841/// @brief create a JSON value from an input in BJData format23842/// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/23843template<typename IteratorType>23844JSON_HEDLEY_WARN_UNUSED_RESULT23845static basic_json from_bjdata(IteratorType first, IteratorType last,23846const bool strict = true,23847const bool allow_exceptions = true)23848{23849basic_json result;23850detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23851auto ia = detail::input_adapter(std::move(first), std::move(last));23852const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);23853return res ? result : basic_json(value_t::discarded);23854}2385523856/// @brief create a JSON value from an input in BSON format23857/// @sa https://json.nlohmann.me/api/basic_json/from_bson/23858template<typename InputType>23859JSON_HEDLEY_WARN_UNUSED_RESULT23860static basic_json from_bson(InputType&& i,23861const bool strict = true,23862const bool allow_exceptions = true)23863{23864basic_json result;23865detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23866auto ia = detail::input_adapter(std::forward<InputType>(i));23867const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);23868return res ? result : basic_json(value_t::discarded);23869}2387023871/// @brief create a JSON value from an input in BSON format23872/// @sa https://json.nlohmann.me/api/basic_json/from_bson/23873template<typename IteratorType>23874JSON_HEDLEY_WARN_UNUSED_RESULT23875static basic_json from_bson(IteratorType first, IteratorType last,23876const bool strict = true,23877const bool allow_exceptions = true)23878{23879basic_json result;23880detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23881auto ia = detail::input_adapter(std::move(first), std::move(last));23882const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);23883return res ? result : basic_json(value_t::discarded);23884}2388523886template<typename T>23887JSON_HEDLEY_WARN_UNUSED_RESULT23888JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))23889static basic_json from_bson(const T* ptr, std::size_t len,23890const bool strict = true,23891const bool allow_exceptions = true)23892{23893return from_bson(ptr, ptr + len, strict, allow_exceptions);23894}2389523896JSON_HEDLEY_WARN_UNUSED_RESULT23897JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))23898static basic_json from_bson(detail::span_input_adapter&& i,23899const bool strict = true,23900const bool allow_exceptions = true)23901{23902basic_json result;23903detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23904auto ia = i.get();23905// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)23906const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);23907return res ? result : basic_json(value_t::discarded);23908}23909/// @}2391023911//////////////////////////23912// JSON Pointer support //23913//////////////////////////2391423915/// @name JSON Pointer functions23916/// @{2391723918/// @brief access specified element via JSON Pointer23919/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/23920reference operator[](const json_pointer& ptr)23921{23922return ptr.get_unchecked(this);23923}2392423925template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>23926JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)23927reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)23928{23929return ptr.get_unchecked(this);23930}2393123932/// @brief access specified element via JSON Pointer23933/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/23934const_reference operator[](const json_pointer& ptr) const23935{23936return ptr.get_unchecked(this);23937}2393823939template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>23940JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)23941const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const23942{23943return ptr.get_unchecked(this);23944}2394523946/// @brief access specified element via JSON Pointer23947/// @sa https://json.nlohmann.me/api/basic_json/at/23948reference at(const json_pointer& ptr)23949{23950return ptr.get_checked(this);23951}2395223953template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>23954JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)23955reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)23956{23957return ptr.get_checked(this);23958}2395923960/// @brief access specified element via JSON Pointer23961/// @sa https://json.nlohmann.me/api/basic_json/at/23962const_reference at(const json_pointer& ptr) const23963{23964return ptr.get_checked(this);23965}2396623967template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>23968JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)23969const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const23970{23971return ptr.get_checked(this);23972}2397323974/// @brief return flattened JSON value23975/// @sa https://json.nlohmann.me/api/basic_json/flatten/23976basic_json flatten() const23977{23978basic_json result(value_t::object);23979json_pointer::flatten("", *this, result);23980return result;23981}2398223983/// @brief unflatten a previously flattened JSON value23984/// @sa https://json.nlohmann.me/api/basic_json/unflatten/23985basic_json unflatten() const23986{23987return json_pointer::unflatten(*this);23988}2398923990/// @}2399123992//////////////////////////23993// JSON Patch functions //23994//////////////////////////2399523996/// @name JSON Patch functions23997/// @{2399823999/// @brief applies a JSON patch in-place without copying the object24000/// @sa https://json.nlohmann.me/api/basic_json/patch/24001void patch_inplace(const basic_json& json_patch)24002{24003basic_json& result = *this;24004// the valid JSON Patch operations24005enum class patch_operations {add, remove, replace, move, copy, test, invalid};2400624007const auto get_op = [](const std::string & op)24008{24009if (op == "add")24010{24011return patch_operations::add;24012}24013if (op == "remove")24014{24015return patch_operations::remove;24016}24017if (op == "replace")24018{24019return patch_operations::replace;24020}24021if (op == "move")24022{24023return patch_operations::move;24024}24025if (op == "copy")24026{24027return patch_operations::copy;24028}24029if (op == "test")24030{24031return patch_operations::test;24032}2403324034return patch_operations::invalid;24035};2403624037// wrapper for "add" operation; add value at ptr24038const auto operation_add = [&result](json_pointer & ptr, basic_json val)24039{24040// adding to the root of the target document means replacing it24041if (ptr.empty())24042{24043result = val;24044return;24045}2404624047// make sure the top element of the pointer exists24048json_pointer const top_pointer = ptr.top();24049if (top_pointer != ptr)24050{24051result.at(top_pointer);24052}2405324054// get reference to parent of JSON pointer ptr24055const auto last_path = ptr.back();24056ptr.pop_back();24057// parent must exist when performing patch add per RFC6902 specs24058basic_json& parent = result.at(ptr);2405924060switch (parent.m_data.m_type)24061{24062case value_t::null:24063case value_t::object:24064{24065// use operator[] to add value24066parent[last_path] = val;24067break;24068}2406924070case value_t::array:24071{24072if (last_path == "-")24073{24074// special case: append to back24075parent.push_back(val);24076}24077else24078{24079const auto idx = json_pointer::template array_index<basic_json_t>(last_path);24080if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))24081{24082// avoid undefined behavior24083JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));24084}2408524086// default case: insert add offset24087parent.insert(parent.begin() + static_cast<difference_type>(idx), val);24088}24089break;24090}2409124092// if there exists a parent it cannot be primitive24093case value_t::string: // LCOV_EXCL_LINE24094case value_t::boolean: // LCOV_EXCL_LINE24095case value_t::number_integer: // LCOV_EXCL_LINE24096case value_t::number_unsigned: // LCOV_EXCL_LINE24097case value_t::number_float: // LCOV_EXCL_LINE24098case value_t::binary: // LCOV_EXCL_LINE24099case value_t::discarded: // LCOV_EXCL_LINE24100default: // LCOV_EXCL_LINE24101JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE24102}24103};2410424105// wrapper for "remove" operation; remove value at ptr24106const auto operation_remove = [this, & result](json_pointer & ptr)24107{24108// get reference to parent of JSON pointer ptr24109const auto last_path = ptr.back();24110ptr.pop_back();24111basic_json& parent = result.at(ptr);2411224113// remove child24114if (parent.is_object())24115{24116// perform range check24117auto it = parent.find(last_path);24118if (JSON_HEDLEY_LIKELY(it != parent.end()))24119{24120parent.erase(it);24121}24122else24123{24124JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));24125}24126}24127else if (parent.is_array())24128{24129// note erase performs range check24130parent.erase(json_pointer::template array_index<basic_json_t>(last_path));24131}24132};2413324134// type check: top level value must be an array24135if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))24136{24137JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));24138}2413924140// iterate and apply the operations24141for (const auto& val : json_patch)24142{24143// wrapper to get a value for an operation24144const auto get_value = [&val](const std::string & op,24145const std::string & member,24146bool string_type) -> basic_json &24147{24148// find value24149auto it = val.m_data.m_value.object->find(member);2415024151// context-sensitive error message24152const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');2415324154// check if desired value is present24155if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))24156{24157// NOLINTNEXTLINE(performance-inefficient-string-concatenation)24158JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));24159}2416024161// check if result is of type string24162if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))24163{24164// NOLINTNEXTLINE(performance-inefficient-string-concatenation)24165JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));24166}2416724168// no error: return value24169return it->second;24170};2417124172// type check: every element of the array must be an object24173if (JSON_HEDLEY_UNLIKELY(!val.is_object()))24174{24175JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));24176}2417724178// collect mandatory members24179const auto op = get_value("op", "op", true).template get<std::string>();24180const auto path = get_value(op, "path", true).template get<std::string>();24181json_pointer ptr(path);2418224183switch (get_op(op))24184{24185case patch_operations::add:24186{24187operation_add(ptr, get_value("add", "value", false));24188break;24189}2419024191case patch_operations::remove:24192{24193operation_remove(ptr);24194break;24195}2419624197case patch_operations::replace:24198{24199// the "path" location must exist - use at()24200result.at(ptr) = get_value("replace", "value", false);24201break;24202}2420324204case patch_operations::move:24205{24206const auto from_path = get_value("move", "from", true).template get<std::string>();24207json_pointer from_ptr(from_path);2420824209// the "from" location must exist - use at()24210basic_json const v = result.at(from_ptr);2421124212// The move operation is functionally identical to a24213// "remove" operation on the "from" location, followed24214// immediately by an "add" operation at the target24215// location with the value that was just removed.24216operation_remove(from_ptr);24217operation_add(ptr, v);24218break;24219}2422024221case patch_operations::copy:24222{24223const auto from_path = get_value("copy", "from", true).template get<std::string>();24224const json_pointer from_ptr(from_path);2422524226// the "from" location must exist - use at()24227basic_json const v = result.at(from_ptr);2422824229// The copy is functionally identical to an "add"24230// operation at the target location using the value24231// specified in the "from" member.24232operation_add(ptr, v);24233break;24234}2423524236case patch_operations::test:24237{24238bool success = false;24239JSON_TRY24240{24241// check if "value" matches the one at "path"24242// the "path" location must exist - use at()24243success = (result.at(ptr) == get_value("test", "value", false));24244}24245JSON_INTERNAL_CATCH (out_of_range&)24246{24247// ignore out of range errors: success remains false24248}2424924250// throw an exception if test fails24251if (JSON_HEDLEY_UNLIKELY(!success))24252{24253JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));24254}2425524256break;24257}2425824259case patch_operations::invalid:24260default:24261{24262// op must be "add", "remove", "replace", "move", "copy", or24263// "test"24264JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));24265}24266}24267}24268}2426924270/// @brief applies a JSON patch to a copy of the current object24271/// @sa https://json.nlohmann.me/api/basic_json/patch/24272basic_json patch(const basic_json& json_patch) const24273{24274basic_json result = *this;24275result.patch_inplace(json_patch);24276return result;24277}2427824279/// @brief creates a diff as a JSON patch24280/// @sa https://json.nlohmann.me/api/basic_json/diff/24281JSON_HEDLEY_WARN_UNUSED_RESULT24282static basic_json diff(const basic_json& source, const basic_json& target,24283const std::string& path = "")24284{24285// the patch24286basic_json result(value_t::array);2428724288// if the values are the same, return empty patch24289if (source == target)24290{24291return result;24292}2429324294if (source.type() != target.type())24295{24296// different types: replace value24297result.push_back(24298{24299{"op", "replace"}, {"path", path}, {"value", target}24300});24301return result;24302}2430324304switch (source.type())24305{24306case value_t::array:24307{24308// first pass: traverse common elements24309std::size_t i = 0;24310while (i < source.size() && i < target.size())24311{24312// recursive call to compare array values at index i24313auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));24314result.insert(result.end(), temp_diff.begin(), temp_diff.end());24315++i;24316}2431724318// We now reached the end of at least one array24319// in a second pass, traverse the remaining elements2432024321// remove my remaining elements24322const auto end_index = static_cast<difference_type>(result.size());24323while (i < source.size())24324{24325// add operations in reverse order to avoid invalid24326// indices24327result.insert(result.begin() + end_index, object(24328{24329{"op", "remove"},24330{"path", detail::concat(path, '/', std::to_string(i))}24331}));24332++i;24333}2433424335// add other remaining elements24336while (i < target.size())24337{24338result.push_back(24339{24340{"op", "add"},24341{"path", detail::concat(path, "/-")},24342{"value", target[i]}24343});24344++i;24345}2434624347break;24348}2434924350case value_t::object:24351{24352// first pass: traverse this object's elements24353for (auto it = source.cbegin(); it != source.cend(); ++it)24354{24355// escape the key name to be used in a JSON patch24356const auto path_key = detail::concat(path, '/', detail::escape(it.key()));2435724358if (target.find(it.key()) != target.end())24359{24360// recursive call to compare object values at key it24361auto temp_diff = diff(it.value(), target[it.key()], path_key);24362result.insert(result.end(), temp_diff.begin(), temp_diff.end());24363}24364else24365{24366// found a key that is not in o -> remove it24367result.push_back(object(24368{24369{"op", "remove"}, {"path", path_key}24370}));24371}24372}2437324374// second pass: traverse other object's elements24375for (auto it = target.cbegin(); it != target.cend(); ++it)24376{24377if (source.find(it.key()) == source.end())24378{24379// found a key that is not in this -> add it24380const auto path_key = detail::concat(path, '/', detail::escape(it.key()));24381result.push_back(24382{24383{"op", "add"}, {"path", path_key},24384{"value", it.value()}24385});24386}24387}2438824389break;24390}2439124392case value_t::null:24393case value_t::string:24394case value_t::boolean:24395case value_t::number_integer:24396case value_t::number_unsigned:24397case value_t::number_float:24398case value_t::binary:24399case value_t::discarded:24400default:24401{24402// both primitive type: replace value24403result.push_back(24404{24405{"op", "replace"}, {"path", path}, {"value", target}24406});24407break;24408}24409}2441024411return result;24412}24413/// @}2441424415////////////////////////////////24416// JSON Merge Patch functions //24417////////////////////////////////2441824419/// @name JSON Merge Patch functions24420/// @{2442124422/// @brief applies a JSON Merge Patch24423/// @sa https://json.nlohmann.me/api/basic_json/merge_patch/24424void merge_patch(const basic_json& apply_patch)24425{24426if (apply_patch.is_object())24427{24428if (!is_object())24429{24430*this = object();24431}24432for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)24433{24434if (it.value().is_null())24435{24436erase(it.key());24437}24438else24439{24440operator[](it.key()).merge_patch(it.value());24441}24442}24443}24444else24445{24446*this = apply_patch;24447}24448}2444924450/// @}24451};2445224453/// @brief user-defined to_string function for JSON values24454/// @sa https://json.nlohmann.me/api/basic_json/to_string/24455NLOHMANN_BASIC_JSON_TPL_DECLARATION24456std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)24457{24458return j.dump();24459}2446024461inline namespace literals24462{24463inline namespace json_literals24464{2446524466/// @brief user-defined string literal for JSON values24467/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/24468JSON_HEDLEY_NON_NULL(1)24469#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)24470inline nlohmann::json operator ""_json(const char* s, std::size_t n)24471#else24472inline nlohmann::json operator "" _json(const char* s, std::size_t n)24473#endif24474{24475return nlohmann::json::parse(s, s + n);24476}2447724478/// @brief user-defined string literal for JSON pointer24479/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/24480JSON_HEDLEY_NON_NULL(1)24481#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)24482inline nlohmann::json::json_pointer operator ""_json_pointer(const char* s, std::size_t n)24483#else24484inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)24485#endif24486{24487return nlohmann::json::json_pointer(std::string(s, n));24488}2448924490} // namespace json_literals24491} // namespace literals24492NLOHMANN_JSON_NAMESPACE_END2449324494///////////////////////24495// nonmember support //24496///////////////////////2449724498namespace std // NOLINT(cert-dcl58-cpp)24499{2450024501/// @brief hash value for JSON objects24502/// @sa https://json.nlohmann.me/api/basic_json/std_hash/24503NLOHMANN_BASIC_JSON_TPL_DECLARATION24504struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp)24505{24506std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const24507{24508return nlohmann::detail::hash(j);24509}24510};2451124512// specialization for std::less<value_t>24513template<>24514struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/67924515{24516/*!24517@brief compare two value_t enum values24518@since version 3.0.024519*/24520bool operator()(::nlohmann::detail::value_t lhs,24521::nlohmann::detail::value_t rhs) const noexcept24522{24523#if JSON_HAS_THREE_WAY_COMPARISON24524return std::is_lt(lhs <=> rhs); // *NOPAD*24525#else24526return ::nlohmann::detail::operator<(lhs, rhs);24527#endif24528}24529};2453024531// C++20 prohibit function specialization in the std namespace.24532#ifndef JSON_HAS_CPP_202453324534/// @brief exchanges the values of two JSON objects24535/// @sa https://json.nlohmann.me/api/basic_json/std_swap/24536NLOHMANN_BASIC_JSON_TPL_DECLARATION24537inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp)24538is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)24539is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)24540{24541j1.swap(j2);24542}2454324544#endif2454524546} // namespace std2454724548#if JSON_USE_GLOBAL_UDLS24549#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)24550using nlohmann::literals::json_literals::operator ""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)24551using nlohmann::literals::json_literals::operator ""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)24552#else24553using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)24554using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)24555#endif24556#endif2455724558// #include <nlohmann/detail/macro_unscope.hpp>24559// __ _____ _____ _____24560// __| | __| | | | JSON for Modern C++24561// | | |__ | | | | | | version 3.11.324562// |_____|_____|_____|_|___| https://github.com/nlohmann/json24563//24564// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>24565// SPDX-License-Identifier: MIT24566245672456824569// restore clang diagnostic settings24570#if defined(__clang__)24571#pragma clang diagnostic pop24572#endif2457324574// clean up24575#undef JSON_ASSERT24576#undef JSON_INTERNAL_CATCH24577#undef JSON_THROW24578#undef JSON_PRIVATE_UNLESS_TESTED24579#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION24580#undef NLOHMANN_BASIC_JSON_TPL24581#undef JSON_EXPLICIT24582#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL24583#undef JSON_INLINE_VARIABLE24584#undef JSON_NO_UNIQUE_ADDRESS24585#undef JSON_DISABLE_ENUM_SERIALIZATION24586#undef JSON_USE_GLOBAL_UDLS2458724588#ifndef JSON_TEST_KEEP_MACROS24589#undef JSON_CATCH24590#undef JSON_TRY24591#undef JSON_HAS_CPP_1124592#undef JSON_HAS_CPP_1424593#undef JSON_HAS_CPP_1724594#undef JSON_HAS_CPP_2024595#undef JSON_HAS_FILESYSTEM24596#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM24597#undef JSON_HAS_THREE_WAY_COMPARISON24598#undef JSON_HAS_RANGES24599#undef JSON_HAS_STATIC_RTTI24600#undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON24601#endif2460224603// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>24604// __ _____ _____ _____24605// __| | __| | | | JSON for Modern C++24606// | | |__ | | | | | | version 3.11.324607// |_____|_____|_____|_|___| https://github.com/nlohmann/json24608//24609// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>24610// SPDX-License-Identifier: MIT24611246122461324614#undef JSON_HEDLEY_ALWAYS_INLINE24615#undef JSON_HEDLEY_ARM_VERSION24616#undef JSON_HEDLEY_ARM_VERSION_CHECK24617#undef JSON_HEDLEY_ARRAY_PARAM24618#undef JSON_HEDLEY_ASSUME24619#undef JSON_HEDLEY_BEGIN_C_DECLS24620#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE24621#undef JSON_HEDLEY_CLANG_HAS_BUILTIN24622#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE24623#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE24624#undef JSON_HEDLEY_CLANG_HAS_EXTENSION24625#undef JSON_HEDLEY_CLANG_HAS_FEATURE24626#undef JSON_HEDLEY_CLANG_HAS_WARNING24627#undef JSON_HEDLEY_COMPCERT_VERSION24628#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK24629#undef JSON_HEDLEY_CONCAT24630#undef JSON_HEDLEY_CONCAT324631#undef JSON_HEDLEY_CONCAT3_EX24632#undef JSON_HEDLEY_CONCAT_EX24633#undef JSON_HEDLEY_CONST24634#undef JSON_HEDLEY_CONSTEXPR24635#undef JSON_HEDLEY_CONST_CAST24636#undef JSON_HEDLEY_CPP_CAST24637#undef JSON_HEDLEY_CRAY_VERSION24638#undef JSON_HEDLEY_CRAY_VERSION_CHECK24639#undef JSON_HEDLEY_C_DECL24640#undef JSON_HEDLEY_DEPRECATED24641#undef JSON_HEDLEY_DEPRECATED_FOR24642#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL24643#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_24644#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED24645#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES24646#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS24647#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION24648#undef JSON_HEDLEY_DIAGNOSTIC_POP24649#undef JSON_HEDLEY_DIAGNOSTIC_PUSH24650#undef JSON_HEDLEY_DMC_VERSION24651#undef JSON_HEDLEY_DMC_VERSION_CHECK24652#undef JSON_HEDLEY_EMPTY_BASES24653#undef JSON_HEDLEY_EMSCRIPTEN_VERSION24654#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK24655#undef JSON_HEDLEY_END_C_DECLS24656#undef JSON_HEDLEY_FLAGS24657#undef JSON_HEDLEY_FLAGS_CAST24658#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE24659#undef JSON_HEDLEY_GCC_HAS_BUILTIN24660#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE24661#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE24662#undef JSON_HEDLEY_GCC_HAS_EXTENSION24663#undef JSON_HEDLEY_GCC_HAS_FEATURE24664#undef JSON_HEDLEY_GCC_HAS_WARNING24665#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK24666#undef JSON_HEDLEY_GCC_VERSION24667#undef JSON_HEDLEY_GCC_VERSION_CHECK24668#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE24669#undef JSON_HEDLEY_GNUC_HAS_BUILTIN24670#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE24671#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE24672#undef JSON_HEDLEY_GNUC_HAS_EXTENSION24673#undef JSON_HEDLEY_GNUC_HAS_FEATURE24674#undef JSON_HEDLEY_GNUC_HAS_WARNING24675#undef JSON_HEDLEY_GNUC_VERSION24676#undef JSON_HEDLEY_GNUC_VERSION_CHECK24677#undef JSON_HEDLEY_HAS_ATTRIBUTE24678#undef JSON_HEDLEY_HAS_BUILTIN24679#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE24680#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS24681#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE24682#undef JSON_HEDLEY_HAS_EXTENSION24683#undef JSON_HEDLEY_HAS_FEATURE24684#undef JSON_HEDLEY_HAS_WARNING24685#undef JSON_HEDLEY_IAR_VERSION24686#undef JSON_HEDLEY_IAR_VERSION_CHECK24687#undef JSON_HEDLEY_IBM_VERSION24688#undef JSON_HEDLEY_IBM_VERSION_CHECK24689#undef JSON_HEDLEY_IMPORT24690#undef JSON_HEDLEY_INLINE24691#undef JSON_HEDLEY_INTEL_CL_VERSION24692#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK24693#undef JSON_HEDLEY_INTEL_VERSION24694#undef JSON_HEDLEY_INTEL_VERSION_CHECK24695#undef JSON_HEDLEY_IS_CONSTANT24696#undef JSON_HEDLEY_IS_CONSTEXPR_24697#undef JSON_HEDLEY_LIKELY24698#undef JSON_HEDLEY_MALLOC24699#undef JSON_HEDLEY_MCST_LCC_VERSION24700#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK24701#undef JSON_HEDLEY_MESSAGE24702#undef JSON_HEDLEY_MSVC_VERSION24703#undef JSON_HEDLEY_MSVC_VERSION_CHECK24704#undef JSON_HEDLEY_NEVER_INLINE24705#undef JSON_HEDLEY_NON_NULL24706#undef JSON_HEDLEY_NO_ESCAPE24707#undef JSON_HEDLEY_NO_RETURN24708#undef JSON_HEDLEY_NO_THROW24709#undef JSON_HEDLEY_NULL24710#undef JSON_HEDLEY_PELLES_VERSION24711#undef JSON_HEDLEY_PELLES_VERSION_CHECK24712#undef JSON_HEDLEY_PGI_VERSION24713#undef JSON_HEDLEY_PGI_VERSION_CHECK24714#undef JSON_HEDLEY_PREDICT24715#undef JSON_HEDLEY_PRINTF_FORMAT24716#undef JSON_HEDLEY_PRIVATE24717#undef JSON_HEDLEY_PUBLIC24718#undef JSON_HEDLEY_PURE24719#undef JSON_HEDLEY_REINTERPRET_CAST24720#undef JSON_HEDLEY_REQUIRE24721#undef JSON_HEDLEY_REQUIRE_CONSTEXPR24722#undef JSON_HEDLEY_REQUIRE_MSG24723#undef JSON_HEDLEY_RESTRICT24724#undef JSON_HEDLEY_RETURNS_NON_NULL24725#undef JSON_HEDLEY_SENTINEL24726#undef JSON_HEDLEY_STATIC_ASSERT24727#undef JSON_HEDLEY_STATIC_CAST24728#undef JSON_HEDLEY_STRINGIFY24729#undef JSON_HEDLEY_STRINGIFY_EX24730#undef JSON_HEDLEY_SUNPRO_VERSION24731#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK24732#undef JSON_HEDLEY_TINYC_VERSION24733#undef JSON_HEDLEY_TINYC_VERSION_CHECK24734#undef JSON_HEDLEY_TI_ARMCL_VERSION24735#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK24736#undef JSON_HEDLEY_TI_CL2000_VERSION24737#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK24738#undef JSON_HEDLEY_TI_CL430_VERSION24739#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK24740#undef JSON_HEDLEY_TI_CL6X_VERSION24741#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK24742#undef JSON_HEDLEY_TI_CL7X_VERSION24743#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK24744#undef JSON_HEDLEY_TI_CLPRU_VERSION24745#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK24746#undef JSON_HEDLEY_TI_VERSION24747#undef JSON_HEDLEY_TI_VERSION_CHECK24748#undef JSON_HEDLEY_UNAVAILABLE24749#undef JSON_HEDLEY_UNLIKELY24750#undef JSON_HEDLEY_UNPREDICTABLE24751#undef JSON_HEDLEY_UNREACHABLE24752#undef JSON_HEDLEY_UNREACHABLE_RETURN24753#undef JSON_HEDLEY_VERSION24754#undef JSON_HEDLEY_VERSION_DECODE_MAJOR24755#undef JSON_HEDLEY_VERSION_DECODE_MINOR24756#undef JSON_HEDLEY_VERSION_DECODE_REVISION24757#undef JSON_HEDLEY_VERSION_ENCODE24758#undef JSON_HEDLEY_WARNING24759#undef JSON_HEDLEY_WARN_UNUSED_RESULT24760#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG24761#undef JSON_HEDLEY_FALL_THROUGH24762247632476424765#endif // INCLUDE_NLOHMANN_JSON_HPP_247662476724768