Path: blob/master/examples/cppwin/TensorflowTTSCppInference/ext/json.hpp
1564 views
/*1__ _____ _____ _____2__| | __| | | | JSON for Modern C++3| | |__ | | | | | | version 3.9.14|_____|_____|_____|_|___| https://github.com/nlohmann/json56Licensed under the MIT License <http://opensource.org/licenses/MIT>.7SPDX-License-Identifier: MIT8Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.910Permission is hereby granted, free of charge, to any person obtaining a copy11of this software and associated documentation files (the "Software"), to deal12in the Software without restriction, including without limitation the rights13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell14copies of the Software, and to permit persons to whom the Software is15furnished to do so, subject to the following conditions:1617The above copyright notice and this permission notice shall be included in all18copies or substantial portions of the Software.1920THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE26SOFTWARE.27*/2829#ifndef INCLUDE_NLOHMANN_JSON_HPP_30#define INCLUDE_NLOHMANN_JSON_HPP_3132#define NLOHMANN_JSON_VERSION_MAJOR 333#define NLOHMANN_JSON_VERSION_MINOR 934#define NLOHMANN_JSON_VERSION_PATCH 13536#include <algorithm> // all_of, find, for_each37#include <cstddef> // nullptr_t, ptrdiff_t, size_t38#include <functional> // hash, less39#include <initializer_list> // initializer_list40#include <iosfwd> // istream, ostream41#include <iterator> // random_access_iterator_tag42#include <memory> // unique_ptr43#include <numeric> // accumulate44#include <string> // string, stoi, to_string45#include <utility> // declval, forward, move, pair, swap46#include <vector> // vector4748// #include <nlohmann/adl_serializer.hpp>495051#include <utility>5253// #include <nlohmann/detail/conversions/from_json.hpp>545556#include <algorithm> // transform57#include <array> // array58#include <forward_list> // forward_list59#include <iterator> // inserter, front_inserter, end60#include <map> // map61#include <string> // string62#include <tuple> // tuple, make_tuple63#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible64#include <unordered_map> // unordered_map65#include <utility> // pair, declval66#include <valarray> // valarray6768// #include <nlohmann/detail/exceptions.hpp>697071#include <exception> // exception72#include <stdexcept> // runtime_error73#include <string> // to_string7475// #include <nlohmann/detail/input/position_t.hpp>767778#include <cstddef> // size_t7980namespace nlohmann81{82namespace detail83{84/// struct to capture the start position of the current token85struct position_t86{87/// the total number of characters read88std::size_t chars_read_total = 0;89/// the number of characters read in the current line90std::size_t chars_read_current_line = 0;91/// the number of lines read92std::size_t lines_read = 0;9394/// conversion to size_t to preserve SAX interface95constexpr operator size_t() const96{97return chars_read_total;98}99};100101} // namespace detail102} // namespace nlohmann103104// #include <nlohmann/detail/macro_scope.hpp>105106107#include <utility> // pair108// #include <nlohmann/thirdparty/hedley/hedley.hpp>109/* Hedley - https://nemequ.github.io/hedley110* Created by Evan Nemerson <[email protected]>111*112* To the extent possible under law, the author(s) have dedicated all113* copyright and related and neighboring rights to this software to114* the public domain worldwide. This software is distributed without115* any warranty.116*117* For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.118* SPDX-License-Identifier: CC0-1.0119*/120121#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 13)122#if defined(JSON_HEDLEY_VERSION)123#undef JSON_HEDLEY_VERSION124#endif125#define JSON_HEDLEY_VERSION 13126127#if defined(JSON_HEDLEY_STRINGIFY_EX)128#undef JSON_HEDLEY_STRINGIFY_EX129#endif130#define JSON_HEDLEY_STRINGIFY_EX(x) #x131132#if defined(JSON_HEDLEY_STRINGIFY)133#undef JSON_HEDLEY_STRINGIFY134#endif135#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)136137#if defined(JSON_HEDLEY_CONCAT_EX)138#undef JSON_HEDLEY_CONCAT_EX139#endif140#define JSON_HEDLEY_CONCAT_EX(a,b) a##b141142#if defined(JSON_HEDLEY_CONCAT)143#undef JSON_HEDLEY_CONCAT144#endif145#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)146147#if defined(JSON_HEDLEY_CONCAT3_EX)148#undef JSON_HEDLEY_CONCAT3_EX149#endif150#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c151152#if defined(JSON_HEDLEY_CONCAT3)153#undef JSON_HEDLEY_CONCAT3154#endif155#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)156157#if defined(JSON_HEDLEY_VERSION_ENCODE)158#undef JSON_HEDLEY_VERSION_ENCODE159#endif160#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))161162#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)163#undef JSON_HEDLEY_VERSION_DECODE_MAJOR164#endif165#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)166167#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)168#undef JSON_HEDLEY_VERSION_DECODE_MINOR169#endif170#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)171172#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)173#undef JSON_HEDLEY_VERSION_DECODE_REVISION174#endif175#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)176177#if defined(JSON_HEDLEY_GNUC_VERSION)178#undef JSON_HEDLEY_GNUC_VERSION179#endif180#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)181#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)182#elif defined(__GNUC__)183#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)184#endif185186#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)187#undef JSON_HEDLEY_GNUC_VERSION_CHECK188#endif189#if defined(JSON_HEDLEY_GNUC_VERSION)190#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))191#else192#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)193#endif194195#if defined(JSON_HEDLEY_MSVC_VERSION)196#undef JSON_HEDLEY_MSVC_VERSION197#endif198#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)199#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)200#elif defined(_MSC_FULL_VER)201#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)202#elif defined(_MSC_VER)203#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)204#endif205206#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)207#undef JSON_HEDLEY_MSVC_VERSION_CHECK208#endif209#if !defined(_MSC_VER)210#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)211#elif defined(_MSC_VER) && (_MSC_VER >= 1400)212#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))213#elif defined(_MSC_VER) && (_MSC_VER >= 1200)214#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))215#else216#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))217#endif218219#if defined(JSON_HEDLEY_INTEL_VERSION)220#undef JSON_HEDLEY_INTEL_VERSION221#endif222#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)223#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)224#elif defined(__INTEL_COMPILER)225#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)226#endif227228#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)229#undef JSON_HEDLEY_INTEL_VERSION_CHECK230#endif231#if defined(JSON_HEDLEY_INTEL_VERSION)232#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))233#else234#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)235#endif236237#if defined(JSON_HEDLEY_PGI_VERSION)238#undef JSON_HEDLEY_PGI_VERSION239#endif240#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)241#define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)242#endif243244#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)245#undef JSON_HEDLEY_PGI_VERSION_CHECK246#endif247#if defined(JSON_HEDLEY_PGI_VERSION)248#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))249#else250#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)251#endif252253#if defined(JSON_HEDLEY_SUNPRO_VERSION)254#undef JSON_HEDLEY_SUNPRO_VERSION255#endif256#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)257#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)258#elif defined(__SUNPRO_C)259#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)260#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)261#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)262#elif defined(__SUNPRO_CC)263#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)264#endif265266#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)267#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK268#endif269#if defined(JSON_HEDLEY_SUNPRO_VERSION)270#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))271#else272#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)273#endif274275#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)276#undef JSON_HEDLEY_EMSCRIPTEN_VERSION277#endif278#if defined(__EMSCRIPTEN__)279#define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)280#endif281282#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)283#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK284#endif285#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)286#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))287#else288#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)289#endif290291#if defined(JSON_HEDLEY_ARM_VERSION)292#undef JSON_HEDLEY_ARM_VERSION293#endif294#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)295#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)296#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)297#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)298#endif299300#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)301#undef JSON_HEDLEY_ARM_VERSION_CHECK302#endif303#if defined(JSON_HEDLEY_ARM_VERSION)304#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))305#else306#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)307#endif308309#if defined(JSON_HEDLEY_IBM_VERSION)310#undef JSON_HEDLEY_IBM_VERSION311#endif312#if defined(__ibmxl__)313#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)314#elif defined(__xlC__) && defined(__xlC_ver__)315#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)316#elif defined(__xlC__)317#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)318#endif319320#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)321#undef JSON_HEDLEY_IBM_VERSION_CHECK322#endif323#if defined(JSON_HEDLEY_IBM_VERSION)324#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))325#else326#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)327#endif328329#if defined(JSON_HEDLEY_TI_VERSION)330#undef JSON_HEDLEY_TI_VERSION331#endif332#if \333defined(__TI_COMPILER_VERSION__) && \334( \335defined(__TMS470__) || defined(__TI_ARM__) || \336defined(__MSP430__) || \337defined(__TMS320C2000__) \338)339#if (__TI_COMPILER_VERSION__ >= 16000000)340#define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))341#endif342#endif343344#if defined(JSON_HEDLEY_TI_VERSION_CHECK)345#undef JSON_HEDLEY_TI_VERSION_CHECK346#endif347#if defined(JSON_HEDLEY_TI_VERSION)348#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))349#else350#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)351#endif352353#if defined(JSON_HEDLEY_TI_CL2000_VERSION)354#undef JSON_HEDLEY_TI_CL2000_VERSION355#endif356#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)357#define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))358#endif359360#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)361#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK362#endif363#if defined(JSON_HEDLEY_TI_CL2000_VERSION)364#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))365#else366#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)367#endif368369#if defined(JSON_HEDLEY_TI_CL430_VERSION)370#undef JSON_HEDLEY_TI_CL430_VERSION371#endif372#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)373#define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))374#endif375376#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)377#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK378#endif379#if defined(JSON_HEDLEY_TI_CL430_VERSION)380#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))381#else382#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)383#endif384385#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)386#undef JSON_HEDLEY_TI_ARMCL_VERSION387#endif388#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))389#define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))390#endif391392#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)393#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK394#endif395#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)396#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))397#else398#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)399#endif400401#if defined(JSON_HEDLEY_TI_CL6X_VERSION)402#undef JSON_HEDLEY_TI_CL6X_VERSION403#endif404#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)405#define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))406#endif407408#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)409#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK410#endif411#if defined(JSON_HEDLEY_TI_CL6X_VERSION)412#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))413#else414#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)415#endif416417#if defined(JSON_HEDLEY_TI_CL7X_VERSION)418#undef JSON_HEDLEY_TI_CL7X_VERSION419#endif420#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)421#define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))422#endif423424#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)425#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK426#endif427#if defined(JSON_HEDLEY_TI_CL7X_VERSION)428#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))429#else430#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)431#endif432433#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)434#undef JSON_HEDLEY_TI_CLPRU_VERSION435#endif436#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)437#define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))438#endif439440#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)441#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK442#endif443#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)444#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))445#else446#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)447#endif448449#if defined(JSON_HEDLEY_CRAY_VERSION)450#undef JSON_HEDLEY_CRAY_VERSION451#endif452#if defined(_CRAYC)453#if defined(_RELEASE_PATCHLEVEL)454#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)455#else456#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)457#endif458#endif459460#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)461#undef JSON_HEDLEY_CRAY_VERSION_CHECK462#endif463#if defined(JSON_HEDLEY_CRAY_VERSION)464#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))465#else466#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)467#endif468469#if defined(JSON_HEDLEY_IAR_VERSION)470#undef JSON_HEDLEY_IAR_VERSION471#endif472#if defined(__IAR_SYSTEMS_ICC__)473#if __VER__ > 1000474#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))475#else476#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)477#endif478#endif479480#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)481#undef JSON_HEDLEY_IAR_VERSION_CHECK482#endif483#if defined(JSON_HEDLEY_IAR_VERSION)484#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))485#else486#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)487#endif488489#if defined(JSON_HEDLEY_TINYC_VERSION)490#undef JSON_HEDLEY_TINYC_VERSION491#endif492#if defined(__TINYC__)493#define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)494#endif495496#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)497#undef JSON_HEDLEY_TINYC_VERSION_CHECK498#endif499#if defined(JSON_HEDLEY_TINYC_VERSION)500#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))501#else502#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)503#endif504505#if defined(JSON_HEDLEY_DMC_VERSION)506#undef JSON_HEDLEY_DMC_VERSION507#endif508#if defined(__DMC__)509#define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)510#endif511512#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)513#undef JSON_HEDLEY_DMC_VERSION_CHECK514#endif515#if defined(JSON_HEDLEY_DMC_VERSION)516#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))517#else518#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)519#endif520521#if defined(JSON_HEDLEY_COMPCERT_VERSION)522#undef JSON_HEDLEY_COMPCERT_VERSION523#endif524#if defined(__COMPCERT_VERSION__)525#define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)526#endif527528#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)529#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK530#endif531#if defined(JSON_HEDLEY_COMPCERT_VERSION)532#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))533#else534#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)535#endif536537#if defined(JSON_HEDLEY_PELLES_VERSION)538#undef JSON_HEDLEY_PELLES_VERSION539#endif540#if defined(__POCC__)541#define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)542#endif543544#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)545#undef JSON_HEDLEY_PELLES_VERSION_CHECK546#endif547#if defined(JSON_HEDLEY_PELLES_VERSION)548#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))549#else550#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)551#endif552553#if defined(JSON_HEDLEY_GCC_VERSION)554#undef JSON_HEDLEY_GCC_VERSION555#endif556#if \557defined(JSON_HEDLEY_GNUC_VERSION) && \558!defined(__clang__) && \559!defined(JSON_HEDLEY_INTEL_VERSION) && \560!defined(JSON_HEDLEY_PGI_VERSION) && \561!defined(JSON_HEDLEY_ARM_VERSION) && \562!defined(JSON_HEDLEY_TI_VERSION) && \563!defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \564!defined(JSON_HEDLEY_TI_CL430_VERSION) && \565!defined(JSON_HEDLEY_TI_CL2000_VERSION) && \566!defined(JSON_HEDLEY_TI_CL6X_VERSION) && \567!defined(JSON_HEDLEY_TI_CL7X_VERSION) && \568!defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \569!defined(__COMPCERT__)570#define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION571#endif572573#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)574#undef JSON_HEDLEY_GCC_VERSION_CHECK575#endif576#if defined(JSON_HEDLEY_GCC_VERSION)577#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))578#else579#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)580#endif581582#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)583#undef JSON_HEDLEY_HAS_ATTRIBUTE584#endif585#if defined(__has_attribute)586#define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)587#else588#define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)589#endif590591#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)592#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE593#endif594#if defined(__has_attribute)595#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)596#else597#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)598#endif599600#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)601#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE602#endif603#if defined(__has_attribute)604#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)605#else606#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)607#endif608609#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)610#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE611#endif612#if \613defined(__has_cpp_attribute) && \614defined(__cplusplus) && \615(!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))616#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)617#else618#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)619#endif620621#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)622#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS623#endif624#if !defined(__cplusplus) || !defined(__has_cpp_attribute)625#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)626#elif \627!defined(JSON_HEDLEY_PGI_VERSION) && \628!defined(JSON_HEDLEY_IAR_VERSION) && \629(!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \630(!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))631#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)632#else633#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)634#endif635636#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)637#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE638#endif639#if defined(__has_cpp_attribute) && defined(__cplusplus)640#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)641#else642#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)643#endif644645#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)646#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE647#endif648#if defined(__has_cpp_attribute) && defined(__cplusplus)649#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)650#else651#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)652#endif653654#if defined(JSON_HEDLEY_HAS_BUILTIN)655#undef JSON_HEDLEY_HAS_BUILTIN656#endif657#if defined(__has_builtin)658#define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)659#else660#define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)661#endif662663#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)664#undef JSON_HEDLEY_GNUC_HAS_BUILTIN665#endif666#if defined(__has_builtin)667#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)668#else669#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)670#endif671672#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)673#undef JSON_HEDLEY_GCC_HAS_BUILTIN674#endif675#if defined(__has_builtin)676#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)677#else678#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)679#endif680681#if defined(JSON_HEDLEY_HAS_FEATURE)682#undef JSON_HEDLEY_HAS_FEATURE683#endif684#if defined(__has_feature)685#define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)686#else687#define JSON_HEDLEY_HAS_FEATURE(feature) (0)688#endif689690#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)691#undef JSON_HEDLEY_GNUC_HAS_FEATURE692#endif693#if defined(__has_feature)694#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)695#else696#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)697#endif698699#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)700#undef JSON_HEDLEY_GCC_HAS_FEATURE701#endif702#if defined(__has_feature)703#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)704#else705#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)706#endif707708#if defined(JSON_HEDLEY_HAS_EXTENSION)709#undef JSON_HEDLEY_HAS_EXTENSION710#endif711#if defined(__has_extension)712#define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)713#else714#define JSON_HEDLEY_HAS_EXTENSION(extension) (0)715#endif716717#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)718#undef JSON_HEDLEY_GNUC_HAS_EXTENSION719#endif720#if defined(__has_extension)721#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)722#else723#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)724#endif725726#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)727#undef JSON_HEDLEY_GCC_HAS_EXTENSION728#endif729#if defined(__has_extension)730#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)731#else732#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)733#endif734735#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)736#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE737#endif738#if defined(__has_declspec_attribute)739#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)740#else741#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)742#endif743744#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)745#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE746#endif747#if defined(__has_declspec_attribute)748#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)749#else750#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)751#endif752753#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)754#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE755#endif756#if defined(__has_declspec_attribute)757#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)758#else759#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)760#endif761762#if defined(JSON_HEDLEY_HAS_WARNING)763#undef JSON_HEDLEY_HAS_WARNING764#endif765#if defined(__has_warning)766#define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)767#else768#define JSON_HEDLEY_HAS_WARNING(warning) (0)769#endif770771#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)772#undef JSON_HEDLEY_GNUC_HAS_WARNING773#endif774#if defined(__has_warning)775#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)776#else777#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)778#endif779780#if defined(JSON_HEDLEY_GCC_HAS_WARNING)781#undef JSON_HEDLEY_GCC_HAS_WARNING782#endif783#if defined(__has_warning)784#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)785#else786#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)787#endif788789/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for790HEDLEY INTERNAL USE ONLY. API subject to change without notice. */791#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)792#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_793#endif794#if defined(__cplusplus)795# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")796# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")797# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \798JSON_HEDLEY_DIAGNOSTIC_PUSH \799_Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \800_Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \801xpr \802JSON_HEDLEY_DIAGNOSTIC_POP803# else804# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \805JSON_HEDLEY_DIAGNOSTIC_PUSH \806_Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \807xpr \808JSON_HEDLEY_DIAGNOSTIC_POP809# endif810# endif811#endif812#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)813#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x814#endif815816#if defined(JSON_HEDLEY_CONST_CAST)817#undef JSON_HEDLEY_CONST_CAST818#endif819#if defined(__cplusplus)820# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))821#elif \822JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \823JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \824JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)825# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \826JSON_HEDLEY_DIAGNOSTIC_PUSH \827JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \828((T) (expr)); \829JSON_HEDLEY_DIAGNOSTIC_POP \830}))831#else832# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))833#endif834835#if defined(JSON_HEDLEY_REINTERPRET_CAST)836#undef JSON_HEDLEY_REINTERPRET_CAST837#endif838#if defined(__cplusplus)839#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))840#else841#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))842#endif843844#if defined(JSON_HEDLEY_STATIC_CAST)845#undef JSON_HEDLEY_STATIC_CAST846#endif847#if defined(__cplusplus)848#define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))849#else850#define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))851#endif852853#if defined(JSON_HEDLEY_CPP_CAST)854#undef JSON_HEDLEY_CPP_CAST855#endif856#if defined(__cplusplus)857# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")858# define JSON_HEDLEY_CPP_CAST(T, expr) \859JSON_HEDLEY_DIAGNOSTIC_PUSH \860_Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \861((T) (expr)) \862JSON_HEDLEY_DIAGNOSTIC_POP863# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)864# define JSON_HEDLEY_CPP_CAST(T, expr) \865JSON_HEDLEY_DIAGNOSTIC_PUSH \866_Pragma("diag_suppress=Pe137") \867JSON_HEDLEY_DIAGNOSTIC_POP \868# else869# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))870# endif871#else872# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)873#endif874875#if \876(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \877defined(__clang__) || \878JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \879JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \880JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \881JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \882JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \883JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \884JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \885JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \886JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \887JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \888JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \889JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \890JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \891JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \892JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \893(JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))894#define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)895#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)896#define JSON_HEDLEY_PRAGMA(value) __pragma(value)897#else898#define JSON_HEDLEY_PRAGMA(value)899#endif900901#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)902#undef JSON_HEDLEY_DIAGNOSTIC_PUSH903#endif904#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)905#undef JSON_HEDLEY_DIAGNOSTIC_POP906#endif907#if defined(__clang__)908#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")909#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")910#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)911#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")912#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")913#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)914#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")915#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")916#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)917#define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))918#define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))919#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)920#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")921#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")922#elif \923JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \924JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \925JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \926JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \927JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \928JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)929#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")930#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")931#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)932#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")933#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")934#else935#define JSON_HEDLEY_DIAGNOSTIC_PUSH936#define JSON_HEDLEY_DIAGNOSTIC_POP937#endif938939#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)940#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED941#endif942#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")943#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")944#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)945#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")946#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)947#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")948#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)949#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")950#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)951#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))952#elif \953JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \954(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \955JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \956(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \957JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \958(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \959JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \960(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \961JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \962JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \963JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)964#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")965#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)966#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")967#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)968#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")969#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)970#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")971#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)972#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")973#else974#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED975#endif976977#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)978#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS979#endif980#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")981#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")982#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)983#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")984#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)985#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")986#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)987#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")988#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)989#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))990#elif \991JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \992JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \993JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \994JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)995#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")996#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)997#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")998#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)999#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")1000#else1001#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS1002#endif10031004#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)1005#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES1006#endif1007#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")1008#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")1009#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)1010#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")1011#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)1012#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")1013#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)1014#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))1015#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)1016#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")1017#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)1018#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")1019#elif \1020JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \1021JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \1022JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)1023#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")1024#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1025#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")1026#else1027#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES1028#endif10291030#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)1031#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL1032#endif1033#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")1034#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")1035#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1036#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")1037#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)1038#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")1039#else1040#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL1041#endif10421043#if defined(JSON_HEDLEY_DEPRECATED)1044#undef JSON_HEDLEY_DEPRECATED1045#endif1046#if defined(JSON_HEDLEY_DEPRECATED_FOR)1047#undef JSON_HEDLEY_DEPRECATED_FOR1048#endif1049#if JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0)1050#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))1051#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))1052#elif defined(__cplusplus) && (__cplusplus >= 201402L)1053#define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])1054#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])1055#elif \1056JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \1057JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \1058JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1059JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \1060JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \1061JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \1062JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \1063JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \1064JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \1065JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1066JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)1067#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))1068#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))1069#elif \1070JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \1071JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \1072JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1073JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1074(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1075JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1076(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1077JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1078(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1079JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1080(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1081JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1082JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1083JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)1084#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))1085#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))1086#elif \1087JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \1088JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0)1089#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)1090#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)1091#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1092#define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")1093#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")1094#else1095#define JSON_HEDLEY_DEPRECATED(since)1096#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)1097#endif10981099#if defined(JSON_HEDLEY_UNAVAILABLE)1100#undef JSON_HEDLEY_UNAVAILABLE1101#endif1102#if \1103JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \1104JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \1105JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1106#define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))1107#else1108#define JSON_HEDLEY_UNAVAILABLE(available_since)1109#endif11101111#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)1112#undef JSON_HEDLEY_WARN_UNUSED_RESULT1113#endif1114#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)1115#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG1116#endif1117#if (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)1118#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])1119#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])1120#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)1121#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])1122#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])1123#elif \1124JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \1125JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \1126JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1127JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1128(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1129JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1130(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1131JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1132(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1133JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1134(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1135JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1136JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1137JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1138(JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \1139JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)1140#define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))1141#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))1142#elif defined(_Check_return_) /* SAL */1143#define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_1144#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_1145#else1146#define JSON_HEDLEY_WARN_UNUSED_RESULT1147#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)1148#endif11491150#if defined(JSON_HEDLEY_SENTINEL)1151#undef JSON_HEDLEY_SENTINEL1152#endif1153#if \1154JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \1155JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \1156JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1157JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)1158#define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))1159#else1160#define JSON_HEDLEY_SENTINEL(position)1161#endif11621163#if defined(JSON_HEDLEY_NO_RETURN)1164#undef JSON_HEDLEY_NO_RETURN1165#endif1166#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1167#define JSON_HEDLEY_NO_RETURN __noreturn1168#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1169#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))1170#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L1171#define JSON_HEDLEY_NO_RETURN _Noreturn1172#elif defined(__cplusplus) && (__cplusplus >= 201103L)1173#define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])1174#elif \1175JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \1176JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \1177JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1178JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1179JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1180JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1181(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1182JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1183(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1184JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1185(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1186JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1187(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1188JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1189JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1190JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)1191#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))1192#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)1193#define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")1194#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)1195#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)1196#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)1197#define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")1198#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)1199#define JSON_HEDLEY_NO_RETURN __attribute((noreturn))1200#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)1201#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)1202#else1203#define JSON_HEDLEY_NO_RETURN1204#endif12051206#if defined(JSON_HEDLEY_NO_ESCAPE)1207#undef JSON_HEDLEY_NO_ESCAPE1208#endif1209#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)1210#define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))1211#else1212#define JSON_HEDLEY_NO_ESCAPE1213#endif12141215#if defined(JSON_HEDLEY_UNREACHABLE)1216#undef JSON_HEDLEY_UNREACHABLE1217#endif1218#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)1219#undef JSON_HEDLEY_UNREACHABLE_RETURN1220#endif1221#if defined(JSON_HEDLEY_ASSUME)1222#undef JSON_HEDLEY_ASSUME1223#endif1224#if \1225JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \1226JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1227#define JSON_HEDLEY_ASSUME(expr) __assume(expr)1228#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)1229#define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)1230#elif \1231JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \1232JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)1233#if defined(__cplusplus)1234#define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)1235#else1236#define JSON_HEDLEY_ASSUME(expr) _nassert(expr)1237#endif1238#endif1239#if \1240(JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \1241JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \1242JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \1243JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1244JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)1245#define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()1246#elif defined(JSON_HEDLEY_ASSUME)1247#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)1248#endif1249#if !defined(JSON_HEDLEY_ASSUME)1250#if defined(JSON_HEDLEY_UNREACHABLE)1251#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))1252#else1253#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)1254#endif1255#endif1256#if defined(JSON_HEDLEY_UNREACHABLE)1257#if \1258JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \1259JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)1260#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))1261#else1262#define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()1263#endif1264#else1265#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)1266#endif1267#if !defined(JSON_HEDLEY_UNREACHABLE)1268#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)1269#endif12701271JSON_HEDLEY_DIAGNOSTIC_PUSH1272#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")1273#pragma clang diagnostic ignored "-Wpedantic"1274#endif1275#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)1276#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"1277#endif1278#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)1279#if defined(__clang__)1280#pragma clang diagnostic ignored "-Wvariadic-macros"1281#elif defined(JSON_HEDLEY_GCC_VERSION)1282#pragma GCC diagnostic ignored "-Wvariadic-macros"1283#endif1284#endif1285#if defined(JSON_HEDLEY_NON_NULL)1286#undef JSON_HEDLEY_NON_NULL1287#endif1288#if \1289JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \1290JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \1291JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1292JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)1293#define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))1294#else1295#define JSON_HEDLEY_NON_NULL(...)1296#endif1297JSON_HEDLEY_DIAGNOSTIC_POP12981299#if defined(JSON_HEDLEY_PRINTF_FORMAT)1300#undef JSON_HEDLEY_PRINTF_FORMAT1301#endif1302#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)1303#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))1304#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)1305#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))1306#elif \1307JSON_HEDLEY_HAS_ATTRIBUTE(format) || \1308JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \1309JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1310JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \1311JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1312JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1313(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1314JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1315(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1316JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1317(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1318JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1319(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1320JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1321JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1322JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)1323#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))1324#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)1325#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))1326#else1327#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)1328#endif13291330#if defined(JSON_HEDLEY_CONSTEXPR)1331#undef JSON_HEDLEY_CONSTEXPR1332#endif1333#if defined(__cplusplus)1334#if __cplusplus >= 201103L1335#define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)1336#endif1337#endif1338#if !defined(JSON_HEDLEY_CONSTEXPR)1339#define JSON_HEDLEY_CONSTEXPR1340#endif13411342#if defined(JSON_HEDLEY_PREDICT)1343#undef JSON_HEDLEY_PREDICT1344#endif1345#if defined(JSON_HEDLEY_LIKELY)1346#undef JSON_HEDLEY_LIKELY1347#endif1348#if defined(JSON_HEDLEY_UNLIKELY)1349#undef JSON_HEDLEY_UNLIKELY1350#endif1351#if defined(JSON_HEDLEY_UNPREDICTABLE)1352#undef JSON_HEDLEY_UNPREDICTABLE1353#endif1354#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)1355#define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))1356#endif1357#if \1358JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \1359JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)1360# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))1361# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))1362# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))1363# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )1364# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )1365#elif \1366JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \1367JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \1368JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1369(JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \1370JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1371JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1372JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1373JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \1374JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \1375JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \1376JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \1377JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1378JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1379JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \1380JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)1381# define JSON_HEDLEY_PREDICT(expr, expected, probability) \1382(((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))1383# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \1384(__extension__ ({ \1385double hedley_probability_ = (probability); \1386((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \1387}))1388# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \1389(__extension__ ({ \1390double hedley_probability_ = (probability); \1391((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \1392}))1393# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)1394# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)1395#else1396# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))1397# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))1398# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))1399# define JSON_HEDLEY_LIKELY(expr) (!!(expr))1400# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))1401#endif1402#if !defined(JSON_HEDLEY_UNPREDICTABLE)1403#define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)1404#endif14051406#if defined(JSON_HEDLEY_MALLOC)1407#undef JSON_HEDLEY_MALLOC1408#endif1409#if \1410JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \1411JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \1412JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1413JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1414JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1415JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \1416JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1417(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1418JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1419(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1420JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1421(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1422JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1423(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1424JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1425JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1426JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)1427#define JSON_HEDLEY_MALLOC __attribute__((__malloc__))1428#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)1429#define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")1430#elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0)1431#define JSON_HEDLEY_MALLOC __declspec(restrict)1432#else1433#define JSON_HEDLEY_MALLOC1434#endif14351436#if defined(JSON_HEDLEY_PURE)1437#undef JSON_HEDLEY_PURE1438#endif1439#if \1440JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \1441JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \1442JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1443JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1444JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1445JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1446JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1447(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1448JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1449(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1450JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1451(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1452JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1453(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1454JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1455JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1456JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1457JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)1458# define JSON_HEDLEY_PURE __attribute__((__pure__))1459#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)1460# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")1461#elif defined(__cplusplus) && \1462( \1463JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \1464JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \1465JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \1466)1467# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")1468#else1469# define JSON_HEDLEY_PURE1470#endif14711472#if defined(JSON_HEDLEY_CONST)1473#undef JSON_HEDLEY_CONST1474#endif1475#if \1476JSON_HEDLEY_HAS_ATTRIBUTE(const) || \1477JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \1478JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1479JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1480JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1481JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1482JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1483(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1484JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1485(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1486JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1487(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1488JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1489(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1490JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1491JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1492JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \1493JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)1494#define JSON_HEDLEY_CONST __attribute__((__const__))1495#elif \1496JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)1497#define JSON_HEDLEY_CONST _Pragma("no_side_effect")1498#else1499#define JSON_HEDLEY_CONST JSON_HEDLEY_PURE1500#endif15011502#if defined(JSON_HEDLEY_RESTRICT)1503#undef JSON_HEDLEY_RESTRICT1504#endif1505#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)1506#define JSON_HEDLEY_RESTRICT restrict1507#elif \1508JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \1509JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \1510JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1511JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1512JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1513JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \1514JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1515JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \1516JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \1517JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1518(JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \1519JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \1520defined(__clang__)1521#define JSON_HEDLEY_RESTRICT __restrict1522#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)1523#define JSON_HEDLEY_RESTRICT _Restrict1524#else1525#define JSON_HEDLEY_RESTRICT1526#endif15271528#if defined(JSON_HEDLEY_INLINE)1529#undef JSON_HEDLEY_INLINE1530#endif1531#if \1532(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \1533(defined(__cplusplus) && (__cplusplus >= 199711L))1534#define JSON_HEDLEY_INLINE inline1535#elif \1536defined(JSON_HEDLEY_GCC_VERSION) || \1537JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)1538#define JSON_HEDLEY_INLINE __inline__1539#elif \1540JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \1541JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1542JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \1543JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \1544JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \1545JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \1546JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1547JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)1548#define JSON_HEDLEY_INLINE __inline1549#else1550#define JSON_HEDLEY_INLINE1551#endif15521553#if defined(JSON_HEDLEY_ALWAYS_INLINE)1554#undef JSON_HEDLEY_ALWAYS_INLINE1555#endif1556#if \1557JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \1558JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \1559JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1560JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1561JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1562JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1563JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1564(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1565JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1566(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1567JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1568(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1569JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1570(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1571JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1572JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1573JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)1574# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE1575#elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0)1576# define JSON_HEDLEY_ALWAYS_INLINE __forceinline1577#elif defined(__cplusplus) && \1578( \1579JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1580JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1581JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1582JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \1583JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1584JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \1585)1586# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")1587#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1588# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")1589#else1590# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE1591#endif15921593#if defined(JSON_HEDLEY_NEVER_INLINE)1594#undef JSON_HEDLEY_NEVER_INLINE1595#endif1596#if \1597JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \1598JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \1599JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1600JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1601JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1602JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \1603JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \1604(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1605JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \1606(JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1607JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \1608(JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1609JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \1610(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1611JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \1612JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \1613JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)1614#define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))1615#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)1616#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)1617#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)1618#define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")1619#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)1620#define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")1621#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1622#define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")1623#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)1624#define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))1625#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)1626#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)1627#else1628#define JSON_HEDLEY_NEVER_INLINE1629#endif16301631#if defined(JSON_HEDLEY_PRIVATE)1632#undef JSON_HEDLEY_PRIVATE1633#endif1634#if defined(JSON_HEDLEY_PUBLIC)1635#undef JSON_HEDLEY_PUBLIC1636#endif1637#if defined(JSON_HEDLEY_IMPORT)1638#undef JSON_HEDLEY_IMPORT1639#endif1640#if defined(_WIN32) || defined(__CYGWIN__)1641# define JSON_HEDLEY_PRIVATE1642# define JSON_HEDLEY_PUBLIC __declspec(dllexport)1643# define JSON_HEDLEY_IMPORT __declspec(dllimport)1644#else1645# if \1646JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \1647JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \1648JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \1649JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1650JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1651JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \1652( \1653defined(__TI_EABI__) && \1654( \1655(JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \1656JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \1657) \1658)1659# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))1660# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))1661# else1662# define JSON_HEDLEY_PRIVATE1663# define JSON_HEDLEY_PUBLIC1664# endif1665# define JSON_HEDLEY_IMPORT extern1666#endif16671668#if defined(JSON_HEDLEY_NO_THROW)1669#undef JSON_HEDLEY_NO_THROW1670#endif1671#if \1672JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \1673JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \1674JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1675#define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))1676#elif \1677JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \1678JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)1679#define JSON_HEDLEY_NO_THROW __declspec(nothrow)1680#else1681#define JSON_HEDLEY_NO_THROW1682#endif16831684#if defined(JSON_HEDLEY_FALL_THROUGH)1685#undef JSON_HEDLEY_FALL_THROUGH1686#endif1687#if \1688JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \1689JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)1690#define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))1691#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)1692#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])1693#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)1694#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])1695#elif defined(__fallthrough) /* SAL */1696#define JSON_HEDLEY_FALL_THROUGH __fallthrough1697#else1698#define JSON_HEDLEY_FALL_THROUGH1699#endif17001701#if defined(JSON_HEDLEY_RETURNS_NON_NULL)1702#undef JSON_HEDLEY_RETURNS_NON_NULL1703#endif1704#if \1705JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \1706JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)1707#define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))1708#elif defined(_Ret_notnull_) /* SAL */1709#define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_1710#else1711#define JSON_HEDLEY_RETURNS_NON_NULL1712#endif17131714#if defined(JSON_HEDLEY_ARRAY_PARAM)1715#undef JSON_HEDLEY_ARRAY_PARAM1716#endif1717#if \1718defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \1719!defined(__STDC_NO_VLA__) && \1720!defined(__cplusplus) && \1721!defined(JSON_HEDLEY_PGI_VERSION) && \1722!defined(JSON_HEDLEY_TINYC_VERSION)1723#define JSON_HEDLEY_ARRAY_PARAM(name) (name)1724#else1725#define JSON_HEDLEY_ARRAY_PARAM(name)1726#endif17271728#if defined(JSON_HEDLEY_IS_CONSTANT)1729#undef JSON_HEDLEY_IS_CONSTANT1730#endif1731#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)1732#undef JSON_HEDLEY_REQUIRE_CONSTEXPR1733#endif1734/* JSON_HEDLEY_IS_CONSTEXPR_ is for1735HEDLEY INTERNAL USE ONLY. API subject to change without notice. */1736#if defined(JSON_HEDLEY_IS_CONSTEXPR_)1737#undef JSON_HEDLEY_IS_CONSTEXPR_1738#endif1739#if \1740JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \1741JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \1742JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1743JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \1744JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \1745JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \1746JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \1747(JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \1748JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)1749#define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)1750#endif1751#if !defined(__cplusplus)1752# if \1753JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \1754JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \1755JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1756JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \1757JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \1758JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \1759JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)1760#if defined(__INTPTR_TYPE__)1761#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)1762#else1763#include <stdint.h>1764#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)1765#endif1766# elif \1767( \1768defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \1769!defined(JSON_HEDLEY_SUNPRO_VERSION) && \1770!defined(JSON_HEDLEY_PGI_VERSION) && \1771!defined(JSON_HEDLEY_IAR_VERSION)) || \1772JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \1773JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \1774JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \1775JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \1776JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)1777#if defined(__INTPTR_TYPE__)1778#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)1779#else1780#include <stdint.h>1781#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)1782#endif1783# elif \1784defined(JSON_HEDLEY_GCC_VERSION) || \1785defined(JSON_HEDLEY_INTEL_VERSION) || \1786defined(JSON_HEDLEY_TINYC_VERSION) || \1787defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \1788JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \1789defined(JSON_HEDLEY_TI_CL2000_VERSION) || \1790defined(JSON_HEDLEY_TI_CL6X_VERSION) || \1791defined(JSON_HEDLEY_TI_CL7X_VERSION) || \1792defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \1793defined(__clang__)1794# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \1795sizeof(void) != \1796sizeof(*( \17971 ? \1798((void*) ((expr) * 0L) ) : \1799((struct { char v[sizeof(void) * 2]; } *) 1) \1800) \1801) \1802)1803# endif1804#endif1805#if defined(JSON_HEDLEY_IS_CONSTEXPR_)1806#if !defined(JSON_HEDLEY_IS_CONSTANT)1807#define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)1808#endif1809#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))1810#else1811#if !defined(JSON_HEDLEY_IS_CONSTANT)1812#define JSON_HEDLEY_IS_CONSTANT(expr) (0)1813#endif1814#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)1815#endif18161817#if defined(JSON_HEDLEY_BEGIN_C_DECLS)1818#undef JSON_HEDLEY_BEGIN_C_DECLS1819#endif1820#if defined(JSON_HEDLEY_END_C_DECLS)1821#undef JSON_HEDLEY_END_C_DECLS1822#endif1823#if defined(JSON_HEDLEY_C_DECL)1824#undef JSON_HEDLEY_C_DECL1825#endif1826#if defined(__cplusplus)1827#define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {1828#define JSON_HEDLEY_END_C_DECLS }1829#define JSON_HEDLEY_C_DECL extern "C"1830#else1831#define JSON_HEDLEY_BEGIN_C_DECLS1832#define JSON_HEDLEY_END_C_DECLS1833#define JSON_HEDLEY_C_DECL1834#endif18351836#if defined(JSON_HEDLEY_STATIC_ASSERT)1837#undef JSON_HEDLEY_STATIC_ASSERT1838#endif1839#if \1840!defined(__cplusplus) && ( \1841(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \1842JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \1843JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \1844JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \1845defined(_Static_assert) \1846)1847# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)1848#elif \1849(defined(__cplusplus) && (__cplusplus >= 201103L)) || \1850JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0)1851# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))1852#else1853# define JSON_HEDLEY_STATIC_ASSERT(expr, message)1854#endif18551856#if defined(JSON_HEDLEY_NULL)1857#undef JSON_HEDLEY_NULL1858#endif1859#if defined(__cplusplus)1860#if __cplusplus >= 201103L1861#define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)1862#elif defined(NULL)1863#define JSON_HEDLEY_NULL NULL1864#else1865#define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)1866#endif1867#elif defined(NULL)1868#define JSON_HEDLEY_NULL NULL1869#else1870#define JSON_HEDLEY_NULL ((void*) 0)1871#endif18721873#if defined(JSON_HEDLEY_MESSAGE)1874#undef JSON_HEDLEY_MESSAGE1875#endif1876#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")1877# define JSON_HEDLEY_MESSAGE(msg) \1878JSON_HEDLEY_DIAGNOSTIC_PUSH \1879JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \1880JSON_HEDLEY_PRAGMA(message msg) \1881JSON_HEDLEY_DIAGNOSTIC_POP1882#elif \1883JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \1884JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1885# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)1886#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)1887# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)1888#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)1889# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))1890#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)1891# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))1892#else1893# define JSON_HEDLEY_MESSAGE(msg)1894#endif18951896#if defined(JSON_HEDLEY_WARNING)1897#undef JSON_HEDLEY_WARNING1898#endif1899#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")1900# define JSON_HEDLEY_WARNING(msg) \1901JSON_HEDLEY_DIAGNOSTIC_PUSH \1902JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \1903JSON_HEDLEY_PRAGMA(clang warning msg) \1904JSON_HEDLEY_DIAGNOSTIC_POP1905#elif \1906JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \1907JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \1908JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)1909# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)1910#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)1911# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))1912#else1913# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)1914#endif19151916#if defined(JSON_HEDLEY_REQUIRE)1917#undef JSON_HEDLEY_REQUIRE1918#endif1919#if defined(JSON_HEDLEY_REQUIRE_MSG)1920#undef JSON_HEDLEY_REQUIRE_MSG1921#endif1922#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)1923# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")1924# define JSON_HEDLEY_REQUIRE(expr) \1925JSON_HEDLEY_DIAGNOSTIC_PUSH \1926_Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \1927__attribute__((diagnose_if(!(expr), #expr, "error"))) \1928JSON_HEDLEY_DIAGNOSTIC_POP1929# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \1930JSON_HEDLEY_DIAGNOSTIC_PUSH \1931_Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \1932__attribute__((diagnose_if(!(expr), msg, "error"))) \1933JSON_HEDLEY_DIAGNOSTIC_POP1934# else1935# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))1936# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))1937# endif1938#else1939# define JSON_HEDLEY_REQUIRE(expr)1940# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)1941#endif19421943#if defined(JSON_HEDLEY_FLAGS)1944#undef JSON_HEDLEY_FLAGS1945#endif1946#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)1947#define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))1948#endif19491950#if defined(JSON_HEDLEY_FLAGS_CAST)1951#undef JSON_HEDLEY_FLAGS_CAST1952#endif1953#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)1954# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \1955JSON_HEDLEY_DIAGNOSTIC_PUSH \1956_Pragma("warning(disable:188)") \1957((T) (expr)); \1958JSON_HEDLEY_DIAGNOSTIC_POP \1959}))1960#else1961# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)1962#endif19631964#if defined(JSON_HEDLEY_EMPTY_BASES)1965#undef JSON_HEDLEY_EMPTY_BASES1966#endif1967#if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)1968#define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)1969#else1970#define JSON_HEDLEY_EMPTY_BASES1971#endif19721973/* Remaining macros are deprecated. */19741975#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)1976#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK1977#endif1978#if defined(__clang__)1979#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)1980#else1981#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)1982#endif19831984#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)1985#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE1986#endif1987#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)19881989#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)1990#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE1991#endif1992#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)19931994#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)1995#undef JSON_HEDLEY_CLANG_HAS_BUILTIN1996#endif1997#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)19981999#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)2000#undef JSON_HEDLEY_CLANG_HAS_FEATURE2001#endif2002#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)20032004#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)2005#undef JSON_HEDLEY_CLANG_HAS_EXTENSION2006#endif2007#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)20082009#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)2010#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE2011#endif2012#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)20132014#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)2015#undef JSON_HEDLEY_CLANG_HAS_WARNING2016#endif2017#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)20182019#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */202020212022// This file contains all internal macro definitions2023// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them20242025// exclude unsupported compilers2026#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)2027#if defined(__clang__)2028#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 304002029#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"2030#endif2031#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))2032#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 408002033#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"2034#endif2035#endif2036#endif20372038// C++ language standard detection2039#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)2040#define JSON_HAS_CPP_202041#define JSON_HAS_CPP_172042#define JSON_HAS_CPP_142043#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #4642044#define JSON_HAS_CPP_172045#define JSON_HAS_CPP_142046#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)2047#define JSON_HAS_CPP_142048#endif20492050// disable float-equal warnings on GCC/clang2051#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)2052#pragma GCC diagnostic push2053#pragma GCC diagnostic ignored "-Wfloat-equal"2054#endif20552056// disable documentation warnings on clang2057#if defined(__clang__)2058#pragma GCC diagnostic push2059#pragma GCC diagnostic ignored "-Wdocumentation"2060#endif20612062// allow to disable exceptions2063#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)2064#define JSON_THROW(exception) throw exception2065#define JSON_TRY try2066#define JSON_CATCH(exception) catch(exception)2067#define JSON_INTERNAL_CATCH(exception) catch(exception)2068#else2069#include <cstdlib>2070#define JSON_THROW(exception) std::abort()2071#define JSON_TRY if(true)2072#define JSON_CATCH(exception) if(false)2073#define JSON_INTERNAL_CATCH(exception) if(false)2074#endif20752076// override exception macros2077#if defined(JSON_THROW_USER)2078#undef JSON_THROW2079#define JSON_THROW JSON_THROW_USER2080#endif2081#if defined(JSON_TRY_USER)2082#undef JSON_TRY2083#define JSON_TRY JSON_TRY_USER2084#endif2085#if defined(JSON_CATCH_USER)2086#undef JSON_CATCH2087#define JSON_CATCH JSON_CATCH_USER2088#undef JSON_INTERNAL_CATCH2089#define JSON_INTERNAL_CATCH JSON_CATCH_USER2090#endif2091#if defined(JSON_INTERNAL_CATCH_USER)2092#undef JSON_INTERNAL_CATCH2093#define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER2094#endif20952096// allow to override assert2097#if !defined(JSON_ASSERT)2098#include <cassert> // assert2099#define JSON_ASSERT(x) assert(x)2100#endif21012102/*!2103@brief macro to briefly define a mapping between an enum and JSON2104@def NLOHMANN_JSON_SERIALIZE_ENUM2105@since version 3.4.02106*/2107#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \2108template<typename BasicJsonType> \2109inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \2110{ \2111static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \2112static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \2113auto it = std::find_if(std::begin(m), std::end(m), \2114[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \2115{ \2116return ej_pair.first == e; \2117}); \2118j = ((it != std::end(m)) ? it : std::begin(m))->second; \2119} \2120template<typename BasicJsonType> \2121inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \2122{ \2123static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \2124static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \2125auto it = std::find_if(std::begin(m), std::end(m), \2126[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \2127{ \2128return ej_pair.second == j; \2129}); \2130e = ((it != std::end(m)) ? it : std::begin(m))->first; \2131}21322133// Ugly macros to avoid uglier copy-paste when specializing basic_json. They2134// may be removed in the future once the class is split.21352136#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \2137template<template<typename, typename, typename...> class ObjectType, \2138template<typename, typename...> class ArrayType, \2139class StringType, class BooleanType, class NumberIntegerType, \2140class NumberUnsignedType, class NumberFloatType, \2141template<typename> class AllocatorType, \2142template<typename, typename = void> class JSONSerializer, \2143class BinaryType>21442145#define NLOHMANN_BASIC_JSON_TPL \2146basic_json<ObjectType, ArrayType, StringType, BooleanType, \2147NumberIntegerType, NumberUnsignedType, NumberFloatType, \2148AllocatorType, JSONSerializer, BinaryType>21492150// Macros to simplify conversion from/to types21512152#define NLOHMANN_JSON_EXPAND( x ) x2153#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,...) NAME2154#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \2155NLOHMANN_JSON_PASTE64, \2156NLOHMANN_JSON_PASTE63, \2157NLOHMANN_JSON_PASTE62, \2158NLOHMANN_JSON_PASTE61, \2159NLOHMANN_JSON_PASTE60, \2160NLOHMANN_JSON_PASTE59, \2161NLOHMANN_JSON_PASTE58, \2162NLOHMANN_JSON_PASTE57, \2163NLOHMANN_JSON_PASTE56, \2164NLOHMANN_JSON_PASTE55, \2165NLOHMANN_JSON_PASTE54, \2166NLOHMANN_JSON_PASTE53, \2167NLOHMANN_JSON_PASTE52, \2168NLOHMANN_JSON_PASTE51, \2169NLOHMANN_JSON_PASTE50, \2170NLOHMANN_JSON_PASTE49, \2171NLOHMANN_JSON_PASTE48, \2172NLOHMANN_JSON_PASTE47, \2173NLOHMANN_JSON_PASTE46, \2174NLOHMANN_JSON_PASTE45, \2175NLOHMANN_JSON_PASTE44, \2176NLOHMANN_JSON_PASTE43, \2177NLOHMANN_JSON_PASTE42, \2178NLOHMANN_JSON_PASTE41, \2179NLOHMANN_JSON_PASTE40, \2180NLOHMANN_JSON_PASTE39, \2181NLOHMANN_JSON_PASTE38, \2182NLOHMANN_JSON_PASTE37, \2183NLOHMANN_JSON_PASTE36, \2184NLOHMANN_JSON_PASTE35, \2185NLOHMANN_JSON_PASTE34, \2186NLOHMANN_JSON_PASTE33, \2187NLOHMANN_JSON_PASTE32, \2188NLOHMANN_JSON_PASTE31, \2189NLOHMANN_JSON_PASTE30, \2190NLOHMANN_JSON_PASTE29, \2191NLOHMANN_JSON_PASTE28, \2192NLOHMANN_JSON_PASTE27, \2193NLOHMANN_JSON_PASTE26, \2194NLOHMANN_JSON_PASTE25, \2195NLOHMANN_JSON_PASTE24, \2196NLOHMANN_JSON_PASTE23, \2197NLOHMANN_JSON_PASTE22, \2198NLOHMANN_JSON_PASTE21, \2199NLOHMANN_JSON_PASTE20, \2200NLOHMANN_JSON_PASTE19, \2201NLOHMANN_JSON_PASTE18, \2202NLOHMANN_JSON_PASTE17, \2203NLOHMANN_JSON_PASTE16, \2204NLOHMANN_JSON_PASTE15, \2205NLOHMANN_JSON_PASTE14, \2206NLOHMANN_JSON_PASTE13, \2207NLOHMANN_JSON_PASTE12, \2208NLOHMANN_JSON_PASTE11, \2209NLOHMANN_JSON_PASTE10, \2210NLOHMANN_JSON_PASTE9, \2211NLOHMANN_JSON_PASTE8, \2212NLOHMANN_JSON_PASTE7, \2213NLOHMANN_JSON_PASTE6, \2214NLOHMANN_JSON_PASTE5, \2215NLOHMANN_JSON_PASTE4, \2216NLOHMANN_JSON_PASTE3, \2217NLOHMANN_JSON_PASTE2, \2218NLOHMANN_JSON_PASTE1)(__VA_ARGS__))2219#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)2220#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)2221#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)2222#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)2223#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)2224#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)2225#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)2226#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)2227#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)2228#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)2229#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)2230#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)2231#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)2232#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)2233#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)2234#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)2235#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)2236#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)2237#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)2238#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)2239#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)2240#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)2241#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)2242#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)2243#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)2244#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)2245#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)2246#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)2247#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)2248#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)2249#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)2250#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)2251#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)2252#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)2253#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)2254#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)2255#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)2256#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)2257#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)2258#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)2259#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)2260#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)2261#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)2262#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)2263#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)2264#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)2265#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)2266#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)2267#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)2268#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)2269#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)2270#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)2271#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)2272#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)2273#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)2274#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)2275#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)2276#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)2277#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)2278#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)2279#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)2280#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)2281#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)22822283#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;2284#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);22852286/*!2287@brief macro2288@def NLOHMANN_DEFINE_TYPE_INTRUSIVE2289@since version 3.9.02290*/2291#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \2292friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \2293friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }22942295/*!2296@brief macro2297@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE2298@since version 3.9.02299*/2300#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \2301inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \2302inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }23032304#ifndef JSON_USE_IMPLICIT_CONVERSIONS2305#define JSON_USE_IMPLICIT_CONVERSIONS 12306#endif23072308#if JSON_USE_IMPLICIT_CONVERSIONS2309#define JSON_EXPLICIT2310#else2311#define JSON_EXPLICIT explicit2312#endif231323142315namespace nlohmann2316{2317namespace detail2318{2319////////////////2320// exceptions //2321////////////////23222323/*!2324@brief general exception of the @ref basic_json class23252326This class is an extension of `std::exception` objects with a member @a id for2327exception ids. It is used as the base class for all exceptions thrown by the2328@ref basic_json class. This class can hence be used as "wildcard" to catch2329exceptions.23302331Subclasses:2332- @ref parse_error for exceptions indicating a parse error2333- @ref invalid_iterator for exceptions indicating errors with iterators2334- @ref type_error for exceptions indicating executing a member function with2335a wrong type2336- @ref out_of_range for exceptions indicating access out of the defined range2337- @ref other_error for exceptions indicating other library errors23382339@internal2340@note To have nothrow-copy-constructible exceptions, we internally use2341`std::runtime_error` which can cope with arbitrary-length error messages.2342Intermediate strings are built with static functions and then passed to2343the actual constructor.2344@endinternal23452346@liveexample{The following code shows how arbitrary library exceptions can be2347caught.,exception}23482349@since version 3.0.02350*/2351class exception : public std::exception2352{2353public:2354/// returns the explanatory string2355JSON_HEDLEY_RETURNS_NON_NULL2356const char* what() const noexcept override2357{2358return m.what();2359}23602361/// the id of the exception2362const int id;23632364protected:2365JSON_HEDLEY_NON_NULL(3)2366exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}23672368static std::string name(const std::string& ename, int id_)2369{2370return "[json.exception." + ename + "." + std::to_string(id_) + "] ";2371}23722373private:2374/// an exception object as storage for error messages2375std::runtime_error m;2376};23772378/*!2379@brief exception indicating a parse error23802381This exception is thrown by the library when a parse error occurs. Parse errors2382can occur during the deserialization of JSON text, CBOR, MessagePack, as well2383as when using JSON Patch.23842385Member @a byte holds the byte index of the last read character in the input2386file.23872388Exceptions have ids 1xx.23892390name / id | example message | description2391------------------------------ | --------------- | -------------------------2392json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position.2393json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.2394json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.2395json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.2396json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.2397json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.2398json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.2399json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences.2400json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.2401json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.2402json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.2403json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.2404json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).2405json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed.24062407@note For an input with n bytes, 1 is the index of the first character and n+12408is the index of the terminating null byte or the end of file. This also2409holds true when reading a byte vector (CBOR or MessagePack).24102411@liveexample{The following code shows how a `parse_error` exception can be2412caught.,parse_error}24132414@sa - @ref exception for the base class of the library exceptions2415@sa - @ref invalid_iterator for exceptions indicating errors with iterators2416@sa - @ref type_error for exceptions indicating executing a member function with2417a wrong type2418@sa - @ref out_of_range for exceptions indicating access out of the defined range2419@sa - @ref other_error for exceptions indicating other library errors24202421@since version 3.0.02422*/2423class parse_error : public exception2424{2425public:2426/*!2427@brief create a parse error exception2428@param[in] id_ the id of the exception2429@param[in] pos the position where the error occurred (or with2430chars_read_total=0 if the position cannot be2431determined)2432@param[in] what_arg the explanatory string2433@return parse_error object2434*/2435static parse_error create(int id_, const position_t& pos, const std::string& what_arg)2436{2437std::string w = exception::name("parse_error", id_) + "parse error" +2438position_string(pos) + ": " + what_arg;2439return parse_error(id_, pos.chars_read_total, w.c_str());2440}24412442static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)2443{2444std::string w = exception::name("parse_error", id_) + "parse error" +2445(byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +2446": " + what_arg;2447return parse_error(id_, byte_, w.c_str());2448}24492450/*!2451@brief byte index of the parse error24522453The byte index of the last read character in the input file.24542455@note For an input with n bytes, 1 is the index of the first character and2456n+1 is the index of the terminating null byte or the end of file.2457This also holds true when reading a byte vector (CBOR or MessagePack).2458*/2459const std::size_t byte;24602461private:2462parse_error(int id_, std::size_t byte_, const char* what_arg)2463: exception(id_, what_arg), byte(byte_) {}24642465static std::string position_string(const position_t& pos)2466{2467return " at line " + std::to_string(pos.lines_read + 1) +2468", column " + std::to_string(pos.chars_read_current_line);2469}2470};24712472/*!2473@brief exception indicating errors with iterators24742475This exception is thrown if iterators passed to a library function do not match2476the expected semantics.24772478Exceptions have ids 2xx.24792480name / id | example message | description2481----------------------------------- | --------------- | -------------------------2482json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.2483json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.2484json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.2485json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid.2486json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.2487json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.2488json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.2489json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.2490json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.2491json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.2492json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to.2493json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.2494json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.2495json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin().24962497@liveexample{The following code shows how an `invalid_iterator` exception can be2498caught.,invalid_iterator}24992500@sa - @ref exception for the base class of the library exceptions2501@sa - @ref parse_error for exceptions indicating a parse error2502@sa - @ref type_error for exceptions indicating executing a member function with2503a wrong type2504@sa - @ref out_of_range for exceptions indicating access out of the defined range2505@sa - @ref other_error for exceptions indicating other library errors25062507@since version 3.0.02508*/2509class invalid_iterator : public exception2510{2511public:2512static invalid_iterator create(int id_, const std::string& what_arg)2513{2514std::string w = exception::name("invalid_iterator", id_) + what_arg;2515return invalid_iterator(id_, w.c_str());2516}25172518private:2519JSON_HEDLEY_NON_NULL(3)2520invalid_iterator(int id_, const char* what_arg)2521: exception(id_, what_arg) {}2522};25232524/*!2525@brief exception indicating executing a member function with a wrong type25262527This exception is thrown in case of a type error; that is, a library function is2528executed on a JSON value whose type does not match the expected semantics.25292530Exceptions have ids 3xx.25312532name / id | example message | description2533----------------------------- | --------------- | -------------------------2534json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.2535json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.2536json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &.2537json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.2538json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.2539json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.2540json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.2541json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types.2542json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.2543json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.2544json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.2545json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.2546json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.2547json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.2548json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.2549json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |2550json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) |25512552@liveexample{The following code shows how a `type_error` exception can be2553caught.,type_error}25542555@sa - @ref exception for the base class of the library exceptions2556@sa - @ref parse_error for exceptions indicating a parse error2557@sa - @ref invalid_iterator for exceptions indicating errors with iterators2558@sa - @ref out_of_range for exceptions indicating access out of the defined range2559@sa - @ref other_error for exceptions indicating other library errors25602561@since version 3.0.02562*/2563class type_error : public exception2564{2565public:2566static type_error create(int id_, const std::string& what_arg)2567{2568std::string w = exception::name("type_error", id_) + what_arg;2569return type_error(id_, w.c_str());2570}25712572private:2573JSON_HEDLEY_NON_NULL(3)2574type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}2575};25762577/*!2578@brief exception indicating access out of the defined range25792580This exception is thrown in case a library function is called on an input2581parameter that exceeds the expected range, for instance in case of array2582indices or nonexisting object keys.25832584Exceptions have ids 4xx.25852586name / id | example message | description2587------------------------------- | --------------- | -------------------------2588json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.2589json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.2590json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.2591json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.2592json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.2593json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.2594json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) |2595json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |2596json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string |25972598@liveexample{The following code shows how an `out_of_range` exception can be2599caught.,out_of_range}26002601@sa - @ref exception for the base class of the library exceptions2602@sa - @ref parse_error for exceptions indicating a parse error2603@sa - @ref invalid_iterator for exceptions indicating errors with iterators2604@sa - @ref type_error for exceptions indicating executing a member function with2605a wrong type2606@sa - @ref other_error for exceptions indicating other library errors26072608@since version 3.0.02609*/2610class out_of_range : public exception2611{2612public:2613static out_of_range create(int id_, const std::string& what_arg)2614{2615std::string w = exception::name("out_of_range", id_) + what_arg;2616return out_of_range(id_, w.c_str());2617}26182619private:2620JSON_HEDLEY_NON_NULL(3)2621out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}2622};26232624/*!2625@brief exception indicating other library errors26262627This exception is thrown in case of errors that cannot be classified with the2628other exception types.26292630Exceptions have ids 5xx.26312632name / id | example message | description2633------------------------------ | --------------- | -------------------------2634json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.26352636@sa - @ref exception for the base class of the library exceptions2637@sa - @ref parse_error for exceptions indicating a parse error2638@sa - @ref invalid_iterator for exceptions indicating errors with iterators2639@sa - @ref type_error for exceptions indicating executing a member function with2640a wrong type2641@sa - @ref out_of_range for exceptions indicating access out of the defined range26422643@liveexample{The following code shows how an `other_error` exception can be2644caught.,other_error}26452646@since version 3.0.02647*/2648class other_error : public exception2649{2650public:2651static other_error create(int id_, const std::string& what_arg)2652{2653std::string w = exception::name("other_error", id_) + what_arg;2654return other_error(id_, w.c_str());2655}26562657private:2658JSON_HEDLEY_NON_NULL(3)2659other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}2660};2661} // namespace detail2662} // namespace nlohmann26632664// #include <nlohmann/detail/macro_scope.hpp>26652666// #include <nlohmann/detail/meta/cpp_future.hpp>266726682669#include <cstddef> // size_t2670#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type26712672namespace nlohmann2673{2674namespace detail2675{2676// alias templates to reduce boilerplate2677template<bool B, typename T = void>2678using enable_if_t = typename std::enable_if<B, T>::type;26792680template<typename T>2681using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;26822683// implementation of C++14 index_sequence and affiliates2684// source: https://stackoverflow.com/a/322233432685template<std::size_t... Ints>2686struct index_sequence2687{2688using type = index_sequence;2689using value_type = std::size_t;2690static constexpr std::size_t size() noexcept2691{2692return sizeof...(Ints);2693}2694};26952696template<class Sequence1, class Sequence2>2697struct merge_and_renumber;26982699template<std::size_t... I1, std::size_t... I2>2700struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>2701: index_sequence < I1..., (sizeof...(I1) + I2)... > {};27022703template<std::size_t N>2704struct make_index_sequence2705: merge_and_renumber < typename make_index_sequence < N / 2 >::type,2706typename make_index_sequence < N - N / 2 >::type > {};27072708template<> struct make_index_sequence<0> : index_sequence<> {};2709template<> struct make_index_sequence<1> : index_sequence<0> {};27102711template<typename... Ts>2712using index_sequence_for = make_index_sequence<sizeof...(Ts)>;27132714// dispatch utility (taken from ranges-v3)2715template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};2716template<> struct priority_tag<0> {};27172718// taken from ranges-v32719template<typename T>2720struct static_const2721{2722static constexpr T value{};2723};27242725template<typename T>2726constexpr T static_const<T>::value;2727} // namespace detail2728} // namespace nlohmann27292730// #include <nlohmann/detail/meta/type_traits.hpp>273127322733#include <limits> // numeric_limits2734#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type2735#include <utility> // declval27362737// #include <nlohmann/detail/iterators/iterator_traits.hpp>273827392740#include <iterator> // random_access_iterator_tag27412742// #include <nlohmann/detail/meta/void_t.hpp>274327442745namespace nlohmann2746{2747namespace detail2748{2749template<typename ...Ts> struct make_void2750{2751using type = void;2752};2753template<typename ...Ts> using void_t = typename make_void<Ts...>::type;2754} // namespace detail2755} // namespace nlohmann27562757// #include <nlohmann/detail/meta/cpp_future.hpp>275827592760namespace nlohmann2761{2762namespace detail2763{2764template<typename It, typename = void>2765struct iterator_types {};27662767template<typename It>2768struct iterator_types <2769It,2770void_t<typename It::difference_type, typename It::value_type, typename It::pointer,2771typename It::reference, typename It::iterator_category >>2772{2773using difference_type = typename It::difference_type;2774using value_type = typename It::value_type;2775using pointer = typename It::pointer;2776using reference = typename It::reference;2777using iterator_category = typename It::iterator_category;2778};27792780// This is required as some compilers implement std::iterator_traits in a way that2781// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.2782template<typename T, typename = void>2783struct iterator_traits2784{2785};27862787template<typename T>2788struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>2789: iterator_types<T>2790{2791};27922793template<typename T>2794struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>2795{2796using iterator_category = std::random_access_iterator_tag;2797using value_type = T;2798using difference_type = ptrdiff_t;2799using pointer = T*;2800using reference = T&;2801};2802} // namespace detail2803} // namespace nlohmann28042805// #include <nlohmann/detail/macro_scope.hpp>28062807// #include <nlohmann/detail/meta/cpp_future.hpp>28082809// #include <nlohmann/detail/meta/detected.hpp>281028112812#include <type_traits>28132814// #include <nlohmann/detail/meta/void_t.hpp>281528162817// https://en.cppreference.com/w/cpp/experimental/is_detected2818namespace nlohmann2819{2820namespace detail2821{2822struct nonesuch2823{2824nonesuch() = delete;2825~nonesuch() = delete;2826nonesuch(nonesuch const&) = delete;2827nonesuch(nonesuch const&&) = delete;2828void operator=(nonesuch const&) = delete;2829void operator=(nonesuch&&) = delete;2830};28312832template<class Default,2833class AlwaysVoid,2834template<class...> class Op,2835class... Args>2836struct detector2837{2838using value_t = std::false_type;2839using type = Default;2840};28412842template<class Default, template<class...> class Op, class... Args>2843struct detector<Default, void_t<Op<Args...>>, Op, Args...>2844{2845using value_t = std::true_type;2846using type = Op<Args...>;2847};28482849template<template<class...> class Op, class... Args>2850using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;28512852template<template<class...> class Op, class... Args>2853using detected_t = typename detector<nonesuch, void, Op, Args...>::type;28542855template<class Default, template<class...> class Op, class... Args>2856using detected_or = detector<Default, void, Op, Args...>;28572858template<class Default, template<class...> class Op, class... Args>2859using detected_or_t = typename detected_or<Default, Op, Args...>::type;28602861template<class Expected, template<class...> class Op, class... Args>2862using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;28632864template<class To, template<class...> class Op, class... Args>2865using is_detected_convertible =2866std::is_convertible<detected_t<Op, Args...>, To>;2867} // namespace detail2868} // namespace nlohmann28692870// #include <nlohmann/json_fwd.hpp>2871#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_2872#define INCLUDE_NLOHMANN_JSON_FWD_HPP_28732874#include <cstdint> // int64_t, uint64_t2875#include <map> // map2876#include <memory> // allocator2877#include <string> // string2878#include <vector> // vector28792880/*!2881@brief namespace for Niels Lohmann2882@see https://github.com/nlohmann2883@since version 1.0.02884*/2885namespace nlohmann2886{2887/*!2888@brief default JSONSerializer template argument28892890This serializer ignores the template arguments and uses ADL2891([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))2892for serialization.2893*/2894template<typename T = void, typename SFINAE = void>2895struct adl_serializer;28962897template<template<typename U, typename V, typename... Args> class ObjectType =2898std::map,2899template<typename U, typename... Args> class ArrayType = std::vector,2900class StringType = std::string, class BooleanType = bool,2901class NumberIntegerType = std::int64_t,2902class NumberUnsignedType = std::uint64_t,2903class NumberFloatType = double,2904template<typename U> class AllocatorType = std::allocator,2905template<typename T, typename SFINAE = void> class JSONSerializer =2906adl_serializer,2907class BinaryType = std::vector<std::uint8_t>>2908class basic_json;29092910/*!2911@brief JSON Pointer29122913A JSON pointer defines a string syntax for identifying a specific value2914within a JSON document. It can be used with functions `at` and2915`operator[]`. Furthermore, JSON pointers are the base for JSON patches.29162917@sa [RFC 6901](https://tools.ietf.org/html/rfc6901)29182919@since version 2.0.02920*/2921template<typename BasicJsonType>2922class json_pointer;29232924/*!2925@brief default JSON class29262927This type is the default specialization of the @ref basic_json class which2928uses the standard template types.29292930@since version 1.0.02931*/2932using json = basic_json<>;29332934template<class Key, class T, class IgnoredLess, class Allocator>2935struct ordered_map;29362937/*!2938@brief ordered JSON class29392940This type preserves the insertion order of object keys.29412942@since version 3.9.02943*/2944using ordered_json = basic_json<nlohmann::ordered_map>;29452946} // namespace nlohmann29472948#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_294929502951namespace nlohmann2952{2953/*!2954@brief detail namespace with internal helper functions29552956This namespace collects functions that should not be exposed,2957implementations of some @ref basic_json methods, and meta-programming helpers.29582959@since version 2.1.02960*/2961namespace detail2962{2963/////////////2964// helpers //2965/////////////29662967// Note to maintainers:2968//2969// Every trait in this file expects a non CV-qualified type.2970// The only exceptions are in the 'aliases for detected' section2971// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))2972//2973// In this case, T has to be properly CV-qualified to constraint the function arguments2974// (e.g. to_json(BasicJsonType&, const T&))29752976template<typename> struct is_basic_json : std::false_type {};29772978NLOHMANN_BASIC_JSON_TPL_DECLARATION2979struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};29802981//////////////////////2982// json_ref helpers //2983//////////////////////29842985template<typename>2986class json_ref;29872988template<typename>2989struct is_json_ref : std::false_type {};29902991template<typename T>2992struct is_json_ref<json_ref<T>> : std::true_type {};29932994//////////////////////////2995// aliases for detected //2996//////////////////////////29972998template<typename T>2999using mapped_type_t = typename T::mapped_type;30003001template<typename T>3002using key_type_t = typename T::key_type;30033004template<typename T>3005using value_type_t = typename T::value_type;30063007template<typename T>3008using difference_type_t = typename T::difference_type;30093010template<typename T>3011using pointer_t = typename T::pointer;30123013template<typename T>3014using reference_t = typename T::reference;30153016template<typename T>3017using iterator_category_t = typename T::iterator_category;30183019template<typename T>3020using iterator_t = typename T::iterator;30213022template<typename T, typename... Args>3023using to_json_function = decltype(T::to_json(std::declval<Args>()...));30243025template<typename T, typename... Args>3026using from_json_function = decltype(T::from_json(std::declval<Args>()...));30273028template<typename T, typename U>3029using get_template_function = decltype(std::declval<T>().template get<U>());30303031// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists3032template<typename BasicJsonType, typename T, typename = void>3033struct has_from_json : std::false_type {};30343035// trait checking if j.get<T> is valid3036// use this trait instead of std::is_constructible or std::is_convertible,3037// both rely on, or make use of implicit conversions, and thus fail when T3038// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)3039template <typename BasicJsonType, typename T>3040struct is_getable3041{3042static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;3043};30443045template<typename BasicJsonType, typename T>3046struct has_from_json < BasicJsonType, T,3047enable_if_t < !is_basic_json<T>::value >>3048{3049using serializer = typename BasicJsonType::template json_serializer<T, void>;30503051static constexpr bool value =3052is_detected_exact<void, from_json_function, serializer,3053const BasicJsonType&, T&>::value;3054};30553056// This trait checks if JSONSerializer<T>::from_json(json const&) exists3057// this overload is used for non-default-constructible user-defined-types3058template<typename BasicJsonType, typename T, typename = void>3059struct has_non_default_from_json : std::false_type {};30603061template<typename BasicJsonType, typename T>3062struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>3063{3064using serializer = typename BasicJsonType::template json_serializer<T, void>;30653066static constexpr bool value =3067is_detected_exact<T, from_json_function, serializer,3068const BasicJsonType&>::value;3069};30703071// This trait checks if BasicJsonType::json_serializer<T>::to_json exists3072// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.3073template<typename BasicJsonType, typename T, typename = void>3074struct has_to_json : std::false_type {};30753076template<typename BasicJsonType, typename T>3077struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>3078{3079using serializer = typename BasicJsonType::template json_serializer<T, void>;30803081static constexpr bool value =3082is_detected_exact<void, to_json_function, serializer, BasicJsonType&,3083T>::value;3084};308530863087///////////////////3088// is_ functions //3089///////////////////30903091template<typename T, typename = void>3092struct is_iterator_traits : std::false_type {};30933094template<typename T>3095struct is_iterator_traits<iterator_traits<T>>3096{3097private:3098using traits = iterator_traits<T>;30993100public:3101static constexpr auto value =3102is_detected<value_type_t, traits>::value &&3103is_detected<difference_type_t, traits>::value &&3104is_detected<pointer_t, traits>::value &&3105is_detected<iterator_category_t, traits>::value &&3106is_detected<reference_t, traits>::value;3107};31083109// source: https://stackoverflow.com/a/37193089/411645331103111template<typename T, typename = void>3112struct is_complete_type : std::false_type {};31133114template<typename T>3115struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};31163117template<typename BasicJsonType, typename CompatibleObjectType,3118typename = void>3119struct is_compatible_object_type_impl : std::false_type {};31203121template<typename BasicJsonType, typename CompatibleObjectType>3122struct is_compatible_object_type_impl <3123BasicJsonType, CompatibleObjectType,3124enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&3125is_detected<key_type_t, CompatibleObjectType>::value >>3126{31273128using object_t = typename BasicJsonType::object_t;31293130// macOS's is_constructible does not play well with nonesuch...3131static constexpr bool value =3132std::is_constructible<typename object_t::key_type,3133typename CompatibleObjectType::key_type>::value &&3134std::is_constructible<typename object_t::mapped_type,3135typename CompatibleObjectType::mapped_type>::value;3136};31373138template<typename BasicJsonType, typename CompatibleObjectType>3139struct is_compatible_object_type3140: is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};31413142template<typename BasicJsonType, typename ConstructibleObjectType,3143typename = void>3144struct is_constructible_object_type_impl : std::false_type {};31453146template<typename BasicJsonType, typename ConstructibleObjectType>3147struct is_constructible_object_type_impl <3148BasicJsonType, ConstructibleObjectType,3149enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&3150is_detected<key_type_t, ConstructibleObjectType>::value >>3151{3152using object_t = typename BasicJsonType::object_t;31533154static constexpr bool value =3155(std::is_default_constructible<ConstructibleObjectType>::value &&3156(std::is_move_assignable<ConstructibleObjectType>::value ||3157std::is_copy_assignable<ConstructibleObjectType>::value) &&3158(std::is_constructible<typename ConstructibleObjectType::key_type,3159typename object_t::key_type>::value &&3160std::is_same <3161typename object_t::mapped_type,3162typename ConstructibleObjectType::mapped_type >::value)) ||3163(has_from_json<BasicJsonType,3164typename ConstructibleObjectType::mapped_type>::value ||3165has_non_default_from_json <3166BasicJsonType,3167typename ConstructibleObjectType::mapped_type >::value);3168};31693170template<typename BasicJsonType, typename ConstructibleObjectType>3171struct is_constructible_object_type3172: is_constructible_object_type_impl<BasicJsonType,3173ConstructibleObjectType> {};31743175template<typename BasicJsonType, typename CompatibleStringType,3176typename = void>3177struct is_compatible_string_type_impl : std::false_type {};31783179template<typename BasicJsonType, typename CompatibleStringType>3180struct is_compatible_string_type_impl <3181BasicJsonType, CompatibleStringType,3182enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,3183value_type_t, CompatibleStringType>::value >>3184{3185static constexpr auto value =3186std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;3187};31883189template<typename BasicJsonType, typename ConstructibleStringType>3190struct is_compatible_string_type3191: is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};31923193template<typename BasicJsonType, typename ConstructibleStringType,3194typename = void>3195struct is_constructible_string_type_impl : std::false_type {};31963197template<typename BasicJsonType, typename ConstructibleStringType>3198struct is_constructible_string_type_impl <3199BasicJsonType, ConstructibleStringType,3200enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,3201value_type_t, ConstructibleStringType>::value >>3202{3203static constexpr auto value =3204std::is_constructible<ConstructibleStringType,3205typename BasicJsonType::string_t>::value;3206};32073208template<typename BasicJsonType, typename ConstructibleStringType>3209struct is_constructible_string_type3210: is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};32113212template<typename BasicJsonType, typename CompatibleArrayType, typename = void>3213struct is_compatible_array_type_impl : std::false_type {};32143215template<typename BasicJsonType, typename CompatibleArrayType>3216struct is_compatible_array_type_impl <3217BasicJsonType, CompatibleArrayType,3218enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&3219is_detected<iterator_t, CompatibleArrayType>::value&&3220// This is needed because json_reverse_iterator has a ::iterator type...3221// Therefore it is detected as a CompatibleArrayType.3222// The real fix would be to have an Iterable concept.3223!is_iterator_traits <3224iterator_traits<CompatibleArrayType >>::value >>3225{3226static constexpr bool value =3227std::is_constructible<BasicJsonType,3228typename CompatibleArrayType::value_type>::value;3229};32303231template<typename BasicJsonType, typename CompatibleArrayType>3232struct is_compatible_array_type3233: is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};32343235template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>3236struct is_constructible_array_type_impl : std::false_type {};32373238template<typename BasicJsonType, typename ConstructibleArrayType>3239struct is_constructible_array_type_impl <3240BasicJsonType, ConstructibleArrayType,3241enable_if_t<std::is_same<ConstructibleArrayType,3242typename BasicJsonType::value_type>::value >>3243: std::true_type {};32443245template<typename BasicJsonType, typename ConstructibleArrayType>3246struct is_constructible_array_type_impl <3247BasicJsonType, ConstructibleArrayType,3248enable_if_t < !std::is_same<ConstructibleArrayType,3249typename BasicJsonType::value_type>::value&&3250std::is_default_constructible<ConstructibleArrayType>::value&&3251(std::is_move_assignable<ConstructibleArrayType>::value ||3252std::is_copy_assignable<ConstructibleArrayType>::value)&&3253is_detected<value_type_t, ConstructibleArrayType>::value&&3254is_detected<iterator_t, ConstructibleArrayType>::value&&3255is_complete_type <3256detected_t<value_type_t, ConstructibleArrayType >>::value >>3257{3258static constexpr bool value =3259// This is needed because json_reverse_iterator has a ::iterator type,3260// furthermore, std::back_insert_iterator (and other iterators) have a3261// base class `iterator`... Therefore it is detected as a3262// ConstructibleArrayType. The real fix would be to have an Iterable3263// concept.3264!is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&32653266(std::is_same<typename ConstructibleArrayType::value_type,3267typename BasicJsonType::array_t::value_type>::value ||3268has_from_json<BasicJsonType,3269typename ConstructibleArrayType::value_type>::value ||3270has_non_default_from_json <3271BasicJsonType, typename ConstructibleArrayType::value_type >::value);3272};32733274template<typename BasicJsonType, typename ConstructibleArrayType>3275struct is_constructible_array_type3276: is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};32773278template<typename RealIntegerType, typename CompatibleNumberIntegerType,3279typename = void>3280struct is_compatible_integer_type_impl : std::false_type {};32813282template<typename RealIntegerType, typename CompatibleNumberIntegerType>3283struct is_compatible_integer_type_impl <3284RealIntegerType, CompatibleNumberIntegerType,3285enable_if_t < std::is_integral<RealIntegerType>::value&&3286std::is_integral<CompatibleNumberIntegerType>::value&&3287!std::is_same<bool, CompatibleNumberIntegerType>::value >>3288{3289// is there an assert somewhere on overflows?3290using RealLimits = std::numeric_limits<RealIntegerType>;3291using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;32923293static constexpr auto value =3294std::is_constructible<RealIntegerType,3295CompatibleNumberIntegerType>::value &&3296CompatibleLimits::is_integer &&3297RealLimits::is_signed == CompatibleLimits::is_signed;3298};32993300template<typename RealIntegerType, typename CompatibleNumberIntegerType>3301struct is_compatible_integer_type3302: is_compatible_integer_type_impl<RealIntegerType,3303CompatibleNumberIntegerType> {};33043305template<typename BasicJsonType, typename CompatibleType, typename = void>3306struct is_compatible_type_impl: std::false_type {};33073308template<typename BasicJsonType, typename CompatibleType>3309struct is_compatible_type_impl <3310BasicJsonType, CompatibleType,3311enable_if_t<is_complete_type<CompatibleType>::value >>3312{3313static constexpr bool value =3314has_to_json<BasicJsonType, CompatibleType>::value;3315};33163317template<typename BasicJsonType, typename CompatibleType>3318struct is_compatible_type3319: is_compatible_type_impl<BasicJsonType, CompatibleType> {};33203321// https://en.cppreference.com/w/cpp/types/conjunction3322template<class...> struct conjunction : std::true_type { };3323template<class B1> struct conjunction<B1> : B1 { };3324template<class B1, class... Bn>3325struct conjunction<B1, Bn...>3326: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};33273328template<typename T1, typename T2>3329struct is_constructible_tuple : std::false_type {};33303331template<typename T1, typename... Args>3332struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};3333} // namespace detail3334} // namespace nlohmann33353336// #include <nlohmann/detail/value_t.hpp>333733383339#include <array> // array3340#include <cstddef> // size_t3341#include <cstdint> // uint8_t3342#include <string> // string33433344namespace nlohmann3345{3346namespace detail3347{3348///////////////////////////3349// JSON type enumeration //3350///////////////////////////33513352/*!3353@brief the JSON type enumeration33543355This enumeration collects the different JSON types. It is internally used to3356distinguish the stored values, and the functions @ref basic_json::is_null(),3357@ref basic_json::is_object(), @ref basic_json::is_array(),3358@ref basic_json::is_string(), @ref basic_json::is_boolean(),3359@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),3360@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),3361@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and3362@ref basic_json::is_structured() rely on it.33633364@note There are three enumeration entries (number_integer, number_unsigned, and3365number_float), because the library distinguishes these three types for numbers:3366@ref basic_json::number_unsigned_t is used for unsigned integers,3367@ref basic_json::number_integer_t is used for signed integers, and3368@ref basic_json::number_float_t is used for floating-point numbers or to3369approximate integers which do not fit in the limits of their respective type.33703371@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON3372value with the default value for a given type33733374@since version 1.0.03375*/3376enum class value_t : std::uint8_t3377{3378null, ///< null value3379object, ///< object (unordered set of name/value pairs)3380array, ///< array (ordered collection of values)3381string, ///< string value3382boolean, ///< boolean value3383number_integer, ///< number value (signed integer)3384number_unsigned, ///< number value (unsigned integer)3385number_float, ///< number value (floating-point)3386binary, ///< binary array (ordered collection of bytes)3387discarded ///< discarded by the parser callback function3388};33893390/*!3391@brief comparison operator for JSON types33923393Returns an ordering that is similar to Python:3394- order: null < boolean < number < object < array < string < binary3395- furthermore, each type is not smaller than itself3396- discarded values are not comparable3397- binary is represented as a b"" string in python and directly comparable to a3398string; however, making a binary array directly comparable with a string would3399be surprising behavior in a JSON file.34003401@since version 1.0.03402*/3403inline bool operator<(const value_t lhs, const value_t rhs) noexcept3404{3405static constexpr std::array<std::uint8_t, 9> order = {{34060 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,34071 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,34086 /* binary */3409}3410};34113412const auto l_index = static_cast<std::size_t>(lhs);3413const auto r_index = static_cast<std::size_t>(rhs);3414return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];3415}3416} // namespace detail3417} // namespace nlohmann341834193420namespace nlohmann3421{3422namespace detail3423{3424template<typename BasicJsonType>3425void from_json(const BasicJsonType& j, typename std::nullptr_t& n)3426{3427if (JSON_HEDLEY_UNLIKELY(!j.is_null()))3428{3429JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));3430}3431n = nullptr;3432}34333434// overloads for basic_json template parameters3435template < typename BasicJsonType, typename ArithmeticType,3436enable_if_t < std::is_arithmetic<ArithmeticType>::value&&3437!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,3438int > = 0 >3439void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)3440{3441switch (static_cast<value_t>(j))3442{3443case value_t::number_unsigned:3444{3445val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());3446break;3447}3448case value_t::number_integer:3449{3450val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());3451break;3452}3453case value_t::number_float:3454{3455val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());3456break;3457}34583459default:3460JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));3461}3462}34633464template<typename BasicJsonType>3465void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)3466{3467if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))3468{3469JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));3470}3471b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();3472}34733474template<typename BasicJsonType>3475void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)3476{3477if (JSON_HEDLEY_UNLIKELY(!j.is_string()))3478{3479JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));3480}3481s = *j.template get_ptr<const typename BasicJsonType::string_t*>();3482}34833484template <3485typename BasicJsonType, typename ConstructibleStringType,3486enable_if_t <3487is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&3488!std::is_same<typename BasicJsonType::string_t,3489ConstructibleStringType>::value,3490int > = 0 >3491void from_json(const BasicJsonType& j, ConstructibleStringType& s)3492{3493if (JSON_HEDLEY_UNLIKELY(!j.is_string()))3494{3495JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));3496}34973498s = *j.template get_ptr<const typename BasicJsonType::string_t*>();3499}35003501template<typename BasicJsonType>3502void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)3503{3504get_arithmetic_value(j, val);3505}35063507template<typename BasicJsonType>3508void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)3509{3510get_arithmetic_value(j, val);3511}35123513template<typename BasicJsonType>3514void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)3515{3516get_arithmetic_value(j, val);3517}35183519template<typename BasicJsonType, typename EnumType,3520enable_if_t<std::is_enum<EnumType>::value, int> = 0>3521void from_json(const BasicJsonType& j, EnumType& e)3522{3523typename std::underlying_type<EnumType>::type val;3524get_arithmetic_value(j, val);3525e = static_cast<EnumType>(val);3526}35273528// forward_list doesn't have an insert method3529template<typename BasicJsonType, typename T, typename Allocator,3530enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>3531void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)3532{3533if (JSON_HEDLEY_UNLIKELY(!j.is_array()))3534{3535JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));3536}3537l.clear();3538std::transform(j.rbegin(), j.rend(),3539std::front_inserter(l), [](const BasicJsonType & i)3540{3541return i.template get<T>();3542});3543}35443545// valarray doesn't have an insert method3546template<typename BasicJsonType, typename T,3547enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>3548void from_json(const BasicJsonType& j, std::valarray<T>& l)3549{3550if (JSON_HEDLEY_UNLIKELY(!j.is_array()))3551{3552JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));3553}3554l.resize(j.size());3555std::transform(j.begin(), j.end(), std::begin(l),3556[](const BasicJsonType & elem)3557{3558return elem.template get<T>();3559});3560}35613562template<typename BasicJsonType, typename T, std::size_t N>3563auto from_json(const BasicJsonType& j, T (&arr)[N])3564-> decltype(j.template get<T>(), void())3565{3566for (std::size_t i = 0; i < N; ++i)3567{3568arr[i] = j.at(i).template get<T>();3569}3570}35713572template<typename BasicJsonType>3573void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)3574{3575arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();3576}35773578template<typename BasicJsonType, typename T, std::size_t N>3579auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,3580priority_tag<2> /*unused*/)3581-> decltype(j.template get<T>(), void())3582{3583for (std::size_t i = 0; i < N; ++i)3584{3585arr[i] = j.at(i).template get<T>();3586}3587}35883589template<typename BasicJsonType, typename ConstructibleArrayType>3590auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)3591-> decltype(3592arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),3593j.template get<typename ConstructibleArrayType::value_type>(),3594void())3595{3596using std::end;35973598ConstructibleArrayType ret;3599ret.reserve(j.size());3600std::transform(j.begin(), j.end(),3601std::inserter(ret, end(ret)), [](const BasicJsonType & i)3602{3603// get<BasicJsonType>() returns *this, this won't call a from_json3604// method when value_type is BasicJsonType3605return i.template get<typename ConstructibleArrayType::value_type>();3606});3607arr = std::move(ret);3608}36093610template<typename BasicJsonType, typename ConstructibleArrayType>3611void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,3612priority_tag<0> /*unused*/)3613{3614using std::end;36153616ConstructibleArrayType ret;3617std::transform(3618j.begin(), j.end(), std::inserter(ret, end(ret)),3619[](const BasicJsonType & i)3620{3621// get<BasicJsonType>() returns *this, this won't call a from_json3622// method when value_type is BasicJsonType3623return i.template get<typename ConstructibleArrayType::value_type>();3624});3625arr = std::move(ret);3626}36273628template < typename BasicJsonType, typename ConstructibleArrayType,3629enable_if_t <3630is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&3631!is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&3632!is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&3633!std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&3634!is_basic_json<ConstructibleArrayType>::value,3635int > = 0 >3636auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)3637-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),3638j.template get<typename ConstructibleArrayType::value_type>(),3639void())3640{3641if (JSON_HEDLEY_UNLIKELY(!j.is_array()))3642{3643JSON_THROW(type_error::create(302, "type must be array, but is " +3644std::string(j.type_name())));3645}36463647from_json_array_impl(j, arr, priority_tag<3> {});3648}36493650template<typename BasicJsonType>3651void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)3652{3653if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))3654{3655JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));3656}36573658bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();3659}36603661template<typename BasicJsonType, typename ConstructibleObjectType,3662enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>3663void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)3664{3665if (JSON_HEDLEY_UNLIKELY(!j.is_object()))3666{3667JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));3668}36693670ConstructibleObjectType ret;3671auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();3672using value_type = typename ConstructibleObjectType::value_type;3673std::transform(3674inner_object->begin(), inner_object->end(),3675std::inserter(ret, ret.begin()),3676[](typename BasicJsonType::object_t::value_type const & p)3677{3678return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());3679});3680obj = std::move(ret);3681}36823683// overload for arithmetic types, not chosen for basic_json template arguments3684// (BooleanType, etc..); note: Is it really necessary to provide explicit3685// overloads for boolean_t etc. in case of a custom BooleanType which is not3686// an arithmetic type?3687template < typename BasicJsonType, typename ArithmeticType,3688enable_if_t <3689std::is_arithmetic<ArithmeticType>::value&&3690!std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&3691!std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&3692!std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&3693!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,3694int > = 0 >3695void from_json(const BasicJsonType& j, ArithmeticType& val)3696{3697switch (static_cast<value_t>(j))3698{3699case value_t::number_unsigned:3700{3701val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());3702break;3703}3704case value_t::number_integer:3705{3706val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());3707break;3708}3709case value_t::number_float:3710{3711val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());3712break;3713}3714case value_t::boolean:3715{3716val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());3717break;3718}37193720default:3721JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));3722}3723}37243725template<typename BasicJsonType, typename A1, typename A2>3726void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)3727{3728p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};3729}37303731template<typename BasicJsonType, typename Tuple, std::size_t... Idx>3732void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)3733{3734t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);3735}37363737template<typename BasicJsonType, typename... Args>3738void from_json(const BasicJsonType& j, std::tuple<Args...>& t)3739{3740from_json_tuple_impl(j, t, index_sequence_for<Args...> {});3741}37423743template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,3744typename = enable_if_t < !std::is_constructible <3745typename BasicJsonType::string_t, Key >::value >>3746void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)3747{3748if (JSON_HEDLEY_UNLIKELY(!j.is_array()))3749{3750JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));3751}3752m.clear();3753for (const auto& p : j)3754{3755if (JSON_HEDLEY_UNLIKELY(!p.is_array()))3756{3757JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));3758}3759m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());3760}3761}37623763template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,3764typename = enable_if_t < !std::is_constructible <3765typename BasicJsonType::string_t, Key >::value >>3766void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)3767{3768if (JSON_HEDLEY_UNLIKELY(!j.is_array()))3769{3770JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));3771}3772m.clear();3773for (const auto& p : j)3774{3775if (JSON_HEDLEY_UNLIKELY(!p.is_array()))3776{3777JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));3778}3779m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());3780}3781}37823783struct from_json_fn3784{3785template<typename BasicJsonType, typename T>3786auto operator()(const BasicJsonType& j, T& val) const3787noexcept(noexcept(from_json(j, val)))3788-> decltype(from_json(j, val), void())3789{3790return from_json(j, val);3791}3792};3793} // namespace detail37943795/// namespace to hold default `from_json` function3796/// to see why this is required:3797/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html3798namespace3799{3800constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;3801} // namespace3802} // namespace nlohmann38033804// #include <nlohmann/detail/conversions/to_json.hpp>380538063807#include <algorithm> // copy3808#include <iterator> // begin, end3809#include <string> // string3810#include <tuple> // tuple, get3811#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type3812#include <utility> // move, forward, declval, pair3813#include <valarray> // valarray3814#include <vector> // vector38153816// #include <nlohmann/detail/iterators/iteration_proxy.hpp>381738183819#include <cstddef> // size_t3820#include <iterator> // input_iterator_tag3821#include <string> // string, to_string3822#include <tuple> // tuple_size, get, tuple_element38233824// #include <nlohmann/detail/meta/type_traits.hpp>38253826// #include <nlohmann/detail/value_t.hpp>382738283829namespace nlohmann3830{3831namespace detail3832{3833template<typename string_type>3834void int_to_string( string_type& target, std::size_t value )3835{3836// For ADL3837using std::to_string;3838target = to_string(value);3839}3840template<typename IteratorType> class iteration_proxy_value3841{3842public:3843using difference_type = std::ptrdiff_t;3844using value_type = iteration_proxy_value;3845using pointer = value_type * ;3846using reference = value_type & ;3847using iterator_category = std::input_iterator_tag;3848using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;38493850private:3851/// the iterator3852IteratorType anchor;3853/// an index for arrays (used to create key names)3854std::size_t array_index = 0;3855/// last stringified array index3856mutable std::size_t array_index_last = 0;3857/// a string representation of the array index3858mutable string_type array_index_str = "0";3859/// an empty string (to return a reference for primitive values)3860const string_type empty_str = "";38613862public:3863explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}38643865/// dereference operator (needed for range-based for)3866iteration_proxy_value& operator*()3867{3868return *this;3869}38703871/// increment operator (needed for range-based for)3872iteration_proxy_value& operator++()3873{3874++anchor;3875++array_index;38763877return *this;3878}38793880/// equality operator (needed for InputIterator)3881bool operator==(const iteration_proxy_value& o) const3882{3883return anchor == o.anchor;3884}38853886/// inequality operator (needed for range-based for)3887bool operator!=(const iteration_proxy_value& o) const3888{3889return anchor != o.anchor;3890}38913892/// return key of the iterator3893const string_type& key() const3894{3895JSON_ASSERT(anchor.m_object != nullptr);38963897switch (anchor.m_object->type())3898{3899// use integer array index as key3900case value_t::array:3901{3902if (array_index != array_index_last)3903{3904int_to_string( array_index_str, array_index );3905array_index_last = array_index;3906}3907return array_index_str;3908}39093910// use key from the object3911case value_t::object:3912return anchor.key();39133914// use an empty key for all primitive types3915default:3916return empty_str;3917}3918}39193920/// return value of the iterator3921typename IteratorType::reference value() const3922{3923return anchor.value();3924}3925};39263927/// proxy class for the items() function3928template<typename IteratorType> class iteration_proxy3929{3930private:3931/// the container to iterate3932typename IteratorType::reference container;39333934public:3935/// construct iteration proxy from a container3936explicit iteration_proxy(typename IteratorType::reference cont) noexcept3937: container(cont) {}39383939/// return iterator begin (needed for range-based for)3940iteration_proxy_value<IteratorType> begin() noexcept3941{3942return iteration_proxy_value<IteratorType>(container.begin());3943}39443945/// return iterator end (needed for range-based for)3946iteration_proxy_value<IteratorType> end() noexcept3947{3948return iteration_proxy_value<IteratorType>(container.end());3949}3950};3951// Structured Bindings Support3952// For further reference see https://blog.tartanllama.xyz/structured-bindings/3953// And see https://github.com/nlohmann/json/pull/13913954template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>3955auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())3956{3957return i.key();3958}3959// Structured Bindings Support3960// For further reference see https://blog.tartanllama.xyz/structured-bindings/3961// And see https://github.com/nlohmann/json/pull/13913962template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>3963auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())3964{3965return i.value();3966}3967} // namespace detail3968} // namespace nlohmann39693970// The Addition to the STD Namespace is required to add3971// Structured Bindings Support to the iteration_proxy_value class3972// For further reference see https://blog.tartanllama.xyz/structured-bindings/3973// And see https://github.com/nlohmann/json/pull/13913974namespace std3975{3976#if defined(__clang__)3977// Fix: https://github.com/nlohmann/json/issues/14013978#pragma clang diagnostic push3979#pragma clang diagnostic ignored "-Wmismatched-tags"3980#endif3981template<typename IteratorType>3982class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>3983: public std::integral_constant<std::size_t, 2> {};39843985template<std::size_t N, typename IteratorType>3986class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>3987{3988public:3989using type = decltype(3990get<N>(std::declval <3991::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));3992};3993#if defined(__clang__)3994#pragma clang diagnostic pop3995#endif3996} // namespace std39973998// #include <nlohmann/detail/meta/cpp_future.hpp>39994000// #include <nlohmann/detail/meta/type_traits.hpp>40014002// #include <nlohmann/detail/value_t.hpp>400340044005namespace nlohmann4006{4007namespace detail4008{4009//////////////////4010// constructors //4011//////////////////40124013template<value_t> struct external_constructor;40144015template<>4016struct external_constructor<value_t::boolean>4017{4018template<typename BasicJsonType>4019static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept4020{4021j.m_type = value_t::boolean;4022j.m_value = b;4023j.assert_invariant();4024}4025};40264027template<>4028struct external_constructor<value_t::string>4029{4030template<typename BasicJsonType>4031static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)4032{4033j.m_type = value_t::string;4034j.m_value = s;4035j.assert_invariant();4036}40374038template<typename BasicJsonType>4039static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)4040{4041j.m_type = value_t::string;4042j.m_value = std::move(s);4043j.assert_invariant();4044}40454046template < typename BasicJsonType, typename CompatibleStringType,4047enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,4048int > = 0 >4049static void construct(BasicJsonType& j, const CompatibleStringType& str)4050{4051j.m_type = value_t::string;4052j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);4053j.assert_invariant();4054}4055};40564057template<>4058struct external_constructor<value_t::binary>4059{4060template<typename BasicJsonType>4061static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)4062{4063j.m_type = value_t::binary;4064typename BasicJsonType::binary_t value{b};4065j.m_value = value;4066j.assert_invariant();4067}40684069template<typename BasicJsonType>4070static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)4071{4072j.m_type = value_t::binary;4073typename BasicJsonType::binary_t value{std::move(b)};4074j.m_value = value;4075j.assert_invariant();4076}4077};40784079template<>4080struct external_constructor<value_t::number_float>4081{4082template<typename BasicJsonType>4083static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept4084{4085j.m_type = value_t::number_float;4086j.m_value = val;4087j.assert_invariant();4088}4089};40904091template<>4092struct external_constructor<value_t::number_unsigned>4093{4094template<typename BasicJsonType>4095static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept4096{4097j.m_type = value_t::number_unsigned;4098j.m_value = val;4099j.assert_invariant();4100}4101};41024103template<>4104struct external_constructor<value_t::number_integer>4105{4106template<typename BasicJsonType>4107static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept4108{4109j.m_type = value_t::number_integer;4110j.m_value = val;4111j.assert_invariant();4112}4113};41144115template<>4116struct external_constructor<value_t::array>4117{4118template<typename BasicJsonType>4119static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)4120{4121j.m_type = value_t::array;4122j.m_value = arr;4123j.assert_invariant();4124}41254126template<typename BasicJsonType>4127static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)4128{4129j.m_type = value_t::array;4130j.m_value = std::move(arr);4131j.assert_invariant();4132}41334134template < typename BasicJsonType, typename CompatibleArrayType,4135enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,4136int > = 0 >4137static void construct(BasicJsonType& j, const CompatibleArrayType& arr)4138{4139using std::begin;4140using std::end;4141j.m_type = value_t::array;4142j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));4143j.assert_invariant();4144}41454146template<typename BasicJsonType>4147static void construct(BasicJsonType& j, const std::vector<bool>& arr)4148{4149j.m_type = value_t::array;4150j.m_value = value_t::array;4151j.m_value.array->reserve(arr.size());4152for (const bool x : arr)4153{4154j.m_value.array->push_back(x);4155}4156j.assert_invariant();4157}41584159template<typename BasicJsonType, typename T,4160enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>4161static void construct(BasicJsonType& j, const std::valarray<T>& arr)4162{4163j.m_type = value_t::array;4164j.m_value = value_t::array;4165j.m_value.array->resize(arr.size());4166if (arr.size() > 0)4167{4168std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());4169}4170j.assert_invariant();4171}4172};41734174template<>4175struct external_constructor<value_t::object>4176{4177template<typename BasicJsonType>4178static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)4179{4180j.m_type = value_t::object;4181j.m_value = obj;4182j.assert_invariant();4183}41844185template<typename BasicJsonType>4186static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)4187{4188j.m_type = value_t::object;4189j.m_value = std::move(obj);4190j.assert_invariant();4191}41924193template < typename BasicJsonType, typename CompatibleObjectType,4194enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >4195static void construct(BasicJsonType& j, const CompatibleObjectType& obj)4196{4197using std::begin;4198using std::end;41994200j.m_type = value_t::object;4201j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));4202j.assert_invariant();4203}4204};42054206/////////////4207// to_json //4208/////////////42094210template<typename BasicJsonType, typename T,4211enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>4212void to_json(BasicJsonType& j, T b) noexcept4213{4214external_constructor<value_t::boolean>::construct(j, b);4215}42164217template<typename BasicJsonType, typename CompatibleString,4218enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>4219void to_json(BasicJsonType& j, const CompatibleString& s)4220{4221external_constructor<value_t::string>::construct(j, s);4222}42234224template<typename BasicJsonType>4225void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)4226{4227external_constructor<value_t::string>::construct(j, std::move(s));4228}42294230template<typename BasicJsonType, typename FloatType,4231enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>4232void to_json(BasicJsonType& j, FloatType val) noexcept4233{4234external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));4235}42364237template<typename BasicJsonType, typename CompatibleNumberUnsignedType,4238enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>4239void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept4240{4241external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));4242}42434244template<typename BasicJsonType, typename CompatibleNumberIntegerType,4245enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>4246void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept4247{4248external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));4249}42504251template<typename BasicJsonType, typename EnumType,4252enable_if_t<std::is_enum<EnumType>::value, int> = 0>4253void to_json(BasicJsonType& j, EnumType e) noexcept4254{4255using underlying_type = typename std::underlying_type<EnumType>::type;4256external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));4257}42584259template<typename BasicJsonType>4260void to_json(BasicJsonType& j, const std::vector<bool>& e)4261{4262external_constructor<value_t::array>::construct(j, e);4263}42644265template < typename BasicJsonType, typename CompatibleArrayType,4266enable_if_t < is_compatible_array_type<BasicJsonType,4267CompatibleArrayType>::value&&4268!is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&4269!is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&4270!std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&4271!is_basic_json<CompatibleArrayType>::value,4272int > = 0 >4273void to_json(BasicJsonType& j, const CompatibleArrayType& arr)4274{4275external_constructor<value_t::array>::construct(j, arr);4276}42774278template<typename BasicJsonType>4279void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)4280{4281external_constructor<value_t::binary>::construct(j, bin);4282}42834284template<typename BasicJsonType, typename T,4285enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>4286void to_json(BasicJsonType& j, const std::valarray<T>& arr)4287{4288external_constructor<value_t::array>::construct(j, std::move(arr));4289}42904291template<typename BasicJsonType>4292void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)4293{4294external_constructor<value_t::array>::construct(j, std::move(arr));4295}42964297template < typename BasicJsonType, typename CompatibleObjectType,4298enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >4299void to_json(BasicJsonType& j, const CompatibleObjectType& obj)4300{4301external_constructor<value_t::object>::construct(j, obj);4302}43034304template<typename BasicJsonType>4305void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)4306{4307external_constructor<value_t::object>::construct(j, std::move(obj));4308}43094310template <4311typename BasicJsonType, typename T, std::size_t N,4312enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,4313const T(&)[N]>::value,4314int > = 0 >4315void to_json(BasicJsonType& j, const T(&arr)[N])4316{4317external_constructor<value_t::array>::construct(j, arr);4318}43194320template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >4321void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)4322{4323j = { p.first, p.second };4324}43254326// for https://github.com/nlohmann/json/pull/11344327template<typename BasicJsonType, typename T,4328enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>4329void to_json(BasicJsonType& j, const T& b)4330{4331j = { {b.key(), b.value()} };4332}43334334template<typename BasicJsonType, typename Tuple, std::size_t... Idx>4335void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)4336{4337j = { std::get<Idx>(t)... };4338}43394340template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>4341void to_json(BasicJsonType& j, const T& t)4342{4343to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});4344}43454346struct to_json_fn4347{4348template<typename BasicJsonType, typename T>4349auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))4350-> decltype(to_json(j, std::forward<T>(val)), void())4351{4352return to_json(j, std::forward<T>(val));4353}4354};4355} // namespace detail43564357/// namespace to hold default `to_json` function4358namespace4359{4360constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;4361} // namespace4362} // namespace nlohmann436343644365namespace nlohmann4366{43674368template<typename, typename>4369struct adl_serializer4370{4371/*!4372@brief convert a JSON value to any value type43734374This function is usually called by the `get()` function of the4375@ref basic_json class (either explicit or via conversion operators).43764377@param[in] j JSON value to read from4378@param[in,out] val value to write to4379*/4380template<typename BasicJsonType, typename ValueType>4381static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(4382noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))4383-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())4384{4385::nlohmann::from_json(std::forward<BasicJsonType>(j), val);4386}43874388/*!4389@brief convert any value type to a JSON value43904391This function is usually called by the constructors of the @ref basic_json4392class.43934394@param[in,out] j JSON value to write to4395@param[in] val value to read from4396*/4397template<typename BasicJsonType, typename ValueType>4398static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(4399noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))4400-> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())4401{4402::nlohmann::to_json(j, std::forward<ValueType>(val));4403}4404};44054406} // namespace nlohmann44074408// #include <nlohmann/byte_container_with_subtype.hpp>440944104411#include <cstdint> // uint8_t4412#include <tuple> // tie4413#include <utility> // move44144415namespace nlohmann4416{44174418/*!4419@brief an internal type for a backed binary type44204421This type extends the template parameter @a BinaryType provided to `basic_json`4422with a subtype used by BSON and MessagePack. This type exists so that the user4423does not have to specify a type themselves with a specific naming scheme in4424order to override the binary type.44254426@tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by4427default)44284429@since version 3.8.04430*/4431template<typename BinaryType>4432class byte_container_with_subtype : public BinaryType4433{4434public:4435/// the type of the underlying container4436using container_type = BinaryType;44374438byte_container_with_subtype() noexcept(noexcept(container_type()))4439: container_type()4440{}44414442byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))4443: container_type(b)4444{}44454446byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))4447: container_type(std::move(b))4448{}44494450byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))4451: container_type(b)4452, m_subtype(subtype)4453, m_has_subtype(true)4454{}44554456byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))4457: container_type(std::move(b))4458, m_subtype(subtype)4459, m_has_subtype(true)4460{}44614462bool operator==(const byte_container_with_subtype& rhs) const4463{4464return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==4465std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);4466}44674468bool operator!=(const byte_container_with_subtype& rhs) const4469{4470return !(rhs == *this);4471}44724473/*!4474@brief sets the binary subtype44754476Sets the binary subtype of the value, also flags a binary JSON value as4477having a subtype, which has implications for serialization.44784479@complexity Constant.44804481@exceptionsafety No-throw guarantee: this member function never throws4482exceptions.44834484@sa @ref subtype() -- return the binary subtype4485@sa @ref clear_subtype() -- clears the binary subtype4486@sa @ref has_subtype() -- returns whether or not the binary value has a4487subtype44884489@since version 3.8.04490*/4491void set_subtype(std::uint8_t subtype) noexcept4492{4493m_subtype = subtype;4494m_has_subtype = true;4495}44964497/*!4498@brief return the binary subtype44994500Returns the numerical subtype of the value if it has a subtype. If it does4501not have a subtype, this function will return size_t(-1) as a sentinel4502value.45034504@return the numerical subtype of the binary value45054506@complexity Constant.45074508@exceptionsafety No-throw guarantee: this member function never throws4509exceptions.45104511@sa @ref set_subtype() -- sets the binary subtype4512@sa @ref clear_subtype() -- clears the binary subtype4513@sa @ref has_subtype() -- returns whether or not the binary value has a4514subtype45154516@since version 3.8.04517*/4518constexpr std::uint8_t subtype() const noexcept4519{4520return m_subtype;4521}45224523/*!4524@brief return whether the value has a subtype45254526@return whether the value has a subtype45274528@complexity Constant.45294530@exceptionsafety No-throw guarantee: this member function never throws4531exceptions.45324533@sa @ref subtype() -- return the binary subtype4534@sa @ref set_subtype() -- sets the binary subtype4535@sa @ref clear_subtype() -- clears the binary subtype45364537@since version 3.8.04538*/4539constexpr bool has_subtype() const noexcept4540{4541return m_has_subtype;4542}45434544/*!4545@brief clears the binary subtype45464547Clears the binary subtype and flags the value as not having a subtype, which4548has implications for serialization; for instance MessagePack will prefer the4549bin family over the ext family.45504551@complexity Constant.45524553@exceptionsafety No-throw guarantee: this member function never throws4554exceptions.45554556@sa @ref subtype() -- return the binary subtype4557@sa @ref set_subtype() -- sets the binary subtype4558@sa @ref has_subtype() -- returns whether or not the binary value has a4559subtype45604561@since version 3.8.04562*/4563void clear_subtype() noexcept4564{4565m_subtype = 0;4566m_has_subtype = false;4567}45684569private:4570std::uint8_t m_subtype = 0;4571bool m_has_subtype = false;4572};45734574} // namespace nlohmann45754576// #include <nlohmann/detail/conversions/from_json.hpp>45774578// #include <nlohmann/detail/conversions/to_json.hpp>45794580// #include <nlohmann/detail/exceptions.hpp>45814582// #include <nlohmann/detail/hash.hpp>458345844585#include <cstddef> // size_t, uint8_t4586#include <functional> // hash45874588namespace nlohmann4589{4590namespace detail4591{45924593// boost::hash_combine4594inline std::size_t combine(std::size_t seed, std::size_t h) noexcept4595{4596seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);4597return seed;4598}45994600/*!4601@brief hash a JSON value46024603The hash function tries to rely on std::hash where possible. Furthermore, the4604type of the JSON value is taken into account to have different hash values for4605null, 0, 0U, and false, etc.46064607@tparam BasicJsonType basic_json specialization4608@param j JSON value to hash4609@return hash value of j4610*/4611template<typename BasicJsonType>4612std::size_t hash(const BasicJsonType& j)4613{4614using string_t = typename BasicJsonType::string_t;4615using number_integer_t = typename BasicJsonType::number_integer_t;4616using number_unsigned_t = typename BasicJsonType::number_unsigned_t;4617using number_float_t = typename BasicJsonType::number_float_t;46184619const auto type = static_cast<std::size_t>(j.type());4620switch (j.type())4621{4622case BasicJsonType::value_t::null:4623case BasicJsonType::value_t::discarded:4624{4625return combine(type, 0);4626}46274628case BasicJsonType::value_t::object:4629{4630auto seed = combine(type, j.size());4631for (const auto& element : j.items())4632{4633const auto h = std::hash<string_t> {}(element.key());4634seed = combine(seed, h);4635seed = combine(seed, hash(element.value()));4636}4637return seed;4638}46394640case BasicJsonType::value_t::array:4641{4642auto seed = combine(type, j.size());4643for (const auto& element : j)4644{4645seed = combine(seed, hash(element));4646}4647return seed;4648}46494650case BasicJsonType::value_t::string:4651{4652const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());4653return combine(type, h);4654}46554656case BasicJsonType::value_t::boolean:4657{4658const auto h = std::hash<bool> {}(j.template get<bool>());4659return combine(type, h);4660}46614662case BasicJsonType::value_t::number_integer:4663{4664const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());4665return combine(type, h);4666}46674668case nlohmann::detail::value_t::number_unsigned:4669{4670const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());4671return combine(type, h);4672}46734674case nlohmann::detail::value_t::number_float:4675{4676const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());4677return combine(type, h);4678}46794680case nlohmann::detail::value_t::binary:4681{4682auto seed = combine(type, j.get_binary().size());4683const auto h = std::hash<bool> {}(j.get_binary().has_subtype());4684seed = combine(seed, h);4685seed = combine(seed, j.get_binary().subtype());4686for (const auto byte : j.get_binary())4687{4688seed = combine(seed, std::hash<std::uint8_t> {}(byte));4689}4690return seed;4691}46924693default: // LCOV_EXCL_LINE4694JSON_ASSERT(false); // LCOV_EXCL_LINE4695}4696}46974698} // namespace detail4699} // namespace nlohmann47004701// #include <nlohmann/detail/input/binary_reader.hpp>470247034704#include <algorithm> // generate_n4705#include <array> // array4706#include <cmath> // ldexp4707#include <cstddef> // size_t4708#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t4709#include <cstdio> // snprintf4710#include <cstring> // memcpy4711#include <iterator> // back_inserter4712#include <limits> // numeric_limits4713#include <string> // char_traits, string4714#include <utility> // make_pair, move47154716// #include <nlohmann/detail/exceptions.hpp>47174718// #include <nlohmann/detail/input/input_adapters.hpp>471947204721#include <array> // array4722#include <cstddef> // size_t4723#include <cstdio> //FILE *4724#include <cstring> // strlen4725#include <istream> // istream4726#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next4727#include <memory> // shared_ptr, make_shared, addressof4728#include <numeric> // accumulate4729#include <string> // string, char_traits4730#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer4731#include <utility> // pair, declval47324733// #include <nlohmann/detail/iterators/iterator_traits.hpp>47344735// #include <nlohmann/detail/macro_scope.hpp>473647374738namespace nlohmann4739{4740namespace detail4741{4742/// the supported input formats4743enum class input_format_t { json, cbor, msgpack, ubjson, bson };47444745////////////////////4746// input adapters //4747////////////////////47484749/*!4750Input adapter for stdio file access. This adapter read only 1 byte and do not use any4751buffer. This adapter is a very low level adapter.4752*/4753class file_input_adapter4754{4755public:4756using char_type = char;47574758JSON_HEDLEY_NON_NULL(2)4759explicit file_input_adapter(std::FILE* f) noexcept4760: m_file(f)4761{}47624763// make class move-only4764file_input_adapter(const file_input_adapter&) = delete;4765file_input_adapter(file_input_adapter&&) = default;4766file_input_adapter& operator=(const file_input_adapter&) = delete;4767file_input_adapter& operator=(file_input_adapter&&) = delete;47684769std::char_traits<char>::int_type get_character() noexcept4770{4771return std::fgetc(m_file);4772}47734774private:4775/// the file pointer to read from4776std::FILE* m_file;4777};477847794780/*!4781Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at4782beginning of input. Does not support changing the underlying std::streambuf4783in mid-input. Maintains underlying std::istream and std::streambuf to support4784subsequent use of standard std::istream operations to process any input4785characters following those used in parsing the JSON input. Clears the4786std::istream flags; any input errors (e.g., EOF) will be detected by the first4787subsequent call for input from the std::istream.4788*/4789class input_stream_adapter4790{4791public:4792using char_type = char;47934794~input_stream_adapter()4795{4796// clear stream flags; we use underlying streambuf I/O, do not4797// maintain ifstream flags, except eof4798if (is != nullptr)4799{4800is->clear(is->rdstate() & std::ios::eofbit);4801}4802}48034804explicit input_stream_adapter(std::istream& i)4805: is(&i), sb(i.rdbuf())4806{}48074808// delete because of pointer members4809input_stream_adapter(const input_stream_adapter&) = delete;4810input_stream_adapter& operator=(input_stream_adapter&) = delete;4811input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;48124813input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb)4814{4815rhs.is = nullptr;4816rhs.sb = nullptr;4817}48184819// std::istream/std::streambuf use std::char_traits<char>::to_int_type, to4820// ensure that std::char_traits<char>::eof() and the character 0xFF do not4821// end up as the same value, eg. 0xFFFFFFFF.4822std::char_traits<char>::int_type get_character()4823{4824auto res = sb->sbumpc();4825// set eof manually, as we don't use the istream interface.4826if (JSON_HEDLEY_UNLIKELY(res == EOF))4827{4828is->clear(is->rdstate() | std::ios::eofbit);4829}4830return res;4831}48324833private:4834/// the associated input stream4835std::istream* is = nullptr;4836std::streambuf* sb = nullptr;4837};48384839// General-purpose iterator-based adapter. It might not be as fast as4840// theoretically possible for some containers, but it is extremely versatile.4841template<typename IteratorType>4842class iterator_input_adapter4843{4844public:4845using char_type = typename std::iterator_traits<IteratorType>::value_type;48464847iterator_input_adapter(IteratorType first, IteratorType last)4848: current(std::move(first)), end(std::move(last)) {}48494850typename std::char_traits<char_type>::int_type get_character()4851{4852if (JSON_HEDLEY_LIKELY(current != end))4853{4854auto result = std::char_traits<char_type>::to_int_type(*current);4855std::advance(current, 1);4856return result;4857}4858else4859{4860return std::char_traits<char_type>::eof();4861}4862}48634864private:4865IteratorType current;4866IteratorType end;48674868template<typename BaseInputAdapter, size_t T>4869friend struct wide_string_input_helper;48704871bool empty() const4872{4873return current == end;4874}48754876};487748784879template<typename BaseInputAdapter, size_t T>4880struct wide_string_input_helper;48814882template<typename BaseInputAdapter>4883struct wide_string_input_helper<BaseInputAdapter, 4>4884{4885// UTF-324886static void fill_buffer(BaseInputAdapter& input,4887std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,4888size_t& utf8_bytes_index,4889size_t& utf8_bytes_filled)4890{4891utf8_bytes_index = 0;48924893if (JSON_HEDLEY_UNLIKELY(input.empty()))4894{4895utf8_bytes[0] = std::char_traits<char>::eof();4896utf8_bytes_filled = 1;4897}4898else4899{4900// get the current character4901const auto wc = input.get_character();49024903// UTF-32 to UTF-8 encoding4904if (wc < 0x80)4905{4906utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);4907utf8_bytes_filled = 1;4908}4909else if (wc <= 0x7FF)4910{4911utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));4912utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));4913utf8_bytes_filled = 2;4914}4915else if (wc <= 0xFFFF)4916{4917utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));4918utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));4919utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));4920utf8_bytes_filled = 3;4921}4922else if (wc <= 0x10FFFF)4923{4924utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));4925utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));4926utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));4927utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));4928utf8_bytes_filled = 4;4929}4930else4931{4932// unknown character4933utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);4934utf8_bytes_filled = 1;4935}4936}4937}4938};49394940template<typename BaseInputAdapter>4941struct wide_string_input_helper<BaseInputAdapter, 2>4942{4943// UTF-164944static void fill_buffer(BaseInputAdapter& input,4945std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,4946size_t& utf8_bytes_index,4947size_t& utf8_bytes_filled)4948{4949utf8_bytes_index = 0;49504951if (JSON_HEDLEY_UNLIKELY(input.empty()))4952{4953utf8_bytes[0] = std::char_traits<char>::eof();4954utf8_bytes_filled = 1;4955}4956else4957{4958// get the current character4959const auto wc = input.get_character();49604961// UTF-16 to UTF-8 encoding4962if (wc < 0x80)4963{4964utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);4965utf8_bytes_filled = 1;4966}4967else if (wc <= 0x7FF)4968{4969utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));4970utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));4971utf8_bytes_filled = 2;4972}4973else if (0xD800 > wc || wc >= 0xE000)4974{4975utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));4976utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));4977utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));4978utf8_bytes_filled = 3;4979}4980else4981{4982if (JSON_HEDLEY_UNLIKELY(!input.empty()))4983{4984const auto wc2 = static_cast<unsigned int>(input.get_character());4985const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));4986utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));4987utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));4988utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));4989utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));4990utf8_bytes_filled = 4;4991}4992else4993{4994utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);4995utf8_bytes_filled = 1;4996}4997}4998}4999}5000};50015002// Wraps another input apdater to convert wide character types into individual bytes.5003template<typename BaseInputAdapter, typename WideCharType>5004class wide_string_input_adapter5005{5006public:5007using char_type = char;50085009wide_string_input_adapter(BaseInputAdapter base)5010: base_adapter(base) {}50115012typename std::char_traits<char>::int_type get_character() noexcept5013{5014// check if buffer needs to be filled5015if (utf8_bytes_index == utf8_bytes_filled)5016{5017fill_buffer<sizeof(WideCharType)>();50185019JSON_ASSERT(utf8_bytes_filled > 0);5020JSON_ASSERT(utf8_bytes_index == 0);5021}50225023// use buffer5024JSON_ASSERT(utf8_bytes_filled > 0);5025JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);5026return utf8_bytes[utf8_bytes_index++];5027}50285029private:5030BaseInputAdapter base_adapter;50315032template<size_t T>5033void fill_buffer()5034{5035wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);5036}50375038/// a buffer for UTF-8 bytes5039std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};50405041/// index to the utf8_codes array for the next valid byte5042std::size_t utf8_bytes_index = 0;5043/// number of valid bytes in the utf8_codes array5044std::size_t utf8_bytes_filled = 0;5045};504650475048template<typename IteratorType, typename Enable = void>5049struct iterator_input_adapter_factory5050{5051using iterator_type = IteratorType;5052using char_type = typename std::iterator_traits<iterator_type>::value_type;5053using adapter_type = iterator_input_adapter<iterator_type>;50545055static adapter_type create(IteratorType first, IteratorType last)5056{5057return adapter_type(std::move(first), std::move(last));5058}5059};50605061template<typename T>5062struct is_iterator_of_multibyte5063{5064using value_type = typename std::iterator_traits<T>::value_type;5065enum5066{5067value = sizeof(value_type) > 15068};5069};50705071template<typename IteratorType>5072struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>5073{5074using iterator_type = IteratorType;5075using char_type = typename std::iterator_traits<iterator_type>::value_type;5076using base_adapter_type = iterator_input_adapter<iterator_type>;5077using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;50785079static adapter_type create(IteratorType first, IteratorType last)5080{5081return adapter_type(base_adapter_type(std::move(first), std::move(last)));5082}5083};50845085// General purpose iterator-based input5086template<typename IteratorType>5087typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)5088{5089using factory_type = iterator_input_adapter_factory<IteratorType>;5090return factory_type::create(first, last);5091}50925093// Convenience shorthand from container to iterator5094template<typename ContainerType>5095auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))5096{5097// Enable ADL5098using std::begin;5099using std::end;51005101return input_adapter(begin(container), end(container));5102}51035104// Special cases with fast paths5105inline file_input_adapter input_adapter(std::FILE* file)5106{5107return file_input_adapter(file);5108}51095110inline input_stream_adapter input_adapter(std::istream& stream)5111{5112return input_stream_adapter(stream);5113}51145115inline input_stream_adapter input_adapter(std::istream&& stream)5116{5117return input_stream_adapter(stream);5118}51195120using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));51215122// Null-delimited strings, and the like.5123template < typename CharT,5124typename std::enable_if <5125std::is_pointer<CharT>::value&&5126!std::is_array<CharT>::value&&5127std::is_integral<typename std::remove_pointer<CharT>::type>::value&&5128sizeof(typename std::remove_pointer<CharT>::type) == 1,5129int >::type = 0 >5130contiguous_bytes_input_adapter input_adapter(CharT b)5131{5132auto length = std::strlen(reinterpret_cast<const char*>(b));5133const auto* ptr = reinterpret_cast<const char*>(b);5134return input_adapter(ptr, ptr + length);5135}51365137template<typename T, std::size_t N>5138auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))5139{5140return input_adapter(array, array + N);5141}51425143// This class only handles inputs of input_buffer_adapter type.5144// It's required so that expressions like {ptr, len} can be implicitely casted5145// to the correct adapter.5146class span_input_adapter5147{5148public:5149template < typename CharT,5150typename std::enable_if <5151std::is_pointer<CharT>::value&&5152std::is_integral<typename std::remove_pointer<CharT>::type>::value&&5153sizeof(typename std::remove_pointer<CharT>::type) == 1,5154int >::type = 0 >5155span_input_adapter(CharT b, std::size_t l)5156: ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}51575158template<class IteratorType,5159typename std::enable_if<5160std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,5161int>::type = 0>5162span_input_adapter(IteratorType first, IteratorType last)5163: ia(input_adapter(first, last)) {}51645165contiguous_bytes_input_adapter&& get()5166{5167return std::move(ia);5168}51695170private:5171contiguous_bytes_input_adapter ia;5172};5173} // namespace detail5174} // namespace nlohmann51755176// #include <nlohmann/detail/input/json_sax.hpp>517751785179#include <cstddef>5180#include <string> // string5181#include <utility> // move5182#include <vector> // vector51835184// #include <nlohmann/detail/exceptions.hpp>51855186// #include <nlohmann/detail/macro_scope.hpp>518751885189namespace nlohmann5190{51915192/*!5193@brief SAX interface51945195This class describes the SAX interface used by @ref nlohmann::json::sax_parse.5196Each function is called in different situations while the input is parsed. The5197boolean return value informs the parser whether to continue processing the5198input.5199*/5200template<typename BasicJsonType>5201struct json_sax5202{5203using number_integer_t = typename BasicJsonType::number_integer_t;5204using number_unsigned_t = typename BasicJsonType::number_unsigned_t;5205using number_float_t = typename BasicJsonType::number_float_t;5206using string_t = typename BasicJsonType::string_t;5207using binary_t = typename BasicJsonType::binary_t;52085209/*!5210@brief a null value was read5211@return whether parsing should proceed5212*/5213virtual bool null() = 0;52145215/*!5216@brief a boolean value was read5217@param[in] val boolean value5218@return whether parsing should proceed5219*/5220virtual bool boolean(bool val) = 0;52215222/*!5223@brief an integer number was read5224@param[in] val integer value5225@return whether parsing should proceed5226*/5227virtual bool number_integer(number_integer_t val) = 0;52285229/*!5230@brief an unsigned integer number was read5231@param[in] val unsigned integer value5232@return whether parsing should proceed5233*/5234virtual bool number_unsigned(number_unsigned_t val) = 0;52355236/*!5237@brief an floating-point number was read5238@param[in] val floating-point value5239@param[in] s raw token value5240@return whether parsing should proceed5241*/5242virtual bool number_float(number_float_t val, const string_t& s) = 0;52435244/*!5245@brief a string was read5246@param[in] val string value5247@return whether parsing should proceed5248@note It is safe to move the passed string.5249*/5250virtual bool string(string_t& val) = 0;52515252/*!5253@brief a binary string was read5254@param[in] val binary value5255@return whether parsing should proceed5256@note It is safe to move the passed binary.5257*/5258virtual bool binary(binary_t& val) = 0;52595260/*!5261@brief the beginning of an object was read5262@param[in] elements number of object elements or -1 if unknown5263@return whether parsing should proceed5264@note binary formats may report the number of elements5265*/5266virtual bool start_object(std::size_t elements) = 0;52675268/*!5269@brief an object key was read5270@param[in] val object key5271@return whether parsing should proceed5272@note It is safe to move the passed string.5273*/5274virtual bool key(string_t& val) = 0;52755276/*!5277@brief the end of an object was read5278@return whether parsing should proceed5279*/5280virtual bool end_object() = 0;52815282/*!5283@brief the beginning of an array was read5284@param[in] elements number of array elements or -1 if unknown5285@return whether parsing should proceed5286@note binary formats may report the number of elements5287*/5288virtual bool start_array(std::size_t elements) = 0;52895290/*!5291@brief the end of an array was read5292@return whether parsing should proceed5293*/5294virtual bool end_array() = 0;52955296/*!5297@brief a parse error occurred5298@param[in] position the position in the input where the error occurs5299@param[in] last_token the last read token5300@param[in] ex an exception object describing the error5301@return whether parsing should proceed (must return false)5302*/5303virtual bool parse_error(std::size_t position,5304const std::string& last_token,5305const detail::exception& ex) = 0;53065307virtual ~json_sax() = default;5308};530953105311namespace detail5312{5313/*!5314@brief SAX implementation to create a JSON value from SAX events53155316This class implements the @ref json_sax interface and processes the SAX events5317to create a JSON value which makes it basically a DOM parser. The structure or5318hierarchy of the JSON value is managed by the stack `ref_stack` which contains5319a pointer to the respective array or object for each recursion depth.53205321After successful parsing, the value that is passed by reference to the5322constructor contains the parsed value.53235324@tparam BasicJsonType the JSON type5325*/5326template<typename BasicJsonType>5327class json_sax_dom_parser5328{5329public:5330using number_integer_t = typename BasicJsonType::number_integer_t;5331using number_unsigned_t = typename BasicJsonType::number_unsigned_t;5332using number_float_t = typename BasicJsonType::number_float_t;5333using string_t = typename BasicJsonType::string_t;5334using binary_t = typename BasicJsonType::binary_t;53355336/*!5337@param[in, out] r reference to a JSON value that is manipulated while5338parsing5339@param[in] allow_exceptions_ whether parse errors yield exceptions5340*/5341explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)5342: root(r), allow_exceptions(allow_exceptions_)5343{}53445345// make class move-only5346json_sax_dom_parser(const json_sax_dom_parser&) = delete;5347json_sax_dom_parser(json_sax_dom_parser&&) = default;5348json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;5349json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;5350~json_sax_dom_parser() = default;53515352bool null()5353{5354handle_value(nullptr);5355return true;5356}53575358bool boolean(bool val)5359{5360handle_value(val);5361return true;5362}53635364bool number_integer(number_integer_t val)5365{5366handle_value(val);5367return true;5368}53695370bool number_unsigned(number_unsigned_t val)5371{5372handle_value(val);5373return true;5374}53755376bool number_float(number_float_t val, const string_t& /*unused*/)5377{5378handle_value(val);5379return true;5380}53815382bool string(string_t& val)5383{5384handle_value(val);5385return true;5386}53875388bool binary(binary_t& val)5389{5390handle_value(std::move(val));5391return true;5392}53935394bool start_object(std::size_t len)5395{5396ref_stack.push_back(handle_value(BasicJsonType::value_t::object));53975398if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))5399{5400JSON_THROW(out_of_range::create(408,5401"excessive object size: " + std::to_string(len)));5402}54035404return true;5405}54065407bool key(string_t& val)5408{5409// add null at given key and store the reference for later5410object_element = &(ref_stack.back()->m_value.object->operator[](val));5411return true;5412}54135414bool end_object()5415{5416ref_stack.pop_back();5417return true;5418}54195420bool start_array(std::size_t len)5421{5422ref_stack.push_back(handle_value(BasicJsonType::value_t::array));54235424if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))5425{5426JSON_THROW(out_of_range::create(408,5427"excessive array size: " + std::to_string(len)));5428}54295430return true;5431}54325433bool end_array()5434{5435ref_stack.pop_back();5436return true;5437}54385439template<class Exception>5440bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,5441const Exception& ex)5442{5443errored = true;5444static_cast<void>(ex);5445if (allow_exceptions)5446{5447JSON_THROW(ex);5448}5449return false;5450}54515452constexpr bool is_errored() const5453{5454return errored;5455}54565457private:5458/*!5459@invariant If the ref stack is empty, then the passed value will be the new5460root.5461@invariant If the ref stack contains a value, then it is an array or an5462object to which we can add elements5463*/5464template<typename Value>5465JSON_HEDLEY_RETURNS_NON_NULL5466BasicJsonType* handle_value(Value&& v)5467{5468if (ref_stack.empty())5469{5470root = BasicJsonType(std::forward<Value>(v));5471return &root;5472}54735474JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());54755476if (ref_stack.back()->is_array())5477{5478ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));5479return &(ref_stack.back()->m_value.array->back());5480}54815482JSON_ASSERT(ref_stack.back()->is_object());5483JSON_ASSERT(object_element);5484*object_element = BasicJsonType(std::forward<Value>(v));5485return object_element;5486}54875488/// the parsed JSON value5489BasicJsonType& root;5490/// stack to model hierarchy of values5491std::vector<BasicJsonType*> ref_stack {};5492/// helper to hold the reference for the next object element5493BasicJsonType* object_element = nullptr;5494/// whether a syntax error occurred5495bool errored = false;5496/// whether to throw exceptions in case of errors5497const bool allow_exceptions = false;5498};54995500template<typename BasicJsonType>5501class json_sax_dom_callback_parser5502{5503public:5504using number_integer_t = typename BasicJsonType::number_integer_t;5505using number_unsigned_t = typename BasicJsonType::number_unsigned_t;5506using number_float_t = typename BasicJsonType::number_float_t;5507using string_t = typename BasicJsonType::string_t;5508using binary_t = typename BasicJsonType::binary_t;5509using parser_callback_t = typename BasicJsonType::parser_callback_t;5510using parse_event_t = typename BasicJsonType::parse_event_t;55115512json_sax_dom_callback_parser(BasicJsonType& r,5513const parser_callback_t cb,5514const bool allow_exceptions_ = true)5515: root(r), callback(cb), allow_exceptions(allow_exceptions_)5516{5517keep_stack.push_back(true);5518}55195520// make class move-only5521json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;5522json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;5523json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;5524json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;5525~json_sax_dom_callback_parser() = default;55265527bool null()5528{5529handle_value(nullptr);5530return true;5531}55325533bool boolean(bool val)5534{5535handle_value(val);5536return true;5537}55385539bool number_integer(number_integer_t val)5540{5541handle_value(val);5542return true;5543}55445545bool number_unsigned(number_unsigned_t val)5546{5547handle_value(val);5548return true;5549}55505551bool number_float(number_float_t val, const string_t& /*unused*/)5552{5553handle_value(val);5554return true;5555}55565557bool string(string_t& val)5558{5559handle_value(val);5560return true;5561}55625563bool binary(binary_t& val)5564{5565handle_value(std::move(val));5566return true;5567}55685569bool start_object(std::size_t len)5570{5571// check callback for object start5572const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);5573keep_stack.push_back(keep);55745575auto val = handle_value(BasicJsonType::value_t::object, true);5576ref_stack.push_back(val.second);55775578// check object limit5579if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))5580{5581JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));5582}55835584return true;5585}55865587bool key(string_t& val)5588{5589BasicJsonType k = BasicJsonType(val);55905591// check callback for key5592const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);5593key_keep_stack.push_back(keep);55945595// add discarded value at given key and store the reference for later5596if (keep && ref_stack.back())5597{5598object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);5599}56005601return true;5602}56035604bool end_object()5605{5606if (ref_stack.back() && !callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))5607{5608// discard object5609*ref_stack.back() = discarded;5610}56115612JSON_ASSERT(!ref_stack.empty());5613JSON_ASSERT(!keep_stack.empty());5614ref_stack.pop_back();5615keep_stack.pop_back();56165617if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())5618{5619// remove discarded value5620for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)5621{5622if (it->is_discarded())5623{5624ref_stack.back()->erase(it);5625break;5626}5627}5628}56295630return true;5631}56325633bool start_array(std::size_t len)5634{5635const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);5636keep_stack.push_back(keep);56375638auto val = handle_value(BasicJsonType::value_t::array, true);5639ref_stack.push_back(val.second);56405641// check array limit5642if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))5643{5644JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));5645}56465647return true;5648}56495650bool end_array()5651{5652bool keep = true;56535654if (ref_stack.back())5655{5656keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());5657if (!keep)5658{5659// discard array5660*ref_stack.back() = discarded;5661}5662}56635664JSON_ASSERT(!ref_stack.empty());5665JSON_ASSERT(!keep_stack.empty());5666ref_stack.pop_back();5667keep_stack.pop_back();56685669// remove discarded value5670if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())5671{5672ref_stack.back()->m_value.array->pop_back();5673}56745675return true;5676}56775678template<class Exception>5679bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,5680const Exception& ex)5681{5682errored = true;5683static_cast<void>(ex);5684if (allow_exceptions)5685{5686JSON_THROW(ex);5687}5688return false;5689}56905691constexpr bool is_errored() const5692{5693return errored;5694}56955696private:5697/*!5698@param[in] v value to add to the JSON value we build during parsing5699@param[in] skip_callback whether we should skip calling the callback5700function; this is required after start_array() and5701start_object() SAX events, because otherwise we would call the5702callback function with an empty array or object, respectively.57035704@invariant If the ref stack is empty, then the passed value will be the new5705root.5706@invariant If the ref stack contains a value, then it is an array or an5707object to which we can add elements57085709@return pair of boolean (whether value should be kept) and pointer (to the5710passed value in the ref_stack hierarchy; nullptr if not kept)5711*/5712template<typename Value>5713std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)5714{5715JSON_ASSERT(!keep_stack.empty());57165717// do not handle this value if we know it would be added to a discarded5718// container5719if (!keep_stack.back())5720{5721return {false, nullptr};5722}57235724// create value5725auto value = BasicJsonType(std::forward<Value>(v));57265727// check callback5728const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);57295730// do not handle this value if we just learnt it shall be discarded5731if (!keep)5732{5733return {false, nullptr};5734}57355736if (ref_stack.empty())5737{5738root = std::move(value);5739return {true, &root};5740}57415742// skip this value if we already decided to skip the parent5743// (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)5744if (!ref_stack.back())5745{5746return {false, nullptr};5747}57485749// we now only expect arrays and objects5750JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());57515752// array5753if (ref_stack.back()->is_array())5754{5755ref_stack.back()->m_value.array->push_back(std::move(value));5756return {true, &(ref_stack.back()->m_value.array->back())};5757}57585759// object5760JSON_ASSERT(ref_stack.back()->is_object());5761// check if we should store an element for the current key5762JSON_ASSERT(!key_keep_stack.empty());5763const bool store_element = key_keep_stack.back();5764key_keep_stack.pop_back();57655766if (!store_element)5767{5768return {false, nullptr};5769}57705771JSON_ASSERT(object_element);5772*object_element = std::move(value);5773return {true, object_element};5774}57755776/// the parsed JSON value5777BasicJsonType& root;5778/// stack to model hierarchy of values5779std::vector<BasicJsonType*> ref_stack {};5780/// stack to manage which values to keep5781std::vector<bool> keep_stack {};5782/// stack to manage which object keys to keep5783std::vector<bool> key_keep_stack {};5784/// helper to hold the reference for the next object element5785BasicJsonType* object_element = nullptr;5786/// whether a syntax error occurred5787bool errored = false;5788/// callback function5789const parser_callback_t callback = nullptr;5790/// whether to throw exceptions in case of errors5791const bool allow_exceptions = true;5792/// a discarded value for the callback5793BasicJsonType discarded = BasicJsonType::value_t::discarded;5794};57955796template<typename BasicJsonType>5797class json_sax_acceptor5798{5799public:5800using number_integer_t = typename BasicJsonType::number_integer_t;5801using number_unsigned_t = typename BasicJsonType::number_unsigned_t;5802using number_float_t = typename BasicJsonType::number_float_t;5803using string_t = typename BasicJsonType::string_t;5804using binary_t = typename BasicJsonType::binary_t;58055806bool null()5807{5808return true;5809}58105811bool boolean(bool /*unused*/)5812{5813return true;5814}58155816bool number_integer(number_integer_t /*unused*/)5817{5818return true;5819}58205821bool number_unsigned(number_unsigned_t /*unused*/)5822{5823return true;5824}58255826bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)5827{5828return true;5829}58305831bool string(string_t& /*unused*/)5832{5833return true;5834}58355836bool binary(binary_t& /*unused*/)5837{5838return true;5839}58405841bool start_object(std::size_t /*unused*/ = std::size_t(-1))5842{5843return true;5844}58455846bool key(string_t& /*unused*/)5847{5848return true;5849}58505851bool end_object()5852{5853return true;5854}58555856bool start_array(std::size_t /*unused*/ = std::size_t(-1))5857{5858return true;5859}58605861bool end_array()5862{5863return true;5864}58655866bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)5867{5868return false;5869}5870};5871} // namespace detail58725873} // namespace nlohmann58745875// #include <nlohmann/detail/input/lexer.hpp>587658775878#include <array> // array5879#include <clocale> // localeconv5880#include <cstddef> // size_t5881#include <cstdio> // snprintf5882#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull5883#include <initializer_list> // initializer_list5884#include <string> // char_traits, string5885#include <utility> // move5886#include <vector> // vector58875888// #include <nlohmann/detail/input/input_adapters.hpp>58895890// #include <nlohmann/detail/input/position_t.hpp>58915892// #include <nlohmann/detail/macro_scope.hpp>589358945895namespace nlohmann5896{5897namespace detail5898{5899///////////5900// lexer //5901///////////59025903template<typename BasicJsonType>5904class lexer_base5905{5906public:5907/// token types for the parser5908enum class token_type5909{5910uninitialized, ///< indicating the scanner is uninitialized5911literal_true, ///< the `true` literal5912literal_false, ///< the `false` literal5913literal_null, ///< the `null` literal5914value_string, ///< a string -- use get_string() for actual value5915value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value5916value_integer, ///< a signed integer -- use get_number_integer() for actual value5917value_float, ///< an floating point number -- use get_number_float() for actual value5918begin_array, ///< the character for array begin `[`5919begin_object, ///< the character for object begin `{`5920end_array, ///< the character for array end `]`5921end_object, ///< the character for object end `}`5922name_separator, ///< the name separator `:`5923value_separator, ///< the value separator `,`5924parse_error, ///< indicating a parse error5925end_of_input, ///< indicating the end of the input buffer5926literal_or_value ///< a literal or the begin of a value (only for diagnostics)5927};59285929/// return name of values of type token_type (only used for errors)5930JSON_HEDLEY_RETURNS_NON_NULL5931JSON_HEDLEY_CONST5932static const char* token_type_name(const token_type t) noexcept5933{5934switch (t)5935{5936case token_type::uninitialized:5937return "<uninitialized>";5938case token_type::literal_true:5939return "true literal";5940case token_type::literal_false:5941return "false literal";5942case token_type::literal_null:5943return "null literal";5944case token_type::value_string:5945return "string literal";5946case token_type::value_unsigned:5947case token_type::value_integer:5948case token_type::value_float:5949return "number literal";5950case token_type::begin_array:5951return "'['";5952case token_type::begin_object:5953return "'{'";5954case token_type::end_array:5955return "']'";5956case token_type::end_object:5957return "'}'";5958case token_type::name_separator:5959return "':'";5960case token_type::value_separator:5961return "','";5962case token_type::parse_error:5963return "<parse error>";5964case token_type::end_of_input:5965return "end of input";5966case token_type::literal_or_value:5967return "'[', '{', or a literal";5968// LCOV_EXCL_START5969default: // catch non-enum values5970return "unknown token";5971// LCOV_EXCL_STOP5972}5973}5974};5975/*!5976@brief lexical analysis59775978This class organizes the lexical analysis during JSON deserialization.5979*/5980template<typename BasicJsonType, typename InputAdapterType>5981class lexer : public lexer_base<BasicJsonType>5982{5983using number_integer_t = typename BasicJsonType::number_integer_t;5984using number_unsigned_t = typename BasicJsonType::number_unsigned_t;5985using number_float_t = typename BasicJsonType::number_float_t;5986using string_t = typename BasicJsonType::string_t;5987using char_type = typename InputAdapterType::char_type;5988using char_int_type = typename std::char_traits<char_type>::int_type;59895990public:5991using token_type = typename lexer_base<BasicJsonType>::token_type;59925993explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false)5994: ia(std::move(adapter))5995, ignore_comments(ignore_comments_)5996, decimal_point_char(static_cast<char_int_type>(get_decimal_point()))5997{}59985999// delete because of pointer members6000lexer(const lexer&) = delete;6001lexer(lexer&&) = default;6002lexer& operator=(lexer&) = delete;6003lexer& operator=(lexer&&) = default;6004~lexer() = default;60056006private:6007/////////////////////6008// locales6009/////////////////////60106011/// return the locale-dependent decimal point6012JSON_HEDLEY_PURE6013static char get_decimal_point() noexcept6014{6015const auto* loc = localeconv();6016JSON_ASSERT(loc != nullptr);6017return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);6018}60196020/////////////////////6021// scan functions6022/////////////////////60236024/*!6025@brief get codepoint from 4 hex characters following `\u`60266027For input "\u c1 c2 c3 c4" the codepoint is:6028(c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c46029= (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)60306031Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'6032must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The6033conversion is done by subtracting the offset (0x30, 0x37, and 0x57)6034between the ASCII value of the character and the desired integer value.60356036@return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or6037non-hex character)6038*/6039int get_codepoint()6040{6041// this function only makes sense after reading `\u`6042JSON_ASSERT(current == 'u');6043int codepoint = 0;60446045const auto factors = { 12u, 8u, 4u, 0u };6046for (const auto factor : factors)6047{6048get();60496050if (current >= '0' && current <= '9')6051{6052codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);6053}6054else if (current >= 'A' && current <= 'F')6055{6056codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);6057}6058else if (current >= 'a' && current <= 'f')6059{6060codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);6061}6062else6063{6064return -1;6065}6066}60676068JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);6069return codepoint;6070}60716072/*!6073@brief check if the next byte(s) are inside a given range60746075Adds the current byte and, for each passed range, reads a new byte and6076checks if it is inside the range. If a violation was detected, set up an6077error message and return false. Otherwise, return true.60786079@param[in] ranges list of integers; interpreted as list of pairs of6080inclusive lower and upper bound, respectively60816082@pre The passed list @a ranges must have 2, 4, or 6 elements; that is,60831, 2, or 3 pairs. This precondition is enforced by an assertion.60846085@return true if and only if no range violation was detected6086*/6087bool next_byte_in_range(std::initializer_list<char_int_type> ranges)6088{6089JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);6090add(current);60916092for (auto range = ranges.begin(); range != ranges.end(); ++range)6093{6094get();6095if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))6096{6097add(current);6098}6099else6100{6101error_message = "invalid string: ill-formed UTF-8 byte";6102return false;6103}6104}61056106return true;6107}61086109/*!6110@brief scan a string literal61116112This function scans a string according to Sect. 7 of RFC 7159. While6113scanning, bytes are escaped and copied into buffer token_buffer. Then the6114function returns successfully, token_buffer is *not* null-terminated (as it6115may contain \0 bytes), and token_buffer.size() is the number of bytes in the6116string.61176118@return token_type::value_string if string could be successfully scanned,6119token_type::parse_error otherwise61206121@note In case of errors, variable error_message contains a textual6122description.6123*/6124token_type scan_string()6125{6126// reset token_buffer (ignore opening quote)6127reset();61286129// we entered the function by reading an open quote6130JSON_ASSERT(current == '\"');61316132while (true)6133{6134// get next character6135switch (get())6136{6137// end of file while parsing string6138case std::char_traits<char_type>::eof():6139{6140error_message = "invalid string: missing closing quote";6141return token_type::parse_error;6142}61436144// closing quote6145case '\"':6146{6147return token_type::value_string;6148}61496150// escapes6151case '\\':6152{6153switch (get())6154{6155// quotation mark6156case '\"':6157add('\"');6158break;6159// reverse solidus6160case '\\':6161add('\\');6162break;6163// solidus6164case '/':6165add('/');6166break;6167// backspace6168case 'b':6169add('\b');6170break;6171// form feed6172case 'f':6173add('\f');6174break;6175// line feed6176case 'n':6177add('\n');6178break;6179// carriage return6180case 'r':6181add('\r');6182break;6183// tab6184case 't':6185add('\t');6186break;61876188// unicode escapes6189case 'u':6190{6191const int codepoint1 = get_codepoint();6192int codepoint = codepoint1; // start with codepoint161936194if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))6195{6196error_message = "invalid string: '\\u' must be followed by 4 hex digits";6197return token_type::parse_error;6198}61996200// check if code point is a high surrogate6201if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)6202{6203// expect next \uxxxx entry6204if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))6205{6206const int codepoint2 = get_codepoint();62076208if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))6209{6210error_message = "invalid string: '\\u' must be followed by 4 hex digits";6211return token_type::parse_error;6212}62136214// check if codepoint2 is a low surrogate6215if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))6216{6217// overwrite codepoint6218codepoint = static_cast<int>(6219// high surrogate occupies the most significant 22 bits6220(static_cast<unsigned int>(codepoint1) << 10u)6221// low surrogate occupies the least significant 15 bits6222+ static_cast<unsigned int>(codepoint2)6223// there is still the 0xD800, 0xDC00 and 0x10000 noise6224// in the result so we have to subtract with:6225// (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC006226- 0x35FDC00u);6227}6228else6229{6230error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";6231return token_type::parse_error;6232}6233}6234else6235{6236error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";6237return token_type::parse_error;6238}6239}6240else6241{6242if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))6243{6244error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";6245return token_type::parse_error;6246}6247}62486249// result of the above calculation yields a proper codepoint6250JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);62516252// translate codepoint into bytes6253if (codepoint < 0x80)6254{6255// 1-byte characters: 0xxxxxxx (ASCII)6256add(static_cast<char_int_type>(codepoint));6257}6258else if (codepoint <= 0x7FF)6259{6260// 2-byte characters: 110xxxxx 10xxxxxx6261add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));6262add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));6263}6264else if (codepoint <= 0xFFFF)6265{6266// 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx6267add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));6268add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));6269add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));6270}6271else6272{6273// 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx6274add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));6275add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));6276add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));6277add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));6278}62796280break;6281}62826283// other characters after escape6284default:6285error_message = "invalid string: forbidden character after backslash";6286return token_type::parse_error;6287}62886289break;6290}62916292// invalid control characters6293case 0x00:6294{6295error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";6296return token_type::parse_error;6297}62986299case 0x01:6300{6301error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";6302return token_type::parse_error;6303}63046305case 0x02:6306{6307error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";6308return token_type::parse_error;6309}63106311case 0x03:6312{6313error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";6314return token_type::parse_error;6315}63166317case 0x04:6318{6319error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";6320return token_type::parse_error;6321}63226323case 0x05:6324{6325error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";6326return token_type::parse_error;6327}63286329case 0x06:6330{6331error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";6332return token_type::parse_error;6333}63346335case 0x07:6336{6337error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";6338return token_type::parse_error;6339}63406341case 0x08:6342{6343error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";6344return token_type::parse_error;6345}63466347case 0x09:6348{6349error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";6350return token_type::parse_error;6351}63526353case 0x0A:6354{6355error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";6356return token_type::parse_error;6357}63586359case 0x0B:6360{6361error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";6362return token_type::parse_error;6363}63646365case 0x0C:6366{6367error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";6368return token_type::parse_error;6369}63706371case 0x0D:6372{6373error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";6374return token_type::parse_error;6375}63766377case 0x0E:6378{6379error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";6380return token_type::parse_error;6381}63826383case 0x0F:6384{6385error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";6386return token_type::parse_error;6387}63886389case 0x10:6390{6391error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";6392return token_type::parse_error;6393}63946395case 0x11:6396{6397error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";6398return token_type::parse_error;6399}64006401case 0x12:6402{6403error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";6404return token_type::parse_error;6405}64066407case 0x13:6408{6409error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";6410return token_type::parse_error;6411}64126413case 0x14:6414{6415error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";6416return token_type::parse_error;6417}64186419case 0x15:6420{6421error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";6422return token_type::parse_error;6423}64246425case 0x16:6426{6427error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";6428return token_type::parse_error;6429}64306431case 0x17:6432{6433error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";6434return token_type::parse_error;6435}64366437case 0x18:6438{6439error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";6440return token_type::parse_error;6441}64426443case 0x19:6444{6445error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";6446return token_type::parse_error;6447}64486449case 0x1A:6450{6451error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";6452return token_type::parse_error;6453}64546455case 0x1B:6456{6457error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";6458return token_type::parse_error;6459}64606461case 0x1C:6462{6463error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";6464return token_type::parse_error;6465}64666467case 0x1D:6468{6469error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";6470return token_type::parse_error;6471}64726473case 0x1E:6474{6475error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";6476return token_type::parse_error;6477}64786479case 0x1F:6480{6481error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";6482return token_type::parse_error;6483}64846485// U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))6486case 0x20:6487case 0x21:6488case 0x23:6489case 0x24:6490case 0x25:6491case 0x26:6492case 0x27:6493case 0x28:6494case 0x29:6495case 0x2A:6496case 0x2B:6497case 0x2C:6498case 0x2D:6499case 0x2E:6500case 0x2F:6501case 0x30:6502case 0x31:6503case 0x32:6504case 0x33:6505case 0x34:6506case 0x35:6507case 0x36:6508case 0x37:6509case 0x38:6510case 0x39:6511case 0x3A:6512case 0x3B:6513case 0x3C:6514case 0x3D:6515case 0x3E:6516case 0x3F:6517case 0x40:6518case 0x41:6519case 0x42:6520case 0x43:6521case 0x44:6522case 0x45:6523case 0x46:6524case 0x47:6525case 0x48:6526case 0x49:6527case 0x4A:6528case 0x4B:6529case 0x4C:6530case 0x4D:6531case 0x4E:6532case 0x4F:6533case 0x50:6534case 0x51:6535case 0x52:6536case 0x53:6537case 0x54:6538case 0x55:6539case 0x56:6540case 0x57:6541case 0x58:6542case 0x59:6543case 0x5A:6544case 0x5B:6545case 0x5D:6546case 0x5E:6547case 0x5F:6548case 0x60:6549case 0x61:6550case 0x62:6551case 0x63:6552case 0x64:6553case 0x65:6554case 0x66:6555case 0x67:6556case 0x68:6557case 0x69:6558case 0x6A:6559case 0x6B:6560case 0x6C:6561case 0x6D:6562case 0x6E:6563case 0x6F:6564case 0x70:6565case 0x71:6566case 0x72:6567case 0x73:6568case 0x74:6569case 0x75:6570case 0x76:6571case 0x77:6572case 0x78:6573case 0x79:6574case 0x7A:6575case 0x7B:6576case 0x7C:6577case 0x7D:6578case 0x7E:6579case 0x7F:6580{6581add(current);6582break;6583}65846585// U+0080..U+07FF: bytes C2..DF 80..BF6586case 0xC2:6587case 0xC3:6588case 0xC4:6589case 0xC5:6590case 0xC6:6591case 0xC7:6592case 0xC8:6593case 0xC9:6594case 0xCA:6595case 0xCB:6596case 0xCC:6597case 0xCD:6598case 0xCE:6599case 0xCF:6600case 0xD0:6601case 0xD1:6602case 0xD2:6603case 0xD3:6604case 0xD4:6605case 0xD5:6606case 0xD6:6607case 0xD7:6608case 0xD8:6609case 0xD9:6610case 0xDA:6611case 0xDB:6612case 0xDC:6613case 0xDD:6614case 0xDE:6615case 0xDF:6616{6617if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))6618{6619return token_type::parse_error;6620}6621break;6622}66236624// U+0800..U+0FFF: bytes E0 A0..BF 80..BF6625case 0xE0:6626{6627if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))6628{6629return token_type::parse_error;6630}6631break;6632}66336634// U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF6635// U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF6636case 0xE1:6637case 0xE2:6638case 0xE3:6639case 0xE4:6640case 0xE5:6641case 0xE6:6642case 0xE7:6643case 0xE8:6644case 0xE9:6645case 0xEA:6646case 0xEB:6647case 0xEC:6648case 0xEE:6649case 0xEF:6650{6651if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))6652{6653return token_type::parse_error;6654}6655break;6656}66576658// U+D000..U+D7FF: bytes ED 80..9F 80..BF6659case 0xED:6660{6661if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))6662{6663return token_type::parse_error;6664}6665break;6666}66676668// U+10000..U+3FFFF F0 90..BF 80..BF 80..BF6669case 0xF0:6670{6671if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))6672{6673return token_type::parse_error;6674}6675break;6676}66776678// U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF6679case 0xF1:6680case 0xF2:6681case 0xF3:6682{6683if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))6684{6685return token_type::parse_error;6686}6687break;6688}66896690// U+100000..U+10FFFF F4 80..8F 80..BF 80..BF6691case 0xF4:6692{6693if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))6694{6695return token_type::parse_error;6696}6697break;6698}66996700// remaining bytes (80..C1 and F5..FF) are ill-formed6701default:6702{6703error_message = "invalid string: ill-formed UTF-8 byte";6704return token_type::parse_error;6705}6706}6707}6708}67096710/*!6711* @brief scan a comment6712* @return whether comment could be scanned successfully6713*/6714bool scan_comment()6715{6716switch (get())6717{6718// single-line comments skip input until a newline or EOF is read6719case '/':6720{6721while (true)6722{6723switch (get())6724{6725case '\n':6726case '\r':6727case std::char_traits<char_type>::eof():6728case '\0':6729return true;67306731default:6732break;6733}6734}6735}67366737// multi-line comments skip input until */ is read6738case '*':6739{6740while (true)6741{6742switch (get())6743{6744case std::char_traits<char_type>::eof():6745case '\0':6746{6747error_message = "invalid comment; missing closing '*/'";6748return false;6749}67506751case '*':6752{6753switch (get())6754{6755case '/':6756return true;67576758default:6759{6760unget();6761continue;6762}6763}6764}67656766default:6767continue;6768}6769}6770}67716772// unexpected character after reading '/'6773default:6774{6775error_message = "invalid comment; expecting '/' or '*' after '/'";6776return false;6777}6778}6779}67806781JSON_HEDLEY_NON_NULL(2)6782static void strtof(float& f, const char* str, char** endptr) noexcept6783{6784f = std::strtof(str, endptr);6785}67866787JSON_HEDLEY_NON_NULL(2)6788static void strtof(double& f, const char* str, char** endptr) noexcept6789{6790f = std::strtod(str, endptr);6791}67926793JSON_HEDLEY_NON_NULL(2)6794static void strtof(long double& f, const char* str, char** endptr) noexcept6795{6796f = std::strtold(str, endptr);6797}67986799/*!6800@brief scan a number literal68016802This function scans a string according to Sect. 6 of RFC 7159.68036804The function is realized with a deterministic finite state machine derived6805from the grammar described in RFC 7159. Starting in state "init", the6806input is read and used to determined the next state. Only state "done"6807accepts the number. State "error" is a trap state to model errors. In the6808table below, "anything" means any character but the ones listed before.68096810state | 0 | 1-9 | e E | + | - | . | anything6811---------|----------|----------|----------|---------|---------|----------|-----------6812init | zero | any1 | [error] | [error] | minus | [error] | [error]6813minus | zero | any1 | [error] | [error] | [error] | [error] | [error]6814zero | done | done | exponent | done | done | decimal1 | done6815any1 | any1 | any1 | exponent | done | done | decimal1 | done6816decimal1 | decimal2 | decimal2 | [error] | [error] | [error] | [error] | [error]6817decimal2 | decimal2 | decimal2 | exponent | done | done | done | done6818exponent | any2 | any2 | [error] | sign | sign | [error] | [error]6819sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]6820any2 | any2 | any2 | done | done | done | done | done68216822The state machine is realized with one label per state (prefixed with6823"scan_number_") and `goto` statements between them. The state machine6824contains cycles, but any cycle can be left when EOF is read. Therefore,6825the function is guaranteed to terminate.68266827During scanning, the read bytes are stored in token_buffer. This string is6828then converted to a signed integer, an unsigned integer, or a6829floating-point number.68306831@return token_type::value_unsigned, token_type::value_integer, or6832token_type::value_float if number could be successfully scanned,6833token_type::parse_error otherwise68346835@note The scanner is independent of the current locale. Internally, the6836locale's decimal point is used instead of `.` to work with the6837locale-dependent converters.6838*/6839token_type scan_number() // lgtm [cpp/use-of-goto]6840{6841// reset token_buffer to store the number's bytes6842reset();68436844// the type of the parsed number; initially set to unsigned; will be6845// changed if minus sign, decimal point or exponent is read6846token_type number_type = token_type::value_unsigned;68476848// state (init): we just found out we need to scan a number6849switch (current)6850{6851case '-':6852{6853add(current);6854goto scan_number_minus;6855}68566857case '0':6858{6859add(current);6860goto scan_number_zero;6861}68626863case '1':6864case '2':6865case '3':6866case '4':6867case '5':6868case '6':6869case '7':6870case '8':6871case '9':6872{6873add(current);6874goto scan_number_any1;6875}68766877// all other characters are rejected outside scan_number()6878default: // LCOV_EXCL_LINE6879JSON_ASSERT(false); // LCOV_EXCL_LINE6880}68816882scan_number_minus:6883// state: we just parsed a leading minus sign6884number_type = token_type::value_integer;6885switch (get())6886{6887case '0':6888{6889add(current);6890goto scan_number_zero;6891}68926893case '1':6894case '2':6895case '3':6896case '4':6897case '5':6898case '6':6899case '7':6900case '8':6901case '9':6902{6903add(current);6904goto scan_number_any1;6905}69066907default:6908{6909error_message = "invalid number; expected digit after '-'";6910return token_type::parse_error;6911}6912}69136914scan_number_zero:6915// state: we just parse a zero (maybe with a leading minus sign)6916switch (get())6917{6918case '.':6919{6920add(decimal_point_char);6921goto scan_number_decimal1;6922}69236924case 'e':6925case 'E':6926{6927add(current);6928goto scan_number_exponent;6929}69306931default:6932goto scan_number_done;6933}69346935scan_number_any1:6936// state: we just parsed a number 0-9 (maybe with a leading minus sign)6937switch (get())6938{6939case '0':6940case '1':6941case '2':6942case '3':6943case '4':6944case '5':6945case '6':6946case '7':6947case '8':6948case '9':6949{6950add(current);6951goto scan_number_any1;6952}69536954case '.':6955{6956add(decimal_point_char);6957goto scan_number_decimal1;6958}69596960case 'e':6961case 'E':6962{6963add(current);6964goto scan_number_exponent;6965}69666967default:6968goto scan_number_done;6969}69706971scan_number_decimal1:6972// state: we just parsed a decimal point6973number_type = token_type::value_float;6974switch (get())6975{6976case '0':6977case '1':6978case '2':6979case '3':6980case '4':6981case '5':6982case '6':6983case '7':6984case '8':6985case '9':6986{6987add(current);6988goto scan_number_decimal2;6989}69906991default:6992{6993error_message = "invalid number; expected digit after '.'";6994return token_type::parse_error;6995}6996}69976998scan_number_decimal2:6999// we just parsed at least one number after a decimal point7000switch (get())7001{7002case '0':7003case '1':7004case '2':7005case '3':7006case '4':7007case '5':7008case '6':7009case '7':7010case '8':7011case '9':7012{7013add(current);7014goto scan_number_decimal2;7015}70167017case 'e':7018case 'E':7019{7020add(current);7021goto scan_number_exponent;7022}70237024default:7025goto scan_number_done;7026}70277028scan_number_exponent:7029// we just parsed an exponent7030number_type = token_type::value_float;7031switch (get())7032{7033case '+':7034case '-':7035{7036add(current);7037goto scan_number_sign;7038}70397040case '0':7041case '1':7042case '2':7043case '3':7044case '4':7045case '5':7046case '6':7047case '7':7048case '8':7049case '9':7050{7051add(current);7052goto scan_number_any2;7053}70547055default:7056{7057error_message =7058"invalid number; expected '+', '-', or digit after exponent";7059return token_type::parse_error;7060}7061}70627063scan_number_sign:7064// we just parsed an exponent sign7065switch (get())7066{7067case '0':7068case '1':7069case '2':7070case '3':7071case '4':7072case '5':7073case '6':7074case '7':7075case '8':7076case '9':7077{7078add(current);7079goto scan_number_any2;7080}70817082default:7083{7084error_message = "invalid number; expected digit after exponent sign";7085return token_type::parse_error;7086}7087}70887089scan_number_any2:7090// we just parsed a number after the exponent or exponent sign7091switch (get())7092{7093case '0':7094case '1':7095case '2':7096case '3':7097case '4':7098case '5':7099case '6':7100case '7':7101case '8':7102case '9':7103{7104add(current);7105goto scan_number_any2;7106}71077108default:7109goto scan_number_done;7110}71117112scan_number_done:7113// unget the character after the number (we only read it to know that7114// we are done scanning a number)7115unget();71167117char* endptr = nullptr;7118errno = 0;71197120// try to parse integers first and fall back to floats7121if (number_type == token_type::value_unsigned)7122{7123const auto x = std::strtoull(token_buffer.data(), &endptr, 10);71247125// we checked the number format before7126JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());71277128if (errno == 0)7129{7130value_unsigned = static_cast<number_unsigned_t>(x);7131if (value_unsigned == x)7132{7133return token_type::value_unsigned;7134}7135}7136}7137else if (number_type == token_type::value_integer)7138{7139const auto x = std::strtoll(token_buffer.data(), &endptr, 10);71407141// we checked the number format before7142JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());71437144if (errno == 0)7145{7146value_integer = static_cast<number_integer_t>(x);7147if (value_integer == x)7148{7149return token_type::value_integer;7150}7151}7152}71537154// this code is reached if we parse a floating-point number or if an7155// integer conversion above failed7156strtof(value_float, token_buffer.data(), &endptr);71577158// we checked the number format before7159JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());71607161return token_type::value_float;7162}71637164/*!7165@param[in] literal_text the literal text to expect7166@param[in] length the length of the passed literal text7167@param[in] return_type the token type to return on success7168*/7169JSON_HEDLEY_NON_NULL(2)7170token_type scan_literal(const char_type* literal_text, const std::size_t length,7171token_type return_type)7172{7173JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);7174for (std::size_t i = 1; i < length; ++i)7175{7176if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))7177{7178error_message = "invalid literal";7179return token_type::parse_error;7180}7181}7182return return_type;7183}71847185/////////////////////7186// input management7187/////////////////////71887189/// reset token_buffer; current character is beginning of token7190void reset() noexcept7191{7192token_buffer.clear();7193token_string.clear();7194token_string.push_back(std::char_traits<char_type>::to_char_type(current));7195}71967197/*7198@brief get next character from the input71997200This function provides the interface to the used input adapter. It does7201not throw in case the input reached EOF, but returns a7202`std::char_traits<char>::eof()` in that case. Stores the scanned characters7203for use in error messages.72047205@return character read from the input7206*/7207char_int_type get()7208{7209++position.chars_read_total;7210++position.chars_read_current_line;72117212if (next_unget)7213{7214// just reset the next_unget variable and work with current7215next_unget = false;7216}7217else7218{7219current = ia.get_character();7220}72217222if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))7223{7224token_string.push_back(std::char_traits<char_type>::to_char_type(current));7225}72267227if (current == '\n')7228{7229++position.lines_read;7230position.chars_read_current_line = 0;7231}72327233return current;7234}72357236/*!7237@brief unget current character (read it again on next get)72387239We implement unget by setting variable next_unget to true. The input is not7240changed - we just simulate ungetting by modifying chars_read_total,7241chars_read_current_line, and token_string. The next call to get() will7242behave as if the unget character is read again.7243*/7244void unget()7245{7246next_unget = true;72477248--position.chars_read_total;72497250// in case we "unget" a newline, we have to also decrement the lines_read7251if (position.chars_read_current_line == 0)7252{7253if (position.lines_read > 0)7254{7255--position.lines_read;7256}7257}7258else7259{7260--position.chars_read_current_line;7261}72627263if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))7264{7265JSON_ASSERT(!token_string.empty());7266token_string.pop_back();7267}7268}72697270/// add a character to token_buffer7271void add(char_int_type c)7272{7273token_buffer.push_back(static_cast<typename string_t::value_type>(c));7274}72757276public:7277/////////////////////7278// value getters7279/////////////////////72807281/// return integer value7282constexpr number_integer_t get_number_integer() const noexcept7283{7284return value_integer;7285}72867287/// return unsigned integer value7288constexpr number_unsigned_t get_number_unsigned() const noexcept7289{7290return value_unsigned;7291}72927293/// return floating-point value7294constexpr number_float_t get_number_float() const noexcept7295{7296return value_float;7297}72987299/// return current string value (implicitly resets the token; useful only once)7300string_t& get_string()7301{7302return token_buffer;7303}73047305/////////////////////7306// diagnostics7307/////////////////////73087309/// return position of last read token7310constexpr position_t get_position() const noexcept7311{7312return position;7313}73147315/// return the last read token (for errors only). Will never contain EOF7316/// (an arbitrary value that is not a valid char value, often -1), because7317/// 255 may legitimately occur. May contain NUL, which should be escaped.7318std::string get_token_string() const7319{7320// escape control characters7321std::string result;7322for (const auto c : token_string)7323{7324if (static_cast<unsigned char>(c) <= '\x1F')7325{7326// escape control characters7327std::array<char, 9> cs{{}};7328(std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));7329result += cs.data();7330}7331else7332{7333// add character as is7334result.push_back(static_cast<std::string::value_type>(c));7335}7336}73377338return result;7339}73407341/// return syntax error message7342JSON_HEDLEY_RETURNS_NON_NULL7343constexpr const char* get_error_message() const noexcept7344{7345return error_message;7346}73477348/////////////////////7349// actual scanner7350/////////////////////73517352/*!7353@brief skip the UTF-8 byte order mark7354@return true iff there is no BOM or the correct BOM has been skipped7355*/7356bool skip_bom()7357{7358if (get() == 0xEF)7359{7360// check if we completely parse the BOM7361return get() == 0xBB && get() == 0xBF;7362}73637364// the first character is not the beginning of the BOM; unget it to7365// process is later7366unget();7367return true;7368}73697370void skip_whitespace()7371{7372do7373{7374get();7375}7376while (current == ' ' || current == '\t' || current == '\n' || current == '\r');7377}73787379token_type scan()7380{7381// initially, skip the BOM7382if (position.chars_read_total == 0 && !skip_bom())7383{7384error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";7385return token_type::parse_error;7386}73877388// read next character and ignore whitespace7389skip_whitespace();73907391// ignore comments7392while (ignore_comments && current == '/')7393{7394if (!scan_comment())7395{7396return token_type::parse_error;7397}73987399// skip following whitespace7400skip_whitespace();7401}74027403switch (current)7404{7405// structural characters7406case '[':7407return token_type::begin_array;7408case ']':7409return token_type::end_array;7410case '{':7411return token_type::begin_object;7412case '}':7413return token_type::end_object;7414case ':':7415return token_type::name_separator;7416case ',':7417return token_type::value_separator;74187419// literals7420case 't':7421{7422std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};7423return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);7424}7425case 'f':7426{7427std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};7428return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);7429}7430case 'n':7431{7432std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};7433return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);7434}74357436// string7437case '\"':7438return scan_string();74397440// number7441case '-':7442case '0':7443case '1':7444case '2':7445case '3':7446case '4':7447case '5':7448case '6':7449case '7':7450case '8':7451case '9':7452return scan_number();74537454// end of input (the null byte is needed when parsing from7455// string literals)7456case '\0':7457case std::char_traits<char_type>::eof():7458return token_type::end_of_input;74597460// error7461default:7462error_message = "invalid literal";7463return token_type::parse_error;7464}7465}74667467private:7468/// input adapter7469InputAdapterType ia;74707471/// whether comments should be ignored (true) or signaled as errors (false)7472const bool ignore_comments = false;74737474/// the current character7475char_int_type current = std::char_traits<char_type>::eof();74767477/// whether the next get() call should just return current7478bool next_unget = false;74797480/// the start position of the current token7481position_t position {};74827483/// raw input token string (for error messages)7484std::vector<char_type> token_string {};74857486/// buffer for variable-length tokens (numbers, strings)7487string_t token_buffer {};74887489/// a description of occurred lexer errors7490const char* error_message = "";74917492// number values7493number_integer_t value_integer = 0;7494number_unsigned_t value_unsigned = 0;7495number_float_t value_float = 0;74967497/// the decimal point7498const char_int_type decimal_point_char = '.';7499};7500} // namespace detail7501} // namespace nlohmann75027503// #include <nlohmann/detail/macro_scope.hpp>75047505// #include <nlohmann/detail/meta/is_sax.hpp>750675077508#include <cstdint> // size_t7509#include <utility> // declval7510#include <string> // string75117512// #include <nlohmann/detail/meta/detected.hpp>75137514// #include <nlohmann/detail/meta/type_traits.hpp>751575167517namespace nlohmann7518{7519namespace detail7520{7521template<typename T>7522using null_function_t = decltype(std::declval<T&>().null());75237524template<typename T>7525using boolean_function_t =7526decltype(std::declval<T&>().boolean(std::declval<bool>()));75277528template<typename T, typename Integer>7529using number_integer_function_t =7530decltype(std::declval<T&>().number_integer(std::declval<Integer>()));75317532template<typename T, typename Unsigned>7533using number_unsigned_function_t =7534decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));75357536template<typename T, typename Float, typename String>7537using number_float_function_t = decltype(std::declval<T&>().number_float(7538std::declval<Float>(), std::declval<const String&>()));75397540template<typename T, typename String>7541using string_function_t =7542decltype(std::declval<T&>().string(std::declval<String&>()));75437544template<typename T, typename Binary>7545using binary_function_t =7546decltype(std::declval<T&>().binary(std::declval<Binary&>()));75477548template<typename T>7549using start_object_function_t =7550decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));75517552template<typename T, typename String>7553using key_function_t =7554decltype(std::declval<T&>().key(std::declval<String&>()));75557556template<typename T>7557using end_object_function_t = decltype(std::declval<T&>().end_object());75587559template<typename T>7560using start_array_function_t =7561decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));75627563template<typename T>7564using end_array_function_t = decltype(std::declval<T&>().end_array());75657566template<typename T, typename Exception>7567using parse_error_function_t = decltype(std::declval<T&>().parse_error(7568std::declval<std::size_t>(), std::declval<const std::string&>(),7569std::declval<const Exception&>()));75707571template<typename SAX, typename BasicJsonType>7572struct is_sax7573{7574private:7575static_assert(is_basic_json<BasicJsonType>::value,7576"BasicJsonType must be of type basic_json<...>");75777578using number_integer_t = typename BasicJsonType::number_integer_t;7579using number_unsigned_t = typename BasicJsonType::number_unsigned_t;7580using number_float_t = typename BasicJsonType::number_float_t;7581using string_t = typename BasicJsonType::string_t;7582using binary_t = typename BasicJsonType::binary_t;7583using exception_t = typename BasicJsonType::exception;75847585public:7586static constexpr bool value =7587is_detected_exact<bool, null_function_t, SAX>::value &&7588is_detected_exact<bool, boolean_function_t, SAX>::value &&7589is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&7590is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&7591is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&7592is_detected_exact<bool, string_function_t, SAX, string_t>::value &&7593is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&7594is_detected_exact<bool, start_object_function_t, SAX>::value &&7595is_detected_exact<bool, key_function_t, SAX, string_t>::value &&7596is_detected_exact<bool, end_object_function_t, SAX>::value &&7597is_detected_exact<bool, start_array_function_t, SAX>::value &&7598is_detected_exact<bool, end_array_function_t, SAX>::value &&7599is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;7600};76017602template<typename SAX, typename BasicJsonType>7603struct is_sax_static_asserts7604{7605private:7606static_assert(is_basic_json<BasicJsonType>::value,7607"BasicJsonType must be of type basic_json<...>");76087609using number_integer_t = typename BasicJsonType::number_integer_t;7610using number_unsigned_t = typename BasicJsonType::number_unsigned_t;7611using number_float_t = typename BasicJsonType::number_float_t;7612using string_t = typename BasicJsonType::string_t;7613using binary_t = typename BasicJsonType::binary_t;7614using exception_t = typename BasicJsonType::exception;76157616public:7617static_assert(is_detected_exact<bool, null_function_t, SAX>::value,7618"Missing/invalid function: bool null()");7619static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,7620"Missing/invalid function: bool boolean(bool)");7621static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,7622"Missing/invalid function: bool boolean(bool)");7623static_assert(7624is_detected_exact<bool, number_integer_function_t, SAX,7625number_integer_t>::value,7626"Missing/invalid function: bool number_integer(number_integer_t)");7627static_assert(7628is_detected_exact<bool, number_unsigned_function_t, SAX,7629number_unsigned_t>::value,7630"Missing/invalid function: bool number_unsigned(number_unsigned_t)");7631static_assert(is_detected_exact<bool, number_float_function_t, SAX,7632number_float_t, string_t>::value,7633"Missing/invalid function: bool number_float(number_float_t, const string_t&)");7634static_assert(7635is_detected_exact<bool, string_function_t, SAX, string_t>::value,7636"Missing/invalid function: bool string(string_t&)");7637static_assert(7638is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,7639"Missing/invalid function: bool binary(binary_t&)");7640static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,7641"Missing/invalid function: bool start_object(std::size_t)");7642static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,7643"Missing/invalid function: bool key(string_t&)");7644static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,7645"Missing/invalid function: bool end_object()");7646static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,7647"Missing/invalid function: bool start_array(std::size_t)");7648static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,7649"Missing/invalid function: bool end_array()");7650static_assert(7651is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,7652"Missing/invalid function: bool parse_error(std::size_t, const "7653"std::string&, const exception&)");7654};7655} // namespace detail7656} // namespace nlohmann76577658// #include <nlohmann/detail/value_t.hpp>765976607661namespace nlohmann7662{7663namespace detail7664{76657666/// how to treat CBOR tags7667enum class cbor_tag_handler_t7668{7669error, ///< throw a parse_error exception in case of a tag7670ignore ///< ignore tags7671};76727673/*!7674@brief determine system byte order76757676@return true if and only if system's byte order is little endian76777678@note from https://stackoverflow.com/a/1001328/2663787679*/7680static inline bool little_endianess(int num = 1) noexcept7681{7682return *reinterpret_cast<char*>(&num) == 1;7683}768476857686///////////////////7687// binary reader //7688///////////////////76897690/*!7691@brief deserialization of CBOR, MessagePack, and UBJSON values7692*/7693template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>7694class binary_reader7695{7696using number_integer_t = typename BasicJsonType::number_integer_t;7697using number_unsigned_t = typename BasicJsonType::number_unsigned_t;7698using number_float_t = typename BasicJsonType::number_float_t;7699using string_t = typename BasicJsonType::string_t;7700using binary_t = typename BasicJsonType::binary_t;7701using json_sax_t = SAX;7702using char_type = typename InputAdapterType::char_type;7703using char_int_type = typename std::char_traits<char_type>::int_type;77047705public:7706/*!7707@brief create a binary reader77087709@param[in] adapter input adapter to read from7710*/7711explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))7712{7713(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};7714}77157716// make class move-only7717binary_reader(const binary_reader&) = delete;7718binary_reader(binary_reader&&) = default;7719binary_reader& operator=(const binary_reader&) = delete;7720binary_reader& operator=(binary_reader&&) = default;7721~binary_reader() = default;77227723/*!7724@param[in] format the binary format to parse7725@param[in] sax_ a SAX event processor7726@param[in] strict whether to expect the input to be consumed completed7727@param[in] tag_handler how to treat CBOR tags77287729@return7730*/7731JSON_HEDLEY_NON_NULL(3)7732bool sax_parse(const input_format_t format,7733json_sax_t* sax_,7734const bool strict = true,7735const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)7736{7737sax = sax_;7738bool result = false;77397740switch (format)7741{7742case input_format_t::bson:7743result = parse_bson_internal();7744break;77457746case input_format_t::cbor:7747result = parse_cbor_internal(true, tag_handler);7748break;77497750case input_format_t::msgpack:7751result = parse_msgpack_internal();7752break;77537754case input_format_t::ubjson:7755result = parse_ubjson_internal();7756break;77577758default: // LCOV_EXCL_LINE7759JSON_ASSERT(false); // LCOV_EXCL_LINE7760}77617762// strict mode: next byte must be EOF7763if (result && strict)7764{7765if (format == input_format_t::ubjson)7766{7767get_ignore_noop();7768}7769else7770{7771get();7772}77737774if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))7775{7776return sax->parse_error(chars_read, get_token_string(),7777parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));7778}7779}77807781return result;7782}77837784private:7785//////////7786// BSON //7787//////////77887789/*!7790@brief Reads in a BSON-object and passes it to the SAX-parser.7791@return whether a valid BSON-value was passed to the SAX parser7792*/7793bool parse_bson_internal()7794{7795std::int32_t document_size{};7796get_number<std::int32_t, true>(input_format_t::bson, document_size);77977798if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))7799{7800return false;7801}78027803if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))7804{7805return false;7806}78077808return sax->end_object();7809}78107811/*!7812@brief Parses a C-style string from the BSON input.7813@param[in, out] result A reference to the string variable where the read7814string is to be stored.7815@return `true` if the \x00-byte indicating the end of the string was7816encountered before the EOF; false` indicates an unexpected EOF.7817*/7818bool get_bson_cstr(string_t& result)7819{7820auto out = std::back_inserter(result);7821while (true)7822{7823get();7824if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))7825{7826return false;7827}7828if (current == 0x00)7829{7830return true;7831}7832*out++ = static_cast<typename string_t::value_type>(current);7833}7834}78357836/*!7837@brief Parses a zero-terminated string of length @a len from the BSON7838input.7839@param[in] len The length (including the zero-byte at the end) of the7840string to be read.7841@param[in, out] result A reference to the string variable where the read7842string is to be stored.7843@tparam NumberType The type of the length @a len7844@pre len >= 17845@return `true` if the string was successfully parsed7846*/7847template<typename NumberType>7848bool get_bson_string(const NumberType len, string_t& result)7849{7850if (JSON_HEDLEY_UNLIKELY(len < 1))7851{7852auto last_token = get_token_string();7853return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));7854}78557856return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();7857}78587859/*!7860@brief Parses a byte array input of length @a len from the BSON input.7861@param[in] len The length of the byte array to be read.7862@param[in, out] result A reference to the binary variable where the read7863array is to be stored.7864@tparam NumberType The type of the length @a len7865@pre len >= 07866@return `true` if the byte array was successfully parsed7867*/7868template<typename NumberType>7869bool get_bson_binary(const NumberType len, binary_t& result)7870{7871if (JSON_HEDLEY_UNLIKELY(len < 0))7872{7873auto last_token = get_token_string();7874return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary")));7875}78767877// All BSON binary values have a subtype7878std::uint8_t subtype{};7879get_number<std::uint8_t>(input_format_t::bson, subtype);7880result.set_subtype(subtype);78817882return get_binary(input_format_t::bson, len, result);7883}78847885/*!7886@brief Read a BSON document element of the given @a element_type.7887@param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html7888@param[in] element_type_parse_position The position in the input stream,7889where the `element_type` was read.7890@warning Not all BSON element types are supported yet. An unsupported7891@a element_type will give rise to a parse_error.114:7892Unsupported BSON record type 0x...7893@return whether a valid BSON-object/array was passed to the SAX parser7894*/7895bool parse_bson_element_internal(const char_int_type element_type,7896const std::size_t element_type_parse_position)7897{7898switch (element_type)7899{7900case 0x01: // double7901{7902double number{};7903return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");7904}79057906case 0x02: // string7907{7908std::int32_t len{};7909string_t value;7910return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);7911}79127913case 0x03: // object7914{7915return parse_bson_internal();7916}79177918case 0x04: // array7919{7920return parse_bson_array();7921}79227923case 0x05: // binary7924{7925std::int32_t len{};7926binary_t value;7927return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);7928}79297930case 0x08: // boolean7931{7932return sax->boolean(get() != 0);7933}79347935case 0x0A: // null7936{7937return sax->null();7938}79397940case 0x10: // int327941{7942std::int32_t value{};7943return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);7944}79457946case 0x12: // int647947{7948std::int64_t value{};7949return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);7950}79517952default: // anything else not supported (yet)7953{7954std::array<char, 3> cr{{}};7955(std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));7956return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data())));7957}7958}7959}79607961/*!7962@brief Read a BSON element list (as specified in the BSON-spec)79637964The same binary layout is used for objects and arrays, hence it must be7965indicated with the argument @a is_array which one is expected7966(true --> array, false --> object).79677968@param[in] is_array Determines if the element list being read is to be7969treated as an object (@a is_array == false), or as an7970array (@a is_array == true).7971@return whether a valid BSON-object/array was passed to the SAX parser7972*/7973bool parse_bson_element_list(const bool is_array)7974{7975string_t key;79767977while (auto element_type = get())7978{7979if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))7980{7981return false;7982}79837984const std::size_t element_type_parse_position = chars_read;7985if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))7986{7987return false;7988}79897990if (!is_array && !sax->key(key))7991{7992return false;7993}79947995if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))7996{7997return false;7998}79998000// get_bson_cstr only appends8001key.clear();8002}80038004return true;8005}80068007/*!8008@brief Reads an array from the BSON input and passes it to the SAX-parser.8009@return whether a valid BSON-array was passed to the SAX parser8010*/8011bool parse_bson_array()8012{8013std::int32_t document_size{};8014get_number<std::int32_t, true>(input_format_t::bson, document_size);80158016if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))8017{8018return false;8019}80208021if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))8022{8023return false;8024}80258026return sax->end_array();8027}80288029//////////8030// CBOR //8031//////////80328033/*!8034@param[in] get_char whether a new character should be retrieved from the8035input (true) or whether the last read character should8036be considered instead (false)8037@param[in] tag_handler how CBOR tags should be treated80388039@return whether a valid CBOR value was passed to the SAX parser8040*/8041bool parse_cbor_internal(const bool get_char,8042const cbor_tag_handler_t tag_handler)8043{8044switch (get_char ? get() : current)8045{8046// EOF8047case std::char_traits<char_type>::eof():8048return unexpect_eof(input_format_t::cbor, "value");80498050// Integer 0x00..0x17 (0..23)8051case 0x00:8052case 0x01:8053case 0x02:8054case 0x03:8055case 0x04:8056case 0x05:8057case 0x06:8058case 0x07:8059case 0x08:8060case 0x09:8061case 0x0A:8062case 0x0B:8063case 0x0C:8064case 0x0D:8065case 0x0E:8066case 0x0F:8067case 0x10:8068case 0x11:8069case 0x12:8070case 0x13:8071case 0x14:8072case 0x15:8073case 0x16:8074case 0x17:8075return sax->number_unsigned(static_cast<number_unsigned_t>(current));80768077case 0x18: // Unsigned integer (one-byte uint8_t follows)8078{8079std::uint8_t number{};8080return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);8081}80828083case 0x19: // Unsigned integer (two-byte uint16_t follows)8084{8085std::uint16_t number{};8086return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);8087}80888089case 0x1A: // Unsigned integer (four-byte uint32_t follows)8090{8091std::uint32_t number{};8092return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);8093}80948095case 0x1B: // Unsigned integer (eight-byte uint64_t follows)8096{8097std::uint64_t number{};8098return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);8099}81008101// Negative integer -1-0x00..-1-0x17 (-1..-24)8102case 0x20:8103case 0x21:8104case 0x22:8105case 0x23:8106case 0x24:8107case 0x25:8108case 0x26:8109case 0x27:8110case 0x28:8111case 0x29:8112case 0x2A:8113case 0x2B:8114case 0x2C:8115case 0x2D:8116case 0x2E:8117case 0x2F:8118case 0x30:8119case 0x31:8120case 0x32:8121case 0x33:8122case 0x34:8123case 0x35:8124case 0x36:8125case 0x37:8126return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));81278128case 0x38: // Negative integer (one-byte uint8_t follows)8129{8130std::uint8_t number{};8131return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);8132}81338134case 0x39: // Negative integer -1-n (two-byte uint16_t follows)8135{8136std::uint16_t number{};8137return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);8138}81398140case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)8141{8142std::uint32_t number{};8143return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);8144}81458146case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)8147{8148std::uint64_t number{};8149return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)8150- static_cast<number_integer_t>(number));8151}81528153// Binary data (0x00..0x17 bytes follow)8154case 0x40:8155case 0x41:8156case 0x42:8157case 0x43:8158case 0x44:8159case 0x45:8160case 0x46:8161case 0x47:8162case 0x48:8163case 0x49:8164case 0x4A:8165case 0x4B:8166case 0x4C:8167case 0x4D:8168case 0x4E:8169case 0x4F:8170case 0x50:8171case 0x51:8172case 0x52:8173case 0x53:8174case 0x54:8175case 0x55:8176case 0x56:8177case 0x57:8178case 0x58: // Binary data (one-byte uint8_t for n follows)8179case 0x59: // Binary data (two-byte uint16_t for n follow)8180case 0x5A: // Binary data (four-byte uint32_t for n follow)8181case 0x5B: // Binary data (eight-byte uint64_t for n follow)8182case 0x5F: // Binary data (indefinite length)8183{8184binary_t b;8185return get_cbor_binary(b) && sax->binary(b);8186}81878188// UTF-8 string (0x00..0x17 bytes follow)8189case 0x60:8190case 0x61:8191case 0x62:8192case 0x63:8193case 0x64:8194case 0x65:8195case 0x66:8196case 0x67:8197case 0x68:8198case 0x69:8199case 0x6A:8200case 0x6B:8201case 0x6C:8202case 0x6D:8203case 0x6E:8204case 0x6F:8205case 0x70:8206case 0x71:8207case 0x72:8208case 0x73:8209case 0x74:8210case 0x75:8211case 0x76:8212case 0x77:8213case 0x78: // UTF-8 string (one-byte uint8_t for n follows)8214case 0x79: // UTF-8 string (two-byte uint16_t for n follow)8215case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)8216case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)8217case 0x7F: // UTF-8 string (indefinite length)8218{8219string_t s;8220return get_cbor_string(s) && sax->string(s);8221}82228223// array (0x00..0x17 data items follow)8224case 0x80:8225case 0x81:8226case 0x82:8227case 0x83:8228case 0x84:8229case 0x85:8230case 0x86:8231case 0x87:8232case 0x88:8233case 0x89:8234case 0x8A:8235case 0x8B:8236case 0x8C:8237case 0x8D:8238case 0x8E:8239case 0x8F:8240case 0x90:8241case 0x91:8242case 0x92:8243case 0x93:8244case 0x94:8245case 0x95:8246case 0x96:8247case 0x97:8248return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);82498250case 0x98: // array (one-byte uint8_t for n follows)8251{8252std::uint8_t len{};8253return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);8254}82558256case 0x99: // array (two-byte uint16_t for n follow)8257{8258std::uint16_t len{};8259return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);8260}82618262case 0x9A: // array (four-byte uint32_t for n follow)8263{8264std::uint32_t len{};8265return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);8266}82678268case 0x9B: // array (eight-byte uint64_t for n follow)8269{8270std::uint64_t len{};8271return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);8272}82738274case 0x9F: // array (indefinite length)8275return get_cbor_array(std::size_t(-1), tag_handler);82768277// map (0x00..0x17 pairs of data items follow)8278case 0xA0:8279case 0xA1:8280case 0xA2:8281case 0xA3:8282case 0xA4:8283case 0xA5:8284case 0xA6:8285case 0xA7:8286case 0xA8:8287case 0xA9:8288case 0xAA:8289case 0xAB:8290case 0xAC:8291case 0xAD:8292case 0xAE:8293case 0xAF:8294case 0xB0:8295case 0xB1:8296case 0xB2:8297case 0xB3:8298case 0xB4:8299case 0xB5:8300case 0xB6:8301case 0xB7:8302return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);83038304case 0xB8: // map (one-byte uint8_t for n follows)8305{8306std::uint8_t len{};8307return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);8308}83098310case 0xB9: // map (two-byte uint16_t for n follow)8311{8312std::uint16_t len{};8313return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);8314}83158316case 0xBA: // map (four-byte uint32_t for n follow)8317{8318std::uint32_t len{};8319return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);8320}83218322case 0xBB: // map (eight-byte uint64_t for n follow)8323{8324std::uint64_t len{};8325return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);8326}83278328case 0xBF: // map (indefinite length)8329return get_cbor_object(std::size_t(-1), tag_handler);83308331case 0xC6: // tagged item8332case 0xC7:8333case 0xC8:8334case 0xC9:8335case 0xCA:8336case 0xCB:8337case 0xCC:8338case 0xCD:8339case 0xCE:8340case 0xCF:8341case 0xD0:8342case 0xD1:8343case 0xD2:8344case 0xD3:8345case 0xD4:8346case 0xD8: // tagged item (1 bytes follow)8347case 0xD9: // tagged item (2 bytes follow)8348case 0xDA: // tagged item (4 bytes follow)8349case 0xDB: // tagged item (8 bytes follow)8350{8351switch (tag_handler)8352{8353case cbor_tag_handler_t::error:8354{8355auto last_token = get_token_string();8356return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));8357}83588359case cbor_tag_handler_t::ignore:8360{8361switch (current)8362{8363case 0xD8:8364{8365std::uint8_t len{};8366get_number(input_format_t::cbor, len);8367break;8368}8369case 0xD9:8370{8371std::uint16_t len{};8372get_number(input_format_t::cbor, len);8373break;8374}8375case 0xDA:8376{8377std::uint32_t len{};8378get_number(input_format_t::cbor, len);8379break;8380}8381case 0xDB:8382{8383std::uint64_t len{};8384get_number(input_format_t::cbor, len);8385break;8386}8387default:8388break;8389}8390return parse_cbor_internal(true, tag_handler);8391}83928393default: // LCOV_EXCL_LINE8394JSON_ASSERT(false); // LCOV_EXCL_LINE8395}8396}83978398case 0xF4: // false8399return sax->boolean(false);84008401case 0xF5: // true8402return sax->boolean(true);84038404case 0xF6: // null8405return sax->null();84068407case 0xF9: // Half-Precision Float (two-byte IEEE 754)8408{8409const auto byte1_raw = get();8410if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))8411{8412return false;8413}8414const auto byte2_raw = get();8415if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))8416{8417return false;8418}84198420const auto byte1 = static_cast<unsigned char>(byte1_raw);8421const auto byte2 = static_cast<unsigned char>(byte2_raw);84228423// code from RFC 7049, Appendix D, Figure 3:8424// As half-precision floating-point numbers were only added8425// to IEEE 754 in 2008, today's programming platforms often8426// still only have limited support for them. It is very8427// easy to include at least decoding support for them even8428// without such support. An example of a small decoder for8429// half-precision floating-point numbers in the C language8430// is shown in Fig. 3.8431const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);8432const double val = [&half]8433{8434const int exp = (half >> 10u) & 0x1Fu;8435const unsigned int mant = half & 0x3FFu;8436JSON_ASSERT(0 <= exp&& exp <= 32);8437JSON_ASSERT(mant <= 1024);8438switch (exp)8439{8440case 0:8441return std::ldexp(mant, -24);8442case 31:8443return (mant == 0)8444? std::numeric_limits<double>::infinity()8445: std::numeric_limits<double>::quiet_NaN();8446default:8447return std::ldexp(mant + 1024, exp - 25);8448}8449}();8450return sax->number_float((half & 0x8000u) != 08451? static_cast<number_float_t>(-val)8452: static_cast<number_float_t>(val), "");8453}84548455case 0xFA: // Single-Precision Float (four-byte IEEE 754)8456{8457float number{};8458return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");8459}84608461case 0xFB: // Double-Precision Float (eight-byte IEEE 754)8462{8463double number{};8464return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");8465}84668467default: // anything else (0xFF is handled inside the other types)8468{8469auto last_token = get_token_string();8470return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));8471}8472}8473}84748475/*!8476@brief reads a CBOR string84778478This function first reads starting bytes to determine the expected8479string length and then copies this number of bytes into a string.8480Additionally, CBOR's strings with indefinite lengths are supported.84818482@param[out] result created string84838484@return whether string creation completed8485*/8486bool get_cbor_string(string_t& result)8487{8488if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))8489{8490return false;8491}84928493switch (current)8494{8495// UTF-8 string (0x00..0x17 bytes follow)8496case 0x60:8497case 0x61:8498case 0x62:8499case 0x63:8500case 0x64:8501case 0x65:8502case 0x66:8503case 0x67:8504case 0x68:8505case 0x69:8506case 0x6A:8507case 0x6B:8508case 0x6C:8509case 0x6D:8510case 0x6E:8511case 0x6F:8512case 0x70:8513case 0x71:8514case 0x72:8515case 0x73:8516case 0x74:8517case 0x75:8518case 0x76:8519case 0x77:8520{8521return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);8522}85238524case 0x78: // UTF-8 string (one-byte uint8_t for n follows)8525{8526std::uint8_t len{};8527return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);8528}85298530case 0x79: // UTF-8 string (two-byte uint16_t for n follow)8531{8532std::uint16_t len{};8533return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);8534}85358536case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)8537{8538std::uint32_t len{};8539return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);8540}85418542case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)8543{8544std::uint64_t len{};8545return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);8546}85478548case 0x7F: // UTF-8 string (indefinite length)8549{8550while (get() != 0xFF)8551{8552string_t chunk;8553if (!get_cbor_string(chunk))8554{8555return false;8556}8557result.append(chunk);8558}8559return true;8560}85618562default:8563{8564auto last_token = get_token_string();8565return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));8566}8567}8568}85698570/*!8571@brief reads a CBOR byte array85728573This function first reads starting bytes to determine the expected8574byte array length and then copies this number of bytes into the byte array.8575Additionally, CBOR's byte arrays with indefinite lengths are supported.85768577@param[out] result created byte array85788579@return whether byte array creation completed8580*/8581bool get_cbor_binary(binary_t& result)8582{8583if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))8584{8585return false;8586}85878588switch (current)8589{8590// Binary data (0x00..0x17 bytes follow)8591case 0x40:8592case 0x41:8593case 0x42:8594case 0x43:8595case 0x44:8596case 0x45:8597case 0x46:8598case 0x47:8599case 0x48:8600case 0x49:8601case 0x4A:8602case 0x4B:8603case 0x4C:8604case 0x4D:8605case 0x4E:8606case 0x4F:8607case 0x50:8608case 0x51:8609case 0x52:8610case 0x53:8611case 0x54:8612case 0x55:8613case 0x56:8614case 0x57:8615{8616return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);8617}86188619case 0x58: // Binary data (one-byte uint8_t for n follows)8620{8621std::uint8_t len{};8622return get_number(input_format_t::cbor, len) &&8623get_binary(input_format_t::cbor, len, result);8624}86258626case 0x59: // Binary data (two-byte uint16_t for n follow)8627{8628std::uint16_t len{};8629return get_number(input_format_t::cbor, len) &&8630get_binary(input_format_t::cbor, len, result);8631}86328633case 0x5A: // Binary data (four-byte uint32_t for n follow)8634{8635std::uint32_t len{};8636return get_number(input_format_t::cbor, len) &&8637get_binary(input_format_t::cbor, len, result);8638}86398640case 0x5B: // Binary data (eight-byte uint64_t for n follow)8641{8642std::uint64_t len{};8643return get_number(input_format_t::cbor, len) &&8644get_binary(input_format_t::cbor, len, result);8645}86468647case 0x5F: // Binary data (indefinite length)8648{8649while (get() != 0xFF)8650{8651binary_t chunk;8652if (!get_cbor_binary(chunk))8653{8654return false;8655}8656result.insert(result.end(), chunk.begin(), chunk.end());8657}8658return true;8659}86608661default:8662{8663auto last_token = get_token_string();8664return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary")));8665}8666}8667}86688669/*!8670@param[in] len the length of the array or std::size_t(-1) for an8671array of indefinite size8672@param[in] tag_handler how CBOR tags should be treated8673@return whether array creation completed8674*/8675bool get_cbor_array(const std::size_t len,8676const cbor_tag_handler_t tag_handler)8677{8678if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))8679{8680return false;8681}86828683if (len != std::size_t(-1))8684{8685for (std::size_t i = 0; i < len; ++i)8686{8687if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))8688{8689return false;8690}8691}8692}8693else8694{8695while (get() != 0xFF)8696{8697if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))8698{8699return false;8700}8701}8702}87038704return sax->end_array();8705}87068707/*!8708@param[in] len the length of the object or std::size_t(-1) for an8709object of indefinite size8710@param[in] tag_handler how CBOR tags should be treated8711@return whether object creation completed8712*/8713bool get_cbor_object(const std::size_t len,8714const cbor_tag_handler_t tag_handler)8715{8716if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))8717{8718return false;8719}87208721string_t key;8722if (len != std::size_t(-1))8723{8724for (std::size_t i = 0; i < len; ++i)8725{8726get();8727if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))8728{8729return false;8730}87318732if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))8733{8734return false;8735}8736key.clear();8737}8738}8739else8740{8741while (get() != 0xFF)8742{8743if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))8744{8745return false;8746}87478748if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))8749{8750return false;8751}8752key.clear();8753}8754}87558756return sax->end_object();8757}87588759/////////////8760// MsgPack //8761/////////////87628763/*!8764@return whether a valid MessagePack value was passed to the SAX parser8765*/8766bool parse_msgpack_internal()8767{8768switch (get())8769{8770// EOF8771case std::char_traits<char_type>::eof():8772return unexpect_eof(input_format_t::msgpack, "value");87738774// positive fixint8775case 0x00:8776case 0x01:8777case 0x02:8778case 0x03:8779case 0x04:8780case 0x05:8781case 0x06:8782case 0x07:8783case 0x08:8784case 0x09:8785case 0x0A:8786case 0x0B:8787case 0x0C:8788case 0x0D:8789case 0x0E:8790case 0x0F:8791case 0x10:8792case 0x11:8793case 0x12:8794case 0x13:8795case 0x14:8796case 0x15:8797case 0x16:8798case 0x17:8799case 0x18:8800case 0x19:8801case 0x1A:8802case 0x1B:8803case 0x1C:8804case 0x1D:8805case 0x1E:8806case 0x1F:8807case 0x20:8808case 0x21:8809case 0x22:8810case 0x23:8811case 0x24:8812case 0x25:8813case 0x26:8814case 0x27:8815case 0x28:8816case 0x29:8817case 0x2A:8818case 0x2B:8819case 0x2C:8820case 0x2D:8821case 0x2E:8822case 0x2F:8823case 0x30:8824case 0x31:8825case 0x32:8826case 0x33:8827case 0x34:8828case 0x35:8829case 0x36:8830case 0x37:8831case 0x38:8832case 0x39:8833case 0x3A:8834case 0x3B:8835case 0x3C:8836case 0x3D:8837case 0x3E:8838case 0x3F:8839case 0x40:8840case 0x41:8841case 0x42:8842case 0x43:8843case 0x44:8844case 0x45:8845case 0x46:8846case 0x47:8847case 0x48:8848case 0x49:8849case 0x4A:8850case 0x4B:8851case 0x4C:8852case 0x4D:8853case 0x4E:8854case 0x4F:8855case 0x50:8856case 0x51:8857case 0x52:8858case 0x53:8859case 0x54:8860case 0x55:8861case 0x56:8862case 0x57:8863case 0x58:8864case 0x59:8865case 0x5A:8866case 0x5B:8867case 0x5C:8868case 0x5D:8869case 0x5E:8870case 0x5F:8871case 0x60:8872case 0x61:8873case 0x62:8874case 0x63:8875case 0x64:8876case 0x65:8877case 0x66:8878case 0x67:8879case 0x68:8880case 0x69:8881case 0x6A:8882case 0x6B:8883case 0x6C:8884case 0x6D:8885case 0x6E:8886case 0x6F:8887case 0x70:8888case 0x71:8889case 0x72:8890case 0x73:8891case 0x74:8892case 0x75:8893case 0x76:8894case 0x77:8895case 0x78:8896case 0x79:8897case 0x7A:8898case 0x7B:8899case 0x7C:8900case 0x7D:8901case 0x7E:8902case 0x7F:8903return sax->number_unsigned(static_cast<number_unsigned_t>(current));89048905// fixmap8906case 0x80:8907case 0x81:8908case 0x82:8909case 0x83:8910case 0x84:8911case 0x85:8912case 0x86:8913case 0x87:8914case 0x88:8915case 0x89:8916case 0x8A:8917case 0x8B:8918case 0x8C:8919case 0x8D:8920case 0x8E:8921case 0x8F:8922return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));89238924// fixarray8925case 0x90:8926case 0x91:8927case 0x92:8928case 0x93:8929case 0x94:8930case 0x95:8931case 0x96:8932case 0x97:8933case 0x98:8934case 0x99:8935case 0x9A:8936case 0x9B:8937case 0x9C:8938case 0x9D:8939case 0x9E:8940case 0x9F:8941return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));89428943// fixstr8944case 0xA0:8945case 0xA1:8946case 0xA2:8947case 0xA3:8948case 0xA4:8949case 0xA5:8950case 0xA6:8951case 0xA7:8952case 0xA8:8953case 0xA9:8954case 0xAA:8955case 0xAB:8956case 0xAC:8957case 0xAD:8958case 0xAE:8959case 0xAF:8960case 0xB0:8961case 0xB1:8962case 0xB2:8963case 0xB3:8964case 0xB4:8965case 0xB5:8966case 0xB6:8967case 0xB7:8968case 0xB8:8969case 0xB9:8970case 0xBA:8971case 0xBB:8972case 0xBC:8973case 0xBD:8974case 0xBE:8975case 0xBF:8976case 0xD9: // str 88977case 0xDA: // str 168978case 0xDB: // str 328979{8980string_t s;8981return get_msgpack_string(s) && sax->string(s);8982}89838984case 0xC0: // nil8985return sax->null();89868987case 0xC2: // false8988return sax->boolean(false);89898990case 0xC3: // true8991return sax->boolean(true);89928993case 0xC4: // bin 88994case 0xC5: // bin 168995case 0xC6: // bin 328996case 0xC7: // ext 88997case 0xC8: // ext 168998case 0xC9: // ext 328999case 0xD4: // fixext 19000case 0xD5: // fixext 29001case 0xD6: // fixext 49002case 0xD7: // fixext 89003case 0xD8: // fixext 169004{9005binary_t b;9006return get_msgpack_binary(b) && sax->binary(b);9007}90089009case 0xCA: // float 329010{9011float number{};9012return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");9013}90149015case 0xCB: // float 649016{9017double number{};9018return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");9019}90209021case 0xCC: // uint 89022{9023std::uint8_t number{};9024return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);9025}90269027case 0xCD: // uint 169028{9029std::uint16_t number{};9030return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);9031}90329033case 0xCE: // uint 329034{9035std::uint32_t number{};9036return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);9037}90389039case 0xCF: // uint 649040{9041std::uint64_t number{};9042return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);9043}90449045case 0xD0: // int 89046{9047std::int8_t number{};9048return get_number(input_format_t::msgpack, number) && sax->number_integer(number);9049}90509051case 0xD1: // int 169052{9053std::int16_t number{};9054return get_number(input_format_t::msgpack, number) && sax->number_integer(number);9055}90569057case 0xD2: // int 329058{9059std::int32_t number{};9060return get_number(input_format_t::msgpack, number) && sax->number_integer(number);9061}90629063case 0xD3: // int 649064{9065std::int64_t number{};9066return get_number(input_format_t::msgpack, number) && sax->number_integer(number);9067}90689069case 0xDC: // array 169070{9071std::uint16_t len{};9072return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));9073}90749075case 0xDD: // array 329076{9077std::uint32_t len{};9078return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));9079}90809081case 0xDE: // map 169082{9083std::uint16_t len{};9084return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));9085}90869087case 0xDF: // map 329088{9089std::uint32_t len{};9090return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));9091}90929093// negative fixint9094case 0xE0:9095case 0xE1:9096case 0xE2:9097case 0xE3:9098case 0xE4:9099case 0xE5:9100case 0xE6:9101case 0xE7:9102case 0xE8:9103case 0xE9:9104case 0xEA:9105case 0xEB:9106case 0xEC:9107case 0xED:9108case 0xEE:9109case 0xEF:9110case 0xF0:9111case 0xF1:9112case 0xF2:9113case 0xF3:9114case 0xF4:9115case 0xF5:9116case 0xF6:9117case 0xF7:9118case 0xF8:9119case 0xF9:9120case 0xFA:9121case 0xFB:9122case 0xFC:9123case 0xFD:9124case 0xFE:9125case 0xFF:9126return sax->number_integer(static_cast<std::int8_t>(current));91279128default: // anything else9129{9130auto last_token = get_token_string();9131return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));9132}9133}9134}91359136/*!9137@brief reads a MessagePack string91389139This function first reads starting bytes to determine the expected9140string length and then copies this number of bytes into a string.91419142@param[out] result created string91439144@return whether string creation completed9145*/9146bool get_msgpack_string(string_t& result)9147{9148if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))9149{9150return false;9151}91529153switch (current)9154{9155// fixstr9156case 0xA0:9157case 0xA1:9158case 0xA2:9159case 0xA3:9160case 0xA4:9161case 0xA5:9162case 0xA6:9163case 0xA7:9164case 0xA8:9165case 0xA9:9166case 0xAA:9167case 0xAB:9168case 0xAC:9169case 0xAD:9170case 0xAE:9171case 0xAF:9172case 0xB0:9173case 0xB1:9174case 0xB2:9175case 0xB3:9176case 0xB4:9177case 0xB5:9178case 0xB6:9179case 0xB7:9180case 0xB8:9181case 0xB9:9182case 0xBA:9183case 0xBB:9184case 0xBC:9185case 0xBD:9186case 0xBE:9187case 0xBF:9188{9189return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);9190}91919192case 0xD9: // str 89193{9194std::uint8_t len{};9195return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);9196}91979198case 0xDA: // str 169199{9200std::uint16_t len{};9201return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);9202}92039204case 0xDB: // str 329205{9206std::uint32_t len{};9207return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);9208}92099210default:9211{9212auto last_token = get_token_string();9213return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));9214}9215}9216}92179218/*!9219@brief reads a MessagePack byte array92209221This function first reads starting bytes to determine the expected9222byte array length and then copies this number of bytes into a byte array.92239224@param[out] result created byte array92259226@return whether byte array creation completed9227*/9228bool get_msgpack_binary(binary_t& result)9229{9230// helper function to set the subtype9231auto assign_and_return_true = [&result](std::int8_t subtype)9232{9233result.set_subtype(static_cast<std::uint8_t>(subtype));9234return true;9235};92369237switch (current)9238{9239case 0xC4: // bin 89240{9241std::uint8_t len{};9242return get_number(input_format_t::msgpack, len) &&9243get_binary(input_format_t::msgpack, len, result);9244}92459246case 0xC5: // bin 169247{9248std::uint16_t len{};9249return get_number(input_format_t::msgpack, len) &&9250get_binary(input_format_t::msgpack, len, result);9251}92529253case 0xC6: // bin 329254{9255std::uint32_t len{};9256return get_number(input_format_t::msgpack, len) &&9257get_binary(input_format_t::msgpack, len, result);9258}92599260case 0xC7: // ext 89261{9262std::uint8_t len{};9263std::int8_t subtype{};9264return get_number(input_format_t::msgpack, len) &&9265get_number(input_format_t::msgpack, subtype) &&9266get_binary(input_format_t::msgpack, len, result) &&9267assign_and_return_true(subtype);9268}92699270case 0xC8: // ext 169271{9272std::uint16_t len{};9273std::int8_t subtype{};9274return get_number(input_format_t::msgpack, len) &&9275get_number(input_format_t::msgpack, subtype) &&9276get_binary(input_format_t::msgpack, len, result) &&9277assign_and_return_true(subtype);9278}92799280case 0xC9: // ext 329281{9282std::uint32_t len{};9283std::int8_t subtype{};9284return get_number(input_format_t::msgpack, len) &&9285get_number(input_format_t::msgpack, subtype) &&9286get_binary(input_format_t::msgpack, len, result) &&9287assign_and_return_true(subtype);9288}92899290case 0xD4: // fixext 19291{9292std::int8_t subtype{};9293return get_number(input_format_t::msgpack, subtype) &&9294get_binary(input_format_t::msgpack, 1, result) &&9295assign_and_return_true(subtype);9296}92979298case 0xD5: // fixext 29299{9300std::int8_t subtype{};9301return get_number(input_format_t::msgpack, subtype) &&9302get_binary(input_format_t::msgpack, 2, result) &&9303assign_and_return_true(subtype);9304}93059306case 0xD6: // fixext 49307{9308std::int8_t subtype{};9309return get_number(input_format_t::msgpack, subtype) &&9310get_binary(input_format_t::msgpack, 4, result) &&9311assign_and_return_true(subtype);9312}93139314case 0xD7: // fixext 89315{9316std::int8_t subtype{};9317return get_number(input_format_t::msgpack, subtype) &&9318get_binary(input_format_t::msgpack, 8, result) &&9319assign_and_return_true(subtype);9320}93219322case 0xD8: // fixext 169323{9324std::int8_t subtype{};9325return get_number(input_format_t::msgpack, subtype) &&9326get_binary(input_format_t::msgpack, 16, result) &&9327assign_and_return_true(subtype);9328}93299330default: // LCOV_EXCL_LINE9331return false; // LCOV_EXCL_LINE9332}9333}93349335/*!9336@param[in] len the length of the array9337@return whether array creation completed9338*/9339bool get_msgpack_array(const std::size_t len)9340{9341if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))9342{9343return false;9344}93459346for (std::size_t i = 0; i < len; ++i)9347{9348if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))9349{9350return false;9351}9352}93539354return sax->end_array();9355}93569357/*!9358@param[in] len the length of the object9359@return whether object creation completed9360*/9361bool get_msgpack_object(const std::size_t len)9362{9363if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))9364{9365return false;9366}93679368string_t key;9369for (std::size_t i = 0; i < len; ++i)9370{9371get();9372if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))9373{9374return false;9375}93769377if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))9378{9379return false;9380}9381key.clear();9382}93839384return sax->end_object();9385}93869387////////////9388// UBJSON //9389////////////93909391/*!9392@param[in] get_char whether a new character should be retrieved from the9393input (true, default) or whether the last read9394character should be considered instead93959396@return whether a valid UBJSON value was passed to the SAX parser9397*/9398bool parse_ubjson_internal(const bool get_char = true)9399{9400return get_ubjson_value(get_char ? get_ignore_noop() : current);9401}94029403/*!9404@brief reads a UBJSON string94059406This function is either called after reading the 'S' byte explicitly9407indicating a string, or in case of an object key where the 'S' byte can be9408left out.94099410@param[out] result created string9411@param[in] get_char whether a new character should be retrieved from the9412input (true, default) or whether the last read9413character should be considered instead94149415@return whether string creation completed9416*/9417bool get_ubjson_string(string_t& result, const bool get_char = true)9418{9419if (get_char)9420{9421get(); // TODO(niels): may we ignore N here?9422}94239424if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))9425{9426return false;9427}94289429switch (current)9430{9431case 'U':9432{9433std::uint8_t len{};9434return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);9435}94369437case 'i':9438{9439std::int8_t len{};9440return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);9441}94429443case 'I':9444{9445std::int16_t len{};9446return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);9447}94489449case 'l':9450{9451std::int32_t len{};9452return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);9453}94549455case 'L':9456{9457std::int64_t len{};9458return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);9459}94609461default:9462auto last_token = get_token_string();9463return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));9464}9465}94669467/*!9468@param[out] result determined size9469@return whether size determination completed9470*/9471bool get_ubjson_size_value(std::size_t& result)9472{9473switch (get_ignore_noop())9474{9475case 'U':9476{9477std::uint8_t number{};9478if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))9479{9480return false;9481}9482result = static_cast<std::size_t>(number);9483return true;9484}94859486case 'i':9487{9488std::int8_t number{};9489if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))9490{9491return false;9492}9493result = static_cast<std::size_t>(number);9494return true;9495}94969497case 'I':9498{9499std::int16_t number{};9500if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))9501{9502return false;9503}9504result = static_cast<std::size_t>(number);9505return true;9506}95079508case 'l':9509{9510std::int32_t number{};9511if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))9512{9513return false;9514}9515result = static_cast<std::size_t>(number);9516return true;9517}95189519case 'L':9520{9521std::int64_t number{};9522if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))9523{9524return false;9525}9526result = static_cast<std::size_t>(number);9527return true;9528}95299530default:9531{9532auto last_token = get_token_string();9533return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));9534}9535}9536}95379538/*!9539@brief determine the type and size for a container95409541In the optimized UBJSON format, a type and a size can be provided to allow9542for a more compact representation.95439544@param[out] result pair of the size and the type95459546@return whether pair creation completed9547*/9548bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)9549{9550result.first = string_t::npos; // size9551result.second = 0; // type95529553get_ignore_noop();95549555if (current == '$')9556{9557result.second = get(); // must not ignore 'N', because 'N' maybe the type9558if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))9559{9560return false;9561}95629563get_ignore_noop();9564if (JSON_HEDLEY_UNLIKELY(current != '#'))9565{9566if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))9567{9568return false;9569}9570auto last_token = get_token_string();9571return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));9572}95739574return get_ubjson_size_value(result.first);9575}95769577if (current == '#')9578{9579return get_ubjson_size_value(result.first);9580}95819582return true;9583}95849585/*!9586@param prefix the previously read or set type prefix9587@return whether value creation completed9588*/9589bool get_ubjson_value(const char_int_type prefix)9590{9591switch (prefix)9592{9593case std::char_traits<char_type>::eof(): // EOF9594return unexpect_eof(input_format_t::ubjson, "value");95959596case 'T': // true9597return sax->boolean(true);9598case 'F': // false9599return sax->boolean(false);96009601case 'Z': // null9602return sax->null();96039604case 'U':9605{9606std::uint8_t number{};9607return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);9608}96099610case 'i':9611{9612std::int8_t number{};9613return get_number(input_format_t::ubjson, number) && sax->number_integer(number);9614}96159616case 'I':9617{9618std::int16_t number{};9619return get_number(input_format_t::ubjson, number) && sax->number_integer(number);9620}96219622case 'l':9623{9624std::int32_t number{};9625return get_number(input_format_t::ubjson, number) && sax->number_integer(number);9626}96279628case 'L':9629{9630std::int64_t number{};9631return get_number(input_format_t::ubjson, number) && sax->number_integer(number);9632}96339634case 'd':9635{9636float number{};9637return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");9638}96399640case 'D':9641{9642double number{};9643return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");9644}96459646case 'H':9647{9648return get_ubjson_high_precision_number();9649}96509651case 'C': // char9652{9653get();9654if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))9655{9656return false;9657}9658if (JSON_HEDLEY_UNLIKELY(current > 127))9659{9660auto last_token = get_token_string();9661return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));9662}9663string_t s(1, static_cast<typename string_t::value_type>(current));9664return sax->string(s);9665}96669667case 'S': // string9668{9669string_t s;9670return get_ubjson_string(s) && sax->string(s);9671}96729673case '[': // array9674return get_ubjson_array();96759676case '{': // object9677return get_ubjson_object();96789679default: // anything else9680{9681auto last_token = get_token_string();9682return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));9683}9684}9685}96869687/*!9688@return whether array creation completed9689*/9690bool get_ubjson_array()9691{9692std::pair<std::size_t, char_int_type> size_and_type;9693if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))9694{9695return false;9696}96979698if (size_and_type.first != string_t::npos)9699{9700if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))9701{9702return false;9703}97049705if (size_and_type.second != 0)9706{9707if (size_and_type.second != 'N')9708{9709for (std::size_t i = 0; i < size_and_type.first; ++i)9710{9711if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))9712{9713return false;9714}9715}9716}9717}9718else9719{9720for (std::size_t i = 0; i < size_and_type.first; ++i)9721{9722if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))9723{9724return false;9725}9726}9727}9728}9729else9730{9731if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))9732{9733return false;9734}97359736while (current != ']')9737{9738if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))9739{9740return false;9741}9742get_ignore_noop();9743}9744}97459746return sax->end_array();9747}97489749/*!9750@return whether object creation completed9751*/9752bool get_ubjson_object()9753{9754std::pair<std::size_t, char_int_type> size_and_type;9755if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))9756{9757return false;9758}97599760string_t key;9761if (size_and_type.first != string_t::npos)9762{9763if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))9764{9765return false;9766}97679768if (size_and_type.second != 0)9769{9770for (std::size_t i = 0; i < size_and_type.first; ++i)9771{9772if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))9773{9774return false;9775}9776if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))9777{9778return false;9779}9780key.clear();9781}9782}9783else9784{9785for (std::size_t i = 0; i < size_and_type.first; ++i)9786{9787if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))9788{9789return false;9790}9791if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))9792{9793return false;9794}9795key.clear();9796}9797}9798}9799else9800{9801if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))9802{9803return false;9804}98059806while (current != '}')9807{9808if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))9809{9810return false;9811}9812if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))9813{9814return false;9815}9816get_ignore_noop();9817key.clear();9818}9819}98209821return sax->end_object();9822}98239824// Note, no reader for UBJSON binary types is implemented because they do9825// not exist98269827bool get_ubjson_high_precision_number()9828{9829// get size of following number string9830std::size_t size{};9831auto res = get_ubjson_size_value(size);9832if (JSON_HEDLEY_UNLIKELY(!res))9833{9834return res;9835}98369837// get number string9838std::vector<char> number_vector;9839for (std::size_t i = 0; i < size; ++i)9840{9841get();9842if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))9843{9844return false;9845}9846number_vector.push_back(static_cast<char>(current));9847}98489849// parse number string9850auto number_ia = detail::input_adapter(std::forward<decltype(number_vector)>(number_vector));9851auto number_lexer = detail::lexer<BasicJsonType, decltype(number_ia)>(std::move(number_ia), false);9852const auto result_number = number_lexer.scan();9853const auto number_string = number_lexer.get_token_string();9854const auto result_remainder = number_lexer.scan();98559856using token_type = typename detail::lexer_base<BasicJsonType>::token_type;98579858if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))9859{9860return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));9861}98629863switch (result_number)9864{9865case token_type::value_integer:9866return sax->number_integer(number_lexer.get_number_integer());9867case token_type::value_unsigned:9868return sax->number_unsigned(number_lexer.get_number_unsigned());9869case token_type::value_float:9870return sax->number_float(number_lexer.get_number_float(), std::move(number_string));9871default:9872return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));9873}9874}98759876///////////////////////9877// Utility functions //9878///////////////////////98799880/*!9881@brief get next character from the input98829883This function provides the interface to the used input adapter. It does9884not throw in case the input reached EOF, but returns a -'ve valued9885`std::char_traits<char_type>::eof()` in that case.98869887@return character read from the input9888*/9889char_int_type get()9890{9891++chars_read;9892return current = ia.get_character();9893}98949895/*!9896@return character read from the input after ignoring all 'N' entries9897*/9898char_int_type get_ignore_noop()9899{9900do9901{9902get();9903}9904while (current == 'N');99059906return current;9907}99089909/*9910@brief read a number from the input99119912@tparam NumberType the type of the number9913@param[in] format the current format (for diagnostics)9914@param[out] result number of type @a NumberType99159916@return whether conversion completed99179918@note This function needs to respect the system's endianess, because9919bytes in CBOR, MessagePack, and UBJSON are stored in network order9920(big endian) and therefore need reordering on little endian systems.9921*/9922template<typename NumberType, bool InputIsLittleEndian = false>9923bool get_number(const input_format_t format, NumberType& result)9924{9925// step 1: read input into array with system's byte order9926std::array<std::uint8_t, sizeof(NumberType)> vec;9927for (std::size_t i = 0; i < sizeof(NumberType); ++i)9928{9929get();9930if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))9931{9932return false;9933}99349935// reverse byte order prior to conversion if necessary9936if (is_little_endian != InputIsLittleEndian)9937{9938vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);9939}9940else9941{9942vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE9943}9944}99459946// step 2: convert array into number of type T and return9947std::memcpy(&result, vec.data(), sizeof(NumberType));9948return true;9949}99509951/*!9952@brief create a string by reading characters from the input99539954@tparam NumberType the type of the number9955@param[in] format the current format (for diagnostics)9956@param[in] len number of characters to read9957@param[out] result string created by reading @a len bytes99589959@return whether string creation completed99609961@note We can not reserve @a len bytes for the result, because @a len9962may be too large. Usually, @ref unexpect_eof() detects the end of9963the input before we run out of string memory.9964*/9965template<typename NumberType>9966bool get_string(const input_format_t format,9967const NumberType len,9968string_t& result)9969{9970bool success = true;9971for (NumberType i = 0; i < len; i++)9972{9973get();9974if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))9975{9976success = false;9977break;9978}9979result.push_back(static_cast<typename string_t::value_type>(current));9980};9981return success;9982}99839984/*!9985@brief create a byte array by reading bytes from the input99869987@tparam NumberType the type of the number9988@param[in] format the current format (for diagnostics)9989@param[in] len number of bytes to read9990@param[out] result byte array created by reading @a len bytes99919992@return whether byte array creation completed99939994@note We can not reserve @a len bytes for the result, because @a len9995may be too large. Usually, @ref unexpect_eof() detects the end of9996the input before we run out of memory.9997*/9998template<typename NumberType>9999bool get_binary(const input_format_t format,10000const NumberType len,10001binary_t& result)10002{10003bool success = true;10004for (NumberType i = 0; i < len; i++)10005{10006get();10007if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))10008{10009success = false;10010break;10011}10012result.push_back(static_cast<std::uint8_t>(current));10013}10014return success;10015}1001610017/*!10018@param[in] format the current format (for diagnostics)10019@param[in] context further context information (for diagnostics)10020@return whether the last read character is not EOF10021*/10022JSON_HEDLEY_NON_NULL(3)10023bool unexpect_eof(const input_format_t format, const char* context) const10024{10025if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))10026{10027return sax->parse_error(chars_read, "<end of file>",10028parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));10029}10030return true;10031}1003210033/*!10034@return a string representation of the last read byte10035*/10036std::string get_token_string() const10037{10038std::array<char, 3> cr{{}};10039(std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));10040return std::string{cr.data()};10041}1004210043/*!10044@param[in] format the current format10045@param[in] detail a detailed error message10046@param[in] context further context information10047@return a message string to use in the parse_error exceptions10048*/10049std::string exception_message(const input_format_t format,10050const std::string& detail,10051const std::string& context) const10052{10053std::string error_msg = "syntax error while parsing ";1005410055switch (format)10056{10057case input_format_t::cbor:10058error_msg += "CBOR";10059break;1006010061case input_format_t::msgpack:10062error_msg += "MessagePack";10063break;1006410065case input_format_t::ubjson:10066error_msg += "UBJSON";10067break;1006810069case input_format_t::bson:10070error_msg += "BSON";10071break;1007210073default: // LCOV_EXCL_LINE10074JSON_ASSERT(false); // LCOV_EXCL_LINE10075}1007610077return error_msg + " " + context + ": " + detail;10078}1007910080private:10081/// input adapter10082InputAdapterType ia;1008310084/// the current character10085char_int_type current = std::char_traits<char_type>::eof();1008610087/// the number of characters read10088std::size_t chars_read = 0;1008910090/// whether we can assume little endianess10091const bool is_little_endian = little_endianess();1009210093/// the SAX parser10094json_sax_t* sax = nullptr;10095};10096} // namespace detail10097} // namespace nlohmann1009810099// #include <nlohmann/detail/input/input_adapters.hpp>1010010101// #include <nlohmann/detail/input/lexer.hpp>1010210103// #include <nlohmann/detail/input/parser.hpp>101041010510106#include <cmath> // isfinite10107#include <cstdint> // uint8_t10108#include <functional> // function10109#include <string> // string10110#include <utility> // move10111#include <vector> // vector1011210113// #include <nlohmann/detail/exceptions.hpp>1011410115// #include <nlohmann/detail/input/input_adapters.hpp>1011610117// #include <nlohmann/detail/input/json_sax.hpp>1011810119// #include <nlohmann/detail/input/lexer.hpp>1012010121// #include <nlohmann/detail/macro_scope.hpp>1012210123// #include <nlohmann/detail/meta/is_sax.hpp>1012410125// #include <nlohmann/detail/value_t.hpp>101261012710128namespace nlohmann10129{10130namespace detail10131{10132////////////10133// parser //10134////////////1013510136enum class parse_event_t : uint8_t10137{10138/// the parser read `{` and started to process a JSON object10139object_start,10140/// the parser read `}` and finished processing a JSON object10141object_end,10142/// the parser read `[` and started to process a JSON array10143array_start,10144/// the parser read `]` and finished processing a JSON array10145array_end,10146/// the parser read a key of a value in an object10147key,10148/// the parser finished reading a JSON value10149value10150};1015110152template<typename BasicJsonType>10153using parser_callback_t =10154std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;1015510156/*!10157@brief syntax analysis1015810159This class implements a recursive descent parser.10160*/10161template<typename BasicJsonType, typename InputAdapterType>10162class parser10163{10164using number_integer_t = typename BasicJsonType::number_integer_t;10165using number_unsigned_t = typename BasicJsonType::number_unsigned_t;10166using number_float_t = typename BasicJsonType::number_float_t;10167using string_t = typename BasicJsonType::string_t;10168using lexer_t = lexer<BasicJsonType, InputAdapterType>;10169using token_type = typename lexer_t::token_type;1017010171public:10172/// a parser reading from an input adapter10173explicit parser(InputAdapterType&& adapter,10174const parser_callback_t<BasicJsonType> cb = nullptr,10175const bool allow_exceptions_ = true,10176const bool skip_comments = false)10177: callback(cb)10178, m_lexer(std::move(adapter), skip_comments)10179, allow_exceptions(allow_exceptions_)10180{10181// read first token10182get_token();10183}1018410185/*!10186@brief public parser interface1018710188@param[in] strict whether to expect the last token to be EOF10189@param[in,out] result parsed JSON value1019010191@throw parse_error.101 in case of an unexpected token10192@throw parse_error.102 if to_unicode fails or surrogate error10193@throw parse_error.103 if to_unicode fails10194*/10195void parse(const bool strict, BasicJsonType& result)10196{10197if (callback)10198{10199json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);10200sax_parse_internal(&sdp);10201result.assert_invariant();1020210203// in strict mode, input must be completely read10204if (strict && (get_token() != token_type::end_of_input))10205{10206sdp.parse_error(m_lexer.get_position(),10207m_lexer.get_token_string(),10208parse_error::create(101, m_lexer.get_position(),10209exception_message(token_type::end_of_input, "value")));10210}1021110212// in case of an error, return discarded value10213if (sdp.is_errored())10214{10215result = value_t::discarded;10216return;10217}1021810219// set top-level value to null if it was discarded by the callback10220// function10221if (result.is_discarded())10222{10223result = nullptr;10224}10225}10226else10227{10228json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);10229sax_parse_internal(&sdp);10230result.assert_invariant();1023110232// in strict mode, input must be completely read10233if (strict && (get_token() != token_type::end_of_input))10234{10235sdp.parse_error(m_lexer.get_position(),10236m_lexer.get_token_string(),10237parse_error::create(101, m_lexer.get_position(),10238exception_message(token_type::end_of_input, "value")));10239}1024010241// in case of an error, return discarded value10242if (sdp.is_errored())10243{10244result = value_t::discarded;10245return;10246}10247}10248}1024910250/*!10251@brief public accept interface1025210253@param[in] strict whether to expect the last token to be EOF10254@return whether the input is a proper JSON text10255*/10256bool accept(const bool strict = true)10257{10258json_sax_acceptor<BasicJsonType> sax_acceptor;10259return sax_parse(&sax_acceptor, strict);10260}1026110262template<typename SAX>10263JSON_HEDLEY_NON_NULL(2)10264bool sax_parse(SAX* sax, const bool strict = true)10265{10266(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};10267const bool result = sax_parse_internal(sax);1026810269// strict mode: next byte must be EOF10270if (result && strict && (get_token() != token_type::end_of_input))10271{10272return sax->parse_error(m_lexer.get_position(),10273m_lexer.get_token_string(),10274parse_error::create(101, m_lexer.get_position(),10275exception_message(token_type::end_of_input, "value")));10276}1027710278return result;10279}1028010281private:10282template<typename SAX>10283JSON_HEDLEY_NON_NULL(2)10284bool sax_parse_internal(SAX* sax)10285{10286// stack to remember the hierarchy of structured values we are parsing10287// true = array; false = object10288std::vector<bool> states;10289// value to avoid a goto (see comment where set to true)10290bool skip_to_state_evaluation = false;1029110292while (true)10293{10294if (!skip_to_state_evaluation)10295{10296// invariant: get_token() was called before each iteration10297switch (last_token)10298{10299case token_type::begin_object:10300{10301if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))10302{10303return false;10304}1030510306// closing } -> we are done10307if (get_token() == token_type::end_object)10308{10309if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))10310{10311return false;10312}10313break;10314}1031510316// parse key10317if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))10318{10319return sax->parse_error(m_lexer.get_position(),10320m_lexer.get_token_string(),10321parse_error::create(101, m_lexer.get_position(),10322exception_message(token_type::value_string, "object key")));10323}10324if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))10325{10326return false;10327}1032810329// parse separator (:)10330if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))10331{10332return sax->parse_error(m_lexer.get_position(),10333m_lexer.get_token_string(),10334parse_error::create(101, m_lexer.get_position(),10335exception_message(token_type::name_separator, "object separator")));10336}1033710338// remember we are now inside an object10339states.push_back(false);1034010341// parse values10342get_token();10343continue;10344}1034510346case token_type::begin_array:10347{10348if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))10349{10350return false;10351}1035210353// closing ] -> we are done10354if (get_token() == token_type::end_array)10355{10356if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))10357{10358return false;10359}10360break;10361}1036210363// remember we are now inside an array10364states.push_back(true);1036510366// parse values (no need to call get_token)10367continue;10368}1036910370case token_type::value_float:10371{10372const auto res = m_lexer.get_number_float();1037310374if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))10375{10376return sax->parse_error(m_lexer.get_position(),10377m_lexer.get_token_string(),10378out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));10379}1038010381if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))10382{10383return false;10384}1038510386break;10387}1038810389case token_type::literal_false:10390{10391if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))10392{10393return false;10394}10395break;10396}1039710398case token_type::literal_null:10399{10400if (JSON_HEDLEY_UNLIKELY(!sax->null()))10401{10402return false;10403}10404break;10405}1040610407case token_type::literal_true:10408{10409if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))10410{10411return false;10412}10413break;10414}1041510416case token_type::value_integer:10417{10418if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))10419{10420return false;10421}10422break;10423}1042410425case token_type::value_string:10426{10427if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))10428{10429return false;10430}10431break;10432}1043310434case token_type::value_unsigned:10435{10436if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))10437{10438return false;10439}10440break;10441}1044210443case token_type::parse_error:10444{10445// using "uninitialized" to avoid "expected" message10446return sax->parse_error(m_lexer.get_position(),10447m_lexer.get_token_string(),10448parse_error::create(101, m_lexer.get_position(),10449exception_message(token_type::uninitialized, "value")));10450}1045110452default: // the last token was unexpected10453{10454return sax->parse_error(m_lexer.get_position(),10455m_lexer.get_token_string(),10456parse_error::create(101, m_lexer.get_position(),10457exception_message(token_type::literal_or_value, "value")));10458}10459}10460}10461else10462{10463skip_to_state_evaluation = false;10464}1046510466// we reached this line after we successfully parsed a value10467if (states.empty())10468{10469// empty stack: we reached the end of the hierarchy: done10470return true;10471}1047210473if (states.back()) // array10474{10475// comma -> next value10476if (get_token() == token_type::value_separator)10477{10478// parse a new value10479get_token();10480continue;10481}1048210483// closing ]10484if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))10485{10486if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))10487{10488return false;10489}1049010491// We are done with this array. Before we can parse a10492// new value, we need to evaluate the new state first.10493// By setting skip_to_state_evaluation to false, we10494// are effectively jumping to the beginning of this if.10495JSON_ASSERT(!states.empty());10496states.pop_back();10497skip_to_state_evaluation = true;10498continue;10499}1050010501return sax->parse_error(m_lexer.get_position(),10502m_lexer.get_token_string(),10503parse_error::create(101, m_lexer.get_position(),10504exception_message(token_type::end_array, "array")));10505}10506else // object10507{10508// comma -> next value10509if (get_token() == token_type::value_separator)10510{10511// parse key10512if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))10513{10514return sax->parse_error(m_lexer.get_position(),10515m_lexer.get_token_string(),10516parse_error::create(101, m_lexer.get_position(),10517exception_message(token_type::value_string, "object key")));10518}1051910520if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))10521{10522return false;10523}1052410525// parse separator (:)10526if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))10527{10528return sax->parse_error(m_lexer.get_position(),10529m_lexer.get_token_string(),10530parse_error::create(101, m_lexer.get_position(),10531exception_message(token_type::name_separator, "object separator")));10532}1053310534// parse values10535get_token();10536continue;10537}1053810539// closing }10540if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))10541{10542if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))10543{10544return false;10545}1054610547// We are done with this object. Before we can parse a10548// new value, we need to evaluate the new state first.10549// By setting skip_to_state_evaluation to false, we10550// are effectively jumping to the beginning of this if.10551JSON_ASSERT(!states.empty());10552states.pop_back();10553skip_to_state_evaluation = true;10554continue;10555}1055610557return sax->parse_error(m_lexer.get_position(),10558m_lexer.get_token_string(),10559parse_error::create(101, m_lexer.get_position(),10560exception_message(token_type::end_object, "object")));10561}10562}10563}1056410565/// get next token from lexer10566token_type get_token()10567{10568return last_token = m_lexer.scan();10569}1057010571std::string exception_message(const token_type expected, const std::string& context)10572{10573std::string error_msg = "syntax error ";1057410575if (!context.empty())10576{10577error_msg += "while parsing " + context + " ";10578}1057910580error_msg += "- ";1058110582if (last_token == token_type::parse_error)10583{10584error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +10585m_lexer.get_token_string() + "'";10586}10587else10588{10589error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));10590}1059110592if (expected != token_type::uninitialized)10593{10594error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));10595}1059610597return error_msg;10598}1059910600private:10601/// callback function10602const parser_callback_t<BasicJsonType> callback = nullptr;10603/// the type of the last read token10604token_type last_token = token_type::uninitialized;10605/// the lexer10606lexer_t m_lexer;10607/// whether to throw exceptions in case of errors10608const bool allow_exceptions = true;10609};10610} // namespace detail10611} // namespace nlohmann1061210613// #include <nlohmann/detail/iterators/internal_iterator.hpp>106141061510616// #include <nlohmann/detail/iterators/primitive_iterator.hpp>106171061810619#include <cstddef> // ptrdiff_t10620#include <limits> // numeric_limits1062110622namespace nlohmann10623{10624namespace detail10625{10626/*10627@brief an iterator for primitive JSON types1062810629This class models an iterator for primitive JSON types (boolean, number,10630string). It's only purpose is to allow the iterator/const_iterator classes10631to "iterate" over primitive values. Internally, the iterator is modeled by10632a `difference_type` variable. Value begin_value (`0`) models the begin,10633end_value (`1`) models past the end.10634*/10635class primitive_iterator_t10636{10637private:10638using difference_type = std::ptrdiff_t;10639static constexpr difference_type begin_value = 0;10640static constexpr difference_type end_value = begin_value + 1;1064110642/// iterator as signed integer type10643difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();1064410645public:10646constexpr difference_type get_value() const noexcept10647{10648return m_it;10649}1065010651/// set iterator to a defined beginning10652void set_begin() noexcept10653{10654m_it = begin_value;10655}1065610657/// set iterator to a defined past the end10658void set_end() noexcept10659{10660m_it = end_value;10661}1066210663/// return whether the iterator can be dereferenced10664constexpr bool is_begin() const noexcept10665{10666return m_it == begin_value;10667}1066810669/// return whether the iterator is at end10670constexpr bool is_end() const noexcept10671{10672return m_it == end_value;10673}1067410675friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept10676{10677return lhs.m_it == rhs.m_it;10678}1067910680friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept10681{10682return lhs.m_it < rhs.m_it;10683}1068410685primitive_iterator_t operator+(difference_type n) noexcept10686{10687auto result = *this;10688result += n;10689return result;10690}1069110692friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept10693{10694return lhs.m_it - rhs.m_it;10695}1069610697primitive_iterator_t& operator++() noexcept10698{10699++m_it;10700return *this;10701}1070210703primitive_iterator_t const operator++(int) noexcept10704{10705auto result = *this;10706++m_it;10707return result;10708}1070910710primitive_iterator_t& operator--() noexcept10711{10712--m_it;10713return *this;10714}1071510716primitive_iterator_t const operator--(int) noexcept10717{10718auto result = *this;10719--m_it;10720return result;10721}1072210723primitive_iterator_t& operator+=(difference_type n) noexcept10724{10725m_it += n;10726return *this;10727}1072810729primitive_iterator_t& operator-=(difference_type n) noexcept10730{10731m_it -= n;10732return *this;10733}10734};10735} // namespace detail10736} // namespace nlohmann107371073810739namespace nlohmann10740{10741namespace detail10742{10743/*!10744@brief an iterator value1074510746@note This structure could easily be a union, but MSVC currently does not allow10747unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.10748*/10749template<typename BasicJsonType> struct internal_iterator10750{10751/// iterator for JSON objects10752typename BasicJsonType::object_t::iterator object_iterator {};10753/// iterator for JSON arrays10754typename BasicJsonType::array_t::iterator array_iterator {};10755/// generic iterator for all other types10756primitive_iterator_t primitive_iterator {};10757};10758} // namespace detail10759} // namespace nlohmann1076010761// #include <nlohmann/detail/iterators/iter_impl.hpp>107621076310764#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next10765#include <type_traits> // conditional, is_const, remove_const1076610767// #include <nlohmann/detail/exceptions.hpp>1076810769// #include <nlohmann/detail/iterators/internal_iterator.hpp>1077010771// #include <nlohmann/detail/iterators/primitive_iterator.hpp>1077210773// #include <nlohmann/detail/macro_scope.hpp>1077410775// #include <nlohmann/detail/meta/cpp_future.hpp>1077610777// #include <nlohmann/detail/meta/type_traits.hpp>1077810779// #include <nlohmann/detail/value_t.hpp>107801078110782namespace nlohmann10783{10784namespace detail10785{10786// forward declare, to be able to friend it later on10787template<typename IteratorType> class iteration_proxy;10788template<typename IteratorType> class iteration_proxy_value;1078910790/*!10791@brief a template for a bidirectional iterator for the @ref basic_json class10792This class implements a both iterators (iterator and const_iterator) for the10793@ref basic_json class.10794@note An iterator is called *initialized* when a pointer to a JSON value has10795been set (e.g., by a constructor or a copy assignment). If the iterator is10796default-constructed, it is *uninitialized* and most methods are undefined.10797**The library uses assertions to detect calls on uninitialized iterators.**10798@requirement The class satisfies the following concept requirements:10799-10800[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):10801The iterator that can be moved can be moved in both directions (i.e.10802incremented and decremented).10803@since version 1.0.0, simplified in version 2.0.9, change to bidirectional10804iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)10805*/10806template<typename BasicJsonType>10807class iter_impl10808{10809/// allow basic_json to access private members10810friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;10811friend BasicJsonType;10812friend iteration_proxy<iter_impl>;10813friend iteration_proxy_value<iter_impl>;1081410815using object_t = typename BasicJsonType::object_t;10816using array_t = typename BasicJsonType::array_t;10817// make sure BasicJsonType is basic_json or const basic_json10818static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,10819"iter_impl only accepts (const) basic_json");1082010821public:1082210823/// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.10824/// The C++ Standard has never required user-defined iterators to derive from std::iterator.10825/// A user-defined iterator should provide publicly accessible typedefs named10826/// iterator_category, value_type, difference_type, pointer, and reference.10827/// Note that value_type is required to be non-const, even for constant iterators.10828using iterator_category = std::bidirectional_iterator_tag;1082910830/// the type of the values when the iterator is dereferenced10831using value_type = typename BasicJsonType::value_type;10832/// a type to represent differences between iterators10833using difference_type = typename BasicJsonType::difference_type;10834/// defines a pointer to the type iterated over (value_type)10835using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,10836typename BasicJsonType::const_pointer,10837typename BasicJsonType::pointer>::type;10838/// defines a reference to the type iterated over (value_type)10839using reference =10840typename std::conditional<std::is_const<BasicJsonType>::value,10841typename BasicJsonType::const_reference,10842typename BasicJsonType::reference>::type;1084310844/// default constructor10845iter_impl() = default;1084610847/*!10848@brief constructor for a given JSON instance10849@param[in] object pointer to a JSON object for this iterator10850@pre object != nullptr10851@post The iterator is initialized; i.e. `m_object != nullptr`.10852*/10853explicit iter_impl(pointer object) noexcept : m_object(object)10854{10855JSON_ASSERT(m_object != nullptr);1085610857switch (m_object->m_type)10858{10859case value_t::object:10860{10861m_it.object_iterator = typename object_t::iterator();10862break;10863}1086410865case value_t::array:10866{10867m_it.array_iterator = typename array_t::iterator();10868break;10869}1087010871default:10872{10873m_it.primitive_iterator = primitive_iterator_t();10874break;10875}10876}10877}1087810879/*!10880@note The conventional copy constructor and copy assignment are implicitly10881defined. Combined with the following converting constructor and10882assignment, they support: (1) copy from iterator to iterator, (2)10883copy from const iterator to const iterator, and (3) conversion from10884iterator to const iterator. However conversion from const iterator10885to iterator is not defined.10886*/1088710888/*!10889@brief const copy constructor10890@param[in] other const iterator to copy from10891@note This copy constructor had to be defined explicitly to circumvent a bug10892occurring on msvc v19.0 compiler (VS 2015) debug build. For more10893information refer to: https://github.com/nlohmann/json/issues/160810894*/10895iter_impl(const iter_impl<const BasicJsonType>& other) noexcept10896: m_object(other.m_object), m_it(other.m_it)10897{}1089810899/*!10900@brief converting assignment10901@param[in] other const iterator to copy from10902@return const/non-const iterator10903@note It is not checked whether @a other is initialized.10904*/10905iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept10906{10907m_object = other.m_object;10908m_it = other.m_it;10909return *this;10910}1091110912/*!10913@brief converting constructor10914@param[in] other non-const iterator to copy from10915@note It is not checked whether @a other is initialized.10916*/10917iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept10918: m_object(other.m_object), m_it(other.m_it)10919{}1092010921/*!10922@brief converting assignment10923@param[in] other non-const iterator to copy from10924@return const/non-const iterator10925@note It is not checked whether @a other is initialized.10926*/10927iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept10928{10929m_object = other.m_object;10930m_it = other.m_it;10931return *this;10932}1093310934private:10935/*!10936@brief set the iterator to the first value10937@pre The iterator is initialized; i.e. `m_object != nullptr`.10938*/10939void set_begin() noexcept10940{10941JSON_ASSERT(m_object != nullptr);1094210943switch (m_object->m_type)10944{10945case value_t::object:10946{10947m_it.object_iterator = m_object->m_value.object->begin();10948break;10949}1095010951case value_t::array:10952{10953m_it.array_iterator = m_object->m_value.array->begin();10954break;10955}1095610957case value_t::null:10958{10959// set to end so begin()==end() is true: null is empty10960m_it.primitive_iterator.set_end();10961break;10962}1096310964default:10965{10966m_it.primitive_iterator.set_begin();10967break;10968}10969}10970}1097110972/*!10973@brief set the iterator past the last value10974@pre The iterator is initialized; i.e. `m_object != nullptr`.10975*/10976void set_end() noexcept10977{10978JSON_ASSERT(m_object != nullptr);1097910980switch (m_object->m_type)10981{10982case value_t::object:10983{10984m_it.object_iterator = m_object->m_value.object->end();10985break;10986}1098710988case value_t::array:10989{10990m_it.array_iterator = m_object->m_value.array->end();10991break;10992}1099310994default:10995{10996m_it.primitive_iterator.set_end();10997break;10998}10999}11000}1100111002public:11003/*!11004@brief return a reference to the value pointed to by the iterator11005@pre The iterator is initialized; i.e. `m_object != nullptr`.11006*/11007reference operator*() const11008{11009JSON_ASSERT(m_object != nullptr);1101011011switch (m_object->m_type)11012{11013case value_t::object:11014{11015JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());11016return m_it.object_iterator->second;11017}1101811019case value_t::array:11020{11021JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());11022return *m_it.array_iterator;11023}1102411025case value_t::null:11026JSON_THROW(invalid_iterator::create(214, "cannot get value"));1102711028default:11029{11030if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))11031{11032return *m_object;11033}1103411035JSON_THROW(invalid_iterator::create(214, "cannot get value"));11036}11037}11038}1103911040/*!11041@brief dereference the iterator11042@pre The iterator is initialized; i.e. `m_object != nullptr`.11043*/11044pointer operator->() const11045{11046JSON_ASSERT(m_object != nullptr);1104711048switch (m_object->m_type)11049{11050case value_t::object:11051{11052JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());11053return &(m_it.object_iterator->second);11054}1105511056case value_t::array:11057{11058JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());11059return &*m_it.array_iterator;11060}1106111062default:11063{11064if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))11065{11066return m_object;11067}1106811069JSON_THROW(invalid_iterator::create(214, "cannot get value"));11070}11071}11072}1107311074/*!11075@brief post-increment (it++)11076@pre The iterator is initialized; i.e. `m_object != nullptr`.11077*/11078iter_impl const operator++(int)11079{11080auto result = *this;11081++(*this);11082return result;11083}1108411085/*!11086@brief pre-increment (++it)11087@pre The iterator is initialized; i.e. `m_object != nullptr`.11088*/11089iter_impl& operator++()11090{11091JSON_ASSERT(m_object != nullptr);1109211093switch (m_object->m_type)11094{11095case value_t::object:11096{11097std::advance(m_it.object_iterator, 1);11098break;11099}1110011101case value_t::array:11102{11103std::advance(m_it.array_iterator, 1);11104break;11105}1110611107default:11108{11109++m_it.primitive_iterator;11110break;11111}11112}1111311114return *this;11115}1111611117/*!11118@brief post-decrement (it--)11119@pre The iterator is initialized; i.e. `m_object != nullptr`.11120*/11121iter_impl const operator--(int)11122{11123auto result = *this;11124--(*this);11125return result;11126}1112711128/*!11129@brief pre-decrement (--it)11130@pre The iterator is initialized; i.e. `m_object != nullptr`.11131*/11132iter_impl& operator--()11133{11134JSON_ASSERT(m_object != nullptr);1113511136switch (m_object->m_type)11137{11138case value_t::object:11139{11140std::advance(m_it.object_iterator, -1);11141break;11142}1114311144case value_t::array:11145{11146std::advance(m_it.array_iterator, -1);11147break;11148}1114911150default:11151{11152--m_it.primitive_iterator;11153break;11154}11155}1115611157return *this;11158}1115911160/*!11161@brief comparison: equal11162@pre The iterator is initialized; i.e. `m_object != nullptr`.11163*/11164bool operator==(const iter_impl& other) const11165{11166// if objects are not the same, the comparison is undefined11167if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))11168{11169JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));11170}1117111172JSON_ASSERT(m_object != nullptr);1117311174switch (m_object->m_type)11175{11176case value_t::object:11177return (m_it.object_iterator == other.m_it.object_iterator);1117811179case value_t::array:11180return (m_it.array_iterator == other.m_it.array_iterator);1118111182default:11183return (m_it.primitive_iterator == other.m_it.primitive_iterator);11184}11185}1118611187/*!11188@brief comparison: not equal11189@pre The iterator is initialized; i.e. `m_object != nullptr`.11190*/11191bool operator!=(const iter_impl& other) const11192{11193return !operator==(other);11194}1119511196/*!11197@brief comparison: smaller11198@pre The iterator is initialized; i.e. `m_object != nullptr`.11199*/11200bool operator<(const iter_impl& other) const11201{11202// if objects are not the same, the comparison is undefined11203if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))11204{11205JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));11206}1120711208JSON_ASSERT(m_object != nullptr);1120911210switch (m_object->m_type)11211{11212case value_t::object:11213JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));1121411215case value_t::array:11216return (m_it.array_iterator < other.m_it.array_iterator);1121711218default:11219return (m_it.primitive_iterator < other.m_it.primitive_iterator);11220}11221}1122211223/*!11224@brief comparison: less than or equal11225@pre The iterator is initialized; i.e. `m_object != nullptr`.11226*/11227bool operator<=(const iter_impl& other) const11228{11229return !other.operator < (*this);11230}1123111232/*!11233@brief comparison: greater than11234@pre The iterator is initialized; i.e. `m_object != nullptr`.11235*/11236bool operator>(const iter_impl& other) const11237{11238return !operator<=(other);11239}1124011241/*!11242@brief comparison: greater than or equal11243@pre The iterator is initialized; i.e. `m_object != nullptr`.11244*/11245bool operator>=(const iter_impl& other) const11246{11247return !operator<(other);11248}1124911250/*!11251@brief add to iterator11252@pre The iterator is initialized; i.e. `m_object != nullptr`.11253*/11254iter_impl& operator+=(difference_type i)11255{11256JSON_ASSERT(m_object != nullptr);1125711258switch (m_object->m_type)11259{11260case value_t::object:11261JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));1126211263case value_t::array:11264{11265std::advance(m_it.array_iterator, i);11266break;11267}1126811269default:11270{11271m_it.primitive_iterator += i;11272break;11273}11274}1127511276return *this;11277}1127811279/*!11280@brief subtract from iterator11281@pre The iterator is initialized; i.e. `m_object != nullptr`.11282*/11283iter_impl& operator-=(difference_type i)11284{11285return operator+=(-i);11286}1128711288/*!11289@brief add to iterator11290@pre The iterator is initialized; i.e. `m_object != nullptr`.11291*/11292iter_impl operator+(difference_type i) const11293{11294auto result = *this;11295result += i;11296return result;11297}1129811299/*!11300@brief addition of distance and iterator11301@pre The iterator is initialized; i.e. `m_object != nullptr`.11302*/11303friend iter_impl operator+(difference_type i, const iter_impl& it)11304{11305auto result = it;11306result += i;11307return result;11308}1130911310/*!11311@brief subtract from iterator11312@pre The iterator is initialized; i.e. `m_object != nullptr`.11313*/11314iter_impl operator-(difference_type i) const11315{11316auto result = *this;11317result -= i;11318return result;11319}1132011321/*!11322@brief return difference11323@pre The iterator is initialized; i.e. `m_object != nullptr`.11324*/11325difference_type operator-(const iter_impl& other) const11326{11327JSON_ASSERT(m_object != nullptr);1132811329switch (m_object->m_type)11330{11331case value_t::object:11332JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));1133311334case value_t::array:11335return m_it.array_iterator - other.m_it.array_iterator;1133611337default:11338return m_it.primitive_iterator - other.m_it.primitive_iterator;11339}11340}1134111342/*!11343@brief access to successor11344@pre The iterator is initialized; i.e. `m_object != nullptr`.11345*/11346reference operator[](difference_type n) const11347{11348JSON_ASSERT(m_object != nullptr);1134911350switch (m_object->m_type)11351{11352case value_t::object:11353JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));1135411355case value_t::array:11356return *std::next(m_it.array_iterator, n);1135711358case value_t::null:11359JSON_THROW(invalid_iterator::create(214, "cannot get value"));1136011361default:11362{11363if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))11364{11365return *m_object;11366}1136711368JSON_THROW(invalid_iterator::create(214, "cannot get value"));11369}11370}11371}1137211373/*!11374@brief return the key of an object iterator11375@pre The iterator is initialized; i.e. `m_object != nullptr`.11376*/11377const typename object_t::key_type& key() const11378{11379JSON_ASSERT(m_object != nullptr);1138011381if (JSON_HEDLEY_LIKELY(m_object->is_object()))11382{11383return m_it.object_iterator->first;11384}1138511386JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));11387}1138811389/*!11390@brief return the value of an iterator11391@pre The iterator is initialized; i.e. `m_object != nullptr`.11392*/11393reference value() const11394{11395return operator*();11396}1139711398private:11399/// associated JSON instance11400pointer m_object = nullptr;11401/// the actual iterator of the associated instance11402internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};11403};11404} // namespace detail11405} // namespace nlohmann1140611407// #include <nlohmann/detail/iterators/iteration_proxy.hpp>1140811409// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>114101141111412#include <cstddef> // ptrdiff_t11413#include <iterator> // reverse_iterator11414#include <utility> // declval1141511416namespace nlohmann11417{11418namespace detail11419{11420//////////////////////11421// reverse_iterator //11422//////////////////////1142311424/*!11425@brief a template for a reverse iterator class1142611427@tparam Base the base iterator type to reverse. Valid types are @ref11428iterator (to create @ref reverse_iterator) and @ref const_iterator (to11429create @ref const_reverse_iterator).1143011431@requirement The class satisfies the following concept requirements:11432-11433[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):11434The iterator that can be moved can be moved in both directions (i.e.11435incremented and decremented).11436- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):11437It is possible to write to the pointed-to element (only if @a Base is11438@ref iterator).1143911440@since version 1.0.011441*/11442template<typename Base>11443class json_reverse_iterator : public std::reverse_iterator<Base>11444{11445public:11446using difference_type = std::ptrdiff_t;11447/// shortcut to the reverse iterator adapter11448using base_iterator = std::reverse_iterator<Base>;11449/// the reference type for the pointed-to element11450using reference = typename Base::reference;1145111452/// create reverse iterator from iterator11453explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept11454: base_iterator(it) {}1145511456/// create reverse iterator from base class11457explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}1145811459/// post-increment (it++)11460json_reverse_iterator const operator++(int)11461{11462return static_cast<json_reverse_iterator>(base_iterator::operator++(1));11463}1146411465/// pre-increment (++it)11466json_reverse_iterator& operator++()11467{11468return static_cast<json_reverse_iterator&>(base_iterator::operator++());11469}1147011471/// post-decrement (it--)11472json_reverse_iterator const operator--(int)11473{11474return static_cast<json_reverse_iterator>(base_iterator::operator--(1));11475}1147611477/// pre-decrement (--it)11478json_reverse_iterator& operator--()11479{11480return static_cast<json_reverse_iterator&>(base_iterator::operator--());11481}1148211483/// add to iterator11484json_reverse_iterator& operator+=(difference_type i)11485{11486return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));11487}1148811489/// add to iterator11490json_reverse_iterator operator+(difference_type i) const11491{11492return static_cast<json_reverse_iterator>(base_iterator::operator+(i));11493}1149411495/// subtract from iterator11496json_reverse_iterator operator-(difference_type i) const11497{11498return static_cast<json_reverse_iterator>(base_iterator::operator-(i));11499}1150011501/// return difference11502difference_type operator-(const json_reverse_iterator& other) const11503{11504return base_iterator(*this) - base_iterator(other);11505}1150611507/// access to successor11508reference operator[](difference_type n) const11509{11510return *(this->operator+(n));11511}1151211513/// return the key of an object iterator11514auto key() const -> decltype(std::declval<Base>().key())11515{11516auto it = --this->base();11517return it.key();11518}1151911520/// return the value of an iterator11521reference value() const11522{11523auto it = --this->base();11524return it.operator * ();11525}11526};11527} // namespace detail11528} // namespace nlohmann1152911530// #include <nlohmann/detail/iterators/primitive_iterator.hpp>1153111532// #include <nlohmann/detail/json_pointer.hpp>115331153411535#include <algorithm> // all_of11536#include <cctype> // isdigit11537#include <limits> // max11538#include <numeric> // accumulate11539#include <string> // string11540#include <utility> // move11541#include <vector> // vector1154211543// #include <nlohmann/detail/exceptions.hpp>1154411545// #include <nlohmann/detail/macro_scope.hpp>1154611547// #include <nlohmann/detail/value_t.hpp>115481154911550namespace nlohmann11551{11552template<typename BasicJsonType>11553class json_pointer11554{11555// allow basic_json to access private members11556NLOHMANN_BASIC_JSON_TPL_DECLARATION11557friend class basic_json;1155811559public:11560/*!11561@brief create JSON pointer1156211563Create a JSON pointer according to the syntax described in11564[Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).1156511566@param[in] s string representing the JSON pointer; if omitted, the empty11567string is assumed which references the whole JSON value1156811569@throw parse_error.107 if the given JSON pointer @a s is nonempty and does11570not begin with a slash (`/`); see example below1157111572@throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is11573not followed by `0` (representing `~`) or `1` (representing `/`); see11574example below1157511576@liveexample{The example shows the construction several valid JSON pointers11577as well as the exceptional behavior.,json_pointer}1157811579@since version 2.0.011580*/11581explicit json_pointer(const std::string& s = "")11582: reference_tokens(split(s))11583{}1158411585/*!11586@brief return a string representation of the JSON pointer1158711588@invariant For each JSON pointer `ptr`, it holds:11589@code {.cpp}11590ptr == json_pointer(ptr.to_string());11591@endcode1159211593@return a string representation of the JSON pointer1159411595@liveexample{The example shows the result of `to_string`.,json_pointer__to_string}1159611597@since version 2.0.011598*/11599std::string to_string() const11600{11601return std::accumulate(reference_tokens.begin(), reference_tokens.end(),11602std::string{},11603[](const std::string & a, const std::string & b)11604{11605return a + "/" + escape(b);11606});11607}1160811609/// @copydoc to_string()11610operator std::string() const11611{11612return to_string();11613}1161411615/*!11616@brief append another JSON pointer at the end of this JSON pointer1161711618@param[in] ptr JSON pointer to append11619@return JSON pointer with @a ptr appended1162011621@liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}1162211623@complexity Linear in the length of @a ptr.1162411625@sa @ref operator/=(std::string) to append a reference token11626@sa @ref operator/=(std::size_t) to append an array index11627@sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator1162811629@since version 3.6.011630*/11631json_pointer& operator/=(const json_pointer& ptr)11632{11633reference_tokens.insert(reference_tokens.end(),11634ptr.reference_tokens.begin(),11635ptr.reference_tokens.end());11636return *this;11637}1163811639/*!11640@brief append an unescaped reference token at the end of this JSON pointer1164111642@param[in] token reference token to append11643@return JSON pointer with @a token appended without escaping @a token1164411645@liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}1164611647@complexity Amortized constant.1164811649@sa @ref operator/=(const json_pointer&) to append a JSON pointer11650@sa @ref operator/=(std::size_t) to append an array index11651@sa @ref operator/(const json_pointer&, std::size_t) for a binary operator1165211653@since version 3.6.011654*/11655json_pointer& operator/=(std::string token)11656{11657push_back(std::move(token));11658return *this;11659}1166011661/*!11662@brief append an array index at the end of this JSON pointer1166311664@param[in] array_idx array index to append11665@return JSON pointer with @a array_idx appended1166611667@liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}1166811669@complexity Amortized constant.1167011671@sa @ref operator/=(const json_pointer&) to append a JSON pointer11672@sa @ref operator/=(std::string) to append a reference token11673@sa @ref operator/(const json_pointer&, std::string) for a binary operator1167411675@since version 3.6.011676*/11677json_pointer& operator/=(std::size_t array_idx)11678{11679return *this /= std::to_string(array_idx);11680}1168111682/*!11683@brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer1168411685@param[in] lhs JSON pointer11686@param[in] rhs JSON pointer11687@return a new JSON pointer with @a rhs appended to @a lhs1168811689@liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}1169011691@complexity Linear in the length of @a lhs and @a rhs.1169211693@sa @ref operator/=(const json_pointer&) to append a JSON pointer1169411695@since version 3.6.011696*/11697friend json_pointer operator/(const json_pointer& lhs,11698const json_pointer& rhs)11699{11700return json_pointer(lhs) /= rhs;11701}1170211703/*!11704@brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer1170511706@param[in] ptr JSON pointer11707@param[in] token reference token11708@return a new JSON pointer with unescaped @a token appended to @a ptr1170911710@liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}1171111712@complexity Linear in the length of @a ptr.1171311714@sa @ref operator/=(std::string) to append a reference token1171511716@since version 3.6.011717*/11718friend json_pointer operator/(const json_pointer& ptr, std::string token)11719{11720return json_pointer(ptr) /= std::move(token);11721}1172211723/*!11724@brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer1172511726@param[in] ptr JSON pointer11727@param[in] array_idx array index11728@return a new JSON pointer with @a array_idx appended to @a ptr1172911730@liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}1173111732@complexity Linear in the length of @a ptr.1173311734@sa @ref operator/=(std::size_t) to append an array index1173511736@since version 3.6.011737*/11738friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)11739{11740return json_pointer(ptr) /= array_idx;11741}1174211743/*!11744@brief returns the parent of this JSON pointer1174511746@return parent of this JSON pointer; in case this JSON pointer is the root,11747the root itself is returned1174811749@complexity Linear in the length of the JSON pointer.1175011751@liveexample{The example shows the result of `parent_pointer` for different11752JSON Pointers.,json_pointer__parent_pointer}1175311754@since version 3.6.011755*/11756json_pointer parent_pointer() const11757{11758if (empty())11759{11760return *this;11761}1176211763json_pointer res = *this;11764res.pop_back();11765return res;11766}1176711768/*!11769@brief remove last reference token1177011771@pre not `empty()`1177211773@liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}1177411775@complexity Constant.1177611777@throw out_of_range.405 if JSON pointer has no parent1177811779@since version 3.6.011780*/11781void pop_back()11782{11783if (JSON_HEDLEY_UNLIKELY(empty()))11784{11785JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));11786}1178711788reference_tokens.pop_back();11789}1179011791/*!11792@brief return last reference token1179311794@pre not `empty()`11795@return last reference token1179611797@liveexample{The example shows the usage of `back`.,json_pointer__back}1179811799@complexity Constant.1180011801@throw out_of_range.405 if JSON pointer has no parent1180211803@since version 3.6.011804*/11805const std::string& back() const11806{11807if (JSON_HEDLEY_UNLIKELY(empty()))11808{11809JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));11810}1181111812return reference_tokens.back();11813}1181411815/*!11816@brief append an unescaped token at the end of the reference pointer1181711818@param[in] token token to add1181911820@complexity Amortized constant.1182111822@liveexample{The example shows the result of `push_back` for different11823JSON Pointers.,json_pointer__push_back}1182411825@since version 3.6.011826*/11827void push_back(const std::string& token)11828{11829reference_tokens.push_back(token);11830}1183111832/// @copydoc push_back(const std::string&)11833void push_back(std::string&& token)11834{11835reference_tokens.push_back(std::move(token));11836}1183711838/*!11839@brief return whether pointer points to the root document1184011841@return true iff the JSON pointer points to the root document1184211843@complexity Constant.1184411845@exceptionsafety No-throw guarantee: this function never throws exceptions.1184611847@liveexample{The example shows the result of `empty` for different JSON11848Pointers.,json_pointer__empty}1184911850@since version 3.6.011851*/11852bool empty() const noexcept11853{11854return reference_tokens.empty();11855}1185611857private:11858/*!11859@param[in] s reference token to be converted into an array index1186011861@return integer representation of @a s1186211863@throw parse_error.106 if an array index begins with '0'11864@throw parse_error.109 if an array index begins not with a digit11865@throw out_of_range.404 if string @a s could not be converted to an integer11866@throw out_of_range.410 if an array index exceeds size_type11867*/11868static typename BasicJsonType::size_type array_index(const std::string& s)11869{11870using size_type = typename BasicJsonType::size_type;1187111872// error condition (cf. RFC 6901, Sect. 4)11873if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))11874{11875JSON_THROW(detail::parse_error::create(106, 0,11876"array index '" + s +11877"' must not begin with '0'"));11878}1187911880// error condition (cf. RFC 6901, Sect. 4)11881if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))11882{11883JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));11884}1188511886std::size_t processed_chars = 0;11887unsigned long long res = 0;11888JSON_TRY11889{11890res = std::stoull(s, &processed_chars);11891}11892JSON_CATCH(std::out_of_range&)11893{11894JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));11895}1189611897// check if the string was completely read11898if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))11899{11900JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));11901}1190211903// only triggered on special platforms (like 32bit), see also11904// https://github.com/nlohmann/json/pull/220311905if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))11906{11907JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE11908}1190911910return static_cast<size_type>(res);11911}1191211913json_pointer top() const11914{11915if (JSON_HEDLEY_UNLIKELY(empty()))11916{11917JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));11918}1191911920json_pointer result = *this;11921result.reference_tokens = {reference_tokens[0]};11922return result;11923}1192411925/*!11926@brief create and return a reference to the pointed to value1192711928@complexity Linear in the number of reference tokens.1192911930@throw parse_error.109 if array index is not a number11931@throw type_error.313 if value cannot be unflattened11932*/11933BasicJsonType& get_and_create(BasicJsonType& j) const11934{11935auto result = &j;1193611937// in case no reference tokens exist, return a reference to the JSON value11938// j which will be overwritten by a primitive value11939for (const auto& reference_token : reference_tokens)11940{11941switch (result->type())11942{11943case detail::value_t::null:11944{11945if (reference_token == "0")11946{11947// start a new array if reference token is 011948result = &result->operator[](0);11949}11950else11951{11952// start a new object otherwise11953result = &result->operator[](reference_token);11954}11955break;11956}1195711958case detail::value_t::object:11959{11960// create an entry in the object11961result = &result->operator[](reference_token);11962break;11963}1196411965case detail::value_t::array:11966{11967// create an entry in the array11968result = &result->operator[](array_index(reference_token));11969break;11970}1197111972/*11973The following code is only reached if there exists a reference11974token _and_ the current value is primitive. In this case, we have11975an error situation, because primitive values may only occur as11976single value; that is, with an empty list of reference tokens.11977*/11978default:11979JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));11980}11981}1198211983return *result;11984}1198511986/*!11987@brief return a reference to the pointed to value1198811989@note This version does not throw if a value is not present, but tries to11990create nested values instead. For instance, calling this function11991with pointer `"/this/that"` on a null value is equivalent to calling11992`operator[]("this").operator[]("that")` on that value, effectively11993changing the null value to an object.1199411995@param[in] ptr a JSON value1199611997@return reference to the JSON value pointed to by the JSON pointer1199811999@complexity Linear in the length of the JSON pointer.1200012001@throw parse_error.106 if an array index begins with '0'12002@throw parse_error.109 if an array index was not a number12003@throw out_of_range.404 if the JSON pointer can not be resolved12004*/12005BasicJsonType& get_unchecked(BasicJsonType* ptr) const12006{12007for (const auto& reference_token : reference_tokens)12008{12009// convert null values to arrays or objects before continuing12010if (ptr->is_null())12011{12012// check if reference token is a number12013const bool nums =12014std::all_of(reference_token.begin(), reference_token.end(),12015[](const unsigned char x)12016{12017return std::isdigit(x);12018});1201912020// change value to array for numbers or "-" or to object otherwise12021*ptr = (nums || reference_token == "-")12022? detail::value_t::array12023: detail::value_t::object;12024}1202512026switch (ptr->type())12027{12028case detail::value_t::object:12029{12030// use unchecked object access12031ptr = &ptr->operator[](reference_token);12032break;12033}1203412035case detail::value_t::array:12036{12037if (reference_token == "-")12038{12039// explicitly treat "-" as index beyond the end12040ptr = &ptr->operator[](ptr->m_value.array->size());12041}12042else12043{12044// convert array index to number; unchecked access12045ptr = &ptr->operator[](array_index(reference_token));12046}12047break;12048}1204912050default:12051JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));12052}12053}1205412055return *ptr;12056}1205712058/*!12059@throw parse_error.106 if an array index begins with '0'12060@throw parse_error.109 if an array index was not a number12061@throw out_of_range.402 if the array index '-' is used12062@throw out_of_range.404 if the JSON pointer can not be resolved12063*/12064BasicJsonType& get_checked(BasicJsonType* ptr) const12065{12066for (const auto& reference_token : reference_tokens)12067{12068switch (ptr->type())12069{12070case detail::value_t::object:12071{12072// note: at performs range check12073ptr = &ptr->at(reference_token);12074break;12075}1207612077case detail::value_t::array:12078{12079if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))12080{12081// "-" always fails the range check12082JSON_THROW(detail::out_of_range::create(402,12083"array index '-' (" + std::to_string(ptr->m_value.array->size()) +12084") is out of range"));12085}1208612087// note: at performs range check12088ptr = &ptr->at(array_index(reference_token));12089break;12090}1209112092default:12093JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));12094}12095}1209612097return *ptr;12098}1209912100/*!12101@brief return a const reference to the pointed to value1210212103@param[in] ptr a JSON value1210412105@return const reference to the JSON value pointed to by the JSON12106pointer1210712108@throw parse_error.106 if an array index begins with '0'12109@throw parse_error.109 if an array index was not a number12110@throw out_of_range.402 if the array index '-' is used12111@throw out_of_range.404 if the JSON pointer can not be resolved12112*/12113const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const12114{12115for (const auto& reference_token : reference_tokens)12116{12117switch (ptr->type())12118{12119case detail::value_t::object:12120{12121// use unchecked object access12122ptr = &ptr->operator[](reference_token);12123break;12124}1212512126case detail::value_t::array:12127{12128if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))12129{12130// "-" cannot be used for const access12131JSON_THROW(detail::out_of_range::create(402,12132"array index '-' (" + std::to_string(ptr->m_value.array->size()) +12133") is out of range"));12134}1213512136// use unchecked array access12137ptr = &ptr->operator[](array_index(reference_token));12138break;12139}1214012141default:12142JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));12143}12144}1214512146return *ptr;12147}1214812149/*!12150@throw parse_error.106 if an array index begins with '0'12151@throw parse_error.109 if an array index was not a number12152@throw out_of_range.402 if the array index '-' is used12153@throw out_of_range.404 if the JSON pointer can not be resolved12154*/12155const BasicJsonType& get_checked(const BasicJsonType* ptr) const12156{12157for (const auto& reference_token : reference_tokens)12158{12159switch (ptr->type())12160{12161case detail::value_t::object:12162{12163// note: at performs range check12164ptr = &ptr->at(reference_token);12165break;12166}1216712168case detail::value_t::array:12169{12170if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))12171{12172// "-" always fails the range check12173JSON_THROW(detail::out_of_range::create(402,12174"array index '-' (" + std::to_string(ptr->m_value.array->size()) +12175") is out of range"));12176}1217712178// note: at performs range check12179ptr = &ptr->at(array_index(reference_token));12180break;12181}1218212183default:12184JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));12185}12186}1218712188return *ptr;12189}1219012191/*!12192@throw parse_error.106 if an array index begins with '0'12193@throw parse_error.109 if an array index was not a number12194*/12195bool contains(const BasicJsonType* ptr) const12196{12197for (const auto& reference_token : reference_tokens)12198{12199switch (ptr->type())12200{12201case detail::value_t::object:12202{12203if (!ptr->contains(reference_token))12204{12205// we did not find the key in the object12206return false;12207}1220812209ptr = &ptr->operator[](reference_token);12210break;12211}1221212213case detail::value_t::array:12214{12215if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))12216{12217// "-" always fails the range check12218return false;12219}12220if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))12221{12222// invalid char12223return false;12224}12225if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))12226{12227if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))12228{12229// first char should be between '1' and '9'12230return false;12231}12232for (std::size_t i = 1; i < reference_token.size(); i++)12233{12234if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))12235{12236// other char should be between '0' and '9'12237return false;12238}12239}12240}1224112242const auto idx = array_index(reference_token);12243if (idx >= ptr->size())12244{12245// index out of range12246return false;12247}1224812249ptr = &ptr->operator[](idx);12250break;12251}1225212253default:12254{12255// we do not expect primitive values if there is still a12256// reference token to process12257return false;12258}12259}12260}1226112262// no reference token left means we found a primitive value12263return true;12264}1226512266/*!12267@brief split the string input to reference tokens1226812269@note This function is only called by the json_pointer constructor.12270All exceptions below are documented there.1227112272@throw parse_error.107 if the pointer is not empty or begins with '/'12273@throw parse_error.108 if character '~' is not followed by '0' or '1'12274*/12275static std::vector<std::string> split(const std::string& reference_string)12276{12277std::vector<std::string> result;1227812279// special case: empty reference string -> no reference tokens12280if (reference_string.empty())12281{12282return result;12283}1228412285// check if nonempty reference string begins with slash12286if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))12287{12288JSON_THROW(detail::parse_error::create(107, 1,12289"JSON pointer must be empty or begin with '/' - was: '" +12290reference_string + "'"));12291}1229212293// extract the reference tokens:12294// - slash: position of the last read slash (or end of string)12295// - start: position after the previous slash12296for (12297// search for the first slash after the first character12298std::size_t slash = reference_string.find_first_of('/', 1),12299// set the beginning of the first reference token12300start = 1;12301// we can stop if start == 0 (if slash == std::string::npos)12302start != 0;12303// set the beginning of the next reference token12304// (will eventually be 0 if slash == std::string::npos)12305start = (slash == std::string::npos) ? 0 : slash + 1,12306// find next slash12307slash = reference_string.find_first_of('/', start))12308{12309// use the text between the beginning of the reference token12310// (start) and the last slash (slash).12311auto reference_token = reference_string.substr(start, slash - start);1231212313// check reference tokens are properly escaped12314for (std::size_t pos = reference_token.find_first_of('~');12315pos != std::string::npos;12316pos = reference_token.find_first_of('~', pos + 1))12317{12318JSON_ASSERT(reference_token[pos] == '~');1231912320// ~ must be followed by 0 or 112321if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||12322(reference_token[pos + 1] != '0' &&12323reference_token[pos + 1] != '1')))12324{12325JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));12326}12327}1232812329// finally, store the reference token12330unescape(reference_token);12331result.push_back(reference_token);12332}1233312334return result;12335}1233612337/*!12338@brief replace all occurrences of a substring by another string1233912340@param[in,out] s the string to manipulate; changed so that all12341occurrences of @a f are replaced with @a t12342@param[in] f the substring to replace with @a t12343@param[in] t the string to replace @a f1234412345@pre The search string @a f must not be empty. **This precondition is12346enforced with an assertion.**1234712348@since version 2.0.012349*/12350static void replace_substring(std::string& s, const std::string& f,12351const std::string& t)12352{12353JSON_ASSERT(!f.empty());12354for (auto pos = s.find(f); // find first occurrence of f12355pos != std::string::npos; // make sure f was found12356s.replace(pos, f.size(), t), // replace with t, and12357pos = s.find(f, pos + t.size())) // find next occurrence of f12358{}12359}1236012361/// escape "~" to "~0" and "/" to "~1"12362static std::string escape(std::string s)12363{12364replace_substring(s, "~", "~0");12365replace_substring(s, "/", "~1");12366return s;12367}1236812369/// unescape "~1" to tilde and "~0" to slash (order is important!)12370static void unescape(std::string& s)12371{12372replace_substring(s, "~1", "/");12373replace_substring(s, "~0", "~");12374}1237512376/*!12377@param[in] reference_string the reference string to the current value12378@param[in] value the value to consider12379@param[in,out] result the result object to insert values to1238012381@note Empty objects or arrays are flattened to `null`.12382*/12383static void flatten(const std::string& reference_string,12384const BasicJsonType& value,12385BasicJsonType& result)12386{12387switch (value.type())12388{12389case detail::value_t::array:12390{12391if (value.m_value.array->empty())12392{12393// flatten empty array as null12394result[reference_string] = nullptr;12395}12396else12397{12398// iterate array and use index as reference string12399for (std::size_t i = 0; i < value.m_value.array->size(); ++i)12400{12401flatten(reference_string + "/" + std::to_string(i),12402value.m_value.array->operator[](i), result);12403}12404}12405break;12406}1240712408case detail::value_t::object:12409{12410if (value.m_value.object->empty())12411{12412// flatten empty object as null12413result[reference_string] = nullptr;12414}12415else12416{12417// iterate object and use keys as reference string12418for (const auto& element : *value.m_value.object)12419{12420flatten(reference_string + "/" + escape(element.first), element.second, result);12421}12422}12423break;12424}1242512426default:12427{12428// add primitive value with its reference string12429result[reference_string] = value;12430break;12431}12432}12433}1243412435/*!12436@param[in] value flattened JSON1243712438@return unflattened JSON1243912440@throw parse_error.109 if array index is not a number12441@throw type_error.314 if value is not an object12442@throw type_error.315 if object values are not primitive12443@throw type_error.313 if value cannot be unflattened12444*/12445static BasicJsonType12446unflatten(const BasicJsonType& value)12447{12448if (JSON_HEDLEY_UNLIKELY(!value.is_object()))12449{12450JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));12451}1245212453BasicJsonType result;1245412455// iterate the JSON object values12456for (const auto& element : *value.m_value.object)12457{12458if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))12459{12460JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));12461}1246212463// assign value to reference pointed to by JSON pointer; Note that if12464// the JSON pointer is "" (i.e., points to the whole value), function12465// get_and_create returns a reference to result itself. An assignment12466// will then create a primitive value.12467json_pointer(element.first).get_and_create(result) = element.second;12468}1246912470return result;12471}1247212473/*!12474@brief compares two JSON pointers for equality1247512476@param[in] lhs JSON pointer to compare12477@param[in] rhs JSON pointer to compare12478@return whether @a lhs is equal to @a rhs1247912480@complexity Linear in the length of the JSON pointer1248112482@exceptionsafety No-throw guarantee: this function never throws exceptions.12483*/12484friend bool operator==(json_pointer const& lhs,12485json_pointer const& rhs) noexcept12486{12487return lhs.reference_tokens == rhs.reference_tokens;12488}1248912490/*!12491@brief compares two JSON pointers for inequality1249212493@param[in] lhs JSON pointer to compare12494@param[in] rhs JSON pointer to compare12495@return whether @a lhs is not equal @a rhs1249612497@complexity Linear in the length of the JSON pointer1249812499@exceptionsafety No-throw guarantee: this function never throws exceptions.12500*/12501friend bool operator!=(json_pointer const& lhs,12502json_pointer const& rhs) noexcept12503{12504return !(lhs == rhs);12505}1250612507/// the reference tokens12508std::vector<std::string> reference_tokens;12509};12510} // namespace nlohmann1251112512// #include <nlohmann/detail/json_ref.hpp>125131251412515#include <initializer_list>12516#include <utility>1251712518// #include <nlohmann/detail/meta/type_traits.hpp>125191252012521namespace nlohmann12522{12523namespace detail12524{12525template<typename BasicJsonType>12526class json_ref12527{12528public:12529using value_type = BasicJsonType;1253012531json_ref(value_type&& value)12532: owned_value(std::move(value))12533, value_ref(&owned_value)12534, is_rvalue(true)12535{}1253612537json_ref(const value_type& value)12538: value_ref(const_cast<value_type*>(&value))12539, is_rvalue(false)12540{}1254112542json_ref(std::initializer_list<json_ref> init)12543: owned_value(init)12544, value_ref(&owned_value)12545, is_rvalue(true)12546{}1254712548template <12549class... Args,12550enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >12551json_ref(Args && ... args)12552: owned_value(std::forward<Args>(args)...)12553, value_ref(&owned_value)12554, is_rvalue(true)12555{}1255612557// class should be movable only12558json_ref(json_ref&&) = default;12559json_ref(const json_ref&) = delete;12560json_ref& operator=(const json_ref&) = delete;12561json_ref& operator=(json_ref&&) = delete;12562~json_ref() = default;1256312564value_type moved_or_copied() const12565{12566if (is_rvalue)12567{12568return std::move(*value_ref);12569}12570return *value_ref;12571}1257212573value_type const& operator*() const12574{12575return *static_cast<value_type const*>(value_ref);12576}1257712578value_type const* operator->() const12579{12580return static_cast<value_type const*>(value_ref);12581}1258212583private:12584mutable value_type owned_value = nullptr;12585value_type* value_ref = nullptr;12586const bool is_rvalue = true;12587};12588} // namespace detail12589} // namespace nlohmann1259012591// #include <nlohmann/detail/macro_scope.hpp>1259212593// #include <nlohmann/detail/meta/cpp_future.hpp>1259412595// #include <nlohmann/detail/meta/type_traits.hpp>1259612597// #include <nlohmann/detail/output/binary_writer.hpp>125981259912600#include <algorithm> // reverse12601#include <array> // array12602#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t12603#include <cstring> // memcpy12604#include <limits> // numeric_limits12605#include <string> // string12606#include <cmath> // isnan, isinf1260712608// #include <nlohmann/detail/input/binary_reader.hpp>1260912610// #include <nlohmann/detail/macro_scope.hpp>1261112612// #include <nlohmann/detail/output/output_adapters.hpp>126131261412615#include <algorithm> // copy12616#include <cstddef> // size_t12617#include <ios> // streamsize12618#include <iterator> // back_inserter12619#include <memory> // shared_ptr, make_shared12620#include <ostream> // basic_ostream12621#include <string> // basic_string12622#include <vector> // vector12623// #include <nlohmann/detail/macro_scope.hpp>126241262512626namespace nlohmann12627{12628namespace detail12629{12630/// abstract output adapter interface12631template<typename CharType> struct output_adapter_protocol12632{12633virtual void write_character(CharType c) = 0;12634virtual void write_characters(const CharType* s, std::size_t length) = 0;12635virtual ~output_adapter_protocol() = default;12636};1263712638/// a type to simplify interfaces12639template<typename CharType>12640using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;1264112642/// output adapter for byte vectors12643template<typename CharType>12644class output_vector_adapter : public output_adapter_protocol<CharType>12645{12646public:12647explicit output_vector_adapter(std::vector<CharType>& vec) noexcept12648: v(vec)12649{}1265012651void write_character(CharType c) override12652{12653v.push_back(c);12654}1265512656JSON_HEDLEY_NON_NULL(2)12657void write_characters(const CharType* s, std::size_t length) override12658{12659std::copy(s, s + length, std::back_inserter(v));12660}1266112662private:12663std::vector<CharType>& v;12664};1266512666/// output adapter for output streams12667template<typename CharType>12668class output_stream_adapter : public output_adapter_protocol<CharType>12669{12670public:12671explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept12672: stream(s)12673{}1267412675void write_character(CharType c) override12676{12677stream.put(c);12678}1267912680JSON_HEDLEY_NON_NULL(2)12681void write_characters(const CharType* s, std::size_t length) override12682{12683stream.write(s, static_cast<std::streamsize>(length));12684}1268512686private:12687std::basic_ostream<CharType>& stream;12688};1268912690/// output adapter for basic_string12691template<typename CharType, typename StringType = std::basic_string<CharType>>12692class output_string_adapter : public output_adapter_protocol<CharType>12693{12694public:12695explicit output_string_adapter(StringType& s) noexcept12696: str(s)12697{}1269812699void write_character(CharType c) override12700{12701str.push_back(c);12702}1270312704JSON_HEDLEY_NON_NULL(2)12705void write_characters(const CharType* s, std::size_t length) override12706{12707str.append(s, length);12708}1270912710private:12711StringType& str;12712};1271312714template<typename CharType, typename StringType = std::basic_string<CharType>>12715class output_adapter12716{12717public:12718output_adapter(std::vector<CharType>& vec)12719: oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}1272012721output_adapter(std::basic_ostream<CharType>& s)12722: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}1272312724output_adapter(StringType& s)12725: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}1272612727operator output_adapter_t<CharType>()12728{12729return oa;12730}1273112732private:12733output_adapter_t<CharType> oa = nullptr;12734};12735} // namespace detail12736} // namespace nlohmann127371273812739namespace nlohmann12740{12741namespace detail12742{12743///////////////////12744// binary writer //12745///////////////////1274612747/*!12748@brief serialization to CBOR and MessagePack values12749*/12750template<typename BasicJsonType, typename CharType>12751class binary_writer12752{12753using string_t = typename BasicJsonType::string_t;12754using binary_t = typename BasicJsonType::binary_t;12755using number_float_t = typename BasicJsonType::number_float_t;1275612757public:12758/*!12759@brief create a binary writer1276012761@param[in] adapter output adapter to write to12762*/12763explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)12764{12765JSON_ASSERT(oa);12766}1276712768/*!12769@param[in] j JSON value to serialize12770@pre j.type() == value_t::object12771*/12772void write_bson(const BasicJsonType& j)12773{12774switch (j.type())12775{12776case value_t::object:12777{12778write_bson_object(*j.m_value.object);12779break;12780}1278112782default:12783{12784JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));12785}12786}12787}1278812789/*!12790@param[in] j JSON value to serialize12791*/12792void write_cbor(const BasicJsonType& j)12793{12794switch (j.type())12795{12796case value_t::null:12797{12798oa->write_character(to_char_type(0xF6));12799break;12800}1280112802case value_t::boolean:12803{12804oa->write_character(j.m_value.boolean12805? to_char_type(0xF5)12806: to_char_type(0xF4));12807break;12808}1280912810case value_t::number_integer:12811{12812if (j.m_value.number_integer >= 0)12813{12814// CBOR does not differentiate between positive signed12815// integers and unsigned integers. Therefore, we used the12816// code from the value_t::number_unsigned case here.12817if (j.m_value.number_integer <= 0x17)12818{12819write_number(static_cast<std::uint8_t>(j.m_value.number_integer));12820}12821else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())12822{12823oa->write_character(to_char_type(0x18));12824write_number(static_cast<std::uint8_t>(j.m_value.number_integer));12825}12826else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())12827{12828oa->write_character(to_char_type(0x19));12829write_number(static_cast<std::uint16_t>(j.m_value.number_integer));12830}12831else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())12832{12833oa->write_character(to_char_type(0x1A));12834write_number(static_cast<std::uint32_t>(j.m_value.number_integer));12835}12836else12837{12838oa->write_character(to_char_type(0x1B));12839write_number(static_cast<std::uint64_t>(j.m_value.number_integer));12840}12841}12842else12843{12844// The conversions below encode the sign in the first12845// byte, and the value is converted to a positive number.12846const auto positive_number = -1 - j.m_value.number_integer;12847if (j.m_value.number_integer >= -24)12848{12849write_number(static_cast<std::uint8_t>(0x20 + positive_number));12850}12851else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())12852{12853oa->write_character(to_char_type(0x38));12854write_number(static_cast<std::uint8_t>(positive_number));12855}12856else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())12857{12858oa->write_character(to_char_type(0x39));12859write_number(static_cast<std::uint16_t>(positive_number));12860}12861else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())12862{12863oa->write_character(to_char_type(0x3A));12864write_number(static_cast<std::uint32_t>(positive_number));12865}12866else12867{12868oa->write_character(to_char_type(0x3B));12869write_number(static_cast<std::uint64_t>(positive_number));12870}12871}12872break;12873}1287412875case value_t::number_unsigned:12876{12877if (j.m_value.number_unsigned <= 0x17)12878{12879write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));12880}12881else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())12882{12883oa->write_character(to_char_type(0x18));12884write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));12885}12886else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())12887{12888oa->write_character(to_char_type(0x19));12889write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));12890}12891else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())12892{12893oa->write_character(to_char_type(0x1A));12894write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));12895}12896else12897{12898oa->write_character(to_char_type(0x1B));12899write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));12900}12901break;12902}1290312904case value_t::number_float:12905{12906if (std::isnan(j.m_value.number_float))12907{12908// NaN is 0xf97e00 in CBOR12909oa->write_character(to_char_type(0xF9));12910oa->write_character(to_char_type(0x7E));12911oa->write_character(to_char_type(0x00));12912}12913else if (std::isinf(j.m_value.number_float))12914{12915// Infinity is 0xf97c00, -Infinity is 0xf9fc0012916oa->write_character(to_char_type(0xf9));12917oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));12918oa->write_character(to_char_type(0x00));12919}12920else12921{12922write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);12923}12924break;12925}1292612927case value_t::string:12928{12929// step 1: write control byte and the string length12930const auto N = j.m_value.string->size();12931if (N <= 0x17)12932{12933write_number(static_cast<std::uint8_t>(0x60 + N));12934}12935else if (N <= (std::numeric_limits<std::uint8_t>::max)())12936{12937oa->write_character(to_char_type(0x78));12938write_number(static_cast<std::uint8_t>(N));12939}12940else if (N <= (std::numeric_limits<std::uint16_t>::max)())12941{12942oa->write_character(to_char_type(0x79));12943write_number(static_cast<std::uint16_t>(N));12944}12945else if (N <= (std::numeric_limits<std::uint32_t>::max)())12946{12947oa->write_character(to_char_type(0x7A));12948write_number(static_cast<std::uint32_t>(N));12949}12950// LCOV_EXCL_START12951else if (N <= (std::numeric_limits<std::uint64_t>::max)())12952{12953oa->write_character(to_char_type(0x7B));12954write_number(static_cast<std::uint64_t>(N));12955}12956// LCOV_EXCL_STOP1295712958// step 2: write the string12959oa->write_characters(12960reinterpret_cast<const CharType*>(j.m_value.string->c_str()),12961j.m_value.string->size());12962break;12963}1296412965case value_t::array:12966{12967// step 1: write control byte and the array size12968const auto N = j.m_value.array->size();12969if (N <= 0x17)12970{12971write_number(static_cast<std::uint8_t>(0x80 + N));12972}12973else if (N <= (std::numeric_limits<std::uint8_t>::max)())12974{12975oa->write_character(to_char_type(0x98));12976write_number(static_cast<std::uint8_t>(N));12977}12978else if (N <= (std::numeric_limits<std::uint16_t>::max)())12979{12980oa->write_character(to_char_type(0x99));12981write_number(static_cast<std::uint16_t>(N));12982}12983else if (N <= (std::numeric_limits<std::uint32_t>::max)())12984{12985oa->write_character(to_char_type(0x9A));12986write_number(static_cast<std::uint32_t>(N));12987}12988// LCOV_EXCL_START12989else if (N <= (std::numeric_limits<std::uint64_t>::max)())12990{12991oa->write_character(to_char_type(0x9B));12992write_number(static_cast<std::uint64_t>(N));12993}12994// LCOV_EXCL_STOP1299512996// step 2: write each element12997for (const auto& el : *j.m_value.array)12998{12999write_cbor(el);13000}13001break;13002}1300313004case value_t::binary:13005{13006if (j.m_value.binary->has_subtype())13007{13008write_number(static_cast<std::uint8_t>(0xd8));13009write_number(j.m_value.binary->subtype());13010}1301113012// step 1: write control byte and the binary array size13013const auto N = j.m_value.binary->size();13014if (N <= 0x17)13015{13016write_number(static_cast<std::uint8_t>(0x40 + N));13017}13018else if (N <= (std::numeric_limits<std::uint8_t>::max)())13019{13020oa->write_character(to_char_type(0x58));13021write_number(static_cast<std::uint8_t>(N));13022}13023else if (N <= (std::numeric_limits<std::uint16_t>::max)())13024{13025oa->write_character(to_char_type(0x59));13026write_number(static_cast<std::uint16_t>(N));13027}13028else if (N <= (std::numeric_limits<std::uint32_t>::max)())13029{13030oa->write_character(to_char_type(0x5A));13031write_number(static_cast<std::uint32_t>(N));13032}13033// LCOV_EXCL_START13034else if (N <= (std::numeric_limits<std::uint64_t>::max)())13035{13036oa->write_character(to_char_type(0x5B));13037write_number(static_cast<std::uint64_t>(N));13038}13039// LCOV_EXCL_STOP1304013041// step 2: write each element13042oa->write_characters(13043reinterpret_cast<const CharType*>(j.m_value.binary->data()),13044N);1304513046break;13047}1304813049case value_t::object:13050{13051// step 1: write control byte and the object size13052const auto N = j.m_value.object->size();13053if (N <= 0x17)13054{13055write_number(static_cast<std::uint8_t>(0xA0 + N));13056}13057else if (N <= (std::numeric_limits<std::uint8_t>::max)())13058{13059oa->write_character(to_char_type(0xB8));13060write_number(static_cast<std::uint8_t>(N));13061}13062else if (N <= (std::numeric_limits<std::uint16_t>::max)())13063{13064oa->write_character(to_char_type(0xB9));13065write_number(static_cast<std::uint16_t>(N));13066}13067else if (N <= (std::numeric_limits<std::uint32_t>::max)())13068{13069oa->write_character(to_char_type(0xBA));13070write_number(static_cast<std::uint32_t>(N));13071}13072// LCOV_EXCL_START13073else if (N <= (std::numeric_limits<std::uint64_t>::max)())13074{13075oa->write_character(to_char_type(0xBB));13076write_number(static_cast<std::uint64_t>(N));13077}13078// LCOV_EXCL_STOP1307913080// step 2: write each element13081for (const auto& el : *j.m_value.object)13082{13083write_cbor(el.first);13084write_cbor(el.second);13085}13086break;13087}1308813089default:13090break;13091}13092}1309313094/*!13095@param[in] j JSON value to serialize13096*/13097void write_msgpack(const BasicJsonType& j)13098{13099switch (j.type())13100{13101case value_t::null: // nil13102{13103oa->write_character(to_char_type(0xC0));13104break;13105}1310613107case value_t::boolean: // true and false13108{13109oa->write_character(j.m_value.boolean13110? to_char_type(0xC3)13111: to_char_type(0xC2));13112break;13113}1311413115case value_t::number_integer:13116{13117if (j.m_value.number_integer >= 0)13118{13119// MessagePack does not differentiate between positive13120// signed integers and unsigned integers. Therefore, we used13121// the code from the value_t::number_unsigned case here.13122if (j.m_value.number_unsigned < 128)13123{13124// positive fixnum13125write_number(static_cast<std::uint8_t>(j.m_value.number_integer));13126}13127else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())13128{13129// uint 813130oa->write_character(to_char_type(0xCC));13131write_number(static_cast<std::uint8_t>(j.m_value.number_integer));13132}13133else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())13134{13135// uint 1613136oa->write_character(to_char_type(0xCD));13137write_number(static_cast<std::uint16_t>(j.m_value.number_integer));13138}13139else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())13140{13141// uint 3213142oa->write_character(to_char_type(0xCE));13143write_number(static_cast<std::uint32_t>(j.m_value.number_integer));13144}13145else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())13146{13147// uint 6413148oa->write_character(to_char_type(0xCF));13149write_number(static_cast<std::uint64_t>(j.m_value.number_integer));13150}13151}13152else13153{13154if (j.m_value.number_integer >= -32)13155{13156// negative fixnum13157write_number(static_cast<std::int8_t>(j.m_value.number_integer));13158}13159else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&13160j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())13161{13162// int 813163oa->write_character(to_char_type(0xD0));13164write_number(static_cast<std::int8_t>(j.m_value.number_integer));13165}13166else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&13167j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())13168{13169// int 1613170oa->write_character(to_char_type(0xD1));13171write_number(static_cast<std::int16_t>(j.m_value.number_integer));13172}13173else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&13174j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())13175{13176// int 3213177oa->write_character(to_char_type(0xD2));13178write_number(static_cast<std::int32_t>(j.m_value.number_integer));13179}13180else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&13181j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())13182{13183// int 6413184oa->write_character(to_char_type(0xD3));13185write_number(static_cast<std::int64_t>(j.m_value.number_integer));13186}13187}13188break;13189}1319013191case value_t::number_unsigned:13192{13193if (j.m_value.number_unsigned < 128)13194{13195// positive fixnum13196write_number(static_cast<std::uint8_t>(j.m_value.number_integer));13197}13198else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())13199{13200// uint 813201oa->write_character(to_char_type(0xCC));13202write_number(static_cast<std::uint8_t>(j.m_value.number_integer));13203}13204else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())13205{13206// uint 1613207oa->write_character(to_char_type(0xCD));13208write_number(static_cast<std::uint16_t>(j.m_value.number_integer));13209}13210else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())13211{13212// uint 3213213oa->write_character(to_char_type(0xCE));13214write_number(static_cast<std::uint32_t>(j.m_value.number_integer));13215}13216else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())13217{13218// uint 6413219oa->write_character(to_char_type(0xCF));13220write_number(static_cast<std::uint64_t>(j.m_value.number_integer));13221}13222break;13223}1322413225case value_t::number_float:13226{13227write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);13228break;13229}1323013231case value_t::string:13232{13233// step 1: write control byte and the string length13234const auto N = j.m_value.string->size();13235if (N <= 31)13236{13237// fixstr13238write_number(static_cast<std::uint8_t>(0xA0 | N));13239}13240else if (N <= (std::numeric_limits<std::uint8_t>::max)())13241{13242// str 813243oa->write_character(to_char_type(0xD9));13244write_number(static_cast<std::uint8_t>(N));13245}13246else if (N <= (std::numeric_limits<std::uint16_t>::max)())13247{13248// str 1613249oa->write_character(to_char_type(0xDA));13250write_number(static_cast<std::uint16_t>(N));13251}13252else if (N <= (std::numeric_limits<std::uint32_t>::max)())13253{13254// str 3213255oa->write_character(to_char_type(0xDB));13256write_number(static_cast<std::uint32_t>(N));13257}1325813259// step 2: write the string13260oa->write_characters(13261reinterpret_cast<const CharType*>(j.m_value.string->c_str()),13262j.m_value.string->size());13263break;13264}1326513266case value_t::array:13267{13268// step 1: write control byte and the array size13269const auto N = j.m_value.array->size();13270if (N <= 15)13271{13272// fixarray13273write_number(static_cast<std::uint8_t>(0x90 | N));13274}13275else if (N <= (std::numeric_limits<std::uint16_t>::max)())13276{13277// array 1613278oa->write_character(to_char_type(0xDC));13279write_number(static_cast<std::uint16_t>(N));13280}13281else if (N <= (std::numeric_limits<std::uint32_t>::max)())13282{13283// array 3213284oa->write_character(to_char_type(0xDD));13285write_number(static_cast<std::uint32_t>(N));13286}1328713288// step 2: write each element13289for (const auto& el : *j.m_value.array)13290{13291write_msgpack(el);13292}13293break;13294}1329513296case value_t::binary:13297{13298// step 0: determine if the binary type has a set subtype to13299// determine whether or not to use the ext or fixext types13300const bool use_ext = j.m_value.binary->has_subtype();1330113302// step 1: write control byte and the byte string length13303const auto N = j.m_value.binary->size();13304if (N <= (std::numeric_limits<std::uint8_t>::max)())13305{13306std::uint8_t output_type{};13307bool fixed = true;13308if (use_ext)13309{13310switch (N)13311{13312case 1:13313output_type = 0xD4; // fixext 113314break;13315case 2:13316output_type = 0xD5; // fixext 213317break;13318case 4:13319output_type = 0xD6; // fixext 413320break;13321case 8:13322output_type = 0xD7; // fixext 813323break;13324case 16:13325output_type = 0xD8; // fixext 1613326break;13327default:13328output_type = 0xC7; // ext 813329fixed = false;13330break;13331}1333213333}13334else13335{13336output_type = 0xC4; // bin 813337fixed = false;13338}1333913340oa->write_character(to_char_type(output_type));13341if (!fixed)13342{13343write_number(static_cast<std::uint8_t>(N));13344}13345}13346else if (N <= (std::numeric_limits<std::uint16_t>::max)())13347{13348std::uint8_t output_type = use_ext13349? 0xC8 // ext 1613350: 0xC5; // bin 161335113352oa->write_character(to_char_type(output_type));13353write_number(static_cast<std::uint16_t>(N));13354}13355else if (N <= (std::numeric_limits<std::uint32_t>::max)())13356{13357std::uint8_t output_type = use_ext13358? 0xC9 // ext 3213359: 0xC6; // bin 321336013361oa->write_character(to_char_type(output_type));13362write_number(static_cast<std::uint32_t>(N));13363}1336413365// step 1.5: if this is an ext type, write the subtype13366if (use_ext)13367{13368write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));13369}1337013371// step 2: write the byte string13372oa->write_characters(13373reinterpret_cast<const CharType*>(j.m_value.binary->data()),13374N);1337513376break;13377}1337813379case value_t::object:13380{13381// step 1: write control byte and the object size13382const auto N = j.m_value.object->size();13383if (N <= 15)13384{13385// fixmap13386write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));13387}13388else if (N <= (std::numeric_limits<std::uint16_t>::max)())13389{13390// map 1613391oa->write_character(to_char_type(0xDE));13392write_number(static_cast<std::uint16_t>(N));13393}13394else if (N <= (std::numeric_limits<std::uint32_t>::max)())13395{13396// map 3213397oa->write_character(to_char_type(0xDF));13398write_number(static_cast<std::uint32_t>(N));13399}1340013401// step 2: write each element13402for (const auto& el : *j.m_value.object)13403{13404write_msgpack(el.first);13405write_msgpack(el.second);13406}13407break;13408}1340913410default:13411break;13412}13413}1341413415/*!13416@param[in] j JSON value to serialize13417@param[in] use_count whether to use '#' prefixes (optimized format)13418@param[in] use_type whether to use '$' prefixes (optimized format)13419@param[in] add_prefix whether prefixes need to be used for this value13420*/13421void write_ubjson(const BasicJsonType& j, const bool use_count,13422const bool use_type, const bool add_prefix = true)13423{13424switch (j.type())13425{13426case value_t::null:13427{13428if (add_prefix)13429{13430oa->write_character(to_char_type('Z'));13431}13432break;13433}1343413435case value_t::boolean:13436{13437if (add_prefix)13438{13439oa->write_character(j.m_value.boolean13440? to_char_type('T')13441: to_char_type('F'));13442}13443break;13444}1344513446case value_t::number_integer:13447{13448write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);13449break;13450}1345113452case value_t::number_unsigned:13453{13454write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);13455break;13456}1345713458case value_t::number_float:13459{13460write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);13461break;13462}1346313464case value_t::string:13465{13466if (add_prefix)13467{13468oa->write_character(to_char_type('S'));13469}13470write_number_with_ubjson_prefix(j.m_value.string->size(), true);13471oa->write_characters(13472reinterpret_cast<const CharType*>(j.m_value.string->c_str()),13473j.m_value.string->size());13474break;13475}1347613477case value_t::array:13478{13479if (add_prefix)13480{13481oa->write_character(to_char_type('['));13482}1348313484bool prefix_required = true;13485if (use_type && !j.m_value.array->empty())13486{13487JSON_ASSERT(use_count);13488const CharType first_prefix = ubjson_prefix(j.front());13489const bool same_prefix = std::all_of(j.begin() + 1, j.end(),13490[this, first_prefix](const BasicJsonType & v)13491{13492return ubjson_prefix(v) == first_prefix;13493});1349413495if (same_prefix)13496{13497prefix_required = false;13498oa->write_character(to_char_type('$'));13499oa->write_character(first_prefix);13500}13501}1350213503if (use_count)13504{13505oa->write_character(to_char_type('#'));13506write_number_with_ubjson_prefix(j.m_value.array->size(), true);13507}1350813509for (const auto& el : *j.m_value.array)13510{13511write_ubjson(el, use_count, use_type, prefix_required);13512}1351313514if (!use_count)13515{13516oa->write_character(to_char_type(']'));13517}1351813519break;13520}1352113522case value_t::binary:13523{13524if (add_prefix)13525{13526oa->write_character(to_char_type('['));13527}1352813529if (use_type && !j.m_value.binary->empty())13530{13531JSON_ASSERT(use_count);13532oa->write_character(to_char_type('$'));13533oa->write_character('U');13534}1353513536if (use_count)13537{13538oa->write_character(to_char_type('#'));13539write_number_with_ubjson_prefix(j.m_value.binary->size(), true);13540}1354113542if (use_type)13543{13544oa->write_characters(13545reinterpret_cast<const CharType*>(j.m_value.binary->data()),13546j.m_value.binary->size());13547}13548else13549{13550for (size_t i = 0; i < j.m_value.binary->size(); ++i)13551{13552oa->write_character(to_char_type('U'));13553oa->write_character(j.m_value.binary->data()[i]);13554}13555}1355613557if (!use_count)13558{13559oa->write_character(to_char_type(']'));13560}1356113562break;13563}1356413565case value_t::object:13566{13567if (add_prefix)13568{13569oa->write_character(to_char_type('{'));13570}1357113572bool prefix_required = true;13573if (use_type && !j.m_value.object->empty())13574{13575JSON_ASSERT(use_count);13576const CharType first_prefix = ubjson_prefix(j.front());13577const bool same_prefix = std::all_of(j.begin(), j.end(),13578[this, first_prefix](const BasicJsonType & v)13579{13580return ubjson_prefix(v) == first_prefix;13581});1358213583if (same_prefix)13584{13585prefix_required = false;13586oa->write_character(to_char_type('$'));13587oa->write_character(first_prefix);13588}13589}1359013591if (use_count)13592{13593oa->write_character(to_char_type('#'));13594write_number_with_ubjson_prefix(j.m_value.object->size(), true);13595}1359613597for (const auto& el : *j.m_value.object)13598{13599write_number_with_ubjson_prefix(el.first.size(), true);13600oa->write_characters(13601reinterpret_cast<const CharType*>(el.first.c_str()),13602el.first.size());13603write_ubjson(el.second, use_count, use_type, prefix_required);13604}1360513606if (!use_count)13607{13608oa->write_character(to_char_type('}'));13609}1361013611break;13612}1361313614default:13615break;13616}13617}1361813619private:13620//////////13621// BSON //13622//////////1362313624/*!13625@return The size of a BSON document entry header, including the id marker13626and the entry name size (and its null-terminator).13627*/13628static std::size_t calc_bson_entry_header_size(const string_t& name)13629{13630const auto it = name.find(static_cast<typename string_t::value_type>(0));13631if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))13632{13633JSON_THROW(out_of_range::create(409,13634"BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));13635}1363613637return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;13638}1363913640/*!13641@brief Writes the given @a element_type and @a name to the output adapter13642*/13643void write_bson_entry_header(const string_t& name,13644const std::uint8_t element_type)13645{13646oa->write_character(to_char_type(element_type)); // boolean13647oa->write_characters(13648reinterpret_cast<const CharType*>(name.c_str()),13649name.size() + 1u);13650}1365113652/*!13653@brief Writes a BSON element with key @a name and boolean value @a value13654*/13655void write_bson_boolean(const string_t& name,13656const bool value)13657{13658write_bson_entry_header(name, 0x08);13659oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));13660}1366113662/*!13663@brief Writes a BSON element with key @a name and double value @a value13664*/13665void write_bson_double(const string_t& name,13666const double value)13667{13668write_bson_entry_header(name, 0x01);13669write_number<double, true>(value);13670}1367113672/*!13673@return The size of the BSON-encoded string in @a value13674*/13675static std::size_t calc_bson_string_size(const string_t& value)13676{13677return sizeof(std::int32_t) + value.size() + 1ul;13678}1367913680/*!13681@brief Writes a BSON element with key @a name and string value @a value13682*/13683void write_bson_string(const string_t& name,13684const string_t& value)13685{13686write_bson_entry_header(name, 0x02);1368713688write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));13689oa->write_characters(13690reinterpret_cast<const CharType*>(value.c_str()),13691value.size() + 1);13692}1369313694/*!13695@brief Writes a BSON element with key @a name and null value13696*/13697void write_bson_null(const string_t& name)13698{13699write_bson_entry_header(name, 0x0A);13700}1370113702/*!13703@return The size of the BSON-encoded integer @a value13704*/13705static std::size_t calc_bson_integer_size(const std::int64_t value)13706{13707return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()13708? sizeof(std::int32_t)13709: sizeof(std::int64_t);13710}1371113712/*!13713@brief Writes a BSON element with key @a name and integer @a value13714*/13715void write_bson_integer(const string_t& name,13716const std::int64_t value)13717{13718if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())13719{13720write_bson_entry_header(name, 0x10); // int3213721write_number<std::int32_t, true>(static_cast<std::int32_t>(value));13722}13723else13724{13725write_bson_entry_header(name, 0x12); // int6413726write_number<std::int64_t, true>(static_cast<std::int64_t>(value));13727}13728}1372913730/*!13731@return The size of the BSON-encoded unsigned integer in @a j13732*/13733static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept13734{13735return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))13736? sizeof(std::int32_t)13737: sizeof(std::int64_t);13738}1373913740/*!13741@brief Writes a BSON element with key @a name and unsigned @a value13742*/13743void write_bson_unsigned(const string_t& name,13744const std::uint64_t value)13745{13746if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))13747{13748write_bson_entry_header(name, 0x10 /* int32 */);13749write_number<std::int32_t, true>(static_cast<std::int32_t>(value));13750}13751else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))13752{13753write_bson_entry_header(name, 0x12 /* int64 */);13754write_number<std::int64_t, true>(static_cast<std::int64_t>(value));13755}13756else13757{13758JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));13759}13760}1376113762/*!13763@brief Writes a BSON element with key @a name and object @a value13764*/13765void write_bson_object_entry(const string_t& name,13766const typename BasicJsonType::object_t& value)13767{13768write_bson_entry_header(name, 0x03); // object13769write_bson_object(value);13770}1377113772/*!13773@return The size of the BSON-encoded array @a value13774*/13775static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)13776{13777std::size_t array_index = 0ul;1377813779const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)13780{13781return result + calc_bson_element_size(std::to_string(array_index++), el);13782});1378313784return sizeof(std::int32_t) + embedded_document_size + 1ul;13785}1378613787/*!13788@return The size of the BSON-encoded binary array @a value13789*/13790static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)13791{13792return sizeof(std::int32_t) + value.size() + 1ul;13793}1379413795/*!13796@brief Writes a BSON element with key @a name and array @a value13797*/13798void write_bson_array(const string_t& name,13799const typename BasicJsonType::array_t& value)13800{13801write_bson_entry_header(name, 0x04); // array13802write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));1380313804std::size_t array_index = 0ul;1380513806for (const auto& el : value)13807{13808write_bson_element(std::to_string(array_index++), el);13809}1381013811oa->write_character(to_char_type(0x00));13812}1381313814/*!13815@brief Writes a BSON element with key @a name and binary value @a value13816*/13817void write_bson_binary(const string_t& name,13818const binary_t& value)13819{13820write_bson_entry_header(name, 0x05);1382113822write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));13823write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));1382413825oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());13826}1382713828/*!13829@brief Calculates the size necessary to serialize the JSON value @a j with its @a name13830@return The calculated size for the BSON document entry for @a j with the given @a name.13831*/13832static std::size_t calc_bson_element_size(const string_t& name,13833const BasicJsonType& j)13834{13835const auto header_size = calc_bson_entry_header_size(name);13836switch (j.type())13837{13838case value_t::object:13839return header_size + calc_bson_object_size(*j.m_value.object);1384013841case value_t::array:13842return header_size + calc_bson_array_size(*j.m_value.array);1384313844case value_t::binary:13845return header_size + calc_bson_binary_size(*j.m_value.binary);1384613847case value_t::boolean:13848return header_size + 1ul;1384913850case value_t::number_float:13851return header_size + 8ul;1385213853case value_t::number_integer:13854return header_size + calc_bson_integer_size(j.m_value.number_integer);1385513856case value_t::number_unsigned:13857return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);1385813859case value_t::string:13860return header_size + calc_bson_string_size(*j.m_value.string);1386113862case value_t::null:13863return header_size + 0ul;1386413865// LCOV_EXCL_START13866default:13867JSON_ASSERT(false);13868return 0ul;13869// LCOV_EXCL_STOP13870}13871}1387213873/*!13874@brief Serializes the JSON value @a j to BSON and associates it with the13875key @a name.13876@param name The name to associate with the JSON entity @a j within the13877current BSON document13878@return The size of the BSON entry13879*/13880void write_bson_element(const string_t& name,13881const BasicJsonType& j)13882{13883switch (j.type())13884{13885case value_t::object:13886return write_bson_object_entry(name, *j.m_value.object);1388713888case value_t::array:13889return write_bson_array(name, *j.m_value.array);1389013891case value_t::binary:13892return write_bson_binary(name, *j.m_value.binary);1389313894case value_t::boolean:13895return write_bson_boolean(name, j.m_value.boolean);1389613897case value_t::number_float:13898return write_bson_double(name, j.m_value.number_float);1389913900case value_t::number_integer:13901return write_bson_integer(name, j.m_value.number_integer);1390213903case value_t::number_unsigned:13904return write_bson_unsigned(name, j.m_value.number_unsigned);1390513906case value_t::string:13907return write_bson_string(name, *j.m_value.string);1390813909case value_t::null:13910return write_bson_null(name);1391113912// LCOV_EXCL_START13913default:13914JSON_ASSERT(false);13915return;13916// LCOV_EXCL_STOP13917}13918}1391913920/*!13921@brief Calculates the size of the BSON serialization of the given13922JSON-object @a j.13923@param[in] j JSON value to serialize13924@pre j.type() == value_t::object13925*/13926static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)13927{13928std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),13929[](size_t result, const typename BasicJsonType::object_t::value_type & el)13930{13931return result += calc_bson_element_size(el.first, el.second);13932});1393313934return sizeof(std::int32_t) + document_size + 1ul;13935}1393613937/*!13938@param[in] j JSON value to serialize13939@pre j.type() == value_t::object13940*/13941void write_bson_object(const typename BasicJsonType::object_t& value)13942{13943write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));1394413945for (const auto& el : value)13946{13947write_bson_element(el.first, el.second);13948}1394913950oa->write_character(to_char_type(0x00));13951}1395213953//////////13954// CBOR //13955//////////1395613957static constexpr CharType get_cbor_float_prefix(float /*unused*/)13958{13959return to_char_type(0xFA); // Single-Precision Float13960}1396113962static constexpr CharType get_cbor_float_prefix(double /*unused*/)13963{13964return to_char_type(0xFB); // Double-Precision Float13965}1396613967/////////////13968// MsgPack //13969/////////////1397013971static constexpr CharType get_msgpack_float_prefix(float /*unused*/)13972{13973return to_char_type(0xCA); // float 3213974}1397513976static constexpr CharType get_msgpack_float_prefix(double /*unused*/)13977{13978return to_char_type(0xCB); // float 6413979}1398013981////////////13982// UBJSON //13983////////////1398413985// UBJSON: write number (floating point)13986template<typename NumberType, typename std::enable_if<13987std::is_floating_point<NumberType>::value, int>::type = 0>13988void write_number_with_ubjson_prefix(const NumberType n,13989const bool add_prefix)13990{13991if (add_prefix)13992{13993oa->write_character(get_ubjson_float_prefix(n));13994}13995write_number(n);13996}1399713998// UBJSON: write number (unsigned integer)13999template<typename NumberType, typename std::enable_if<14000std::is_unsigned<NumberType>::value, int>::type = 0>14001void write_number_with_ubjson_prefix(const NumberType n,14002const bool add_prefix)14003{14004if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))14005{14006if (add_prefix)14007{14008oa->write_character(to_char_type('i')); // int814009}14010write_number(static_cast<std::uint8_t>(n));14011}14012else if (n <= (std::numeric_limits<std::uint8_t>::max)())14013{14014if (add_prefix)14015{14016oa->write_character(to_char_type('U')); // uint814017}14018write_number(static_cast<std::uint8_t>(n));14019}14020else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))14021{14022if (add_prefix)14023{14024oa->write_character(to_char_type('I')); // int1614025}14026write_number(static_cast<std::int16_t>(n));14027}14028else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))14029{14030if (add_prefix)14031{14032oa->write_character(to_char_type('l')); // int3214033}14034write_number(static_cast<std::int32_t>(n));14035}14036else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))14037{14038if (add_prefix)14039{14040oa->write_character(to_char_type('L')); // int6414041}14042write_number(static_cast<std::int64_t>(n));14043}14044else14045{14046if (add_prefix)14047{14048oa->write_character(to_char_type('H')); // high-precision number14049}1405014051const auto number = BasicJsonType(n).dump();14052write_number_with_ubjson_prefix(number.size(), true);14053for (std::size_t i = 0; i < number.size(); ++i)14054{14055oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));14056}14057}14058}1405914060// UBJSON: write number (signed integer)14061template < typename NumberType, typename std::enable_if <14062std::is_signed<NumberType>::value&&14063!std::is_floating_point<NumberType>::value, int >::type = 0 >14064void write_number_with_ubjson_prefix(const NumberType n,14065const bool add_prefix)14066{14067if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())14068{14069if (add_prefix)14070{14071oa->write_character(to_char_type('i')); // int814072}14073write_number(static_cast<std::int8_t>(n));14074}14075else 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)()))14076{14077if (add_prefix)14078{14079oa->write_character(to_char_type('U')); // uint814080}14081write_number(static_cast<std::uint8_t>(n));14082}14083else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())14084{14085if (add_prefix)14086{14087oa->write_character(to_char_type('I')); // int1614088}14089write_number(static_cast<std::int16_t>(n));14090}14091else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())14092{14093if (add_prefix)14094{14095oa->write_character(to_char_type('l')); // int3214096}14097write_number(static_cast<std::int32_t>(n));14098}14099else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())14100{14101if (add_prefix)14102{14103oa->write_character(to_char_type('L')); // int6414104}14105write_number(static_cast<std::int64_t>(n));14106}14107// LCOV_EXCL_START14108else14109{14110if (add_prefix)14111{14112oa->write_character(to_char_type('H')); // high-precision number14113}1411414115const auto number = BasicJsonType(n).dump();14116write_number_with_ubjson_prefix(number.size(), true);14117for (std::size_t i = 0; i < number.size(); ++i)14118{14119oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));14120}14121}14122// LCOV_EXCL_STOP14123}1412414125/*!14126@brief determine the type prefix of container values14127*/14128CharType ubjson_prefix(const BasicJsonType& j) const noexcept14129{14130switch (j.type())14131{14132case value_t::null:14133return 'Z';1413414135case value_t::boolean:14136return j.m_value.boolean ? 'T' : 'F';1413714138case value_t::number_integer:14139{14140if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())14141{14142return 'i';14143}14144if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())14145{14146return 'U';14147}14148if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())14149{14150return 'I';14151}14152if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())14153{14154return 'l';14155}14156if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())14157{14158return 'L';14159}14160// anything else is treated as high-precision number14161return 'H'; // LCOV_EXCL_LINE14162}1416314164case value_t::number_unsigned:14165{14166if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))14167{14168return 'i';14169}14170if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))14171{14172return 'U';14173}14174if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))14175{14176return 'I';14177}14178if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))14179{14180return 'l';14181}14182if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))14183{14184return 'L';14185}14186// anything else is treated as high-precision number14187return 'H'; // LCOV_EXCL_LINE14188}1418914190case value_t::number_float:14191return get_ubjson_float_prefix(j.m_value.number_float);1419214193case value_t::string:14194return 'S';1419514196case value_t::array: // fallthrough14197case value_t::binary:14198return '[';1419914200case value_t::object:14201return '{';1420214203default: // discarded values14204return 'N';14205}14206}1420714208static constexpr CharType get_ubjson_float_prefix(float /*unused*/)14209{14210return 'd'; // float 3214211}1421214213static constexpr CharType get_ubjson_float_prefix(double /*unused*/)14214{14215return 'D'; // float 6414216}1421714218///////////////////////14219// Utility functions //14220///////////////////////1422114222/*14223@brief write a number to output input14224@param[in] n number of type @a NumberType14225@tparam NumberType the type of the number14226@tparam OutputIsLittleEndian Set to true if output data is14227required to be little endian1422814229@note This function needs to respect the system's endianess, because bytes14230in CBOR, MessagePack, and UBJSON are stored in network order (big14231endian) and therefore need reordering on little endian systems.14232*/14233template<typename NumberType, bool OutputIsLittleEndian = false>14234void write_number(const NumberType n)14235{14236// step 1: write number to array of length NumberType14237std::array<CharType, sizeof(NumberType)> vec;14238std::memcpy(vec.data(), &n, sizeof(NumberType));1423914240// step 2: write array to output (with possible reordering)14241if (is_little_endian != OutputIsLittleEndian)14242{14243// reverse byte order prior to conversion if necessary14244std::reverse(vec.begin(), vec.end());14245}1424614247oa->write_characters(vec.data(), sizeof(NumberType));14248}1424914250void write_compact_float(const number_float_t n, detail::input_format_t format)14251{14252if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&14253static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&14254static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))14255{14256oa->write_character(format == detail::input_format_t::cbor14257? get_cbor_float_prefix(static_cast<float>(n))14258: get_msgpack_float_prefix(static_cast<float>(n)));14259write_number(static_cast<float>(n));14260}14261else14262{14263oa->write_character(format == detail::input_format_t::cbor14264? get_cbor_float_prefix(n)14265: get_msgpack_float_prefix(n));14266write_number(n);14267}14268}1426914270public:14271// The following to_char_type functions are implement the conversion14272// between uint8_t and CharType. In case CharType is not unsigned,14273// such a conversion is required to allow values greater than 128.14274// See <https://github.com/nlohmann/json/issues/1286> for a discussion.14275template < typename C = CharType,14276enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >14277static constexpr CharType to_char_type(std::uint8_t x) noexcept14278{14279return *reinterpret_cast<char*>(&x);14280}1428114282template < typename C = CharType,14283enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >14284static CharType to_char_type(std::uint8_t x) noexcept14285{14286static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");14287static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");14288CharType result;14289std::memcpy(&result, &x, sizeof(x));14290return result;14291}1429214293template<typename C = CharType,14294enable_if_t<std::is_unsigned<C>::value>* = nullptr>14295static constexpr CharType to_char_type(std::uint8_t x) noexcept14296{14297return x;14298}1429914300template < typename InputCharType, typename C = CharType,14301enable_if_t <14302std::is_signed<C>::value &&14303std::is_signed<char>::value &&14304std::is_same<char, typename std::remove_cv<InputCharType>::type>::value14305> * = nullptr >14306static constexpr CharType to_char_type(InputCharType x) noexcept14307{14308return x;14309}1431014311private:14312/// whether we can assume little endianess14313const bool is_little_endian = little_endianess();1431414315/// the output14316output_adapter_t<CharType> oa = nullptr;14317};14318} // namespace detail14319} // namespace nlohmann1432014321// #include <nlohmann/detail/output/output_adapters.hpp>1432214323// #include <nlohmann/detail/output/serializer.hpp>143241432514326#include <algorithm> // reverse, remove, fill, find, none_of14327#include <array> // array14328#include <clocale> // localeconv, lconv14329#include <cmath> // labs, isfinite, isnan, signbit14330#include <cstddef> // size_t, ptrdiff_t14331#include <cstdint> // uint8_t14332#include <cstdio> // snprintf14333#include <limits> // numeric_limits14334#include <string> // string, char_traits14335#include <type_traits> // is_same14336#include <utility> // move1433714338// #include <nlohmann/detail/conversions/to_chars.hpp>143391434014341#include <array> // array14342#include <cmath> // signbit, isfinite14343#include <cstdint> // intN_t, uintN_t14344#include <cstring> // memcpy, memmove14345#include <limits> // numeric_limits14346#include <type_traits> // conditional1434714348// #include <nlohmann/detail/macro_scope.hpp>143491435014351namespace nlohmann14352{14353namespace detail14354{1435514356/*!14357@brief implements the Grisu2 algorithm for binary to decimal floating-point14358conversion.1435914360This implementation is a slightly modified version of the reference14361implementation which may be obtained from14362http://florian.loitsch.com/publications (bench.tar.gz).1436314364The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.1436514366For a detailed description of the algorithm see:1436714368[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with14369Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming14370Language Design and Implementation, PLDI 201014371[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",14372Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language14373Design and Implementation, PLDI 199614374*/14375namespace dtoa_impl14376{1437714378template<typename Target, typename Source>14379Target reinterpret_bits(const Source source)14380{14381static_assert(sizeof(Target) == sizeof(Source), "size mismatch");1438214383Target target;14384std::memcpy(&target, &source, sizeof(Source));14385return target;14386}1438714388struct diyfp // f * 2^e14389{14390static constexpr int kPrecision = 64; // = q1439114392std::uint64_t f = 0;14393int e = 0;1439414395constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}1439614397/*!14398@brief returns x - y14399@pre x.e == y.e and x.f >= y.f14400*/14401static diyfp sub(const diyfp& x, const diyfp& y) noexcept14402{14403JSON_ASSERT(x.e == y.e);14404JSON_ASSERT(x.f >= y.f);1440514406return {x.f - y.f, x.e};14407}1440814409/*!14410@brief returns x * y14411@note The result is rounded. (Only the upper q bits are returned.)14412*/14413static diyfp mul(const diyfp& x, const diyfp& y) noexcept14414{14415static_assert(kPrecision == 64, "internal error");1441614417// Computes:14418// f = round((x.f * y.f) / 2^q)14419// e = x.e + y.e + q1442014421// Emulate the 64-bit * 64-bit multiplication:14422//14423// p = u * v14424// = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)14425// = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )14426// = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )14427// = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )14428// = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)14429// = (p0_lo ) + 2^32 (Q ) + 2^64 (H )14430// = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )14431//14432// (Since Q might be larger than 2^32 - 1)14433//14434// = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)14435//14436// (Q_hi + H does not overflow a 64-bit int)14437//14438// = p_lo + 2^64 p_hi1443914440const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;14441const std::uint64_t u_hi = x.f >> 32u;14442const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;14443const std::uint64_t v_hi = y.f >> 32u;1444414445const std::uint64_t p0 = u_lo * v_lo;14446const std::uint64_t p1 = u_lo * v_hi;14447const std::uint64_t p2 = u_hi * v_lo;14448const std::uint64_t p3 = u_hi * v_hi;1444914450const std::uint64_t p0_hi = p0 >> 32u;14451const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;14452const std::uint64_t p1_hi = p1 >> 32u;14453const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;14454const std::uint64_t p2_hi = p2 >> 32u;1445514456std::uint64_t Q = p0_hi + p1_lo + p2_lo;1445714458// The full product might now be computed as14459//14460// p_hi = p3 + p2_hi + p1_hi + (Q >> 32)14461// p_lo = p0_lo + (Q << 32)14462//14463// But in this particular case here, the full p_lo is not required.14464// Effectively we only need to add the highest bit in p_lo to p_hi (and14465// Q_hi + 1 does not overflow).1446614467Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up1446814469const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);1447014471return {h, x.e + y.e + 64};14472}1447314474/*!14475@brief normalize x such that the significand is >= 2^(q-1)14476@pre x.f != 014477*/14478static diyfp normalize(diyfp x) noexcept14479{14480JSON_ASSERT(x.f != 0);1448114482while ((x.f >> 63u) == 0)14483{14484x.f <<= 1u;14485x.e--;14486}1448714488return x;14489}1449014491/*!14492@brief normalize x such that the result has the exponent E14493@pre e >= x.e and the upper e - x.e bits of x.f must be zero.14494*/14495static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept14496{14497const int delta = x.e - target_exponent;1449814499JSON_ASSERT(delta >= 0);14500JSON_ASSERT(((x.f << delta) >> delta) == x.f);1450114502return {x.f << delta, target_exponent};14503}14504};1450514506struct boundaries14507{14508diyfp w;14509diyfp minus;14510diyfp plus;14511};1451214513/*!14514Compute the (normalized) diyfp representing the input number 'value' and its14515boundaries.1451614517@pre value must be finite and positive14518*/14519template<typename FloatType>14520boundaries compute_boundaries(FloatType value)14521{14522JSON_ASSERT(std::isfinite(value));14523JSON_ASSERT(value > 0);1452414525// Convert the IEEE representation into a diyfp.14526//14527// If v is denormal:14528// value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))14529// If v is normalized:14530// value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))1453114532static_assert(std::numeric_limits<FloatType>::is_iec559,14533"internal error: dtoa_short requires an IEEE-754 floating-point implementation");1453414535constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)14536constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);14537constexpr int kMinExp = 1 - kBias;14538constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)1453914540using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;1454114542const std::uint64_t bits = reinterpret_bits<bits_type>(value);14543const std::uint64_t E = bits >> (kPrecision - 1);14544const std::uint64_t F = bits & (kHiddenBit - 1);1454514546const bool is_denormal = E == 0;14547const diyfp v = is_denormal14548? diyfp(F, kMinExp)14549: diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);1455014551// Compute the boundaries m- and m+ of the floating-point value14552// v = f * 2^e.14553//14554// Determine v- and v+, the floating-point predecessor and successor if v,14555// respectively.14556//14557// v- = v - 2^e if f != 2^(p-1) or e == e_min (A)14558// = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)14559//14560// v+ = v + 2^e14561//14562// Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_14563// between m- and m+ round to v, regardless of how the input rounding14564// algorithm breaks ties.14565//14566// ---+-------------+-------------+-------------+-------------+--- (A)14567// v- m- v m+ v+14568//14569// -----------------+------+------+-------------+-------------+--- (B)14570// v- m- v m+ v+1457114572const bool lower_boundary_is_closer = F == 0 && E > 1;14573const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);14574const diyfp m_minus = lower_boundary_is_closer14575? diyfp(4 * v.f - 1, v.e - 2) // (B)14576: diyfp(2 * v.f - 1, v.e - 1); // (A)1457714578// Determine the normalized w+ = m+.14579const diyfp w_plus = diyfp::normalize(m_plus);1458014581// Determine w- = m- such that e_(w-) = e_(w+).14582const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);1458314584return {diyfp::normalize(v), w_minus, w_plus};14585}1458614587// Given normalized diyfp w, Grisu needs to find a (normalized) cached14588// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies14589// within a certain range [alpha, gamma] (Definition 3.2 from [1])14590//14591// alpha <= e = e_c + e_w + q <= gamma14592//14593// or14594//14595// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q14596// <= f_c * f_w * 2^gamma14597//14598// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies14599//14600// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma14601//14602// or14603//14604// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)14605//14606// The choice of (alpha,gamma) determines the size of the table and the form of14607// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well14608// in practice:14609//14610// The idea is to cut the number c * w = f * 2^e into two parts, which can be14611// processed independently: An integral part p1, and a fractional part p2:14612//14613// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e14614// = (f div 2^-e) + (f mod 2^-e) * 2^e14615// = p1 + p2 * 2^e14616//14617// The conversion of p1 into decimal form requires a series of divisions and14618// modulos by (a power of) 10. These operations are faster for 32-bit than for14619// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be14620// achieved by choosing14621//14622// -e >= 32 or e <= -32 := gamma14623//14624// In order to convert the fractional part14625//14626// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...14627//14628// into decimal form, the fraction is repeatedly multiplied by 10 and the digits14629// d[-i] are extracted in order:14630//14631// (10 * p2) div 2^-e = d[-1]14632// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...14633//14634// The multiplication by 10 must not overflow. It is sufficient to choose14635//14636// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.14637//14638// Since p2 = f mod 2^-e < 2^-e,14639//14640// -e <= 60 or e >= -60 := alpha1464114642constexpr int kAlpha = -60;14643constexpr int kGamma = -32;1464414645struct cached_power // c = f * 2^e ~= 10^k14646{14647std::uint64_t f;14648int e;14649int k;14650};1465114652/*!14653For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached14654power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c14655satisfies (Definition 3.2 from [1])1465614657alpha <= e_c + e + q <= gamma.14658*/14659inline cached_power get_cached_power_for_binary_exponent(int e)14660{14661// Now14662//14663// alpha <= e_c + e + q <= gamma (1)14664// ==> f_c * 2^alpha <= c * 2^e * 2^q14665//14666// and since the c's are normalized, 2^(q-1) <= f_c,14667//14668// ==> 2^(q - 1 + alpha) <= c * 2^(e + q)14669// ==> 2^(alpha - e - 1) <= c14670//14671// If c were an exact power of ten, i.e. c = 10^k, one may determine k as14672//14673// k = ceil( log_10( 2^(alpha - e - 1) ) )14674// = ceil( (alpha - e - 1) * log_10(2) )14675//14676// From the paper:14677// "In theory the result of the procedure could be wrong since c is rounded,14678// and the computation itself is approximated [...]. In practice, however,14679// this simple function is sufficient."14680//14681// For IEEE double precision floating-point numbers converted into14682// normalized diyfp's w = f * 2^e, with q = 64,14683//14684// e >= -1022 (min IEEE exponent)14685// -52 (p - 1)14686// -52 (p - 1, possibly normalize denormal IEEE numbers)14687// -11 (normalize the diyfp)14688// = -113714689//14690// and14691//14692// e <= +1023 (max IEEE exponent)14693// -52 (p - 1)14694// -11 (normalize the diyfp)14695// = 96014696//14697// This binary exponent range [-1137,960] results in a decimal exponent14698// range [-307,324]. One does not need to store a cached power for each14699// k in this range. For each such k it suffices to find a cached power14700// such that the exponent of the product lies in [alpha,gamma].14701// This implies that the difference of the decimal exponents of adjacent14702// table entries must be less than or equal to14703//14704// floor( (gamma - alpha) * log_10(2) ) = 8.14705//14706// (A smaller distance gamma-alpha would require a larger table.)1470714708// NB:14709// Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.1471014711constexpr int kCachedPowersMinDecExp = -300;14712constexpr int kCachedPowersDecStep = 8;1471314714static constexpr std::array<cached_power, 79> kCachedPowers =14715{14716{14717{ 0xAB70FE17C79AC6CA, -1060, -300 },14718{ 0xFF77B1FCBEBCDC4F, -1034, -292 },14719{ 0xBE5691EF416BD60C, -1007, -284 },14720{ 0x8DD01FAD907FFC3C, -980, -276 },14721{ 0xD3515C2831559A83, -954, -268 },14722{ 0x9D71AC8FADA6C9B5, -927, -260 },14723{ 0xEA9C227723EE8BCB, -901, -252 },14724{ 0xAECC49914078536D, -874, -244 },14725{ 0x823C12795DB6CE57, -847, -236 },14726{ 0xC21094364DFB5637, -821, -228 },14727{ 0x9096EA6F3848984F, -794, -220 },14728{ 0xD77485CB25823AC7, -768, -212 },14729{ 0xA086CFCD97BF97F4, -741, -204 },14730{ 0xEF340A98172AACE5, -715, -196 },14731{ 0xB23867FB2A35B28E, -688, -188 },14732{ 0x84C8D4DFD2C63F3B, -661, -180 },14733{ 0xC5DD44271AD3CDBA, -635, -172 },14734{ 0x936B9FCEBB25C996, -608, -164 },14735{ 0xDBAC6C247D62A584, -582, -156 },14736{ 0xA3AB66580D5FDAF6, -555, -148 },14737{ 0xF3E2F893DEC3F126, -529, -140 },14738{ 0xB5B5ADA8AAFF80B8, -502, -132 },14739{ 0x87625F056C7C4A8B, -475, -124 },14740{ 0xC9BCFF6034C13053, -449, -116 },14741{ 0x964E858C91BA2655, -422, -108 },14742{ 0xDFF9772470297EBD, -396, -100 },14743{ 0xA6DFBD9FB8E5B88F, -369, -92 },14744{ 0xF8A95FCF88747D94, -343, -84 },14745{ 0xB94470938FA89BCF, -316, -76 },14746{ 0x8A08F0F8BF0F156B, -289, -68 },14747{ 0xCDB02555653131B6, -263, -60 },14748{ 0x993FE2C6D07B7FAC, -236, -52 },14749{ 0xE45C10C42A2B3B06, -210, -44 },14750{ 0xAA242499697392D3, -183, -36 },14751{ 0xFD87B5F28300CA0E, -157, -28 },14752{ 0xBCE5086492111AEB, -130, -20 },14753{ 0x8CBCCC096F5088CC, -103, -12 },14754{ 0xD1B71758E219652C, -77, -4 },14755{ 0x9C40000000000000, -50, 4 },14756{ 0xE8D4A51000000000, -24, 12 },14757{ 0xAD78EBC5AC620000, 3, 20 },14758{ 0x813F3978F8940984, 30, 28 },14759{ 0xC097CE7BC90715B3, 56, 36 },14760{ 0x8F7E32CE7BEA5C70, 83, 44 },14761{ 0xD5D238A4ABE98068, 109, 52 },14762{ 0x9F4F2726179A2245, 136, 60 },14763{ 0xED63A231D4C4FB27, 162, 68 },14764{ 0xB0DE65388CC8ADA8, 189, 76 },14765{ 0x83C7088E1AAB65DB, 216, 84 },14766{ 0xC45D1DF942711D9A, 242, 92 },14767{ 0x924D692CA61BE758, 269, 100 },14768{ 0xDA01EE641A708DEA, 295, 108 },14769{ 0xA26DA3999AEF774A, 322, 116 },14770{ 0xF209787BB47D6B85, 348, 124 },14771{ 0xB454E4A179DD1877, 375, 132 },14772{ 0x865B86925B9BC5C2, 402, 140 },14773{ 0xC83553C5C8965D3D, 428, 148 },14774{ 0x952AB45CFA97A0B3, 455, 156 },14775{ 0xDE469FBD99A05FE3, 481, 164 },14776{ 0xA59BC234DB398C25, 508, 172 },14777{ 0xF6C69A72A3989F5C, 534, 180 },14778{ 0xB7DCBF5354E9BECE, 561, 188 },14779{ 0x88FCF317F22241E2, 588, 196 },14780{ 0xCC20CE9BD35C78A5, 614, 204 },14781{ 0x98165AF37B2153DF, 641, 212 },14782{ 0xE2A0B5DC971F303A, 667, 220 },14783{ 0xA8D9D1535CE3B396, 694, 228 },14784{ 0xFB9B7CD9A4A7443C, 720, 236 },14785{ 0xBB764C4CA7A44410, 747, 244 },14786{ 0x8BAB8EEFB6409C1A, 774, 252 },14787{ 0xD01FEF10A657842C, 800, 260 },14788{ 0x9B10A4E5E9913129, 827, 268 },14789{ 0xE7109BFBA19C0C9D, 853, 276 },14790{ 0xAC2820D9623BF429, 880, 284 },14791{ 0x80444B5E7AA7CF85, 907, 292 },14792{ 0xBF21E44003ACDD2D, 933, 300 },14793{ 0x8E679C2F5E44FF8F, 960, 308 },14794{ 0xD433179D9C8CB841, 986, 316 },14795{ 0x9E19DB92B4E31BA9, 1013, 324 },14796}14797};1479814799// This computation gives exactly the same results for k as14800// k = ceil((kAlpha - e - 1) * 0.30102999566398114)14801// for |e| <= 1500, but doesn't require floating-point operations.14802// NB: log_10(2) ~= 78913 / 2^1814803JSON_ASSERT(e >= -1500);14804JSON_ASSERT(e <= 1500);14805const int f = kAlpha - e - 1;14806const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);1480714808const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;14809JSON_ASSERT(index >= 0);14810JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());1481114812const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];14813JSON_ASSERT(kAlpha <= cached.e + e + 64);14814JSON_ASSERT(kGamma >= cached.e + e + 64);1481514816return cached;14817}1481814819/*!14820For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.14821For n == 0, returns 1 and sets pow10 := 1.14822*/14823inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)14824{14825// LCOV_EXCL_START14826if (n >= 1000000000)14827{14828pow10 = 1000000000;14829return 10;14830}14831// LCOV_EXCL_STOP14832else if (n >= 100000000)14833{14834pow10 = 100000000;14835return 9;14836}14837else if (n >= 10000000)14838{14839pow10 = 10000000;14840return 8;14841}14842else if (n >= 1000000)14843{14844pow10 = 1000000;14845return 7;14846}14847else if (n >= 100000)14848{14849pow10 = 100000;14850return 6;14851}14852else if (n >= 10000)14853{14854pow10 = 10000;14855return 5;14856}14857else if (n >= 1000)14858{14859pow10 = 1000;14860return 4;14861}14862else if (n >= 100)14863{14864pow10 = 100;14865return 3;14866}14867else if (n >= 10)14868{14869pow10 = 10;14870return 2;14871}14872else14873{14874pow10 = 1;14875return 1;14876}14877}1487814879inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,14880std::uint64_t rest, std::uint64_t ten_k)14881{14882JSON_ASSERT(len >= 1);14883JSON_ASSERT(dist <= delta);14884JSON_ASSERT(rest <= delta);14885JSON_ASSERT(ten_k > 0);1488614887// <--------------------------- delta ---->14888// <---- dist --------->14889// --------------[------------------+-------------------]--------------14890// M- w M+14891//14892// ten_k14893// <------>14894// <---- rest ---->14895// --------------[------------------+----+--------------]--------------14896// w V14897// = buf * 10^k14898//14899// ten_k represents a unit-in-the-last-place in the decimal representation14900// stored in buf.14901// Decrement buf by ten_k while this takes buf closer to w.1490214903// The tests are written in this order to avoid overflow in unsigned14904// integer arithmetic.1490514906while (rest < dist14907&& delta - rest >= ten_k14908&& (rest + ten_k < dist || dist - rest > rest + ten_k - dist))14909{14910JSON_ASSERT(buf[len - 1] != '0');14911buf[len - 1]--;14912rest += ten_k;14913}14914}1491514916/*!14917Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.14918M- and M+ must be normalized and share the same exponent -60 <= e <= -32.14919*/14920inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,14921diyfp M_minus, diyfp w, diyfp M_plus)14922{14923static_assert(kAlpha >= -60, "internal error");14924static_assert(kGamma <= -32, "internal error");1492514926// Generates the digits (and the exponent) of a decimal floating-point14927// number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's14928// w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.14929//14930// <--------------------------- delta ---->14931// <---- dist --------->14932// --------------[------------------+-------------------]--------------14933// M- w M+14934//14935// Grisu2 generates the digits of M+ from left to right and stops as soon as14936// V is in [M-,M+].1493714938JSON_ASSERT(M_plus.e >= kAlpha);14939JSON_ASSERT(M_plus.e <= kGamma);1494014941std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)14942std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)1494314944// Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):14945//14946// M+ = f * 2^e14947// = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e14948// = ((p1 ) * 2^-e + (p2 )) * 2^e14949// = p1 + p2 * 2^e1495014951const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);1495214953auto 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.)14954std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e1495514956// 1)14957//14958// Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]1495914960JSON_ASSERT(p1 > 0);1496114962std::uint32_t pow10;14963const int k = find_largest_pow10(p1, pow10);1496414965// 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)14966//14967// p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))14968// = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))14969//14970// M+ = p1 + p2 * 2^e14971// = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e14972// = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e14973// = d[k-1] * 10^(k-1) + ( rest) * 2^e14974//14975// Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)14976//14977// p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]14978//14979// but stop as soon as14980//14981// rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e1498214983int n = k;14984while (n > 0)14985{14986// Invariants:14987// M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)14988// pow10 = 10^(n-1) <= p1 < 10^n14989//14990const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)14991const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)14992//14993// M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e14994// = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)14995//14996JSON_ASSERT(d <= 9);14997buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d14998//14999// M+ = buffer * 10^(n-1) + (r + p2 * 2^e)15000//15001p1 = r;15002n--;15003//15004// M+ = buffer * 10^n + (p1 + p2 * 2^e)15005// pow10 = 10^n15006//1500715008// Now check if enough digits have been generated.15009// Compute15010//15011// p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e15012//15013// Note:15014// Since rest and delta share the same exponent e, it suffices to15015// compare the significands.15016const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;15017if (rest <= delta)15018{15019// V = buffer * 10^n, with M- <= V <= M+.1502015021decimal_exponent += n;1502215023// We may now just stop. But instead look if the buffer could be15024// decremented to bring V closer to w.15025//15026// pow10 = 10^n is now 1 ulp in the decimal representation V.15027// The rounding procedure works with diyfp's with an implicit15028// exponent of e.15029//15030// 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e15031//15032const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;15033grisu2_round(buffer, length, dist, delta, rest, ten_n);1503415035return;15036}1503715038pow10 /= 10;15039//15040// pow10 = 10^(n-1) <= p1 < 10^n15041// Invariants restored.15042}1504315044// 2)15045//15046// The digits of the integral part have been generated:15047//15048// M+ = d[k-1]...d[1]d[0] + p2 * 2^e15049// = buffer + p2 * 2^e15050//15051// Now generate the digits of the fractional part p2 * 2^e.15052//15053// Note:15054// No decimal point is generated: the exponent is adjusted instead.15055//15056// p2 actually represents the fraction15057//15058// p2 * 2^e15059// = p2 / 2^-e15060// = d[-1] / 10^1 + d[-2] / 10^2 + ...15061//15062// Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)15063//15064// p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m15065// + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)15066//15067// using15068//15069// 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)15070// = ( d) * 2^-e + ( r)15071//15072// or15073// 10^m * p2 * 2^e = d + r * 2^e15074//15075// i.e.15076//15077// M+ = buffer + p2 * 2^e15078// = buffer + 10^-m * (d + r * 2^e)15079// = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e15080//15081// and stop as soon as 10^-m * r * 2^e <= delta * 2^e1508215083JSON_ASSERT(p2 > delta);1508415085int m = 0;15086for (;;)15087{15088// Invariant:15089// M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e15090// = buffer * 10^-m + 10^-m * (p2 ) * 2^e15091// = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e15092// = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e15093//15094JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);15095p2 *= 10;15096const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e15097const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e15098//15099// M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e15100// = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))15101// = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e15102//15103JSON_ASSERT(d <= 9);15104buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d15105//15106// M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e15107//15108p2 = r;15109m++;15110//15111// M+ = buffer * 10^-m + 10^-m * p2 * 2^e15112// Invariant restored.1511315114// Check if enough digits have been generated.15115//15116// 10^-m * p2 * 2^e <= delta * 2^e15117// p2 * 2^e <= 10^m * delta * 2^e15118// p2 <= 10^m * delta15119delta *= 10;15120dist *= 10;15121if (p2 <= delta)15122{15123break;15124}15125}1512615127// V = buffer * 10^-m, with M- <= V <= M+.1512815129decimal_exponent -= m;1513015131// 1 ulp in the decimal representation is now 10^-m.15132// Since delta and dist are now scaled by 10^m, we need to do the15133// same with ulp in order to keep the units in sync.15134//15135// 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e15136//15137const std::uint64_t ten_m = one.f;15138grisu2_round(buffer, length, dist, delta, p2, ten_m);1513915140// By construction this algorithm generates the shortest possible decimal15141// number (Loitsch, Theorem 6.2) which rounds back to w.15142// For an input number of precision p, at least15143//15144// N = 1 + ceil(p * log_10(2))15145//15146// decimal digits are sufficient to identify all binary floating-point15147// numbers (Matula, "In-and-Out conversions").15148// This implies that the algorithm does not produce more than N decimal15149// digits.15150//15151// N = 17 for p = 53 (IEEE double precision)15152// N = 9 for p = 24 (IEEE single precision)15153}1515415155/*!15156v = buf * 10^decimal_exponent15157len is the length of the buffer (number of decimal digits)15158The buffer must be large enough, i.e. >= max_digits10.15159*/15160JSON_HEDLEY_NON_NULL(1)15161inline void grisu2(char* buf, int& len, int& decimal_exponent,15162diyfp m_minus, diyfp v, diyfp m_plus)15163{15164JSON_ASSERT(m_plus.e == m_minus.e);15165JSON_ASSERT(m_plus.e == v.e);1516615167// --------(-----------------------+-----------------------)-------- (A)15168// m- v m+15169//15170// --------------------(-----------+-----------------------)-------- (B)15171// m- v m+15172//15173// First scale v (and m- and m+) such that the exponent is in the range15174// [alpha, gamma].1517515176const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);1517715178const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k1517915180// The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]15181const diyfp w = diyfp::mul(v, c_minus_k);15182const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);15183const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);1518415185// ----(---+---)---------------(---+---)---------------(---+---)----15186// w- w w+15187// = c*m- = c*v = c*m+15188//15189// diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and15190// w+ are now off by a small amount.15191// In fact:15192//15193// w - v * 10^k < 1 ulp15194//15195// To account for this inaccuracy, add resp. subtract 1 ulp.15196//15197// --------+---[---------------(---+---)---------------]---+--------15198// w- M- w M+ w+15199//15200// Now any number in [M-, M+] (bounds included) will round to w when input,15201// regardless of how the input rounding algorithm breaks ties.15202//15203// And digit_gen generates the shortest possible such number in [M-, M+].15204// Note that this does not mean that Grisu2 always generates the shortest15205// possible number in the interval (m-, m+).15206const diyfp M_minus(w_minus.f + 1, w_minus.e);15207const diyfp M_plus (w_plus.f - 1, w_plus.e );1520815209decimal_exponent = -cached.k; // = -(-k) = k1521015211grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);15212}1521315214/*!15215v = buf * 10^decimal_exponent15216len is the length of the buffer (number of decimal digits)15217The buffer must be large enough, i.e. >= max_digits10.15218*/15219template<typename FloatType>15220JSON_HEDLEY_NON_NULL(1)15221void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)15222{15223static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,15224"internal error: not enough precision");1522515226JSON_ASSERT(std::isfinite(value));15227JSON_ASSERT(value > 0);1522815229// If the neighbors (and boundaries) of 'value' are always computed for double-precision15230// numbers, all float's can be recovered using strtod (and strtof). However, the resulting15231// decimal representations are not exactly "short".15232//15233// The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)15234// says "value is converted to a string as if by std::sprintf in the default ("C") locale"15235// and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'15236// does.15237// On the other hand, the documentation for 'std::to_chars' requires that "parsing the15238// representation using the corresponding std::from_chars function recovers value exactly". That15239// indicates that single precision floating-point numbers should be recovered using15240// 'std::strtof'.15241//15242// NB: If the neighbors are computed for single-precision numbers, there is a single float15243// (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision15244// value is off by 1 ulp.15245#if 015246const boundaries w = compute_boundaries(static_cast<double>(value));15247#else15248const boundaries w = compute_boundaries(value);15249#endif1525015251grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);15252}1525315254/*!15255@brief appends a decimal representation of e to buf15256@return a pointer to the element following the exponent.15257@pre -1000 < e < 100015258*/15259JSON_HEDLEY_NON_NULL(1)15260JSON_HEDLEY_RETURNS_NON_NULL15261inline char* append_exponent(char* buf, int e)15262{15263JSON_ASSERT(e > -1000);15264JSON_ASSERT(e < 1000);1526515266if (e < 0)15267{15268e = -e;15269*buf++ = '-';15270}15271else15272{15273*buf++ = '+';15274}1527515276auto k = static_cast<std::uint32_t>(e);15277if (k < 10)15278{15279// Always print at least two digits in the exponent.15280// This is for compatibility with printf("%g").15281*buf++ = '0';15282*buf++ = static_cast<char>('0' + k);15283}15284else if (k < 100)15285{15286*buf++ = static_cast<char>('0' + k / 10);15287k %= 10;15288*buf++ = static_cast<char>('0' + k);15289}15290else15291{15292*buf++ = static_cast<char>('0' + k / 100);15293k %= 100;15294*buf++ = static_cast<char>('0' + k / 10);15295k %= 10;15296*buf++ = static_cast<char>('0' + k);15297}1529815299return buf;15300}1530115302/*!15303@brief prettify v = buf * 10^decimal_exponent1530415305If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point15306notation. Otherwise it will be printed in exponential notation.1530715308@pre min_exp < 015309@pre max_exp > 015310*/15311JSON_HEDLEY_NON_NULL(1)15312JSON_HEDLEY_RETURNS_NON_NULL15313inline char* format_buffer(char* buf, int len, int decimal_exponent,15314int min_exp, int max_exp)15315{15316JSON_ASSERT(min_exp < 0);15317JSON_ASSERT(max_exp > 0);1531815319const int k = len;15320const int n = len + decimal_exponent;1532115322// v = buf * 10^(n-k)15323// k is the length of the buffer (number of decimal digits)15324// n is the position of the decimal point relative to the start of the buffer.1532515326if (k <= n && n <= max_exp)15327{15328// digits[000]15329// len <= max_exp + 21533015331std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));15332// Make it look like a floating-point number (#362, #378)15333buf[n + 0] = '.';15334buf[n + 1] = '0';15335return buf + (static_cast<size_t>(n) + 2);15336}1533715338if (0 < n && n <= max_exp)15339{15340// dig.its15341// len <= max_digits10 + 11534215343JSON_ASSERT(k > n);1534415345std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));15346buf[n] = '.';15347return buf + (static_cast<size_t>(k) + 1U);15348}1534915350if (min_exp < n && n <= 0)15351{15352// 0.[000]digits15353// len <= 2 + (-min_exp - 1) + max_digits101535415355std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));15356buf[0] = '0';15357buf[1] = '.';15358std::memset(buf + 2, '0', static_cast<size_t>(-n));15359return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));15360}1536115362if (k == 1)15363{15364// dE+12315365// len <= 1 + 51536615367buf += 1;15368}15369else15370{15371// d.igitsE+12315372// len <= max_digits10 + 1 + 51537315374std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);15375buf[1] = '.';15376buf += 1 + static_cast<size_t>(k);15377}1537815379*buf++ = 'e';15380return append_exponent(buf, n - 1);15381}1538215383} // namespace dtoa_impl1538415385/*!15386@brief generates a decimal representation of the floating-point number value in [first, last).1538715388The format of the resulting decimal representation is similar to printf's %g15389format. Returns an iterator pointing past-the-end of the decimal representation.1539015391@note The input number must be finite, i.e. NaN's and Inf's are not supported.15392@note The buffer must be large enough.15393@note The result is NOT null-terminated.15394*/15395template<typename FloatType>15396JSON_HEDLEY_NON_NULL(1, 2)15397JSON_HEDLEY_RETURNS_NON_NULL15398char* to_chars(char* first, const char* last, FloatType value)15399{15400static_cast<void>(last); // maybe unused - fix warning15401JSON_ASSERT(std::isfinite(value));1540215403// Use signbit(value) instead of (value < 0) since signbit works for -0.15404if (std::signbit(value))15405{15406value = -value;15407*first++ = '-';15408}1540915410if (value == 0) // +-015411{15412*first++ = '0';15413// Make it look like a floating-point number (#362, #378)15414*first++ = '.';15415*first++ = '0';15416return first;15417}1541815419JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);1542015421// Compute v = buffer * 10^decimal_exponent.15422// The decimal digits are stored in the buffer, which needs to be interpreted15423// as an unsigned decimal integer.15424// len is the length of the buffer, i.e. the number of decimal digits.15425int len = 0;15426int decimal_exponent = 0;15427dtoa_impl::grisu2(first, len, decimal_exponent, value);1542815429JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);1543015431// Format the buffer like printf("%.*g", prec, value)15432constexpr int kMinExp = -4;15433// Use digits10 here to increase compatibility with version 2.15434constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;1543515436JSON_ASSERT(last - first >= kMaxExp + 2);15437JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);15438JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);1543915440return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);15441}1544215443} // namespace detail15444} // namespace nlohmann1544515446// #include <nlohmann/detail/exceptions.hpp>1544715448// #include <nlohmann/detail/macro_scope.hpp>1544915450// #include <nlohmann/detail/meta/cpp_future.hpp>1545115452// #include <nlohmann/detail/output/binary_writer.hpp>1545315454// #include <nlohmann/detail/output/output_adapters.hpp>1545515456// #include <nlohmann/detail/value_t.hpp>154571545815459namespace nlohmann15460{15461namespace detail15462{15463///////////////////15464// serialization //15465///////////////////1546615467/// how to treat decoding errors15468enum class error_handler_t15469{15470strict, ///< throw a type_error exception in case of invalid UTF-815471replace, ///< replace invalid UTF-8 sequences with U+FFFD15472ignore ///< ignore invalid UTF-8 sequences15473};1547415475template<typename BasicJsonType>15476class serializer15477{15478using string_t = typename BasicJsonType::string_t;15479using number_float_t = typename BasicJsonType::number_float_t;15480using number_integer_t = typename BasicJsonType::number_integer_t;15481using number_unsigned_t = typename BasicJsonType::number_unsigned_t;15482using binary_char_t = typename BasicJsonType::binary_t::value_type;15483static constexpr std::uint8_t UTF8_ACCEPT = 0;15484static constexpr std::uint8_t UTF8_REJECT = 1;1548515486public:15487/*!15488@param[in] s output stream to serialize to15489@param[in] ichar indentation character to use15490@param[in] error_handler_ how to react on decoding errors15491*/15492serializer(output_adapter_t<char> s, const char ichar,15493error_handler_t error_handler_ = error_handler_t::strict)15494: o(std::move(s))15495, loc(std::localeconv())15496, thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))15497, decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))15498, indent_char(ichar)15499, indent_string(512, indent_char)15500, error_handler(error_handler_)15501{}1550215503// delete because of pointer members15504serializer(const serializer&) = delete;15505serializer& operator=(const serializer&) = delete;15506serializer(serializer&&) = delete;15507serializer& operator=(serializer&&) = delete;15508~serializer() = default;1550915510/*!15511@brief internal implementation of the serialization function1551215513This function is called by the public member function dump and organizes15514the serialization internally. The indentation level is propagated as15515additional parameter. In case of arrays and objects, the function is15516called recursively.1551715518- strings and object keys are escaped using `escape_string()`15519- integer numbers are converted implicitly via `operator<<`15520- floating-point numbers are converted to a string using `"%g"` format15521- binary values are serialized as objects containing the subtype and the15522byte array1552315524@param[in] val value to serialize15525@param[in] pretty_print whether the output shall be pretty-printed15526@param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters15527in the output are escaped with `\uXXXX` sequences, and the result consists15528of ASCII characters only.15529@param[in] indent_step the indent level15530@param[in] current_indent the current indent level (only used internally)15531*/15532void dump(const BasicJsonType& val,15533const bool pretty_print,15534const bool ensure_ascii,15535const unsigned int indent_step,15536const unsigned int current_indent = 0)15537{15538switch (val.m_type)15539{15540case value_t::object:15541{15542if (val.m_value.object->empty())15543{15544o->write_characters("{}", 2);15545return;15546}1554715548if (pretty_print)15549{15550o->write_characters("{\n", 2);1555115552// variable to hold indentation for recursive calls15553const auto new_indent = current_indent + indent_step;15554if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))15555{15556indent_string.resize(indent_string.size() * 2, ' ');15557}1555815559// first n-1 elements15560auto i = val.m_value.object->cbegin();15561for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)15562{15563o->write_characters(indent_string.c_str(), new_indent);15564o->write_character('\"');15565dump_escaped(i->first, ensure_ascii);15566o->write_characters("\": ", 3);15567dump(i->second, true, ensure_ascii, indent_step, new_indent);15568o->write_characters(",\n", 2);15569}1557015571// last element15572JSON_ASSERT(i != val.m_value.object->cend());15573JSON_ASSERT(std::next(i) == val.m_value.object->cend());15574o->write_characters(indent_string.c_str(), new_indent);15575o->write_character('\"');15576dump_escaped(i->first, ensure_ascii);15577o->write_characters("\": ", 3);15578dump(i->second, true, ensure_ascii, indent_step, new_indent);1557915580o->write_character('\n');15581o->write_characters(indent_string.c_str(), current_indent);15582o->write_character('}');15583}15584else15585{15586o->write_character('{');1558715588// first n-1 elements15589auto i = val.m_value.object->cbegin();15590for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)15591{15592o->write_character('\"');15593dump_escaped(i->first, ensure_ascii);15594o->write_characters("\":", 2);15595dump(i->second, false, ensure_ascii, indent_step, current_indent);15596o->write_character(',');15597}1559815599// last element15600JSON_ASSERT(i != val.m_value.object->cend());15601JSON_ASSERT(std::next(i) == val.m_value.object->cend());15602o->write_character('\"');15603dump_escaped(i->first, ensure_ascii);15604o->write_characters("\":", 2);15605dump(i->second, false, ensure_ascii, indent_step, current_indent);1560615607o->write_character('}');15608}1560915610return;15611}1561215613case value_t::array:15614{15615if (val.m_value.array->empty())15616{15617o->write_characters("[]", 2);15618return;15619}1562015621if (pretty_print)15622{15623o->write_characters("[\n", 2);1562415625// variable to hold indentation for recursive calls15626const auto new_indent = current_indent + indent_step;15627if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))15628{15629indent_string.resize(indent_string.size() * 2, ' ');15630}1563115632// first n-1 elements15633for (auto i = val.m_value.array->cbegin();15634i != val.m_value.array->cend() - 1; ++i)15635{15636o->write_characters(indent_string.c_str(), new_indent);15637dump(*i, true, ensure_ascii, indent_step, new_indent);15638o->write_characters(",\n", 2);15639}1564015641// last element15642JSON_ASSERT(!val.m_value.array->empty());15643o->write_characters(indent_string.c_str(), new_indent);15644dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);1564515646o->write_character('\n');15647o->write_characters(indent_string.c_str(), current_indent);15648o->write_character(']');15649}15650else15651{15652o->write_character('[');1565315654// first n-1 elements15655for (auto i = val.m_value.array->cbegin();15656i != val.m_value.array->cend() - 1; ++i)15657{15658dump(*i, false, ensure_ascii, indent_step, current_indent);15659o->write_character(',');15660}1566115662// last element15663JSON_ASSERT(!val.m_value.array->empty());15664dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);1566515666o->write_character(']');15667}1566815669return;15670}1567115672case value_t::string:15673{15674o->write_character('\"');15675dump_escaped(*val.m_value.string, ensure_ascii);15676o->write_character('\"');15677return;15678}1567915680case value_t::binary:15681{15682if (pretty_print)15683{15684o->write_characters("{\n", 2);1568515686// variable to hold indentation for recursive calls15687const auto new_indent = current_indent + indent_step;15688if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))15689{15690indent_string.resize(indent_string.size() * 2, ' ');15691}1569215693o->write_characters(indent_string.c_str(), new_indent);1569415695o->write_characters("\"bytes\": [", 10);1569615697if (!val.m_value.binary->empty())15698{15699for (auto i = val.m_value.binary->cbegin();15700i != val.m_value.binary->cend() - 1; ++i)15701{15702dump_integer(*i);15703o->write_characters(", ", 2);15704}15705dump_integer(val.m_value.binary->back());15706}1570715708o->write_characters("],\n", 3);15709o->write_characters(indent_string.c_str(), new_indent);1571015711o->write_characters("\"subtype\": ", 11);15712if (val.m_value.binary->has_subtype())15713{15714dump_integer(val.m_value.binary->subtype());15715}15716else15717{15718o->write_characters("null", 4);15719}15720o->write_character('\n');15721o->write_characters(indent_string.c_str(), current_indent);15722o->write_character('}');15723}15724else15725{15726o->write_characters("{\"bytes\":[", 10);1572715728if (!val.m_value.binary->empty())15729{15730for (auto i = val.m_value.binary->cbegin();15731i != val.m_value.binary->cend() - 1; ++i)15732{15733dump_integer(*i);15734o->write_character(',');15735}15736dump_integer(val.m_value.binary->back());15737}1573815739o->write_characters("],\"subtype\":", 12);15740if (val.m_value.binary->has_subtype())15741{15742dump_integer(val.m_value.binary->subtype());15743o->write_character('}');15744}15745else15746{15747o->write_characters("null}", 5);15748}15749}15750return;15751}1575215753case value_t::boolean:15754{15755if (val.m_value.boolean)15756{15757o->write_characters("true", 4);15758}15759else15760{15761o->write_characters("false", 5);15762}15763return;15764}1576515766case value_t::number_integer:15767{15768dump_integer(val.m_value.number_integer);15769return;15770}1577115772case value_t::number_unsigned:15773{15774dump_integer(val.m_value.number_unsigned);15775return;15776}1577715778case value_t::number_float:15779{15780dump_float(val.m_value.number_float);15781return;15782}1578315784case value_t::discarded:15785{15786o->write_characters("<discarded>", 11);15787return;15788}1578915790case value_t::null:15791{15792o->write_characters("null", 4);15793return;15794}1579515796default: // LCOV_EXCL_LINE15797JSON_ASSERT(false); // LCOV_EXCL_LINE15798}15799}1580015801private:15802/*!15803@brief dump escaped string1580415805Escape a string by replacing certain special characters by a sequence of an15806escape character (backslash) and another character and other control15807characters by a sequence of "\u" followed by a four-digit hex15808representation. The escaped string is written to output stream @a o.1580915810@param[in] s the string to escape15811@param[in] ensure_ascii whether to escape non-ASCII characters with15812\uXXXX sequences1581315814@complexity Linear in the length of string @a s.15815*/15816void dump_escaped(const string_t& s, const bool ensure_ascii)15817{15818std::uint32_t codepoint;15819std::uint8_t state = UTF8_ACCEPT;15820std::size_t bytes = 0; // number of bytes written to string_buffer1582115822// number of bytes written at the point of the last valid byte15823std::size_t bytes_after_last_accept = 0;15824std::size_t undumped_chars = 0;1582515826for (std::size_t i = 0; i < s.size(); ++i)15827{15828const auto byte = static_cast<uint8_t>(s[i]);1582915830switch (decode(state, codepoint, byte))15831{15832case UTF8_ACCEPT: // decode found a new code point15833{15834switch (codepoint)15835{15836case 0x08: // backspace15837{15838string_buffer[bytes++] = '\\';15839string_buffer[bytes++] = 'b';15840break;15841}1584215843case 0x09: // horizontal tab15844{15845string_buffer[bytes++] = '\\';15846string_buffer[bytes++] = 't';15847break;15848}1584915850case 0x0A: // newline15851{15852string_buffer[bytes++] = '\\';15853string_buffer[bytes++] = 'n';15854break;15855}1585615857case 0x0C: // formfeed15858{15859string_buffer[bytes++] = '\\';15860string_buffer[bytes++] = 'f';15861break;15862}1586315864case 0x0D: // carriage return15865{15866string_buffer[bytes++] = '\\';15867string_buffer[bytes++] = 'r';15868break;15869}1587015871case 0x22: // quotation mark15872{15873string_buffer[bytes++] = '\\';15874string_buffer[bytes++] = '\"';15875break;15876}1587715878case 0x5C: // reverse solidus15879{15880string_buffer[bytes++] = '\\';15881string_buffer[bytes++] = '\\';15882break;15883}1588415885default:15886{15887// escape control characters (0x00..0x1F) or, if15888// ensure_ascii parameter is used, non-ASCII characters15889if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))15890{15891if (codepoint <= 0xFFFF)15892{15893(std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",15894static_cast<std::uint16_t>(codepoint));15895bytes += 6;15896}15897else15898{15899(std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",15900static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),15901static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));15902bytes += 12;15903}15904}15905else15906{15907// copy byte to buffer (all previous bytes15908// been copied have in default case above)15909string_buffer[bytes++] = s[i];15910}15911break;15912}15913}1591415915// write buffer and reset index; there must be 13 bytes15916// left, as this is the maximal number of bytes to be15917// written ("\uxxxx\uxxxx\0") for one code point15918if (string_buffer.size() - bytes < 13)15919{15920o->write_characters(string_buffer.data(), bytes);15921bytes = 0;15922}1592315924// remember the byte position of this accept15925bytes_after_last_accept = bytes;15926undumped_chars = 0;15927break;15928}1592915930case UTF8_REJECT: // decode found invalid UTF-8 byte15931{15932switch (error_handler)15933{15934case error_handler_t::strict:15935{15936std::string sn(3, '\0');15937(std::snprintf)(&sn[0], sn.size(), "%.2X", byte);15938JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));15939}1594015941case error_handler_t::ignore:15942case error_handler_t::replace:15943{15944// in case we saw this character the first time, we15945// would like to read it again, because the byte15946// may be OK for itself, but just not OK for the15947// previous sequence15948if (undumped_chars > 0)15949{15950--i;15951}1595215953// reset length buffer to the last accepted index;15954// thus removing/ignoring the invalid characters15955bytes = bytes_after_last_accept;1595615957if (error_handler == error_handler_t::replace)15958{15959// add a replacement character15960if (ensure_ascii)15961{15962string_buffer[bytes++] = '\\';15963string_buffer[bytes++] = 'u';15964string_buffer[bytes++] = 'f';15965string_buffer[bytes++] = 'f';15966string_buffer[bytes++] = 'f';15967string_buffer[bytes++] = 'd';15968}15969else15970{15971string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');15972string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');15973string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');15974}1597515976// write buffer and reset index; there must be 13 bytes15977// left, as this is the maximal number of bytes to be15978// written ("\uxxxx\uxxxx\0") for one code point15979if (string_buffer.size() - bytes < 13)15980{15981o->write_characters(string_buffer.data(), bytes);15982bytes = 0;15983}1598415985bytes_after_last_accept = bytes;15986}1598715988undumped_chars = 0;1598915990// continue processing the string15991state = UTF8_ACCEPT;15992break;15993}1599415995default: // LCOV_EXCL_LINE15996JSON_ASSERT(false); // LCOV_EXCL_LINE15997}15998break;15999}1600016001default: // decode found yet incomplete multi-byte code point16002{16003if (!ensure_ascii)16004{16005// code point will not be escaped - copy byte to buffer16006string_buffer[bytes++] = s[i];16007}16008++undumped_chars;16009break;16010}16011}16012}1601316014// we finished processing the string16015if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))16016{16017// write buffer16018if (bytes > 0)16019{16020o->write_characters(string_buffer.data(), bytes);16021}16022}16023else16024{16025// we finish reading, but do not accept: string was incomplete16026switch (error_handler)16027{16028case error_handler_t::strict:16029{16030std::string sn(3, '\0');16031(std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));16032JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));16033}1603416035case error_handler_t::ignore:16036{16037// write all accepted bytes16038o->write_characters(string_buffer.data(), bytes_after_last_accept);16039break;16040}1604116042case error_handler_t::replace:16043{16044// write all accepted bytes16045o->write_characters(string_buffer.data(), bytes_after_last_accept);16046// add a replacement character16047if (ensure_ascii)16048{16049o->write_characters("\\ufffd", 6);16050}16051else16052{16053o->write_characters("\xEF\xBF\xBD", 3);16054}16055break;16056}1605716058default: // LCOV_EXCL_LINE16059JSON_ASSERT(false); // LCOV_EXCL_LINE16060}16061}16062}1606316064/*!16065@brief count digits1606616067Count the number of decimal (base 10) digits for an input unsigned integer.1606816069@param[in] x unsigned integer number to count its digits16070@return number of decimal digits16071*/16072inline unsigned int count_digits(number_unsigned_t x) noexcept16073{16074unsigned int n_digits = 1;16075for (;;)16076{16077if (x < 10)16078{16079return n_digits;16080}16081if (x < 100)16082{16083return n_digits + 1;16084}16085if (x < 1000)16086{16087return n_digits + 2;16088}16089if (x < 10000)16090{16091return n_digits + 3;16092}16093x = x / 10000u;16094n_digits += 4;16095}16096}1609716098/*!16099@brief dump an integer1610016101Dump a given integer to output stream @a o. Works internally with16102@a number_buffer.1610316104@param[in] x integer number (signed or unsigned) to dump16105@tparam NumberType either @a number_integer_t or @a number_unsigned_t16106*/16107template < typename NumberType, detail::enable_if_t <16108std::is_same<NumberType, number_unsigned_t>::value ||16109std::is_same<NumberType, number_integer_t>::value ||16110std::is_same<NumberType, binary_char_t>::value,16111int > = 0 >16112void dump_integer(NumberType x)16113{16114static constexpr std::array<std::array<char, 2>, 100> digits_to_9916115{16116{16117{{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},16118{{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},16119{{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},16120{{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},16121{{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},16122{{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},16123{{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},16124{{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},16125{{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},16126{{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},16127}16128};1612916130// special case for "0"16131if (x == 0)16132{16133o->write_character('0');16134return;16135}1613616137// use a pointer to fill the buffer16138auto buffer_ptr = number_buffer.begin();1613916140const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #75516141number_unsigned_t abs_value;1614216143unsigned int n_chars;1614416145if (is_negative)16146{16147*buffer_ptr = '-';16148abs_value = remove_sign(static_cast<number_integer_t>(x));1614916150// account one more byte for the minus sign16151n_chars = 1 + count_digits(abs_value);16152}16153else16154{16155abs_value = static_cast<number_unsigned_t>(x);16156n_chars = count_digits(abs_value);16157}1615816159// spare 1 byte for '\0'16160JSON_ASSERT(n_chars < number_buffer.size() - 1);1616116162// jump to the end to generate the string from backward16163// so we later avoid reversing the result16164buffer_ptr += n_chars;1616516166// Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu16167// See: https://www.youtube.com/watch?v=o4-CwDo2zpg16168while (abs_value >= 100)16169{16170const auto digits_index = static_cast<unsigned>((abs_value % 100));16171abs_value /= 100;16172*(--buffer_ptr) = digits_to_99[digits_index][1];16173*(--buffer_ptr) = digits_to_99[digits_index][0];16174}1617516176if (abs_value >= 10)16177{16178const auto digits_index = static_cast<unsigned>(abs_value);16179*(--buffer_ptr) = digits_to_99[digits_index][1];16180*(--buffer_ptr) = digits_to_99[digits_index][0];16181}16182else16183{16184*(--buffer_ptr) = static_cast<char>('0' + abs_value);16185}1618616187o->write_characters(number_buffer.data(), n_chars);16188}1618916190/*!16191@brief dump a floating-point number1619216193Dump a given floating-point number to output stream @a o. Works internally16194with @a number_buffer.1619516196@param[in] x floating-point number to dump16197*/16198void dump_float(number_float_t x)16199{16200// NaN / inf16201if (!std::isfinite(x))16202{16203o->write_characters("null", 4);16204return;16205}1620616207// If number_float_t is an IEEE-754 single or double precision number,16208// use the Grisu2 algorithm to produce short numbers which are16209// guaranteed to round-trip, using strtof and strtod, resp.16210//16211// NB: The test below works if <long double> == <double>.16212static constexpr bool is_ieee_single_or_double16213= (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) ||16214(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);1621516216dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());16217}1621816219void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)16220{16221char* begin = number_buffer.data();16222char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);1622316224o->write_characters(begin, static_cast<size_t>(end - begin));16225}1622616227void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)16228{16229// get number of digits for a float -> text -> float round-trip16230static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;1623116232// the actual conversion16233std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);1623416235// negative value indicates an error16236JSON_ASSERT(len > 0);16237// check if buffer was large enough16238JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());1623916240// erase thousands separator16241if (thousands_sep != '\0')16242{16243const auto end = std::remove(number_buffer.begin(),16244number_buffer.begin() + len, thousands_sep);16245std::fill(end, number_buffer.end(), '\0');16246JSON_ASSERT((end - number_buffer.begin()) <= len);16247len = (end - number_buffer.begin());16248}1624916250// convert decimal point to '.'16251if (decimal_point != '\0' && decimal_point != '.')16252{16253const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);16254if (dec_pos != number_buffer.end())16255{16256*dec_pos = '.';16257}16258}1625916260o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));1626116262// determine if need to append ".0"16263const bool value_is_int_like =16264std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,16265[](char c)16266{16267return c == '.' || c == 'e';16268});1626916270if (value_is_int_like)16271{16272o->write_characters(".0", 2);16273}16274}1627516276/*!16277@brief check whether a string is UTF-8 encoded1627816279The function checks each byte of a string whether it is UTF-8 encoded. The16280result of the check is stored in the @a state parameter. The function must16281be called initially with state 0 (accept). State 1 means the string must16282be rejected, because the current byte is not allowed. If the string is16283completely processed, but the state is non-zero, the string ended16284prematurely; that is, the last byte indicated more bytes should have16285followed.1628616287@param[in,out] state the state of the decoding16288@param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)16289@param[in] byte next byte to decode16290@return new state1629116292@note The function has been edited: a std::array is used.1629316294@copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <[email protected]>16295@sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/16296*/16297static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept16298{16299static const std::array<std::uint8_t, 400> utf8d =16300{16301{163020, 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..1F163030, 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..3F163040, 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..5F163050, 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..7F163061, 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..9F163077, 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..BF163088, 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..DF163090xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF163100xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF163110x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0163121, 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..s2163131, 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..s4163141, 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..s6163151, 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..s816316}16317};1631816319const std::uint8_t type = utf8d[byte];1632016321codep = (state != UTF8_ACCEPT)16322? (byte & 0x3fu) | (codep << 6u)16323: (0xFFu >> type) & (byte);1632416325std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);16326JSON_ASSERT(index < 400);16327state = utf8d[index];16328return state;16329}1633016331/*16332* Overload to make the compiler happy while it is instantiating16333* dump_integer for number_unsigned_t.16334* Must never be called.16335*/16336number_unsigned_t remove_sign(number_unsigned_t x)16337{16338JSON_ASSERT(false); // LCOV_EXCL_LINE16339return x; // LCOV_EXCL_LINE16340}1634116342/*16343* Helper function for dump_integer16344*16345* This function takes a negative signed integer and returns its absolute16346* value as unsigned integer. The plus/minus shuffling is necessary as we can16347* not directly remove the sign of an arbitrary signed integer as the16348* absolute values of INT_MIN and INT_MAX are usually not the same. See16349* #1708 for details.16350*/16351inline number_unsigned_t remove_sign(number_integer_t x) noexcept16352{16353JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)());16354return static_cast<number_unsigned_t>(-(x + 1)) + 1;16355}1635616357private:16358/// the output of the serializer16359output_adapter_t<char> o = nullptr;1636016361/// a (hopefully) large enough character buffer16362std::array<char, 64> number_buffer{{}};1636316364/// the locale16365const std::lconv* loc = nullptr;16366/// the locale's thousand separator character16367const char thousands_sep = '\0';16368/// the locale's decimal point character16369const char decimal_point = '\0';1637016371/// string buffer16372std::array<char, 512> string_buffer{{}};1637316374/// the indentation character16375const char indent_char;16376/// the indentation string16377string_t indent_string;1637816379/// error_handler how to react on decoding errors16380const error_handler_t error_handler;16381};16382} // namespace detail16383} // namespace nlohmann1638416385// #include <nlohmann/detail/value_t.hpp>1638616387// #include <nlohmann/json_fwd.hpp>1638816389// #include <nlohmann/ordered_map.hpp>163901639116392#include <functional> // less16393#include <memory> // allocator16394#include <utility> // pair16395#include <vector> // vector1639616397namespace nlohmann16398{1639916400/// ordered_map: a minimal map-like container that preserves insertion order16401/// for use within nlohmann::basic_json<ordered_map>16402template <class Key, class T, class IgnoredLess = std::less<Key>,16403class Allocator = std::allocator<std::pair<const Key, T>>>16404struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>16405{16406using key_type = Key;16407using mapped_type = T;16408using Container = std::vector<std::pair<const Key, T>, Allocator>;16409using typename Container::iterator;16410using typename Container::const_iterator;16411using typename Container::size_type;16412using typename Container::value_type;1641316414// Explicit constructors instead of `using Container::Container`16415// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)16416ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}16417template <class It>16418ordered_map(It first, It last, const Allocator& alloc = Allocator())16419: Container{first, last, alloc} {}16420ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )16421: Container{init, alloc} {}1642216423std::pair<iterator, bool> emplace(const key_type& key, T&& t)16424{16425for (auto it = this->begin(); it != this->end(); ++it)16426{16427if (it->first == key)16428{16429return {it, false};16430}16431}16432Container::emplace_back(key, t);16433return {--this->end(), true};16434}1643516436T& operator[](const Key& key)16437{16438return emplace(key, T{}).first->second;16439}1644016441const T& operator[](const Key& key) const16442{16443return at(key);16444}1644516446T& at(const Key& key)16447{16448for (auto it = this->begin(); it != this->end(); ++it)16449{16450if (it->first == key)16451{16452return it->second;16453}16454}1645516456throw std::out_of_range("key not found");16457}1645816459const T& at(const Key& key) const16460{16461for (auto it = this->begin(); it != this->end(); ++it)16462{16463if (it->first == key)16464{16465return it->second;16466}16467}1646816469throw std::out_of_range("key not found");16470}1647116472size_type erase(const Key& key)16473{16474for (auto it = this->begin(); it != this->end(); ++it)16475{16476if (it->first == key)16477{16478// Since we cannot move const Keys, re-construct them in place16479for (auto next = it; ++next != this->end(); ++it)16480{16481it->~value_type(); // Destroy but keep allocation16482new (&*it) value_type{std::move(*next)};16483}16484Container::pop_back();16485return 1;16486}16487}16488return 0;16489}1649016491iterator erase(iterator pos)16492{16493auto it = pos;1649416495// Since we cannot move const Keys, re-construct them in place16496for (auto next = it; ++next != this->end(); ++it)16497{16498it->~value_type(); // Destroy but keep allocation16499new (&*it) value_type{std::move(*next)};16500}16501Container::pop_back();16502return pos;16503}1650416505size_type count(const Key& key) const16506{16507for (auto it = this->begin(); it != this->end(); ++it)16508{16509if (it->first == key)16510{16511return 1;16512}16513}16514return 0;16515}1651616517iterator find(const Key& key)16518{16519for (auto it = this->begin(); it != this->end(); ++it)16520{16521if (it->first == key)16522{16523return it;16524}16525}16526return Container::end();16527}1652816529const_iterator find(const Key& key) const16530{16531for (auto it = this->begin(); it != this->end(); ++it)16532{16533if (it->first == key)16534{16535return it;16536}16537}16538return Container::end();16539}1654016541std::pair<iterator, bool> insert( value_type&& value )16542{16543return emplace(value.first, std::move(value.second));16544}1654516546std::pair<iterator, bool> insert( const value_type& value )16547{16548for (auto it = this->begin(); it != this->end(); ++it)16549{16550if (it->first == value.first)16551{16552return {it, false};16553}16554}16555Container::push_back(value);16556return {--this->end(), true};16557}16558};1655916560} // namespace nlohmann165611656216563/*!16564@brief namespace for Niels Lohmann16565@see https://github.com/nlohmann16566@since version 1.0.016567*/16568namespace nlohmann16569{1657016571/*!16572@brief a class to store JSON values1657316574@tparam ObjectType type for JSON objects (`std::map` by default; will be used16575in @ref object_t)16576@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used16577in @ref array_t)16578@tparam StringType type for JSON strings and object keys (`std::string` by16579default; will be used in @ref string_t)16580@tparam BooleanType type for JSON booleans (`bool` by default; will be used16581in @ref boolean_t)16582@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by16583default; will be used in @ref number_integer_t)16584@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c16585`uint64_t` by default; will be used in @ref number_unsigned_t)16586@tparam NumberFloatType type for JSON floating-point numbers (`double` by16587default; will be used in @ref number_float_t)16588@tparam BinaryType type for packed binary data for compatibility with binary16589serialization formats (`std::vector<std::uint8_t>` by default; will be used in16590@ref binary_t)16591@tparam AllocatorType type of the allocator to use (`std::allocator` by16592default)16593@tparam JSONSerializer the serializer to resolve internal calls to `to_json()`16594and `from_json()` (@ref adl_serializer by default)1659516596@requirement The class satisfies the following concept requirements:16597- Basic16598- [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):16599JSON values can be default constructed. The result will be a JSON null16600value.16601- [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):16602A JSON value can be constructed from an rvalue argument.16603- [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):16604A JSON value can be copy-constructed from an lvalue expression.16605- [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):16606A JSON value van be assigned from an rvalue argument.16607- [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):16608A JSON value can be copy-assigned from an lvalue expression.16609- [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):16610JSON values can be destructed.16611- Layout16612- [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):16613JSON values have16614[standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):16615All non-static data members are private and standard layout types, the16616class has no virtual functions or (virtual) base classes.16617- Library-wide16618- [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):16619JSON values can be compared with `==`, see @ref16620operator==(const_reference,const_reference).16621- [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):16622JSON values can be compared with `<`, see @ref16623operator<(const_reference,const_reference).16624- [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):16625Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of16626other compatible types, using unqualified function call @ref swap().16627- [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):16628JSON values can be compared against `std::nullptr_t` objects which are used16629to model the `null` value.16630- Container16631- [Container](https://en.cppreference.com/w/cpp/named_req/Container):16632JSON values can be used like STL containers and provide iterator access.16633- [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);16634JSON values can be used like STL containers and provide reverse iterator16635access.1663616637@invariant The member variables @a m_value and @a m_type have the following16638relationship:16639- If `m_type == value_t::object`, then `m_value.object != nullptr`.16640- If `m_type == value_t::array`, then `m_value.array != nullptr`.16641- If `m_type == value_t::string`, then `m_value.string != nullptr`.16642The invariants are checked by member function assert_invariant().1664316644@internal16645@note ObjectType trick from https://stackoverflow.com/a/986091116646@endinternal1664716648@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange16649Format](http://rfc7159.net/rfc7159)1665016651@since version 1.0.01665216653@nosubgrouping16654*/16655NLOHMANN_BASIC_JSON_TPL_DECLARATION16656class basic_json16657{16658private:16659template<detail::value_t> friend struct detail::external_constructor;16660friend ::nlohmann::json_pointer<basic_json>;1666116662template<typename BasicJsonType, typename InputType>16663friend class ::nlohmann::detail::parser;16664friend ::nlohmann::detail::serializer<basic_json>;16665template<typename BasicJsonType>16666friend class ::nlohmann::detail::iter_impl;16667template<typename BasicJsonType, typename CharType>16668friend class ::nlohmann::detail::binary_writer;16669template<typename BasicJsonType, typename InputType, typename SAX>16670friend class ::nlohmann::detail::binary_reader;16671template<typename BasicJsonType>16672friend class ::nlohmann::detail::json_sax_dom_parser;16673template<typename BasicJsonType>16674friend class ::nlohmann::detail::json_sax_dom_callback_parser;1667516676/// workaround type for MSVC16677using basic_json_t = NLOHMANN_BASIC_JSON_TPL;1667816679// convenience aliases for types residing in namespace detail;16680using lexer = ::nlohmann::detail::lexer_base<basic_json>;1668116682template<typename InputAdapterType>16683static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(16684InputAdapterType adapter,16685detail::parser_callback_t<basic_json>cb = nullptr,16686const bool allow_exceptions = true,16687const bool ignore_comments = false16688)16689{16690return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),16691std::move(cb), allow_exceptions, ignore_comments);16692}1669316694using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;16695template<typename BasicJsonType>16696using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;16697template<typename BasicJsonType>16698using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;16699template<typename Iterator>16700using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;16701template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;1670216703template<typename CharType>16704using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;1670516706template<typename InputType>16707using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;16708template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;1670916710using serializer = ::nlohmann::detail::serializer<basic_json>;1671116712public:16713using value_t = detail::value_t;16714/// JSON Pointer, see @ref nlohmann::json_pointer16715using json_pointer = ::nlohmann::json_pointer<basic_json>;16716template<typename T, typename SFINAE>16717using json_serializer = JSONSerializer<T, SFINAE>;16718/// how to treat decoding errors16719using error_handler_t = detail::error_handler_t;16720/// how to treat CBOR tags16721using cbor_tag_handler_t = detail::cbor_tag_handler_t;16722/// helper type for initializer lists of basic_json values16723using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;1672416725using input_format_t = detail::input_format_t;16726/// SAX interface type, see @ref nlohmann::json_sax16727using json_sax_t = json_sax<basic_json>;1672816729////////////////16730// exceptions //16731////////////////1673216733/// @name exceptions16734/// Classes to implement user-defined exceptions.16735/// @{1673616737/// @copydoc detail::exception16738using exception = detail::exception;16739/// @copydoc detail::parse_error16740using parse_error = detail::parse_error;16741/// @copydoc detail::invalid_iterator16742using invalid_iterator = detail::invalid_iterator;16743/// @copydoc detail::type_error16744using type_error = detail::type_error;16745/// @copydoc detail::out_of_range16746using out_of_range = detail::out_of_range;16747/// @copydoc detail::other_error16748using other_error = detail::other_error;1674916750/// @}167511675216753/////////////////////16754// container types //16755/////////////////////1675616757/// @name container types16758/// The canonic container types to use @ref basic_json like any other STL16759/// container.16760/// @{1676116762/// the type of elements in a basic_json container16763using value_type = basic_json;1676416765/// the type of an element reference16766using reference = value_type&;16767/// the type of an element const reference16768using const_reference = const value_type&;1676916770/// a type to represent differences between iterators16771using difference_type = std::ptrdiff_t;16772/// a type to represent container sizes16773using size_type = std::size_t;1677416775/// the allocator type16776using allocator_type = AllocatorType<basic_json>;1677716778/// the type of an element pointer16779using pointer = typename std::allocator_traits<allocator_type>::pointer;16780/// the type of an element const pointer16781using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;1678216783/// an iterator for a basic_json container16784using iterator = iter_impl<basic_json>;16785/// a const iterator for a basic_json container16786using const_iterator = iter_impl<const basic_json>;16787/// a reverse iterator for a basic_json container16788using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;16789/// a const reverse iterator for a basic_json container16790using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;1679116792/// @}167931679416795/*!16796@brief returns the allocator associated with the container16797*/16798static allocator_type get_allocator()16799{16800return allocator_type();16801}1680216803/*!16804@brief returns version information on the library1680516806This function returns a JSON object with information about the library,16807including the version number and information on the platform and compiler.1680816809@return JSON object holding version information16810key | description16811----------- | ---------------16812`compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version).16813`copyright` | The copyright line for the library as string.16814`name` | The name of the library as string.16815`platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.16816`url` | The URL of the project as string.16817`version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string).1681816819@liveexample{The following code shows an example output of the `meta()`16820function.,meta}1682116822@exceptionsafety Strong guarantee: if an exception is thrown, there are no16823changes to any JSON value.1682416825@complexity Constant.1682616827@since 2.1.016828*/16829JSON_HEDLEY_WARN_UNUSED_RESULT16830static basic_json meta()16831{16832basic_json result;1683316834result["copyright"] = "(C) 2013-2020 Niels Lohmann";16835result["name"] = "JSON for Modern C++";16836result["url"] = "https://github.com/nlohmann/json";16837result["version"]["string"] =16838std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +16839std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +16840std::to_string(NLOHMANN_JSON_VERSION_PATCH);16841result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;16842result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;16843result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;1684416845#ifdef _WIN3216846result["platform"] = "win32";16847#elif defined __linux__16848result["platform"] = "linux";16849#elif defined __APPLE__16850result["platform"] = "apple";16851#elif defined __unix__16852result["platform"] = "unix";16853#else16854result["platform"] = "unknown";16855#endif1685616857#if defined(__ICC) || defined(__INTEL_COMPILER)16858result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};16859#elif defined(__clang__)16860result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};16861#elif defined(__GNUC__) || defined(__GNUG__)16862result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};16863#elif defined(__HP_cc) || defined(__HP_aCC)16864result["compiler"] = "hp"16865#elif defined(__IBMCPP__)16866result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};16867#elif defined(_MSC_VER)16868result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};16869#elif defined(__PGI)16870result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};16871#elif defined(__SUNPRO_CC)16872result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};16873#else16874result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};16875#endif1687616877#ifdef __cplusplus16878result["compiler"]["c++"] = std::to_string(__cplusplus);16879#else16880result["compiler"]["c++"] = "unknown";16881#endif16882return result;16883}168841688516886///////////////////////////16887// JSON value data types //16888///////////////////////////1688916890/// @name JSON value data types16891/// The data types to store a JSON value. These types are derived from16892/// the template arguments passed to class @ref basic_json.16893/// @{1689416895#if defined(JSON_HAS_CPP_14)16896// Use transparent comparator if possible, combined with perfect forwarding16897// on find() and count() calls prevents unnecessary string construction.16898using object_comparator_t = std::less<>;16899#else16900using object_comparator_t = std::less<StringType>;16901#endif1690216903/*!16904@brief a type for an object1690516906[RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:16907> An object is an unordered collection of zero or more name/value pairs,16908> where a name is a string and a value is a string, number, boolean, null,16909> object, or array.1691016911To store objects in C++, a type is defined by the template parameters16912described below.1691316914@tparam ObjectType the container to store objects (e.g., `std::map` or16915`std::unordered_map`)16916@tparam StringType the type of the keys or names (e.g., `std::string`).16917The comparison function `std::less<StringType>` is used to order elements16918inside the container.16919@tparam AllocatorType the allocator to use for objects (e.g.,16920`std::allocator`)1692116922#### Default type1692316924With the default values for @a ObjectType (`std::map`), @a StringType16925(`std::string`), and @a AllocatorType (`std::allocator`), the default16926value for @a object_t is:1692716928@code {.cpp}16929std::map<16930std::string, // key_type16931basic_json, // value_type16932std::less<std::string>, // key_compare16933std::allocator<std::pair<const std::string, basic_json>> // allocator_type16934>16935@endcode1693616937#### Behavior1693816939The choice of @a object_t influences the behavior of the JSON class. With16940the default type, objects have the following behavior:1694116942- When all names are unique, objects will be interoperable in the sense16943that all software implementations receiving that object will agree on16944the name-value mappings.16945- When the names within an object are not unique, it is unspecified which16946one of the values for a given key will be chosen. For instance,16947`{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or16948`{"key": 2}`.16949- Internally, name/value pairs are stored in lexicographical order of the16950names. Objects will also be serialized (see @ref dump) in this order.16951For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored16952and serialized as `{"a": 2, "b": 1}`.16953- When comparing objects, the order of the name/value pairs is irrelevant.16954This makes objects interoperable in the sense that they will not be16955affected by these differences. For instance, `{"b": 1, "a": 2}` and16956`{"a": 2, "b": 1}` will be treated as equal.1695716958#### Limits1695916960[RFC 7159](http://rfc7159.net/rfc7159) specifies:16961> An implementation may set limits on the maximum depth of nesting.1696216963In this class, the object's limit of nesting is not explicitly constrained.16964However, a maximum depth of nesting may be introduced by the compiler or16965runtime environment. A theoretical limit can be queried by calling the16966@ref max_size function of a JSON object.1696716968#### Storage1696916970Objects are stored as pointers in a @ref basic_json type. That is, for any16971access to object values, a pointer of type `object_t*` must be16972dereferenced.1697316974@sa @ref array_t -- type for an array value1697516976@since version 1.0.01697716978@note The order name/value pairs are added to the object is *not*16979preserved by the library. Therefore, iterating an object may return16980name/value pairs in a different order than they were originally stored. In16981fact, keys will be traversed in alphabetical order as `std::map` with16982`std::less` is used by default. Please note this behavior conforms to [RFC169837159](http://rfc7159.net/rfc7159), because any order implements the16984specified "unordered" nature of JSON objects.16985*/16986using object_t = ObjectType<StringType,16987basic_json,16988object_comparator_t,16989AllocatorType<std::pair<const StringType,16990basic_json>>>;1699116992/*!16993@brief a type for an array1699416995[RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:16996> An array is an ordered sequence of zero or more values.1699716998To store objects in C++, a type is defined by the template parameters16999explained below.1700017001@tparam ArrayType container type to store arrays (e.g., `std::vector` or17002`std::list`)17003@tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)1700417005#### Default type1700617007With the default values for @a ArrayType (`std::vector`) and @a17008AllocatorType (`std::allocator`), the default value for @a array_t is:1700917010@code {.cpp}17011std::vector<17012basic_json, // value_type17013std::allocator<basic_json> // allocator_type17014>17015@endcode1701617017#### Limits1701817019[RFC 7159](http://rfc7159.net/rfc7159) specifies:17020> An implementation may set limits on the maximum depth of nesting.1702117022In this class, the array's limit of nesting is not explicitly constrained.17023However, a maximum depth of nesting may be introduced by the compiler or17024runtime environment. A theoretical limit can be queried by calling the17025@ref max_size function of a JSON array.1702617027#### Storage1702817029Arrays are stored as pointers in a @ref basic_json type. That is, for any17030access to array values, a pointer of type `array_t*` must be dereferenced.1703117032@sa @ref object_t -- type for an object value1703317034@since version 1.0.017035*/17036using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;1703717038/*!17039@brief a type for a string1704017041[RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:17042> A string is a sequence of zero or more Unicode characters.1704317044To store objects in C++, a type is defined by the template parameter17045described below. Unicode values are split by the JSON class into17046byte-sized characters during deserialization.1704717048@tparam StringType the container to store strings (e.g., `std::string`).17049Note this container is used for keys/names in objects, see @ref object_t.1705017051#### Default type1705217053With the default values for @a StringType (`std::string`), the default17054value for @a string_t is:1705517056@code {.cpp}17057std::string17058@endcode1705917060#### Encoding1706117062Strings are stored in UTF-8 encoding. Therefore, functions like17063`std::string::size()` or `std::string::length()` return the number of17064bytes in the string rather than the number of characters or glyphs.1706517066#### String comparison1706717068[RFC 7159](http://rfc7159.net/rfc7159) states:17069> Software implementations are typically required to test names of object17070> members for equality. Implementations that transform the textual17071> representation into sequences of Unicode code units and then perform the17072> comparison numerically, code unit by code unit, are interoperable in the17073> sense that implementations will agree in all cases on equality or17074> inequality of two strings. For example, implementations that compare17075> strings with escaped characters unconverted may incorrectly find that17076> `"a\\b"` and `"a\u005Cb"` are not equal.1707717078This implementation is interoperable as it does compare strings code unit17079by code unit.1708017081#### Storage1708217083String values are stored as pointers in a @ref basic_json type. That is,17084for any access to string values, a pointer of type `string_t*` must be17085dereferenced.1708617087@since version 1.0.017088*/17089using string_t = StringType;1709017091/*!17092@brief a type for a boolean1709317094[RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a17095type which differentiates the two literals `true` and `false`.1709617097To store objects in C++, a type is defined by the template parameter @a17098BooleanType which chooses the type to use.1709917100#### Default type1710117102With the default values for @a BooleanType (`bool`), the default value for17103@a boolean_t is:1710417105@code {.cpp}17106bool17107@endcode1710817109#### Storage1711017111Boolean values are stored directly inside a @ref basic_json type.1711217113@since version 1.0.017114*/17115using boolean_t = BooleanType;1711617117/*!17118@brief a type for a number (integer)1711917120[RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:17121> The representation of numbers is similar to that used in most17122> programming languages. A number is represented in base 10 using decimal17123> digits. It contains an integer component that may be prefixed with an17124> optional minus sign, which may be followed by a fraction part and/or an17125> exponent part. Leading zeros are not allowed. (...) Numeric values that17126> cannot be represented in the grammar below (such as Infinity and NaN)17127> are not permitted.1712817129This description includes both integer and floating-point numbers.17130However, C++ allows more precise storage if it is known whether the number17131is a signed integer, an unsigned integer or a floating-point number.17132Therefore, three different types, @ref number_integer_t, @ref17133number_unsigned_t and @ref number_float_t are used.1713417135To store integer numbers in C++, a type is defined by the template17136parameter @a NumberIntegerType which chooses the type to use.1713717138#### Default type1713917140With the default values for @a NumberIntegerType (`int64_t`), the default17141value for @a number_integer_t is:1714217143@code {.cpp}17144int64_t17145@endcode1714617147#### Default behavior1714817149- The restrictions about leading zeros is not enforced in C++. Instead,17150leading zeros in integer literals lead to an interpretation as octal17151number. Internally, the value will be stored as decimal number. For17152instance, the C++ integer literal `010` will be serialized to `8`.17153During deserialization, leading zeros yield an error.17154- Not-a-number (NaN) values will be serialized to `null`.1715517156#### Limits1715717158[RFC 7159](http://rfc7159.net/rfc7159) specifies:17159> An implementation may set limits on the range and precision of numbers.1716017161When the default type is used, the maximal integer number that can be17162stored is `9223372036854775807` (INT64_MAX) and the minimal integer number17163that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers17164that are out of range will yield over/underflow when used in a17165constructor. During deserialization, too large or small integer numbers17166will be automatically be stored as @ref number_unsigned_t or @ref17167number_float_t.1716817169[RFC 7159](http://rfc7159.net/rfc7159) further states:17170> Note that when such software is used, numbers that are integers and are17171> in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense17172> that implementations will agree exactly on their numeric values.1717317174As this range is a subrange of the exactly supported range [INT64_MIN,17175INT64_MAX], this class's integer type is interoperable.1717617177#### Storage1717817179Integer number values are stored directly inside a @ref basic_json type.1718017181@sa @ref number_float_t -- type for number values (floating-point)1718217183@sa @ref number_unsigned_t -- type for number values (unsigned integer)1718417185@since version 1.0.017186*/17187using number_integer_t = NumberIntegerType;1718817189/*!17190@brief a type for a number (unsigned)1719117192[RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:17193> The representation of numbers is similar to that used in most17194> programming languages. A number is represented in base 10 using decimal17195> digits. It contains an integer component that may be prefixed with an17196> optional minus sign, which may be followed by a fraction part and/or an17197> exponent part. Leading zeros are not allowed. (...) Numeric values that17198> cannot be represented in the grammar below (such as Infinity and NaN)17199> are not permitted.1720017201This description includes both integer and floating-point numbers.17202However, C++ allows more precise storage if it is known whether the number17203is a signed integer, an unsigned integer or a floating-point number.17204Therefore, three different types, @ref number_integer_t, @ref17205number_unsigned_t and @ref number_float_t are used.1720617207To store unsigned integer numbers in C++, a type is defined by the17208template parameter @a NumberUnsignedType which chooses the type to use.1720917210#### Default type1721117212With the default values for @a NumberUnsignedType (`uint64_t`), the17213default value for @a number_unsigned_t is:1721417215@code {.cpp}17216uint64_t17217@endcode1721817219#### Default behavior1722017221- The restrictions about leading zeros is not enforced in C++. Instead,17222leading zeros in integer literals lead to an interpretation as octal17223number. Internally, the value will be stored as decimal number. For17224instance, the C++ integer literal `010` will be serialized to `8`.17225During deserialization, leading zeros yield an error.17226- Not-a-number (NaN) values will be serialized to `null`.1722717228#### Limits1722917230[RFC 7159](http://rfc7159.net/rfc7159) specifies:17231> An implementation may set limits on the range and precision of numbers.1723217233When the default type is used, the maximal integer number that can be17234stored is `18446744073709551615` (UINT64_MAX) and the minimal integer17235number that can be stored is `0`. Integer numbers that are out of range17236will yield over/underflow when used in a constructor. During17237deserialization, too large or small integer numbers will be automatically17238be stored as @ref number_integer_t or @ref number_float_t.1723917240[RFC 7159](http://rfc7159.net/rfc7159) further states:17241> Note that when such software is used, numbers that are integers and are17242> in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense17243> that implementations will agree exactly on their numeric values.1724417245As this range is a subrange (when considered in conjunction with the17246number_integer_t type) of the exactly supported range [0, UINT64_MAX],17247this class's integer type is interoperable.1724817249#### Storage1725017251Integer number values are stored directly inside a @ref basic_json type.1725217253@sa @ref number_float_t -- type for number values (floating-point)17254@sa @ref number_integer_t -- type for number values (integer)1725517256@since version 2.0.017257*/17258using number_unsigned_t = NumberUnsignedType;1725917260/*!17261@brief a type for a number (floating-point)1726217263[RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:17264> The representation of numbers is similar to that used in most17265> programming languages. A number is represented in base 10 using decimal17266> digits. It contains an integer component that may be prefixed with an17267> optional minus sign, which may be followed by a fraction part and/or an17268> exponent part. Leading zeros are not allowed. (...) Numeric values that17269> cannot be represented in the grammar below (such as Infinity and NaN)17270> are not permitted.1727117272This description includes both integer and floating-point numbers.17273However, C++ allows more precise storage if it is known whether the number17274is a signed integer, an unsigned integer or a floating-point number.17275Therefore, three different types, @ref number_integer_t, @ref17276number_unsigned_t and @ref number_float_t are used.1727717278To store floating-point numbers in C++, a type is defined by the template17279parameter @a NumberFloatType which chooses the type to use.1728017281#### Default type1728217283With the default values for @a NumberFloatType (`double`), the default17284value for @a number_float_t is:1728517286@code {.cpp}17287double17288@endcode1728917290#### Default behavior1729117292- The restrictions about leading zeros is not enforced in C++. Instead,17293leading zeros in floating-point literals will be ignored. Internally,17294the value will be stored as decimal number. For instance, the C++17295floating-point literal `01.2` will be serialized to `1.2`. During17296deserialization, leading zeros yield an error.17297- Not-a-number (NaN) values will be serialized to `null`.1729817299#### Limits1730017301[RFC 7159](http://rfc7159.net/rfc7159) states:17302> This specification allows implementations to set limits on the range and17303> precision of numbers accepted. Since software that implements IEEE17304> 754-2008 binary64 (double precision) numbers is generally available and17305> widely used, good interoperability can be achieved by implementations17306> that expect no more precision or range than these provide, in the sense17307> that implementations will approximate JSON numbers within the expected17308> precision.1730917310This implementation does exactly follow this approach, as it uses double17311precision floating-point numbers. Note values smaller than17312`-1.79769313486232e+308` and values greater than `1.79769313486232e+308`17313will be stored as NaN internally and be serialized to `null`.1731417315#### Storage1731617317Floating-point number values are stored directly inside a @ref basic_json17318type.1731917320@sa @ref number_integer_t -- type for number values (integer)1732117322@sa @ref number_unsigned_t -- type for number values (unsigned integer)1732317324@since version 1.0.017325*/17326using number_float_t = NumberFloatType;1732717328/*!17329@brief a type for a packed binary type1733017331This type is a type designed to carry binary data that appears in various17332serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and17333BSON's generic binary subtype. This type is NOT a part of standard JSON and17334exists solely for compatibility with these binary types. As such, it is17335simply defined as an ordered sequence of zero or more byte values.1733617337Additionally, as an implementation detail, the subtype of the binary data is17338carried around as a `std::uint8_t`, which is compatible with both of the17339binary data formats that use binary subtyping, (though the specific17340numbering is incompatible with each other, and it is up to the user to17341translate between them).1734217343[CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type17344as:17345> Major type 2: a byte string. The string's length in bytes is represented17346> following the rules for positive integers (major type 0).1734717348[MessagePack's documentation on the bin type17349family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)17350describes this type as:17351> Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes17352> in addition to the size of the byte array.1735317354[BSON's specifications](http://bsonspec.org/spec.html) describe several17355binary types; however, this type is intended to represent the generic binary17356type which has the description:17357> Generic binary subtype - This is the most commonly used binary subtype and17358> should be the 'default' for drivers and tools.1735917360None of these impose any limitations on the internal representation other17361than the basic unit of storage be some type of array whose parts are17362decomposable into bytes.1736317364The default representation of this binary format is a17365`std::vector<std::uint8_t>`, which is a very common way to represent a byte17366array in modern C++.1736717368#### Default type1736917370The default values for @a BinaryType is `std::vector<std::uint8_t>`1737117372#### Storage1737317374Binary Arrays are stored as pointers in a @ref basic_json type. That is,17375for any access to array values, a pointer of the type `binary_t*` must be17376dereferenced.1737717378#### Notes on subtypes1737917380- CBOR17381- Binary values are represented as byte strings. No subtypes are17382supported and will be ignored when CBOR is written.17383- MessagePack17384- If a subtype is given and the binary array contains exactly 1, 2, 4, 8,17385or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)17386is used. For other sizes, the ext family (ext8, ext16, ext32) is used.17387The subtype is then added as singed 8-bit integer.17388- If no subtype is given, the bin family (bin8, bin16, bin32) is used.17389- BSON17390- If a subtype is given, it is used and added as unsigned 8-bit integer.17391- If no subtype is given, the generic binary subtype 0x00 is used.1739217393@sa @ref binary -- create a binary array1739417395@since version 3.8.017396*/17397using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;17398/// @}1739917400private:1740117402/// helper for exception-safe object creation17403template<typename T, typename... Args>17404JSON_HEDLEY_RETURNS_NON_NULL17405static T* create(Args&& ... args)17406{17407AllocatorType<T> alloc;17408using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;1740917410auto deleter = [&](T * object)17411{17412AllocatorTraits::deallocate(alloc, object, 1);17413};17414std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);17415AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);17416JSON_ASSERT(object != nullptr);17417return object.release();17418}1741917420////////////////////////17421// JSON value storage //17422////////////////////////1742317424/*!17425@brief a JSON value1742617427The actual storage for a JSON value of the @ref basic_json class. This17428union combines the different storage types for the JSON value types17429defined in @ref value_t.1743017431JSON type | value_t type | used type17432--------- | --------------- | ------------------------17433object | object | pointer to @ref object_t17434array | array | pointer to @ref array_t17435string | string | pointer to @ref string_t17436boolean | boolean | @ref boolean_t17437number | number_integer | @ref number_integer_t17438number | number_unsigned | @ref number_unsigned_t17439number | number_float | @ref number_float_t17440binary | binary | pointer to @ref binary_t17441null | null | *no value is stored*1744217443@note Variable-length types (objects, arrays, and strings) are stored as17444pointers. The size of the union should not exceed 64 bits if the default17445value types are used.1744617447@since version 1.0.017448*/17449union json_value17450{17451/// object (stored with pointer to save storage)17452object_t* object;17453/// array (stored with pointer to save storage)17454array_t* array;17455/// string (stored with pointer to save storage)17456string_t* string;17457/// binary (stored with pointer to save storage)17458binary_t* binary;17459/// boolean17460boolean_t boolean;17461/// number (integer)17462number_integer_t number_integer;17463/// number (unsigned integer)17464number_unsigned_t number_unsigned;17465/// number (floating-point)17466number_float_t number_float;1746717468/// default constructor (for null values)17469json_value() = default;17470/// constructor for booleans17471json_value(boolean_t v) noexcept : boolean(v) {}17472/// constructor for numbers (integer)17473json_value(number_integer_t v) noexcept : number_integer(v) {}17474/// constructor for numbers (unsigned)17475json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}17476/// constructor for numbers (floating-point)17477json_value(number_float_t v) noexcept : number_float(v) {}17478/// constructor for empty values of a given type17479json_value(value_t t)17480{17481switch (t)17482{17483case value_t::object:17484{17485object = create<object_t>();17486break;17487}1748817489case value_t::array:17490{17491array = create<array_t>();17492break;17493}1749417495case value_t::string:17496{17497string = create<string_t>("");17498break;17499}1750017501case value_t::binary:17502{17503binary = create<binary_t>();17504break;17505}1750617507case value_t::boolean:17508{17509boolean = boolean_t(false);17510break;17511}1751217513case value_t::number_integer:17514{17515number_integer = number_integer_t(0);17516break;17517}1751817519case value_t::number_unsigned:17520{17521number_unsigned = number_unsigned_t(0);17522break;17523}1752417525case value_t::number_float:17526{17527number_float = number_float_t(0.0);17528break;17529}1753017531case value_t::null:17532{17533object = nullptr; // silence warning, see #82117534break;17535}1753617537default:17538{17539object = nullptr; // silence warning, see #82117540if (JSON_HEDLEY_UNLIKELY(t == value_t::null))17541{17542JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE17543}17544break;17545}17546}17547}1754817549/// constructor for strings17550json_value(const string_t& value)17551{17552string = create<string_t>(value);17553}1755417555/// constructor for rvalue strings17556json_value(string_t&& value)17557{17558string = create<string_t>(std::move(value));17559}1756017561/// constructor for objects17562json_value(const object_t& value)17563{17564object = create<object_t>(value);17565}1756617567/// constructor for rvalue objects17568json_value(object_t&& value)17569{17570object = create<object_t>(std::move(value));17571}1757217573/// constructor for arrays17574json_value(const array_t& value)17575{17576array = create<array_t>(value);17577}1757817579/// constructor for rvalue arrays17580json_value(array_t&& value)17581{17582array = create<array_t>(std::move(value));17583}1758417585/// constructor for binary arrays17586json_value(const typename binary_t::container_type& value)17587{17588binary = create<binary_t>(value);17589}1759017591/// constructor for rvalue binary arrays17592json_value(typename binary_t::container_type&& value)17593{17594binary = create<binary_t>(std::move(value));17595}1759617597/// constructor for binary arrays (internal type)17598json_value(const binary_t& value)17599{17600binary = create<binary_t>(value);17601}1760217603/// constructor for rvalue binary arrays (internal type)17604json_value(binary_t&& value)17605{17606binary = create<binary_t>(std::move(value));17607}1760817609void destroy(value_t t) noexcept17610{17611// flatten the current json_value to a heap-allocated stack17612std::vector<basic_json> stack;1761317614// move the top-level items to stack17615if (t == value_t::array)17616{17617stack.reserve(array->size());17618std::move(array->begin(), array->end(), std::back_inserter(stack));17619}17620else if (t == value_t::object)17621{17622stack.reserve(object->size());17623for (auto&& it : *object)17624{17625stack.push_back(std::move(it.second));17626}17627}1762817629while (!stack.empty())17630{17631// move the last item to local variable to be processed17632basic_json current_item(std::move(stack.back()));17633stack.pop_back();1763417635// if current_item is array/object, move17636// its children to the stack to be processed later17637if (current_item.is_array())17638{17639std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),17640std::back_inserter(stack));1764117642current_item.m_value.array->clear();17643}17644else if (current_item.is_object())17645{17646for (auto&& it : *current_item.m_value.object)17647{17648stack.push_back(std::move(it.second));17649}1765017651current_item.m_value.object->clear();17652}1765317654// it's now safe that current_item get destructed17655// since it doesn't have any children17656}1765717658switch (t)17659{17660case value_t::object:17661{17662AllocatorType<object_t> alloc;17663std::allocator_traits<decltype(alloc)>::destroy(alloc, object);17664std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);17665break;17666}1766717668case value_t::array:17669{17670AllocatorType<array_t> alloc;17671std::allocator_traits<decltype(alloc)>::destroy(alloc, array);17672std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);17673break;17674}1767517676case value_t::string:17677{17678AllocatorType<string_t> alloc;17679std::allocator_traits<decltype(alloc)>::destroy(alloc, string);17680std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);17681break;17682}1768317684case value_t::binary:17685{17686AllocatorType<binary_t> alloc;17687std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);17688std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);17689break;17690}1769117692default:17693{17694break;17695}17696}17697}17698};1769917700/*!17701@brief checks the class invariants1770217703This function asserts the class invariants. It needs to be called at the17704end of every constructor to make sure that created objects respect the17705invariant. Furthermore, it has to be called each time the type of a JSON17706value is changed, because the invariant expresses a relationship between17707@a m_type and @a m_value.17708*/17709void assert_invariant() const noexcept17710{17711JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);17712JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);17713JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);17714JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);17715}1771617717public:17718//////////////////////////17719// JSON parser callback //17720//////////////////////////1772117722/*!17723@brief parser event types1772417725The parser callback distinguishes the following events:17726- `object_start`: the parser read `{` and started to process a JSON object17727- `key`: the parser read a key of a value in an object17728- `object_end`: the parser read `}` and finished processing a JSON object17729- `array_start`: the parser read `[` and started to process a JSON array17730- `array_end`: the parser read `]` and finished processing a JSON array17731- `value`: the parser finished reading a JSON value1773217733@image html callback_events.png "Example when certain parse events are triggered"1773417735@sa @ref parser_callback_t for more information and examples17736*/17737using parse_event_t = detail::parse_event_t;1773817739/*!17740@brief per-element parser callback type1774117742With a parser callback function, the result of parsing a JSON text can be17743influenced. When passed to @ref parse, it is called on certain events17744(passed as @ref parse_event_t via parameter @a event) with a set recursion17745depth @a depth and context JSON value @a parsed. The return value of the17746callback function is a boolean indicating whether the element that emitted17747the callback shall be kept or not.1774817749We distinguish six scenarios (determined by the event type) in which the17750callback function can be called. The following table describes the values17751of the parameters @a depth, @a event, and @a parsed.1775217753parameter @a event | description | parameter @a depth | parameter @a parsed17754------------------ | ----------- | ------------------ | -------------------17755parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded17756parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key17757parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object17758parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded17759parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array17760parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value1776117762@image html callback_events.png "Example when certain parse events are triggered"1776317764Discarding a value (i.e., returning `false`) has different effects17765depending on the context in which function was called:1776617767- Discarded values in structured types are skipped. That is, the parser17768will behave as if the discarded value was never read.17769- In case a value outside a structured type is skipped, it is replaced17770with `null`. This case happens if the top-level element is skipped.1777117772@param[in] depth the depth of the recursion during parsing1777317774@param[in] event an event of type parse_event_t indicating the context in17775the callback function has been called1777617777@param[in,out] parsed the current intermediate parse result; note that17778writing to this value has no effect for parse_event_t::key events1777917780@return Whether the JSON value which called the function during parsing17781should be kept (`true`) or not (`false`). In the latter case, it is either17782skipped completely or replaced by an empty discarded object.1778317784@sa @ref parse for examples1778517786@since version 1.0.017787*/17788using parser_callback_t = detail::parser_callback_t<basic_json>;1778917790//////////////////17791// constructors //17792//////////////////1779317794/// @name constructors and destructors17795/// Constructors of class @ref basic_json, copy/move constructor, copy17796/// assignment, static functions creating objects, and the destructor.17797/// @{1779817799/*!17800@brief create an empty value with a given type1780117802Create an empty JSON value with a given type. The value will be default17803initialized with an empty value which depends on the type:1780417805Value type | initial value17806----------- | -------------17807null | `null`17808boolean | `false`17809string | `""`17810number | `0`17811object | `{}`17812array | `[]`17813binary | empty array1781417815@param[in] v the type of the value to create1781617817@complexity Constant.1781817819@exceptionsafety Strong guarantee: if an exception is thrown, there are no17820changes to any JSON value.1782117822@liveexample{The following code shows the constructor for different @ref17823value_t values,basic_json__value_t}1782417825@sa @ref clear() -- restores the postcondition of this constructor1782617827@since version 1.0.017828*/17829basic_json(const value_t v)17830: m_type(v), m_value(v)17831{17832assert_invariant();17833}1783417835/*!17836@brief create a null object1783717838Create a `null` JSON value. It either takes a null pointer as parameter17839(explicitly creating `null`) or no parameter (implicitly creating `null`).17840The passed null pointer itself is not read -- it is only used to choose17841the right constructor.1784217843@complexity Constant.1784417845@exceptionsafety No-throw guarantee: this constructor never throws17846exceptions.1784717848@liveexample{The following code shows the constructor with and without a17849null pointer parameter.,basic_json__nullptr_t}1785017851@since version 1.0.017852*/17853basic_json(std::nullptr_t = nullptr) noexcept17854: basic_json(value_t::null)17855{17856assert_invariant();17857}1785817859/*!17860@brief create a JSON value1786117862This is a "catch all" constructor for all compatible JSON types; that is,17863types for which a `to_json()` method exists. The constructor forwards the17864parameter @a val to that method (to `json_serializer<U>::to_json` method17865with `U = uncvref_t<CompatibleType>`, to be exact).1786617867Template type @a CompatibleType includes, but is not limited to, the17868following types:17869- **arrays**: @ref array_t and all kinds of compatible containers such as17870`std::vector`, `std::deque`, `std::list`, `std::forward_list`,17871`std::array`, `std::valarray`, `std::set`, `std::unordered_set`,17872`std::multiset`, and `std::unordered_multiset` with a `value_type` from17873which a @ref basic_json value can be constructed.17874- **objects**: @ref object_t and all kinds of compatible associative17875containers such as `std::map`, `std::unordered_map`, `std::multimap`,17876and `std::unordered_multimap` with a `key_type` compatible to17877@ref string_t and a `value_type` from which a @ref basic_json value can17878be constructed.17879- **strings**: @ref string_t, string literals, and all compatible string17880containers can be used.17881- **numbers**: @ref number_integer_t, @ref number_unsigned_t,17882@ref number_float_t, and all convertible number types such as `int`,17883`size_t`, `int64_t`, `float` or `double` can be used.17884- **boolean**: @ref boolean_t / `bool` can be used.17885- **binary**: @ref binary_t / `std::vector<uint8_t>` may be used,17886unfortunately because string literals cannot be distinguished from binary17887character arrays by the C++ type system, all types compatible with `const17888char*` will be directed to the string constructor instead. This is both17889for backwards compatibility, and due to the fact that a binary type is not17890a standard JSON type.1789117892See the examples below.1789317894@tparam CompatibleType a type such that:17895- @a CompatibleType is not derived from `std::istream`,17896- @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move17897constructors),17898- @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)17899- @a CompatibleType is not a @ref basic_json nested type (e.g.,17900@ref json_pointer, @ref iterator, etc ...)17901- @ref @ref json_serializer<U> has a17902`to_json(basic_json_t&, CompatibleType&&)` method1790317904@tparam U = `uncvref_t<CompatibleType>`1790517906@param[in] val the value to be forwarded to the respective constructor1790717908@complexity Usually linear in the size of the passed @a val, also17909depending on the implementation of the called `to_json()`17910method.1791117912@exceptionsafety Depends on the called constructor. For types directly17913supported by the library (i.e., all types for which no `to_json()` function17914was provided), strong guarantee holds: if an exception is thrown, there are17915no changes to any JSON value.1791617917@liveexample{The following code shows the constructor with several17918compatible types.,basic_json__CompatibleType}1791917920@since version 2.1.017921*/17922template < typename CompatibleType,17923typename U = detail::uncvref_t<CompatibleType>,17924detail::enable_if_t <17925!detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >17926basic_json(CompatibleType && val) noexcept(noexcept(17927JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),17928std::forward<CompatibleType>(val))))17929{17930JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));17931assert_invariant();17932}1793317934/*!17935@brief create a JSON value from an existing one1793617937This is a constructor for existing @ref basic_json types.17938It does not hijack copy/move constructors, since the parameter has different17939template arguments than the current ones.1794017941The constructor tries to convert the internal @ref m_value of the parameter.1794217943@tparam BasicJsonType a type such that:17944- @a BasicJsonType is a @ref basic_json type.17945- @a BasicJsonType has different template arguments than @ref basic_json_t.1794617947@param[in] val the @ref basic_json value to be converted.1794817949@complexity Usually linear in the size of the passed @a val, also17950depending on the implementation of the called `to_json()`17951method.1795217953@exceptionsafety Depends on the called constructor. For types directly17954supported by the library (i.e., all types for which no `to_json()` function17955was provided), strong guarantee holds: if an exception is thrown, there are17956no changes to any JSON value.1795717958@since version 3.2.017959*/17960template < typename BasicJsonType,17961detail::enable_if_t <17962detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >17963basic_json(const BasicJsonType& val)17964{17965using other_boolean_t = typename BasicJsonType::boolean_t;17966using other_number_float_t = typename BasicJsonType::number_float_t;17967using other_number_integer_t = typename BasicJsonType::number_integer_t;17968using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;17969using other_string_t = typename BasicJsonType::string_t;17970using other_object_t = typename BasicJsonType::object_t;17971using other_array_t = typename BasicJsonType::array_t;17972using other_binary_t = typename BasicJsonType::binary_t;1797317974switch (val.type())17975{17976case value_t::boolean:17977JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());17978break;17979case value_t::number_float:17980JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());17981break;17982case value_t::number_integer:17983JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());17984break;17985case value_t::number_unsigned:17986JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());17987break;17988case value_t::string:17989JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());17990break;17991case value_t::object:17992JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());17993break;17994case value_t::array:17995JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());17996break;17997case value_t::binary:17998JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());17999break;18000case value_t::null:18001*this = nullptr;18002break;18003case value_t::discarded:18004m_type = value_t::discarded;18005break;18006default: // LCOV_EXCL_LINE18007JSON_ASSERT(false); // LCOV_EXCL_LINE18008}18009assert_invariant();18010}1801118012/*!18013@brief create a container (array or object) from an initializer list1801418015Creates a JSON value of type array or object from the passed initializer18016list @a init. In case @a type_deduction is `true` (default), the type of18017the JSON value to be created is deducted from the initializer list @a init18018according to the following rules:18019180201. If the list is empty, an empty JSON object value `{}` is created.180212. If the list consists of pairs whose first element is a string, a JSON18022object value is created where the first elements of the pairs are18023treated as keys and the second elements are as values.180243. In all other cases, an array is created.1802518026The rules aim to create the best fit between a C++ initializer list and18027JSON values. The rationale is as follows:18028180291. The empty initializer list is written as `{}` which is exactly an empty18030JSON object.180312. C++ has no way of describing mapped types other than to list a list of18032pairs. As JSON requires that keys must be of type string, rule 2 is the18033weakest constraint one can pose on initializer lists to interpret them18034as an object.180353. In all other cases, the initializer list could not be interpreted as18036JSON object type, so interpreting it as JSON array type is safe.1803718038With the rules described above, the following JSON values cannot be18039expressed by an initializer list:1804018041- the empty array (`[]`): use @ref array(initializer_list_t)18042with an empty initializer list in this case18043- arrays whose elements satisfy rule 2: use @ref18044array(initializer_list_t) with the same initializer list18045in this case1804618047@note When used without parentheses around an empty initializer list, @ref18048basic_json() is called instead of this function, yielding the JSON null18049value.1805018051@param[in] init initializer list with JSON values1805218053@param[in] type_deduction internal parameter; when set to `true`, the type18054of the JSON value is deducted from the initializer list @a init; when set18055to `false`, the type provided via @a manual_type is forced. This mode is18056used by the functions @ref array(initializer_list_t) and18057@ref object(initializer_list_t).1805818059@param[in] manual_type internal parameter; when @a type_deduction is set18060to `false`, the created JSON value will use the provided type (only @ref18061value_t::array and @ref value_t::object are valid); when @a type_deduction18062is set to `true`, this parameter has no effect1806318064@throw type_error.301 if @a type_deduction is `false`, @a manual_type is18065`value_t::object`, but @a init contains an element which is not a pair18066whose first element is a string. In this case, the constructor could not18067create an object. If @a type_deduction would have be `true`, an array18068would have been created. See @ref object(initializer_list_t)18069for an example.1807018071@complexity Linear in the size of the initializer list @a init.1807218073@exceptionsafety Strong guarantee: if an exception is thrown, there are no18074changes to any JSON value.1807518076@liveexample{The example below shows how JSON values are created from18077initializer lists.,basic_json__list_init_t}1807818079@sa @ref array(initializer_list_t) -- create a JSON array18080value from an initializer list18081@sa @ref object(initializer_list_t) -- create a JSON object18082value from an initializer list1808318084@since version 1.0.018085*/18086basic_json(initializer_list_t init,18087bool type_deduction = true,18088value_t manual_type = value_t::array)18089{18090// check if each element is an array with two elements whose first18091// element is a string18092bool is_an_object = std::all_of(init.begin(), init.end(),18093[](const detail::json_ref<basic_json>& element_ref)18094{18095return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();18096});1809718098// adjust type if type deduction is not wanted18099if (!type_deduction)18100{18101// if array is wanted, do not create an object though possible18102if (manual_type == value_t::array)18103{18104is_an_object = false;18105}1810618107// if object is wanted but impossible, throw an exception18108if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))18109{18110JSON_THROW(type_error::create(301, "cannot create object from initializer list"));18111}18112}1811318114if (is_an_object)18115{18116// the initializer list is a list of pairs -> create object18117m_type = value_t::object;18118m_value = value_t::object;1811918120std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)18121{18122auto element = element_ref.moved_or_copied();18123m_value.object->emplace(18124std::move(*((*element.m_value.array)[0].m_value.string)),18125std::move((*element.m_value.array)[1]));18126});18127}18128else18129{18130// the initializer list describes an array -> create array18131m_type = value_t::array;18132m_value.array = create<array_t>(init.begin(), init.end());18133}1813418135assert_invariant();18136}1813718138/*!18139@brief explicitly create a binary array (without subtype)1814018141Creates a JSON binary array value from a given binary container. Binary18142values are part of various binary formats, such as CBOR, MessagePack, and18143BSON. This constructor is used to create a value for serialization to those18144formats.1814518146@note Note, this function exists because of the difficulty in correctly18147specifying the correct template overload in the standard value ctor, as both18148JSON arrays and JSON binary arrays are backed with some form of a18149`std::vector`. Because JSON binary arrays are a non-standard extension it18150was decided that it would be best to prevent automatic initialization of a18151binary array type, for backwards compatibility and so it does not happen on18152accident.1815318154@param[in] init container containing bytes to use as binary type1815518156@return JSON binary array value1815718158@complexity Linear in the size of @a init.1815918160@exceptionsafety Strong guarantee: if an exception is thrown, there are no18161changes to any JSON value.1816218163@since version 3.8.018164*/18165JSON_HEDLEY_WARN_UNUSED_RESULT18166static basic_json binary(const typename binary_t::container_type& init)18167{18168auto res = basic_json();18169res.m_type = value_t::binary;18170res.m_value = init;18171return res;18172}1817318174/*!18175@brief explicitly create a binary array (with subtype)1817618177Creates a JSON binary array value from a given binary container. Binary18178values are part of various binary formats, such as CBOR, MessagePack, and18179BSON. This constructor is used to create a value for serialization to those18180formats.1818118182@note Note, this function exists because of the difficulty in correctly18183specifying the correct template overload in the standard value ctor, as both18184JSON arrays and JSON binary arrays are backed with some form of a18185`std::vector`. Because JSON binary arrays are a non-standard extension it18186was decided that it would be best to prevent automatic initialization of a18187binary array type, for backwards compatibility and so it does not happen on18188accident.1818918190@param[in] init container containing bytes to use as binary type18191@param[in] subtype subtype to use in MessagePack and BSON1819218193@return JSON binary array value1819418195@complexity Linear in the size of @a init.1819618197@exceptionsafety Strong guarantee: if an exception is thrown, there are no18198changes to any JSON value.1819918200@since version 3.8.018201*/18202JSON_HEDLEY_WARN_UNUSED_RESULT18203static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)18204{18205auto res = basic_json();18206res.m_type = value_t::binary;18207res.m_value = binary_t(init, subtype);18208return res;18209}1821018211/// @copydoc binary(const typename binary_t::container_type&)18212JSON_HEDLEY_WARN_UNUSED_RESULT18213static basic_json binary(typename binary_t::container_type&& init)18214{18215auto res = basic_json();18216res.m_type = value_t::binary;18217res.m_value = std::move(init);18218return res;18219}1822018221/// @copydoc binary(const typename binary_t::container_type&, std::uint8_t)18222JSON_HEDLEY_WARN_UNUSED_RESULT18223static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)18224{18225auto res = basic_json();18226res.m_type = value_t::binary;18227res.m_value = binary_t(std::move(init), subtype);18228return res;18229}1823018231/*!18232@brief explicitly create an array from an initializer list1823318234Creates a JSON array value from a given initializer list. That is, given a18235list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the18236initializer list is empty, the empty array `[]` is created.1823718238@note This function is only needed to express two edge cases that cannot18239be realized with the initializer list constructor (@ref18240basic_json(initializer_list_t, bool, value_t)). These cases18241are:182421. creating an array whose elements are all pairs whose first element is a18243string -- in this case, the initializer list constructor would create an18244object, taking the first elements as keys182452. creating an empty array -- passing the empty initializer list to the18246initializer list constructor yields an empty object1824718248@param[in] init initializer list with JSON values to create an array from18249(optional)1825018251@return JSON array value1825218253@complexity Linear in the size of @a init.1825418255@exceptionsafety Strong guarantee: if an exception is thrown, there are no18256changes to any JSON value.1825718258@liveexample{The following code shows an example for the `array`18259function.,array}1826018261@sa @ref basic_json(initializer_list_t, bool, value_t) --18262create a JSON value from an initializer list18263@sa @ref object(initializer_list_t) -- create a JSON object18264value from an initializer list1826518266@since version 1.0.018267*/18268JSON_HEDLEY_WARN_UNUSED_RESULT18269static basic_json array(initializer_list_t init = {})18270{18271return basic_json(init, false, value_t::array);18272}1827318274/*!18275@brief explicitly create an object from an initializer list1827618277Creates a JSON object value from a given initializer list. The initializer18278lists elements must be pairs, and their first elements must be strings. If18279the initializer list is empty, the empty object `{}` is created.1828018281@note This function is only added for symmetry reasons. In contrast to the18282related function @ref array(initializer_list_t), there are18283no cases which can only be expressed by this function. That is, any18284initializer list @a init can also be passed to the initializer list18285constructor @ref basic_json(initializer_list_t, bool, value_t).1828618287@param[in] init initializer list to create an object from (optional)1828818289@return JSON object value1829018291@throw type_error.301 if @a init is not a list of pairs whose first18292elements are strings. In this case, no object can be created. When such a18293value is passed to @ref basic_json(initializer_list_t, bool, value_t),18294an array would have been created from the passed initializer list @a init.18295See example below.1829618297@complexity Linear in the size of @a init.1829818299@exceptionsafety Strong guarantee: if an exception is thrown, there are no18300changes to any JSON value.1830118302@liveexample{The following code shows an example for the `object`18303function.,object}1830418305@sa @ref basic_json(initializer_list_t, bool, value_t) --18306create a JSON value from an initializer list18307@sa @ref array(initializer_list_t) -- create a JSON array18308value from an initializer list1830918310@since version 1.0.018311*/18312JSON_HEDLEY_WARN_UNUSED_RESULT18313static basic_json object(initializer_list_t init = {})18314{18315return basic_json(init, false, value_t::object);18316}1831718318/*!18319@brief construct an array with count copies of given value1832018321Constructs a JSON array value by creating @a cnt copies of a passed value.18322In case @a cnt is `0`, an empty array is created.1832318324@param[in] cnt the number of JSON copies of @a val to create18325@param[in] val the JSON value to copy1832618327@post `std::distance(begin(),end()) == cnt` holds.1832818329@complexity Linear in @a cnt.1833018331@exceptionsafety Strong guarantee: if an exception is thrown, there are no18332changes to any JSON value.1833318334@liveexample{The following code shows examples for the @ref18335basic_json(size_type\, const basic_json&)18336constructor.,basic_json__size_type_basic_json}1833718338@since version 1.0.018339*/18340basic_json(size_type cnt, const basic_json& val)18341: m_type(value_t::array)18342{18343m_value.array = create<array_t>(cnt, val);18344assert_invariant();18345}1834618347/*!18348@brief construct a JSON container given an iterator range1834918350Constructs the JSON value with the contents of the range `[first, last)`.18351The semantics depends on the different types a JSON value can have:18352- In case of a null type, invalid_iterator.206 is thrown.18353- In case of other primitive types (number, boolean, or string), @a first18354must be `begin()` and @a last must be `end()`. In this case, the value is18355copied. Otherwise, invalid_iterator.204 is thrown.18356- In case of structured types (array, object), the constructor behaves as18357similar versions for `std::vector` or `std::map`; that is, a JSON array18358or object is constructed from the values in the range.1835918360@tparam InputIT an input iterator type (@ref iterator or @ref18361const_iterator)1836218363@param[in] first begin of the range to copy from (included)18364@param[in] last end of the range to copy from (excluded)1836518366@pre Iterators @a first and @a last must be initialized. **This18367precondition is enforced with an assertion (see warning).** If18368assertions are switched off, a violation of this precondition yields18369undefined behavior.1837018371@pre Range `[first, last)` is valid. Usually, this precondition cannot be18372checked efficiently. Only certain edge cases are detected; see the18373description of the exceptions below. A violation of this precondition18374yields undefined behavior.1837518376@warning A precondition is enforced with a runtime assertion that will18377result in calling `std::abort` if this precondition is not met.18378Assertions can be disabled by defining `NDEBUG` at compile time.18379See https://en.cppreference.com/w/cpp/error/assert for more18380information.1838118382@throw invalid_iterator.201 if iterators @a first and @a last are not18383compatible (i.e., do not belong to the same JSON value). In this case,18384the range `[first, last)` is undefined.18385@throw invalid_iterator.204 if iterators @a first and @a last belong to a18386primitive type (number, boolean, or string), but @a first does not point18387to the first element any more. In this case, the range `[first, last)` is18388undefined. See example code below.18389@throw invalid_iterator.206 if iterators @a first and @a last belong to a18390null value. In this case, the range `[first, last)` is undefined.1839118392@complexity Linear in distance between @a first and @a last.1839318394@exceptionsafety Strong guarantee: if an exception is thrown, there are no18395changes to any JSON value.1839618397@liveexample{The example below shows several ways to create JSON values by18398specifying a subrange with iterators.,basic_json__InputIt_InputIt}1839918400@since version 1.0.018401*/18402template < class InputIT, typename std::enable_if <18403std::is_same<InputIT, typename basic_json_t::iterator>::value ||18404std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >18405basic_json(InputIT first, InputIT last)18406{18407JSON_ASSERT(first.m_object != nullptr);18408JSON_ASSERT(last.m_object != nullptr);1840918410// make sure iterator fits the current value18411if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))18412{18413JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));18414}1841518416// copy type from first iterator18417m_type = first.m_object->m_type;1841818419// check if iterator range is complete for primitive values18420switch (m_type)18421{18422case value_t::boolean:18423case value_t::number_float:18424case value_t::number_integer:18425case value_t::number_unsigned:18426case value_t::string:18427{18428if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()18429|| !last.m_it.primitive_iterator.is_end()))18430{18431JSON_THROW(invalid_iterator::create(204, "iterators out of range"));18432}18433break;18434}1843518436default:18437break;18438}1843918440switch (m_type)18441{18442case value_t::number_integer:18443{18444m_value.number_integer = first.m_object->m_value.number_integer;18445break;18446}1844718448case value_t::number_unsigned:18449{18450m_value.number_unsigned = first.m_object->m_value.number_unsigned;18451break;18452}1845318454case value_t::number_float:18455{18456m_value.number_float = first.m_object->m_value.number_float;18457break;18458}1845918460case value_t::boolean:18461{18462m_value.boolean = first.m_object->m_value.boolean;18463break;18464}1846518466case value_t::string:18467{18468m_value = *first.m_object->m_value.string;18469break;18470}1847118472case value_t::object:18473{18474m_value.object = create<object_t>(first.m_it.object_iterator,18475last.m_it.object_iterator);18476break;18477}1847818479case value_t::array:18480{18481m_value.array = create<array_t>(first.m_it.array_iterator,18482last.m_it.array_iterator);18483break;18484}1848518486case value_t::binary:18487{18488m_value = *first.m_object->m_value.binary;18489break;18490}1849118492default:18493JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +18494std::string(first.m_object->type_name())));18495}1849618497assert_invariant();18498}184991850018501///////////////////////////////////////18502// other constructors and destructor //18503///////////////////////////////////////1850418505template<typename JsonRef,18506detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,18507std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >18508basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}1850918510/*!18511@brief copy constructor1851218513Creates a copy of a given JSON value.1851418515@param[in] other the JSON value to copy1851618517@post `*this == other`1851818519@complexity Linear in the size of @a other.1852018521@exceptionsafety Strong guarantee: if an exception is thrown, there are no18522changes to any JSON value.1852318524@requirement This function helps `basic_json` satisfying the18525[Container](https://en.cppreference.com/w/cpp/named_req/Container)18526requirements:18527- The complexity is linear.18528- As postcondition, it holds: `other == basic_json(other)`.1852918530@liveexample{The following code shows an example for the copy18531constructor.,basic_json__basic_json}1853218533@since version 1.0.018534*/18535basic_json(const basic_json& other)18536: m_type(other.m_type)18537{18538// check of passed value is valid18539other.assert_invariant();1854018541switch (m_type)18542{18543case value_t::object:18544{18545m_value = *other.m_value.object;18546break;18547}1854818549case value_t::array:18550{18551m_value = *other.m_value.array;18552break;18553}1855418555case value_t::string:18556{18557m_value = *other.m_value.string;18558break;18559}1856018561case value_t::boolean:18562{18563m_value = other.m_value.boolean;18564break;18565}1856618567case value_t::number_integer:18568{18569m_value = other.m_value.number_integer;18570break;18571}1857218573case value_t::number_unsigned:18574{18575m_value = other.m_value.number_unsigned;18576break;18577}1857818579case value_t::number_float:18580{18581m_value = other.m_value.number_float;18582break;18583}1858418585case value_t::binary:18586{18587m_value = *other.m_value.binary;18588break;18589}1859018591default:18592break;18593}1859418595assert_invariant();18596}1859718598/*!18599@brief move constructor1860018601Move constructor. Constructs a JSON value with the contents of the given18602value @a other using move semantics. It "steals" the resources from @a18603other and leaves it as JSON null value.1860418605@param[in,out] other value to move to this object1860618607@post `*this` has the same value as @a other before the call.18608@post @a other is a JSON null value.1860918610@complexity Constant.1861118612@exceptionsafety No-throw guarantee: this constructor never throws18613exceptions.1861418615@requirement This function helps `basic_json` satisfying the18616[MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)18617requirements.1861818619@liveexample{The code below shows the move constructor explicitly called18620via std::move.,basic_json__moveconstructor}1862118622@since version 1.0.018623*/18624basic_json(basic_json&& other) noexcept18625: m_type(std::move(other.m_type)),18626m_value(std::move(other.m_value))18627{18628// check that passed value is valid18629other.assert_invariant();1863018631// invalidate payload18632other.m_type = value_t::null;18633other.m_value = {};1863418635assert_invariant();18636}1863718638/*!18639@brief copy assignment1864018641Copy assignment operator. Copies a JSON value via the "copy and swap"18642strategy: It is expressed in terms of the copy constructor, destructor,18643and the `swap()` member function.1864418645@param[in] other value to copy from1864618647@complexity Linear.1864818649@requirement This function helps `basic_json` satisfying the18650[Container](https://en.cppreference.com/w/cpp/named_req/Container)18651requirements:18652- The complexity is linear.1865318654@liveexample{The code below shows and example for the copy assignment. It18655creates a copy of value `a` which is then swapped with `b`. Finally\, the18656copy of `a` (which is the null value after the swap) is18657destroyed.,basic_json__copyassignment}1865818659@since version 1.0.018660*/18661basic_json& operator=(basic_json other) noexcept (18662std::is_nothrow_move_constructible<value_t>::value&&18663std::is_nothrow_move_assignable<value_t>::value&&18664std::is_nothrow_move_constructible<json_value>::value&&18665std::is_nothrow_move_assignable<json_value>::value18666)18667{18668// check that passed value is valid18669other.assert_invariant();1867018671using std::swap;18672swap(m_type, other.m_type);18673swap(m_value, other.m_value);1867418675assert_invariant();18676return *this;18677}1867818679/*!18680@brief destructor1868118682Destroys the JSON value and frees all allocated memory.1868318684@complexity Linear.1868518686@requirement This function helps `basic_json` satisfying the18687[Container](https://en.cppreference.com/w/cpp/named_req/Container)18688requirements:18689- The complexity is linear.18690- All stored elements are destroyed and all memory is freed.1869118692@since version 1.0.018693*/18694~basic_json() noexcept18695{18696assert_invariant();18697m_value.destroy(m_type);18698}1869918700/// @}1870118702public:18703///////////////////////18704// object inspection //18705///////////////////////1870618707/// @name object inspection18708/// Functions to inspect the type of a JSON value.18709/// @{1871018711/*!18712@brief serialization1871318714Serialization function for JSON values. The function tries to mimic18715Python's `json.dumps()` function, and currently supports its @a indent18716and @a ensure_ascii parameters.1871718718@param[in] indent If indent is nonnegative, then array elements and object18719members will be pretty-printed with that indent level. An indent level of18720`0` will only insert newlines. `-1` (the default) selects the most compact18721representation.18722@param[in] indent_char The character to use for indentation if @a indent is18723greater than `0`. The default is ` ` (space).18724@param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters18725in the output are escaped with `\uXXXX` sequences, and the result consists18726of ASCII characters only.18727@param[in] error_handler how to react on decoding errors; there are three18728possible values: `strict` (throws and exception in case a decoding error18729occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),18730and `ignore` (ignore invalid UTF-8 sequences during serialization; all18731bytes are copied to the output unchanged).1873218733@return string containing the serialization of the JSON value1873418735@throw type_error.316 if a string stored inside the JSON value is not18736UTF-8 encoded and @a error_handler is set to strict1873718738@note Binary values are serialized as object containing two keys:18739- "bytes": an array of bytes as integers18740- "subtype": the subtype as integer or "null" if the binary has no subtype1874118742@complexity Linear.1874318744@exceptionsafety Strong guarantee: if an exception is thrown, there are no18745changes in the JSON value.1874618747@liveexample{The following example shows the effect of different @a indent\,18748@a indent_char\, and @a ensure_ascii parameters to the result of the18749serialization.,dump}1875018751@see https://docs.python.org/2/library/json.html#json.dump1875218753@since version 1.0.0; indentation character @a indent_char, option18754@a ensure_ascii and exceptions added in version 3.0.0; error18755handlers added in version 3.4.0; serialization of binary values added18756in version 3.8.0.18757*/18758string_t dump(const int indent = -1,18759const char indent_char = ' ',18760const bool ensure_ascii = false,18761const error_handler_t error_handler = error_handler_t::strict) const18762{18763string_t result;18764serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);1876518766if (indent >= 0)18767{18768s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));18769}18770else18771{18772s.dump(*this, false, ensure_ascii, 0);18773}1877418775return result;18776}1877718778/*!18779@brief return the type of the JSON value (explicit)1878018781Return the type of the JSON value as a value from the @ref value_t18782enumeration.1878318784@return the type of the JSON value18785Value type | return value18786------------------------- | -------------------------18787null | value_t::null18788boolean | value_t::boolean18789string | value_t::string18790number (integer) | value_t::number_integer18791number (unsigned integer) | value_t::number_unsigned18792number (floating-point) | value_t::number_float18793object | value_t::object18794array | value_t::array18795binary | value_t::binary18796discarded | value_t::discarded1879718798@complexity Constant.1879918800@exceptionsafety No-throw guarantee: this member function never throws18801exceptions.1880218803@liveexample{The following code exemplifies `type()` for all JSON18804types.,type}1880518806@sa @ref operator value_t() -- return the type of the JSON value (implicit)18807@sa @ref type_name() -- return the type as string1880818809@since version 1.0.018810*/18811constexpr value_t type() const noexcept18812{18813return m_type;18814}1881518816/*!18817@brief return whether type is primitive1881818819This function returns true if and only if the JSON type is primitive18820(string, number, boolean, or null).1882118822@return `true` if type is primitive (string, number, boolean, or null),18823`false` otherwise.1882418825@complexity Constant.1882618827@exceptionsafety No-throw guarantee: this member function never throws18828exceptions.1882918830@liveexample{The following code exemplifies `is_primitive()` for all JSON18831types.,is_primitive}1883218833@sa @ref is_structured() -- returns whether JSON value is structured18834@sa @ref is_null() -- returns whether JSON value is `null`18835@sa @ref is_string() -- returns whether JSON value is a string18836@sa @ref is_boolean() -- returns whether JSON value is a boolean18837@sa @ref is_number() -- returns whether JSON value is a number18838@sa @ref is_binary() -- returns whether JSON value is a binary array1883918840@since version 1.0.018841*/18842constexpr bool is_primitive() const noexcept18843{18844return is_null() || is_string() || is_boolean() || is_number() || is_binary();18845}1884618847/*!18848@brief return whether type is structured1884918850This function returns true if and only if the JSON type is structured18851(array or object).1885218853@return `true` if type is structured (array or object), `false` otherwise.1885418855@complexity Constant.1885618857@exceptionsafety No-throw guarantee: this member function never throws18858exceptions.1885918860@liveexample{The following code exemplifies `is_structured()` for all JSON18861types.,is_structured}1886218863@sa @ref is_primitive() -- returns whether value is primitive18864@sa @ref is_array() -- returns whether value is an array18865@sa @ref is_object() -- returns whether value is an object1886618867@since version 1.0.018868*/18869constexpr bool is_structured() const noexcept18870{18871return is_array() || is_object();18872}1887318874/*!18875@brief return whether value is null1887618877This function returns true if and only if the JSON value is null.1887818879@return `true` if type is null, `false` otherwise.1888018881@complexity Constant.1888218883@exceptionsafety No-throw guarantee: this member function never throws18884exceptions.1888518886@liveexample{The following code exemplifies `is_null()` for all JSON18887types.,is_null}1888818889@since version 1.0.018890*/18891constexpr bool is_null() const noexcept18892{18893return m_type == value_t::null;18894}1889518896/*!18897@brief return whether value is a boolean1889818899This function returns true if and only if the JSON value is a boolean.1890018901@return `true` if type is boolean, `false` otherwise.1890218903@complexity Constant.1890418905@exceptionsafety No-throw guarantee: this member function never throws18906exceptions.1890718908@liveexample{The following code exemplifies `is_boolean()` for all JSON18909types.,is_boolean}1891018911@since version 1.0.018912*/18913constexpr bool is_boolean() const noexcept18914{18915return m_type == value_t::boolean;18916}1891718918/*!18919@brief return whether value is a number1892018921This function returns true if and only if the JSON value is a number. This18922includes both integer (signed and unsigned) and floating-point values.1892318924@return `true` if type is number (regardless whether integer, unsigned18925integer or floating-type), `false` otherwise.1892618927@complexity Constant.1892818929@exceptionsafety No-throw guarantee: this member function never throws18930exceptions.1893118932@liveexample{The following code exemplifies `is_number()` for all JSON18933types.,is_number}1893418935@sa @ref is_number_integer() -- check if value is an integer or unsigned18936integer number18937@sa @ref is_number_unsigned() -- check if value is an unsigned integer18938number18939@sa @ref is_number_float() -- check if value is a floating-point number1894018941@since version 1.0.018942*/18943constexpr bool is_number() const noexcept18944{18945return is_number_integer() || is_number_float();18946}1894718948/*!18949@brief return whether value is an integer number1895018951This function returns true if and only if the JSON value is a signed or18952unsigned integer number. This excludes floating-point values.1895318954@return `true` if type is an integer or unsigned integer number, `false`18955otherwise.1895618957@complexity Constant.1895818959@exceptionsafety No-throw guarantee: this member function never throws18960exceptions.1896118962@liveexample{The following code exemplifies `is_number_integer()` for all18963JSON types.,is_number_integer}1896418965@sa @ref is_number() -- check if value is a number18966@sa @ref is_number_unsigned() -- check if value is an unsigned integer18967number18968@sa @ref is_number_float() -- check if value is a floating-point number1896918970@since version 1.0.018971*/18972constexpr bool is_number_integer() const noexcept18973{18974return m_type == value_t::number_integer || m_type == value_t::number_unsigned;18975}1897618977/*!18978@brief return whether value is an unsigned integer number1897918980This function returns true if and only if the JSON value is an unsigned18981integer number. This excludes floating-point and signed integer values.1898218983@return `true` if type is an unsigned integer number, `false` otherwise.1898418985@complexity Constant.1898618987@exceptionsafety No-throw guarantee: this member function never throws18988exceptions.1898918990@liveexample{The following code exemplifies `is_number_unsigned()` for all18991JSON types.,is_number_unsigned}1899218993@sa @ref is_number() -- check if value is a number18994@sa @ref is_number_integer() -- check if value is an integer or unsigned18995integer number18996@sa @ref is_number_float() -- check if value is a floating-point number1899718998@since version 2.0.018999*/19000constexpr bool is_number_unsigned() const noexcept19001{19002return m_type == value_t::number_unsigned;19003}1900419005/*!19006@brief return whether value is a floating-point number1900719008This function returns true if and only if the JSON value is a19009floating-point number. This excludes signed and unsigned integer values.1901019011@return `true` if type is a floating-point number, `false` otherwise.1901219013@complexity Constant.1901419015@exceptionsafety No-throw guarantee: this member function never throws19016exceptions.1901719018@liveexample{The following code exemplifies `is_number_float()` for all19019JSON types.,is_number_float}1902019021@sa @ref is_number() -- check if value is number19022@sa @ref is_number_integer() -- check if value is an integer number19023@sa @ref is_number_unsigned() -- check if value is an unsigned integer19024number1902519026@since version 1.0.019027*/19028constexpr bool is_number_float() const noexcept19029{19030return m_type == value_t::number_float;19031}1903219033/*!19034@brief return whether value is an object1903519036This function returns true if and only if the JSON value is an object.1903719038@return `true` if type is object, `false` otherwise.1903919040@complexity Constant.1904119042@exceptionsafety No-throw guarantee: this member function never throws19043exceptions.1904419045@liveexample{The following code exemplifies `is_object()` for all JSON19046types.,is_object}1904719048@since version 1.0.019049*/19050constexpr bool is_object() const noexcept19051{19052return m_type == value_t::object;19053}1905419055/*!19056@brief return whether value is an array1905719058This function returns true if and only if the JSON value is an array.1905919060@return `true` if type is array, `false` otherwise.1906119062@complexity Constant.1906319064@exceptionsafety No-throw guarantee: this member function never throws19065exceptions.1906619067@liveexample{The following code exemplifies `is_array()` for all JSON19068types.,is_array}1906919070@since version 1.0.019071*/19072constexpr bool is_array() const noexcept19073{19074return m_type == value_t::array;19075}1907619077/*!19078@brief return whether value is a string1907919080This function returns true if and only if the JSON value is a string.1908119082@return `true` if type is string, `false` otherwise.1908319084@complexity Constant.1908519086@exceptionsafety No-throw guarantee: this member function never throws19087exceptions.1908819089@liveexample{The following code exemplifies `is_string()` for all JSON19090types.,is_string}1909119092@since version 1.0.019093*/19094constexpr bool is_string() const noexcept19095{19096return m_type == value_t::string;19097}1909819099/*!19100@brief return whether value is a binary array1910119102This function returns true if and only if the JSON value is a binary array.1910319104@return `true` if type is binary array, `false` otherwise.1910519106@complexity Constant.1910719108@exceptionsafety No-throw guarantee: this member function never throws19109exceptions.1911019111@liveexample{The following code exemplifies `is_binary()` for all JSON19112types.,is_binary}1911319114@since version 3.8.019115*/19116constexpr bool is_binary() const noexcept19117{19118return m_type == value_t::binary;19119}1912019121/*!19122@brief return whether value is discarded1912319124This function returns true if and only if the JSON value was discarded19125during parsing with a callback function (see @ref parser_callback_t).1912619127@note This function will always be `false` for JSON values after parsing.19128That is, discarded values can only occur during parsing, but will be19129removed when inside a structured value or replaced by null in other cases.1913019131@return `true` if type is discarded, `false` otherwise.1913219133@complexity Constant.1913419135@exceptionsafety No-throw guarantee: this member function never throws19136exceptions.1913719138@liveexample{The following code exemplifies `is_discarded()` for all JSON19139types.,is_discarded}1914019141@since version 1.0.019142*/19143constexpr bool is_discarded() const noexcept19144{19145return m_type == value_t::discarded;19146}1914719148/*!19149@brief return the type of the JSON value (implicit)1915019151Implicitly return the type of the JSON value as a value from the @ref19152value_t enumeration.1915319154@return the type of the JSON value1915519156@complexity Constant.1915719158@exceptionsafety No-throw guarantee: this member function never throws19159exceptions.1916019161@liveexample{The following code exemplifies the @ref value_t operator for19162all JSON types.,operator__value_t}1916319164@sa @ref type() -- return the type of the JSON value (explicit)19165@sa @ref type_name() -- return the type as string1916619167@since version 1.0.019168*/19169constexpr operator value_t() const noexcept19170{19171return m_type;19172}1917319174/// @}1917519176private:19177//////////////////19178// value access //19179//////////////////1918019181/// get a boolean (explicit)19182boolean_t get_impl(boolean_t* /*unused*/) const19183{19184if (JSON_HEDLEY_LIKELY(is_boolean()))19185{19186return m_value.boolean;19187}1918819189JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));19190}1919119192/// get a pointer to the value (object)19193object_t* get_impl_ptr(object_t* /*unused*/) noexcept19194{19195return is_object() ? m_value.object : nullptr;19196}1919719198/// get a pointer to the value (object)19199constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept19200{19201return is_object() ? m_value.object : nullptr;19202}1920319204/// get a pointer to the value (array)19205array_t* get_impl_ptr(array_t* /*unused*/) noexcept19206{19207return is_array() ? m_value.array : nullptr;19208}1920919210/// get a pointer to the value (array)19211constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept19212{19213return is_array() ? m_value.array : nullptr;19214}1921519216/// get a pointer to the value (string)19217string_t* get_impl_ptr(string_t* /*unused*/) noexcept19218{19219return is_string() ? m_value.string : nullptr;19220}1922119222/// get a pointer to the value (string)19223constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept19224{19225return is_string() ? m_value.string : nullptr;19226}1922719228/// get a pointer to the value (boolean)19229boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept19230{19231return is_boolean() ? &m_value.boolean : nullptr;19232}1923319234/// get a pointer to the value (boolean)19235constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept19236{19237return is_boolean() ? &m_value.boolean : nullptr;19238}1923919240/// get a pointer to the value (integer number)19241number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept19242{19243return is_number_integer() ? &m_value.number_integer : nullptr;19244}1924519246/// get a pointer to the value (integer number)19247constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept19248{19249return is_number_integer() ? &m_value.number_integer : nullptr;19250}1925119252/// get a pointer to the value (unsigned number)19253number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept19254{19255return is_number_unsigned() ? &m_value.number_unsigned : nullptr;19256}1925719258/// get a pointer to the value (unsigned number)19259constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept19260{19261return is_number_unsigned() ? &m_value.number_unsigned : nullptr;19262}1926319264/// get a pointer to the value (floating-point number)19265number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept19266{19267return is_number_float() ? &m_value.number_float : nullptr;19268}1926919270/// get a pointer to the value (floating-point number)19271constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept19272{19273return is_number_float() ? &m_value.number_float : nullptr;19274}1927519276/// get a pointer to the value (binary)19277binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept19278{19279return is_binary() ? m_value.binary : nullptr;19280}1928119282/// get a pointer to the value (binary)19283constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept19284{19285return is_binary() ? m_value.binary : nullptr;19286}1928719288/*!19289@brief helper function to implement get_ref()1929019291This function helps to implement get_ref() without code duplication for19292const and non-const overloads1929319294@tparam ThisType will be deduced as `basic_json` or `const basic_json`1929519296@throw type_error.303 if ReferenceType does not match underlying value19297type of the current JSON19298*/19299template<typename ReferenceType, typename ThisType>19300static ReferenceType get_ref_impl(ThisType& obj)19301{19302// delegate the call to get_ptr<>()19303auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();1930419305if (JSON_HEDLEY_LIKELY(ptr != nullptr))19306{19307return *ptr;19308}1930919310JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));19311}1931219313public:19314/// @name value access19315/// Direct access to the stored value of a JSON value.19316/// @{1931719318/*!19319@brief get special-case overload1932019321This overloads avoids a lot of template boilerplate, it can be seen as the19322identity method1932319324@tparam BasicJsonType == @ref basic_json1932519326@return a copy of *this1932719328@complexity Constant.1932919330@since version 2.1.019331*/19332template<typename BasicJsonType, detail::enable_if_t<19333std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,19334int> = 0>19335basic_json get() const19336{19337return *this;19338}1933919340/*!19341@brief get special-case overload1934219343This overloads converts the current @ref basic_json in a different19344@ref basic_json type1934519346@tparam BasicJsonType == @ref basic_json1934719348@return a copy of *this, converted into @tparam BasicJsonType1934919350@complexity Depending on the implementation of the called `from_json()`19351method.1935219353@since version 3.2.019354*/19355template < typename BasicJsonType, detail::enable_if_t <19356!std::is_same<BasicJsonType, basic_json>::value&&19357detail::is_basic_json<BasicJsonType>::value, int > = 0 >19358BasicJsonType get() const19359{19360return *this;19361}1936219363/*!19364@brief get a value (explicit)1936519366Explicit type conversion between the JSON value and a compatible value19367which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)19368and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).19369The value is converted by calling the @ref json_serializer<ValueType>19370`from_json()` method.1937119372The function is equivalent to executing19373@code {.cpp}19374ValueType ret;19375JSONSerializer<ValueType>::from_json(*this, ret);19376return ret;19377@endcode1937819379This overloads is chosen if:19380- @a ValueType is not @ref basic_json,19381- @ref json_serializer<ValueType> has a `from_json()` method of the form19382`void from_json(const basic_json&, ValueType&)`, and19383- @ref json_serializer<ValueType> does not have a `from_json()` method of19384the form `ValueType from_json(const basic_json&)`1938519386@tparam ValueTypeCV the provided value type19387@tparam ValueType the returned value type1938819389@return copy of the JSON value, converted to @a ValueType1939019391@throw what @ref json_serializer<ValueType> `from_json()` method throws1939219393@liveexample{The example below shows several conversions from JSON values19394to other types. There a few things to note: (1) Floating-point numbers can19395be converted to integers\, (2) A JSON array can be converted to a standard19396`std::vector<short>`\, (3) A JSON object can be converted to C++19397associative containers such as `std::unordered_map<std::string\,19398json>`.,get__ValueType_const}1939919400@since version 2.1.019401*/19402template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,19403detail::enable_if_t <19404!detail::is_basic_json<ValueType>::value &&19405detail::has_from_json<basic_json_t, ValueType>::value &&19406!detail::has_non_default_from_json<basic_json_t, ValueType>::value,19407int > = 0 >19408ValueType get() const noexcept(noexcept(19409JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))19410{19411// we cannot static_assert on ValueTypeCV being non-const, because19412// there is support for get<const basic_json_t>(), which is why we19413// still need the uncvref19414static_assert(!std::is_reference<ValueTypeCV>::value,19415"get() cannot be used with reference types, you might want to use get_ref()");19416static_assert(std::is_default_constructible<ValueType>::value,19417"types must be DefaultConstructible when used with get()");1941819419ValueType ret;19420JSONSerializer<ValueType>::from_json(*this, ret);19421return ret;19422}1942319424/*!19425@brief get a value (explicit); special case1942619427Explicit type conversion between the JSON value and a compatible value19428which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)19429and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).19430The value is converted by calling the @ref json_serializer<ValueType>19431`from_json()` method.1943219433The function is equivalent to executing19434@code {.cpp}19435return JSONSerializer<ValueTypeCV>::from_json(*this);19436@endcode1943719438This overloads is chosen if:19439- @a ValueType is not @ref basic_json and19440- @ref json_serializer<ValueType> has a `from_json()` method of the form19441`ValueType from_json(const basic_json&)`1944219443@note If @ref json_serializer<ValueType> has both overloads of19444`from_json()`, this one is chosen.1944519446@tparam ValueTypeCV the provided value type19447@tparam ValueType the returned value type1944819449@return copy of the JSON value, converted to @a ValueType1945019451@throw what @ref json_serializer<ValueType> `from_json()` method throws1945219453@since version 2.1.019454*/19455template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,19456detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&19457detail::has_non_default_from_json<basic_json_t, ValueType>::value,19458int > = 0 >19459ValueType get() const noexcept(noexcept(19460JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))19461{19462static_assert(!std::is_reference<ValueTypeCV>::value,19463"get() cannot be used with reference types, you might want to use get_ref()");19464return JSONSerializer<ValueType>::from_json(*this);19465}1946619467/*!19468@brief get a value (explicit)1946919470Explicit type conversion between the JSON value and a compatible value.19471The value is filled into the input parameter by calling the @ref json_serializer<ValueType>19472`from_json()` method.1947319474The function is equivalent to executing19475@code {.cpp}19476ValueType v;19477JSONSerializer<ValueType>::from_json(*this, v);19478@endcode1947919480This overloads is chosen if:19481- @a ValueType is not @ref basic_json,19482- @ref json_serializer<ValueType> has a `from_json()` method of the form19483`void from_json(const basic_json&, ValueType&)`, and1948419485@tparam ValueType the input parameter type.1948619487@return the input parameter, allowing chaining calls.1948819489@throw what @ref json_serializer<ValueType> `from_json()` method throws1949019491@liveexample{The example below shows several conversions from JSON values19492to other types. There a few things to note: (1) Floating-point numbers can19493be converted to integers\, (2) A JSON array can be converted to a standard19494`std::vector<short>`\, (3) A JSON object can be converted to C++19495associative containers such as `std::unordered_map<std::string\,19496json>`.,get_to}1949719498@since version 3.3.019499*/19500template < typename ValueType,19501detail::enable_if_t <19502!detail::is_basic_json<ValueType>::value&&19503detail::has_from_json<basic_json_t, ValueType>::value,19504int > = 0 >19505ValueType & get_to(ValueType& v) const noexcept(noexcept(19506JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))19507{19508JSONSerializer<ValueType>::from_json(*this, v);19509return v;19510}1951119512// specialization to allow to call get_to with a basic_json value19513// see https://github.com/nlohmann/json/issues/217519514template<typename ValueType,19515detail::enable_if_t <19516detail::is_basic_json<ValueType>::value,19517int> = 0>19518ValueType & get_to(ValueType& v) const19519{19520v = *this;19521return v;19522}1952319524template <19525typename T, std::size_t N,19526typename Array = T (&)[N],19527detail::enable_if_t <19528detail::has_from_json<basic_json_t, Array>::value, int > = 0 >19529Array get_to(T (&v)[N]) const19530noexcept(noexcept(JSONSerializer<Array>::from_json(19531std::declval<const basic_json_t&>(), v)))19532{19533JSONSerializer<Array>::from_json(*this, v);19534return v;19535}195361953719538/*!19539@brief get a pointer value (implicit)1954019541Implicit pointer access to the internally stored JSON value. No copies are19542made.1954319544@warning Writing data to the pointee of the result yields an undefined19545state.1954619547@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref19548object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,19549@ref number_unsigned_t, or @ref number_float_t. Enforced by a static19550assertion.1955119552@return pointer to the internally stored JSON value if the requested19553pointer type @a PointerType fits to the JSON value; `nullptr` otherwise1955419555@complexity Constant.1955619557@liveexample{The example below shows how pointers to internal values of a19558JSON value can be requested. Note that no type conversions are made and a19559`nullptr` is returned if the value and the requested pointer type does not19560match.,get_ptr}1956119562@since version 1.0.019563*/19564template<typename PointerType, typename std::enable_if<19565std::is_pointer<PointerType>::value, int>::type = 0>19566auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))19567{19568// delegate the call to get_impl_ptr<>()19569return get_impl_ptr(static_cast<PointerType>(nullptr));19570}1957119572/*!19573@brief get a pointer value (implicit)19574@copydoc get_ptr()19575*/19576template < typename PointerType, typename std::enable_if <19577std::is_pointer<PointerType>::value&&19578std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >19579constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))19580{19581// delegate the call to get_impl_ptr<>() const19582return get_impl_ptr(static_cast<PointerType>(nullptr));19583}1958419585/*!19586@brief get a pointer value (explicit)1958719588Explicit pointer access to the internally stored JSON value. No copies are19589made.1959019591@warning The pointer becomes invalid if the underlying JSON object19592changes.1959319594@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref19595object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,19596@ref number_unsigned_t, or @ref number_float_t.1959719598@return pointer to the internally stored JSON value if the requested19599pointer type @a PointerType fits to the JSON value; `nullptr` otherwise1960019601@complexity Constant.1960219603@liveexample{The example below shows how pointers to internal values of a19604JSON value can be requested. Note that no type conversions are made and a19605`nullptr` is returned if the value and the requested pointer type does not19606match.,get__PointerType}1960719608@sa @ref get_ptr() for explicit pointer-member access1960919610@since version 1.0.019611*/19612template<typename PointerType, typename std::enable_if<19613std::is_pointer<PointerType>::value, int>::type = 0>19614auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())19615{19616// delegate the call to get_ptr19617return get_ptr<PointerType>();19618}1961919620/*!19621@brief get a pointer value (explicit)19622@copydoc get()19623*/19624template<typename PointerType, typename std::enable_if<19625std::is_pointer<PointerType>::value, int>::type = 0>19626constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())19627{19628// delegate the call to get_ptr19629return get_ptr<PointerType>();19630}1963119632/*!19633@brief get a reference value (implicit)1963419635Implicit reference access to the internally stored JSON value. No copies19636are made.1963719638@warning Writing data to the referee of the result yields an undefined19639state.1964019641@tparam ReferenceType reference type; must be a reference to @ref array_t,19642@ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or19643@ref number_float_t. Enforced by static assertion.1964419645@return reference to the internally stored JSON value if the requested19646reference type @a ReferenceType fits to the JSON value; throws19647type_error.303 otherwise1964819649@throw type_error.303 in case passed type @a ReferenceType is incompatible19650with the stored JSON value; see example below1965119652@complexity Constant.1965319654@liveexample{The example shows several calls to `get_ref()`.,get_ref}1965519656@since version 1.1.019657*/19658template<typename ReferenceType, typename std::enable_if<19659std::is_reference<ReferenceType>::value, int>::type = 0>19660ReferenceType get_ref()19661{19662// delegate call to get_ref_impl19663return get_ref_impl<ReferenceType>(*this);19664}1966519666/*!19667@brief get a reference value (implicit)19668@copydoc get_ref()19669*/19670template < typename ReferenceType, typename std::enable_if <19671std::is_reference<ReferenceType>::value&&19672std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >19673ReferenceType get_ref() const19674{19675// delegate call to get_ref_impl19676return get_ref_impl<ReferenceType>(*this);19677}1967819679/*!19680@brief get a value (implicit)1968119682Implicit type conversion between the JSON value and a compatible value.19683The call is realized by calling @ref get() const.1968419685@tparam ValueType non-pointer type compatible to the JSON value, for19686instance `int` for JSON integer numbers, `bool` for JSON booleans, or19687`std::vector` types for JSON arrays. The character type of @ref string_t19688as well as an initializer list of this type is excluded to avoid19689ambiguities as these types implicitly convert to `std::string`.1969019691@return copy of the JSON value, converted to type @a ValueType1969219693@throw type_error.302 in case passed type @a ValueType is incompatible19694to the JSON value type (e.g., the JSON value is of type boolean, but a19695string is requested); see example below1969619697@complexity Linear in the size of the JSON value.1969819699@liveexample{The example below shows several conversions from JSON values19700to other types. There a few things to note: (1) Floating-point numbers can19701be converted to integers\, (2) A JSON array can be converted to a standard19702`std::vector<short>`\, (3) A JSON object can be converted to C++19703associative containers such as `std::unordered_map<std::string\,19704json>`.,operator__ValueType}1970519706@since version 1.0.019707*/19708template < typename ValueType, typename std::enable_if <19709!std::is_pointer<ValueType>::value&&19710!std::is_same<ValueType, detail::json_ref<basic_json>>::value&&19711!std::is_same<ValueType, typename string_t::value_type>::value&&19712!detail::is_basic_json<ValueType>::value19713&& !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value19714#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))19715&& !std::is_same<ValueType, typename std::string_view>::value19716#endif19717&& detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value19718, int >::type = 0 >19719JSON_EXPLICIT operator ValueType() const19720{19721// delegate the call to get<>() const19722return get<ValueType>();19723}1972419725/*!19726@return reference to the binary value1972719728@throw type_error.302 if the value is not binary1972919730@sa @ref is_binary() to check if the value is binary1973119732@since version 3.8.019733*/19734binary_t& get_binary()19735{19736if (!is_binary())19737{19738JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));19739}1974019741return *get_ptr<binary_t*>();19742}1974319744/// @copydoc get_binary()19745const binary_t& get_binary() const19746{19747if (!is_binary())19748{19749JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));19750}1975119752return *get_ptr<const binary_t*>();19753}1975419755/// @}197561975719758////////////////////19759// element access //19760////////////////////1976119762/// @name element access19763/// Access to the JSON value.19764/// @{1976519766/*!19767@brief access specified array element with bounds checking1976819769Returns a reference to the element at specified location @a idx, with19770bounds checking.1977119772@param[in] idx index of the element to access1977319774@return reference to the element at index @a idx1977519776@throw type_error.304 if the JSON value is not an array; in this case,19777calling `at` with an index makes no sense. See example below.19778@throw out_of_range.401 if the index @a idx is out of range of the array;19779that is, `idx >= size()`. See example below.1978019781@exceptionsafety Strong guarantee: if an exception is thrown, there are no19782changes in the JSON value.1978319784@complexity Constant.1978519786@since version 1.0.01978719788@liveexample{The example below shows how array elements can be read and19789written using `at()`. It also demonstrates the different exceptions that19790can be thrown.,at__size_type}19791*/19792reference at(size_type idx)19793{19794// at only works for arrays19795if (JSON_HEDLEY_LIKELY(is_array()))19796{19797JSON_TRY19798{19799return m_value.array->at(idx);19800}19801JSON_CATCH (std::out_of_range&)19802{19803// create better exception explanation19804JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));19805}19806}19807else19808{19809JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));19810}19811}1981219813/*!19814@brief access specified array element with bounds checking1981519816Returns a const reference to the element at specified location @a idx,19817with bounds checking.1981819819@param[in] idx index of the element to access1982019821@return const reference to the element at index @a idx1982219823@throw type_error.304 if the JSON value is not an array; in this case,19824calling `at` with an index makes no sense. See example below.19825@throw out_of_range.401 if the index @a idx is out of range of the array;19826that is, `idx >= size()`. See example below.1982719828@exceptionsafety Strong guarantee: if an exception is thrown, there are no19829changes in the JSON value.1983019831@complexity Constant.1983219833@since version 1.0.01983419835@liveexample{The example below shows how array elements can be read using19836`at()`. It also demonstrates the different exceptions that can be thrown.,19837at__size_type_const}19838*/19839const_reference at(size_type idx) const19840{19841// at only works for arrays19842if (JSON_HEDLEY_LIKELY(is_array()))19843{19844JSON_TRY19845{19846return m_value.array->at(idx);19847}19848JSON_CATCH (std::out_of_range&)19849{19850// create better exception explanation19851JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));19852}19853}19854else19855{19856JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));19857}19858}1985919860/*!19861@brief access specified object element with bounds checking1986219863Returns a reference to the element at with specified key @a key, with19864bounds checking.1986519866@param[in] key key of the element to access1986719868@return reference to the element at key @a key1986919870@throw type_error.304 if the JSON value is not an object; in this case,19871calling `at` with a key makes no sense. See example below.19872@throw out_of_range.403 if the key @a key is is not stored in the object;19873that is, `find(key) == end()`. See example below.1987419875@exceptionsafety Strong guarantee: if an exception is thrown, there are no19876changes in the JSON value.1987719878@complexity Logarithmic in the size of the container.1987919880@sa @ref operator[](const typename object_t::key_type&) for unchecked19881access by reference19882@sa @ref value() for access by value with a default value1988319884@since version 1.0.01988519886@liveexample{The example below shows how object elements can be read and19887written using `at()`. It also demonstrates the different exceptions that19888can be thrown.,at__object_t_key_type}19889*/19890reference at(const typename object_t::key_type& key)19891{19892// at only works for objects19893if (JSON_HEDLEY_LIKELY(is_object()))19894{19895JSON_TRY19896{19897return m_value.object->at(key);19898}19899JSON_CATCH (std::out_of_range&)19900{19901// create better exception explanation19902JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));19903}19904}19905else19906{19907JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));19908}19909}1991019911/*!19912@brief access specified object element with bounds checking1991319914Returns a const reference to the element at with specified key @a key,19915with bounds checking.1991619917@param[in] key key of the element to access1991819919@return const reference to the element at key @a key1992019921@throw type_error.304 if the JSON value is not an object; in this case,19922calling `at` with a key makes no sense. See example below.19923@throw out_of_range.403 if the key @a key is is not stored in the object;19924that is, `find(key) == end()`. See example below.1992519926@exceptionsafety Strong guarantee: if an exception is thrown, there are no19927changes in the JSON value.1992819929@complexity Logarithmic in the size of the container.1993019931@sa @ref operator[](const typename object_t::key_type&) for unchecked19932access by reference19933@sa @ref value() for access by value with a default value1993419935@since version 1.0.01993619937@liveexample{The example below shows how object elements can be read using19938`at()`. It also demonstrates the different exceptions that can be thrown.,19939at__object_t_key_type_const}19940*/19941const_reference at(const typename object_t::key_type& key) const19942{19943// at only works for objects19944if (JSON_HEDLEY_LIKELY(is_object()))19945{19946JSON_TRY19947{19948return m_value.object->at(key);19949}19950JSON_CATCH (std::out_of_range&)19951{19952// create better exception explanation19953JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));19954}19955}19956else19957{19958JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));19959}19960}1996119962/*!19963@brief access specified array element1996419965Returns a reference to the element at specified location @a idx.1996619967@note If @a idx is beyond the range of the array (i.e., `idx >= size()`),19968then the array is silently filled up with `null` values to make `idx` a19969valid reference to the last stored element.1997019971@param[in] idx index of the element to access1997219973@return reference to the element at index @a idx1997419975@throw type_error.305 if the JSON value is not an array or null; in that19976cases, using the [] operator with an index makes no sense.1997719978@complexity Constant if @a idx is in the range of the array. Otherwise19979linear in `idx - size()`.1998019981@liveexample{The example below shows how array elements can be read and19982written using `[]` operator. Note the addition of `null`19983values.,operatorarray__size_type}1998419985@since version 1.0.019986*/19987reference operator[](size_type idx)19988{19989// implicitly convert null value to an empty array19990if (is_null())19991{19992m_type = value_t::array;19993m_value.array = create<array_t>();19994assert_invariant();19995}1999619997// operator[] only works for arrays19998if (JSON_HEDLEY_LIKELY(is_array()))19999{20000// fill up array with null values if given idx is outside range20001if (idx >= m_value.array->size())20002{20003m_value.array->insert(m_value.array->end(),20004idx - m_value.array->size() + 1,20005basic_json());20006}2000720008return m_value.array->operator[](idx);20009}2001020011JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));20012}2001320014/*!20015@brief access specified array element2001620017Returns a const reference to the element at specified location @a idx.2001820019@param[in] idx index of the element to access2002020021@return const reference to the element at index @a idx2002220023@throw type_error.305 if the JSON value is not an array; in that case,20024using the [] operator with an index makes no sense.2002520026@complexity Constant.2002720028@liveexample{The example below shows how array elements can be read using20029the `[]` operator.,operatorarray__size_type_const}2003020031@since version 1.0.020032*/20033const_reference operator[](size_type idx) const20034{20035// const operator[] only works for arrays20036if (JSON_HEDLEY_LIKELY(is_array()))20037{20038return m_value.array->operator[](idx);20039}2004020041JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));20042}2004320044/*!20045@brief access specified object element2004620047Returns a reference to the element at with specified key @a key.2004820049@note If @a key is not found in the object, then it is silently added to20050the object and filled with a `null` value to make `key` a valid reference.20051In case the value was `null` before, it is converted to an object.2005220053@param[in] key key of the element to access2005420055@return reference to the element at key @a key2005620057@throw type_error.305 if the JSON value is not an object or null; in that20058cases, using the [] operator with a key makes no sense.2005920060@complexity Logarithmic in the size of the container.2006120062@liveexample{The example below shows how object elements can be read and20063written using the `[]` operator.,operatorarray__key_type}2006420065@sa @ref at(const typename object_t::key_type&) for access by reference20066with range checking20067@sa @ref value() for access by value with a default value2006820069@since version 1.0.020070*/20071reference operator[](const typename object_t::key_type& key)20072{20073// implicitly convert null value to an empty object20074if (is_null())20075{20076m_type = value_t::object;20077m_value.object = create<object_t>();20078assert_invariant();20079}2008020081// operator[] only works for objects20082if (JSON_HEDLEY_LIKELY(is_object()))20083{20084return m_value.object->operator[](key);20085}2008620087JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));20088}2008920090/*!20091@brief read-only access specified object element2009220093Returns a const reference to the element at with specified key @a key. No20094bounds checking is performed.2009520096@warning If the element with key @a key does not exist, the behavior is20097undefined.2009820099@param[in] key key of the element to access2010020101@return const reference to the element at key @a key2010220103@pre The element with key @a key must exist. **This precondition is20104enforced with an assertion.**2010520106@throw type_error.305 if the JSON value is not an object; in that case,20107using the [] operator with a key makes no sense.2010820109@complexity Logarithmic in the size of the container.2011020111@liveexample{The example below shows how object elements can be read using20112the `[]` operator.,operatorarray__key_type_const}2011320114@sa @ref at(const typename object_t::key_type&) for access by reference20115with range checking20116@sa @ref value() for access by value with a default value2011720118@since version 1.0.020119*/20120const_reference operator[](const typename object_t::key_type& key) const20121{20122// const operator[] only works for objects20123if (JSON_HEDLEY_LIKELY(is_object()))20124{20125JSON_ASSERT(m_value.object->find(key) != m_value.object->end());20126return m_value.object->find(key)->second;20127}2012820129JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));20130}2013120132/*!20133@brief access specified object element2013420135Returns a reference to the element at with specified key @a key.2013620137@note If @a key is not found in the object, then it is silently added to20138the object and filled with a `null` value to make `key` a valid reference.20139In case the value was `null` before, it is converted to an object.2014020141@param[in] key key of the element to access2014220143@return reference to the element at key @a key2014420145@throw type_error.305 if the JSON value is not an object or null; in that20146cases, using the [] operator with a key makes no sense.2014720148@complexity Logarithmic in the size of the container.2014920150@liveexample{The example below shows how object elements can be read and20151written using the `[]` operator.,operatorarray__key_type}2015220153@sa @ref at(const typename object_t::key_type&) for access by reference20154with range checking20155@sa @ref value() for access by value with a default value2015620157@since version 1.1.020158*/20159template<typename T>20160JSON_HEDLEY_NON_NULL(2)20161reference operator[](T* key)20162{20163// implicitly convert null to object20164if (is_null())20165{20166m_type = value_t::object;20167m_value = value_t::object;20168assert_invariant();20169}2017020171// at only works for objects20172if (JSON_HEDLEY_LIKELY(is_object()))20173{20174return m_value.object->operator[](key);20175}2017620177JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));20178}2017920180/*!20181@brief read-only access specified object element2018220183Returns a const reference to the element at with specified key @a key. No20184bounds checking is performed.2018520186@warning If the element with key @a key does not exist, the behavior is20187undefined.2018820189@param[in] key key of the element to access2019020191@return const reference to the element at key @a key2019220193@pre The element with key @a key must exist. **This precondition is20194enforced with an assertion.**2019520196@throw type_error.305 if the JSON value is not an object; in that case,20197using the [] operator with a key makes no sense.2019820199@complexity Logarithmic in the size of the container.2020020201@liveexample{The example below shows how object elements can be read using20202the `[]` operator.,operatorarray__key_type_const}2020320204@sa @ref at(const typename object_t::key_type&) for access by reference20205with range checking20206@sa @ref value() for access by value with a default value2020720208@since version 1.1.020209*/20210template<typename T>20211JSON_HEDLEY_NON_NULL(2)20212const_reference operator[](T* key) const20213{20214// at only works for objects20215if (JSON_HEDLEY_LIKELY(is_object()))20216{20217JSON_ASSERT(m_value.object->find(key) != m_value.object->end());20218return m_value.object->find(key)->second;20219}2022020221JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));20222}2022320224/*!20225@brief access specified object element with default value2022620227Returns either a copy of an object's element at the specified key @a key20228or a given default value if no element with key @a key exists.2022920230The function is basically equivalent to executing20231@code {.cpp}20232try {20233return at(key);20234} catch(out_of_range) {20235return default_value;20236}20237@endcode2023820239@note Unlike @ref at(const typename object_t::key_type&), this function20240does not throw if the given key @a key was not found.2024120242@note Unlike @ref operator[](const typename object_t::key_type& key), this20243function does not implicitly add an element to the position defined by @a20244key. This function is furthermore also applicable to const objects.2024520246@param[in] key key of the element to access20247@param[in] default_value the value to return if @a key is not found2024820249@tparam ValueType type compatible to JSON values, for instance `int` for20250JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for20251JSON arrays. Note the type of the expected value at @a key and the default20252value @a default_value must be compatible.2025320254@return copy of the element at key @a key or @a default_value if @a key20255is not found2025620257@throw type_error.302 if @a default_value does not match the type of the20258value at @a key20259@throw type_error.306 if the JSON value is not an object; in that case,20260using `value()` with a key makes no sense.2026120262@complexity Logarithmic in the size of the container.2026320264@liveexample{The example below shows how object elements can be queried20265with a default value.,basic_json__value}2026620267@sa @ref at(const typename object_t::key_type&) for access by reference20268with range checking20269@sa @ref operator[](const typename object_t::key_type&) for unchecked20270access by reference2027120272@since version 1.0.020273*/20274// using std::is_convertible in a std::enable_if will fail when using explicit conversions20275template < class ValueType, typename std::enable_if <20276detail::is_getable<basic_json_t, ValueType>::value20277&& !std::is_same<value_t, ValueType>::value, int >::type = 0 >20278ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const20279{20280// at only works for objects20281if (JSON_HEDLEY_LIKELY(is_object()))20282{20283// if key is found, return value and given default value otherwise20284const auto it = find(key);20285if (it != end())20286{20287return it->template get<ValueType>();20288}2028920290return default_value;20291}2029220293JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));20294}2029520296/*!20297@brief overload for a default value of type const char*20298@copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const20299*/20300string_t value(const typename object_t::key_type& key, const char* default_value) const20301{20302return value(key, string_t(default_value));20303}2030420305/*!20306@brief access specified object element via JSON Pointer with default value2030720308Returns either a copy of an object's element at the specified key @a key20309or a given default value if no element with key @a key exists.2031020311The function is basically equivalent to executing20312@code {.cpp}20313try {20314return at(ptr);20315} catch(out_of_range) {20316return default_value;20317}20318@endcode2031920320@note Unlike @ref at(const json_pointer&), this function does not throw20321if the given key @a key was not found.2032220323@param[in] ptr a JSON pointer to the element to access20324@param[in] default_value the value to return if @a ptr found no value2032520326@tparam ValueType type compatible to JSON values, for instance `int` for20327JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for20328JSON arrays. Note the type of the expected value at @a key and the default20329value @a default_value must be compatible.2033020331@return copy of the element at key @a key or @a default_value if @a key20332is not found2033320334@throw type_error.302 if @a default_value does not match the type of the20335value at @a ptr20336@throw type_error.306 if the JSON value is not an object; in that case,20337using `value()` with a key makes no sense.2033820339@complexity Logarithmic in the size of the container.2034020341@liveexample{The example below shows how object elements can be queried20342with a default value.,basic_json__value_ptr}2034320344@sa @ref operator[](const json_pointer&) for unchecked access by reference2034520346@since version 2.0.220347*/20348template<class ValueType, typename std::enable_if<20349detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>20350ValueType value(const json_pointer& ptr, const ValueType& default_value) const20351{20352// at only works for objects20353if (JSON_HEDLEY_LIKELY(is_object()))20354{20355// if pointer resolves a value, return it or use default value20356JSON_TRY20357{20358return ptr.get_checked(this).template get<ValueType>();20359}20360JSON_INTERNAL_CATCH (out_of_range&)20361{20362return default_value;20363}20364}2036520366JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));20367}2036820369/*!20370@brief overload for a default value of type const char*20371@copydoc basic_json::value(const json_pointer&, ValueType) const20372*/20373JSON_HEDLEY_NON_NULL(3)20374string_t value(const json_pointer& ptr, const char* default_value) const20375{20376return value(ptr, string_t(default_value));20377}2037820379/*!20380@brief access the first element2038120382Returns a reference to the first element in the container. For a JSON20383container `c`, the expression `c.front()` is equivalent to `*c.begin()`.2038420385@return In case of a structured type (array or object), a reference to the20386first element is returned. In case of number, string, boolean, or binary20387values, a reference to the value is returned.2038820389@complexity Constant.2039020391@pre The JSON value must not be `null` (would throw `std::out_of_range`)20392or an empty array or object (undefined behavior, **guarded by20393assertions**).20394@post The JSON value remains unchanged.2039520396@throw invalid_iterator.214 when called on `null` value2039720398@liveexample{The following code shows an example for `front()`.,front}2039920400@sa @ref back() -- access the last element2040120402@since version 1.0.020403*/20404reference front()20405{20406return *begin();20407}2040820409/*!20410@copydoc basic_json::front()20411*/20412const_reference front() const20413{20414return *cbegin();20415}2041620417/*!20418@brief access the last element2041920420Returns a reference to the last element in the container. For a JSON20421container `c`, the expression `c.back()` is equivalent to20422@code {.cpp}20423auto tmp = c.end();20424--tmp;20425return *tmp;20426@endcode2042720428@return In case of a structured type (array or object), a reference to the20429last element is returned. In case of number, string, boolean, or binary20430values, a reference to the value is returned.2043120432@complexity Constant.2043320434@pre The JSON value must not be `null` (would throw `std::out_of_range`)20435or an empty array or object (undefined behavior, **guarded by20436assertions**).20437@post The JSON value remains unchanged.2043820439@throw invalid_iterator.214 when called on a `null` value. See example20440below.2044120442@liveexample{The following code shows an example for `back()`.,back}2044320444@sa @ref front() -- access the first element2044520446@since version 1.0.020447*/20448reference back()20449{20450auto tmp = end();20451--tmp;20452return *tmp;20453}2045420455/*!20456@copydoc basic_json::back()20457*/20458const_reference back() const20459{20460auto tmp = cend();20461--tmp;20462return *tmp;20463}2046420465/*!20466@brief remove element given an iterator2046720468Removes the element specified by iterator @a pos. The iterator @a pos must20469be valid and dereferenceable. Thus the `end()` iterator (which is valid,20470but is not dereferenceable) cannot be used as a value for @a pos.2047120472If called on a primitive type other than `null`, the resulting JSON value20473will be `null`.2047420475@param[in] pos iterator to the element to remove20476@return Iterator following the last removed element. If the iterator @a20477pos refers to the last element, the `end()` iterator is returned.2047820479@tparam IteratorType an @ref iterator or @ref const_iterator2048020481@post Invalidates iterators and references at or after the point of the20482erase, including the `end()` iterator.2048320484@throw type_error.307 if called on a `null` value; example: `"cannot use20485erase() with null"`20486@throw invalid_iterator.202 if called on an iterator which does not belong20487to the current JSON value; example: `"iterator does not fit current20488value"`20489@throw invalid_iterator.205 if called on a primitive type with invalid20490iterator (i.e., any iterator which is not `begin()`); example: `"iterator20491out of range"`2049220493@complexity The complexity depends on the type:20494- objects: amortized constant20495- arrays: linear in distance between @a pos and the end of the container20496- strings and binary: linear in the length of the member20497- other types: constant2049820499@liveexample{The example shows the result of `erase()` for different JSON20500types.,erase__IteratorType}2050120502@sa @ref erase(IteratorType, IteratorType) -- removes the elements in20503the given range20504@sa @ref erase(const typename object_t::key_type&) -- removes the element20505from an object at the given key20506@sa @ref erase(const size_type) -- removes the element from an array at20507the given index2050820509@since version 1.0.020510*/20511template < class IteratorType, typename std::enable_if <20512std::is_same<IteratorType, typename basic_json_t::iterator>::value ||20513std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type20514= 0 >20515IteratorType erase(IteratorType pos)20516{20517// make sure iterator fits the current value20518if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))20519{20520JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));20521}2052220523IteratorType result = end();2052420525switch (m_type)20526{20527case value_t::boolean:20528case value_t::number_float:20529case value_t::number_integer:20530case value_t::number_unsigned:20531case value_t::string:20532case value_t::binary:20533{20534if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))20535{20536JSON_THROW(invalid_iterator::create(205, "iterator out of range"));20537}2053820539if (is_string())20540{20541AllocatorType<string_t> alloc;20542std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);20543std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);20544m_value.string = nullptr;20545}20546else if (is_binary())20547{20548AllocatorType<binary_t> alloc;20549std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);20550std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);20551m_value.binary = nullptr;20552}2055320554m_type = value_t::null;20555assert_invariant();20556break;20557}2055820559case value_t::object:20560{20561result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);20562break;20563}2056420565case value_t::array:20566{20567result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);20568break;20569}2057020571default:20572JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));20573}2057420575return result;20576}2057720578/*!20579@brief remove elements given an iterator range2058020581Removes the element specified by the range `[first; last)`. The iterator20582@a first does not need to be dereferenceable if `first == last`: erasing20583an empty range is a no-op.2058420585If called on a primitive type other than `null`, the resulting JSON value20586will be `null`.2058720588@param[in] first iterator to the beginning of the range to remove20589@param[in] last iterator past the end of the range to remove20590@return Iterator following the last removed element. If the iterator @a20591second refers to the last element, the `end()` iterator is returned.2059220593@tparam IteratorType an @ref iterator or @ref const_iterator2059420595@post Invalidates iterators and references at or after the point of the20596erase, including the `end()` iterator.2059720598@throw type_error.307 if called on a `null` value; example: `"cannot use20599erase() with null"`20600@throw invalid_iterator.203 if called on iterators which does not belong20601to the current JSON value; example: `"iterators do not fit current value"`20602@throw invalid_iterator.204 if called on a primitive type with invalid20603iterators (i.e., if `first != begin()` and `last != end()`); example:20604`"iterators out of range"`2060520606@complexity The complexity depends on the type:20607- objects: `log(size()) + std::distance(first, last)`20608- arrays: linear in the distance between @a first and @a last, plus linear20609in the distance between @a last and end of the container20610- strings and binary: linear in the length of the member20611- other types: constant2061220613@liveexample{The example shows the result of `erase()` for different JSON20614types.,erase__IteratorType_IteratorType}2061520616@sa @ref erase(IteratorType) -- removes the element at a given position20617@sa @ref erase(const typename object_t::key_type&) -- removes the element20618from an object at the given key20619@sa @ref erase(const size_type) -- removes the element from an array at20620the given index2062120622@since version 1.0.020623*/20624template < class IteratorType, typename std::enable_if <20625std::is_same<IteratorType, typename basic_json_t::iterator>::value ||20626std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type20627= 0 >20628IteratorType erase(IteratorType first, IteratorType last)20629{20630// make sure iterator fits the current value20631if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))20632{20633JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));20634}2063520636IteratorType result = end();2063720638switch (m_type)20639{20640case value_t::boolean:20641case value_t::number_float:20642case value_t::number_integer:20643case value_t::number_unsigned:20644case value_t::string:20645case value_t::binary:20646{20647if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()20648|| !last.m_it.primitive_iterator.is_end()))20649{20650JSON_THROW(invalid_iterator::create(204, "iterators out of range"));20651}2065220653if (is_string())20654{20655AllocatorType<string_t> alloc;20656std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);20657std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);20658m_value.string = nullptr;20659}20660else if (is_binary())20661{20662AllocatorType<binary_t> alloc;20663std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);20664std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);20665m_value.binary = nullptr;20666}2066720668m_type = value_t::null;20669assert_invariant();20670break;20671}2067220673case value_t::object:20674{20675result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,20676last.m_it.object_iterator);20677break;20678}2067920680case value_t::array:20681{20682result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,20683last.m_it.array_iterator);20684break;20685}2068620687default:20688JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));20689}2069020691return result;20692}2069320694/*!20695@brief remove element from a JSON object given a key2069620697Removes elements from a JSON object with the key value @a key.2069820699@param[in] key value of the elements to remove2070020701@return Number of elements removed. If @a ObjectType is the default20702`std::map` type, the return value will always be `0` (@a key was not20703found) or `1` (@a key was found).2070420705@post References and iterators to the erased elements are invalidated.20706Other references and iterators are not affected.2070720708@throw type_error.307 when called on a type other than JSON object;20709example: `"cannot use erase() with null"`2071020711@complexity `log(size()) + count(key)`2071220713@liveexample{The example shows the effect of `erase()`.,erase__key_type}2071420715@sa @ref erase(IteratorType) -- removes the element at a given position20716@sa @ref erase(IteratorType, IteratorType) -- removes the elements in20717the given range20718@sa @ref erase(const size_type) -- removes the element from an array at20719the given index2072020721@since version 1.0.020722*/20723size_type erase(const typename object_t::key_type& key)20724{20725// this erase only works for objects20726if (JSON_HEDLEY_LIKELY(is_object()))20727{20728return m_value.object->erase(key);20729}2073020731JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));20732}2073320734/*!20735@brief remove element from a JSON array given an index2073620737Removes element from a JSON array at the index @a idx.2073820739@param[in] idx index of the element to remove2074020741@throw type_error.307 when called on a type other than JSON object;20742example: `"cannot use erase() with null"`20743@throw out_of_range.401 when `idx >= size()`; example: `"array index 1720744is out of range"`2074520746@complexity Linear in distance between @a idx and the end of the container.2074720748@liveexample{The example shows the effect of `erase()`.,erase__size_type}2074920750@sa @ref erase(IteratorType) -- removes the element at a given position20751@sa @ref erase(IteratorType, IteratorType) -- removes the elements in20752the given range20753@sa @ref erase(const typename object_t::key_type&) -- removes the element20754from an object at the given key2075520756@since version 1.0.020757*/20758void erase(const size_type idx)20759{20760// this erase only works for arrays20761if (JSON_HEDLEY_LIKELY(is_array()))20762{20763if (JSON_HEDLEY_UNLIKELY(idx >= size()))20764{20765JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));20766}2076720768m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));20769}20770else20771{20772JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));20773}20774}2077520776/// @}207772077820779////////////20780// lookup //20781////////////2078220783/// @name lookup20784/// @{2078520786/*!20787@brief find an element in a JSON object2078820789Finds an element in a JSON object with key equivalent to @a key. If the20790element is not found or the JSON value is not an object, end() is20791returned.2079220793@note This method always returns @ref end() when executed on a JSON type20794that is not an object.2079520796@param[in] key key value of the element to search for.2079720798@return Iterator to an element with key equivalent to @a key. If no such20799element is found or the JSON value is not an object, past-the-end (see20800@ref end()) iterator is returned.2080120802@complexity Logarithmic in the size of the JSON object.2080320804@liveexample{The example shows how `find()` is used.,find__key_type}2080520806@sa @ref contains(KeyT&&) const -- checks whether a key exists2080720808@since version 1.0.020809*/20810template<typename KeyT>20811iterator find(KeyT&& key)20812{20813auto result = end();2081420815if (is_object())20816{20817result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));20818}2081920820return result;20821}2082220823/*!20824@brief find an element in a JSON object20825@copydoc find(KeyT&&)20826*/20827template<typename KeyT>20828const_iterator find(KeyT&& key) const20829{20830auto result = cend();2083120832if (is_object())20833{20834result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));20835}2083620837return result;20838}2083920840/*!20841@brief returns the number of occurrences of a key in a JSON object2084220843Returns the number of elements with key @a key. If ObjectType is the20844default `std::map` type, the return value will always be `0` (@a key was20845not found) or `1` (@a key was found).2084620847@note This method always returns `0` when executed on a JSON type that is20848not an object.2084920850@param[in] key key value of the element to count2085120852@return Number of elements with key @a key. If the JSON value is not an20853object, the return value will be `0`.2085420855@complexity Logarithmic in the size of the JSON object.2085620857@liveexample{The example shows how `count()` is used.,count}2085820859@since version 1.0.020860*/20861template<typename KeyT>20862size_type count(KeyT&& key) const20863{20864// return 0 for all nonobject types20865return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;20866}2086720868/*!20869@brief check the existence of an element in a JSON object2087020871Check whether an element exists in a JSON object with key equivalent to20872@a key. If the element is not found or the JSON value is not an object,20873false is returned.2087420875@note This method always returns false when executed on a JSON type20876that is not an object.2087720878@param[in] key key value to check its existence.2087920880@return true if an element with specified @a key exists. If no such20881element with such key is found or the JSON value is not an object,20882false is returned.2088320884@complexity Logarithmic in the size of the JSON object.2088520886@liveexample{The following code shows an example for `contains()`.,contains}2088720888@sa @ref find(KeyT&&) -- returns an iterator to an object element20889@sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer2089020891@since version 3.6.020892*/20893template < typename KeyT, typename std::enable_if <20894!std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >20895bool contains(KeyT && key) const20896{20897return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();20898}2089920900/*!20901@brief check the existence of an element in a JSON object given a JSON pointer2090220903Check whether the given JSON pointer @a ptr can be resolved in the current20904JSON value.2090520906@note This method can be executed on any JSON value type.2090720908@param[in] ptr JSON pointer to check its existence.2090920910@return true if the JSON pointer can be resolved to a stored value, false20911otherwise.2091220913@post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.2091420915@throw parse_error.106 if an array index begins with '0'20916@throw parse_error.109 if an array index was not a number2091720918@complexity Logarithmic in the size of the JSON object.2091920920@liveexample{The following code shows an example for `contains()`.,contains_json_pointer}2092120922@sa @ref contains(KeyT &&) const -- checks the existence of a key2092320924@since version 3.7.020925*/20926bool contains(const json_pointer& ptr) const20927{20928return ptr.contains(this);20929}2093020931/// @}209322093320934///////////////20935// iterators //20936///////////////2093720938/// @name iterators20939/// @{2094020941/*!20942@brief returns an iterator to the first element2094320944Returns an iterator to the first element.2094520946@image html range-begin-end.svg "Illustration from cppreference.com"2094720948@return iterator to the first element2094920950@complexity Constant.2095120952@requirement This function helps `basic_json` satisfying the20953[Container](https://en.cppreference.com/w/cpp/named_req/Container)20954requirements:20955- The complexity is constant.2095620957@liveexample{The following code shows an example for `begin()`.,begin}2095820959@sa @ref cbegin() -- returns a const iterator to the beginning20960@sa @ref end() -- returns an iterator to the end20961@sa @ref cend() -- returns a const iterator to the end2096220963@since version 1.0.020964*/20965iterator begin() noexcept20966{20967iterator result(this);20968result.set_begin();20969return result;20970}2097120972/*!20973@copydoc basic_json::cbegin()20974*/20975const_iterator begin() const noexcept20976{20977return cbegin();20978}2097920980/*!20981@brief returns a const iterator to the first element2098220983Returns a const iterator to the first element.2098420985@image html range-begin-end.svg "Illustration from cppreference.com"2098620987@return const iterator to the first element2098820989@complexity Constant.2099020991@requirement This function helps `basic_json` satisfying the20992[Container](https://en.cppreference.com/w/cpp/named_req/Container)20993requirements:20994- The complexity is constant.20995- Has the semantics of `const_cast<const basic_json&>(*this).begin()`.2099620997@liveexample{The following code shows an example for `cbegin()`.,cbegin}2099820999@sa @ref begin() -- returns an iterator to the beginning21000@sa @ref end() -- returns an iterator to the end21001@sa @ref cend() -- returns a const iterator to the end2100221003@since version 1.0.021004*/21005const_iterator cbegin() const noexcept21006{21007const_iterator result(this);21008result.set_begin();21009return result;21010}2101121012/*!21013@brief returns an iterator to one past the last element2101421015Returns an iterator to one past the last element.2101621017@image html range-begin-end.svg "Illustration from cppreference.com"2101821019@return iterator one past the last element2102021021@complexity Constant.2102221023@requirement This function helps `basic_json` satisfying the21024[Container](https://en.cppreference.com/w/cpp/named_req/Container)21025requirements:21026- The complexity is constant.2102721028@liveexample{The following code shows an example for `end()`.,end}2102921030@sa @ref cend() -- returns a const iterator to the end21031@sa @ref begin() -- returns an iterator to the beginning21032@sa @ref cbegin() -- returns a const iterator to the beginning2103321034@since version 1.0.021035*/21036iterator end() noexcept21037{21038iterator result(this);21039result.set_end();21040return result;21041}2104221043/*!21044@copydoc basic_json::cend()21045*/21046const_iterator end() const noexcept21047{21048return cend();21049}2105021051/*!21052@brief returns a const iterator to one past the last element2105321054Returns a const iterator to one past the last element.2105521056@image html range-begin-end.svg "Illustration from cppreference.com"2105721058@return const iterator one past the last element2105921060@complexity Constant.2106121062@requirement This function helps `basic_json` satisfying the21063[Container](https://en.cppreference.com/w/cpp/named_req/Container)21064requirements:21065- The complexity is constant.21066- Has the semantics of `const_cast<const basic_json&>(*this).end()`.2106721068@liveexample{The following code shows an example for `cend()`.,cend}2106921070@sa @ref end() -- returns an iterator to the end21071@sa @ref begin() -- returns an iterator to the beginning21072@sa @ref cbegin() -- returns a const iterator to the beginning2107321074@since version 1.0.021075*/21076const_iterator cend() const noexcept21077{21078const_iterator result(this);21079result.set_end();21080return result;21081}2108221083/*!21084@brief returns an iterator to the reverse-beginning2108521086Returns an iterator to the reverse-beginning; that is, the last element.2108721088@image html range-rbegin-rend.svg "Illustration from cppreference.com"2108921090@complexity Constant.2109121092@requirement This function helps `basic_json` satisfying the21093[ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)21094requirements:21095- The complexity is constant.21096- Has the semantics of `reverse_iterator(end())`.2109721098@liveexample{The following code shows an example for `rbegin()`.,rbegin}2109921100@sa @ref crbegin() -- returns a const reverse iterator to the beginning21101@sa @ref rend() -- returns a reverse iterator to the end21102@sa @ref crend() -- returns a const reverse iterator to the end2110321104@since version 1.0.021105*/21106reverse_iterator rbegin() noexcept21107{21108return reverse_iterator(end());21109}2111021111/*!21112@copydoc basic_json::crbegin()21113*/21114const_reverse_iterator rbegin() const noexcept21115{21116return crbegin();21117}2111821119/*!21120@brief returns an iterator to the reverse-end2112121122Returns an iterator to the reverse-end; that is, one before the first21123element.2112421125@image html range-rbegin-rend.svg "Illustration from cppreference.com"2112621127@complexity Constant.2112821129@requirement This function helps `basic_json` satisfying the21130[ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)21131requirements:21132- The complexity is constant.21133- Has the semantics of `reverse_iterator(begin())`.2113421135@liveexample{The following code shows an example for `rend()`.,rend}2113621137@sa @ref crend() -- returns a const reverse iterator to the end21138@sa @ref rbegin() -- returns a reverse iterator to the beginning21139@sa @ref crbegin() -- returns a const reverse iterator to the beginning2114021141@since version 1.0.021142*/21143reverse_iterator rend() noexcept21144{21145return reverse_iterator(begin());21146}2114721148/*!21149@copydoc basic_json::crend()21150*/21151const_reverse_iterator rend() const noexcept21152{21153return crend();21154}2115521156/*!21157@brief returns a const reverse iterator to the last element2115821159Returns a const iterator to the reverse-beginning; that is, the last21160element.2116121162@image html range-rbegin-rend.svg "Illustration from cppreference.com"2116321164@complexity Constant.2116521166@requirement This function helps `basic_json` satisfying the21167[ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)21168requirements:21169- The complexity is constant.21170- Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.2117121172@liveexample{The following code shows an example for `crbegin()`.,crbegin}2117321174@sa @ref rbegin() -- returns a reverse iterator to the beginning21175@sa @ref rend() -- returns a reverse iterator to the end21176@sa @ref crend() -- returns a const reverse iterator to the end2117721178@since version 1.0.021179*/21180const_reverse_iterator crbegin() const noexcept21181{21182return const_reverse_iterator(cend());21183}2118421185/*!21186@brief returns a const reverse iterator to one before the first2118721188Returns a const reverse iterator to the reverse-end; that is, one before21189the first element.2119021191@image html range-rbegin-rend.svg "Illustration from cppreference.com"2119221193@complexity Constant.2119421195@requirement This function helps `basic_json` satisfying the21196[ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)21197requirements:21198- The complexity is constant.21199- Has the semantics of `const_cast<const basic_json&>(*this).rend()`.2120021201@liveexample{The following code shows an example for `crend()`.,crend}2120221203@sa @ref rend() -- returns a reverse iterator to the end21204@sa @ref rbegin() -- returns a reverse iterator to the beginning21205@sa @ref crbegin() -- returns a const reverse iterator to the beginning2120621207@since version 1.0.021208*/21209const_reverse_iterator crend() const noexcept21210{21211return const_reverse_iterator(cbegin());21212}2121321214public:21215/*!21216@brief wrapper to access iterator member functions in range-based for2121721218This function allows to access @ref iterator::key() and @ref21219iterator::value() during range-based for loops. In these loops, a21220reference to the JSON values is returned, so there is no access to the21221underlying iterator.2122221223For loop without iterator_wrapper:2122421225@code{cpp}21226for (auto it = j_object.begin(); it != j_object.end(); ++it)21227{21228std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';21229}21230@endcode2123121232Range-based for loop without iterator proxy:2123321234@code{cpp}21235for (auto it : j_object)21236{21237// "it" is of type json::reference and has no key() member21238std::cout << "value: " << it << '\n';21239}21240@endcode2124121242Range-based for loop with iterator proxy:2124321244@code{cpp}21245for (auto it : json::iterator_wrapper(j_object))21246{21247std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';21248}21249@endcode2125021251@note When iterating over an array, `key()` will return the index of the21252element as string (see example).2125321254@param[in] ref reference to a JSON value21255@return iteration proxy object wrapping @a ref with an interface to use in21256range-based for loops2125721258@liveexample{The following code shows how the wrapper is used,iterator_wrapper}2125921260@exceptionsafety Strong guarantee: if an exception is thrown, there are no21261changes in the JSON value.2126221263@complexity Constant.2126421265@note The name of this function is not yet final and may change in the21266future.2126721268@deprecated This stream operator is deprecated and will be removed in21269future 4.0.0 of the library. Please use @ref items() instead;21270that is, replace `json::iterator_wrapper(j)` with `j.items()`.21271*/21272JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())21273static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept21274{21275return ref.items();21276}2127721278/*!21279@copydoc iterator_wrapper(reference)21280*/21281JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())21282static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept21283{21284return ref.items();21285}2128621287/*!21288@brief helper to access iterator member functions in range-based for2128921290This function allows to access @ref iterator::key() and @ref21291iterator::value() during range-based for loops. In these loops, a21292reference to the JSON values is returned, so there is no access to the21293underlying iterator.2129421295For loop without `items()` function:2129621297@code{cpp}21298for (auto it = j_object.begin(); it != j_object.end(); ++it)21299{21300std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';21301}21302@endcode2130321304Range-based for loop without `items()` function:2130521306@code{cpp}21307for (auto it : j_object)21308{21309// "it" is of type json::reference and has no key() member21310std::cout << "value: " << it << '\n';21311}21312@endcode2131321314Range-based for loop with `items()` function:2131521316@code{cpp}21317for (auto& el : j_object.items())21318{21319std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';21320}21321@endcode2132221323The `items()` function also allows to use21324[structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)21325(C++17):2132621327@code{cpp}21328for (auto& [key, val] : j_object.items())21329{21330std::cout << "key: " << key << ", value:" << val << '\n';21331}21332@endcode2133321334@note When iterating over an array, `key()` will return the index of the21335element as string (see example). For primitive types (e.g., numbers),21336`key()` returns an empty string.2133721338@warning Using `items()` on temporary objects is dangerous. Make sure the21339object's lifetime exeeds the iteration. See21340<https://github.com/nlohmann/json/issues/2040> for more21341information.2134221343@return iteration proxy object wrapping @a ref with an interface to use in21344range-based for loops2134521346@liveexample{The following code shows how the function is used.,items}2134721348@exceptionsafety Strong guarantee: if an exception is thrown, there are no21349changes in the JSON value.2135021351@complexity Constant.2135221353@since version 3.1.0, structured bindings support since 3.5.0.21354*/21355iteration_proxy<iterator> items() noexcept21356{21357return iteration_proxy<iterator>(*this);21358}2135921360/*!21361@copydoc items()21362*/21363iteration_proxy<const_iterator> items() const noexcept21364{21365return iteration_proxy<const_iterator>(*this);21366}2136721368/// @}213692137021371//////////////21372// capacity //21373//////////////2137421375/// @name capacity21376/// @{2137721378/*!21379@brief checks whether the container is empty.2138021381Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).2138221383@return The return value depends on the different types and is21384defined as follows:21385Value type | return value21386----------- | -------------21387null | `true`21388boolean | `false`21389string | `false`21390number | `false`21391binary | `false`21392object | result of function `object_t::empty()`21393array | result of function `array_t::empty()`2139421395@liveexample{The following code uses `empty()` to check if a JSON21396object contains any elements.,empty}2139721398@complexity Constant, as long as @ref array_t and @ref object_t satisfy21399the Container concept; that is, their `empty()` functions have constant21400complexity.2140121402@iterators No changes.2140321404@exceptionsafety No-throw guarantee: this function never throws exceptions.2140521406@note This function does not return whether a string stored as JSON value21407is empty - it returns whether the JSON container itself is empty which is21408false in the case of a string.2140921410@requirement This function helps `basic_json` satisfying the21411[Container](https://en.cppreference.com/w/cpp/named_req/Container)21412requirements:21413- The complexity is constant.21414- Has the semantics of `begin() == end()`.2141521416@sa @ref size() -- returns the number of elements2141721418@since version 1.0.021419*/21420bool empty() const noexcept21421{21422switch (m_type)21423{21424case value_t::null:21425{21426// null values are empty21427return true;21428}2142921430case value_t::array:21431{21432// delegate call to array_t::empty()21433return m_value.array->empty();21434}2143521436case value_t::object:21437{21438// delegate call to object_t::empty()21439return m_value.object->empty();21440}2144121442default:21443{21444// all other types are nonempty21445return false;21446}21447}21448}2144921450/*!21451@brief returns the number of elements2145221453Returns the number of elements in a JSON value.2145421455@return The return value depends on the different types and is21456defined as follows:21457Value type | return value21458----------- | -------------21459null | `0`21460boolean | `1`21461string | `1`21462number | `1`21463binary | `1`21464object | result of function object_t::size()21465array | result of function array_t::size()2146621467@liveexample{The following code calls `size()` on the different value21468types.,size}2146921470@complexity Constant, as long as @ref array_t and @ref object_t satisfy21471the Container concept; that is, their size() functions have constant21472complexity.2147321474@iterators No changes.2147521476@exceptionsafety No-throw guarantee: this function never throws exceptions.2147721478@note This function does not return the length of a string stored as JSON21479value - it returns the number of elements in the JSON value which is 1 in21480the case of a string.2148121482@requirement This function helps `basic_json` satisfying the21483[Container](https://en.cppreference.com/w/cpp/named_req/Container)21484requirements:21485- The complexity is constant.21486- Has the semantics of `std::distance(begin(), end())`.2148721488@sa @ref empty() -- checks whether the container is empty21489@sa @ref max_size() -- returns the maximal number of elements2149021491@since version 1.0.021492*/21493size_type size() const noexcept21494{21495switch (m_type)21496{21497case value_t::null:21498{21499// null values are empty21500return 0;21501}2150221503case value_t::array:21504{21505// delegate call to array_t::size()21506return m_value.array->size();21507}2150821509case value_t::object:21510{21511// delegate call to object_t::size()21512return m_value.object->size();21513}2151421515default:21516{21517// all other types have size 121518return 1;21519}21520}21521}2152221523/*!21524@brief returns the maximum possible number of elements2152521526Returns the maximum number of elements a JSON value is able to hold due to21527system or library implementation limitations, i.e. `std::distance(begin(),21528end())` for the JSON value.2152921530@return The return value depends on the different types and is21531defined as follows:21532Value type | return value21533----------- | -------------21534null | `0` (same as `size()`)21535boolean | `1` (same as `size()`)21536string | `1` (same as `size()`)21537number | `1` (same as `size()`)21538binary | `1` (same as `size()`)21539object | result of function `object_t::max_size()`21540array | result of function `array_t::max_size()`2154121542@liveexample{The following code calls `max_size()` on the different value21543types. Note the output is implementation specific.,max_size}2154421545@complexity Constant, as long as @ref array_t and @ref object_t satisfy21546the Container concept; that is, their `max_size()` functions have constant21547complexity.2154821549@iterators No changes.2155021551@exceptionsafety No-throw guarantee: this function never throws exceptions.2155221553@requirement This function helps `basic_json` satisfying the21554[Container](https://en.cppreference.com/w/cpp/named_req/Container)21555requirements:21556- The complexity is constant.21557- Has the semantics of returning `b.size()` where `b` is the largest21558possible JSON value.2155921560@sa @ref size() -- returns the number of elements2156121562@since version 1.0.021563*/21564size_type max_size() const noexcept21565{21566switch (m_type)21567{21568case value_t::array:21569{21570// delegate call to array_t::max_size()21571return m_value.array->max_size();21572}2157321574case value_t::object:21575{21576// delegate call to object_t::max_size()21577return m_value.object->max_size();21578}2157921580default:21581{21582// all other types have max_size() == size()21583return size();21584}21585}21586}2158721588/// @}215892159021591///////////////21592// modifiers //21593///////////////2159421595/// @name modifiers21596/// @{2159721598/*!21599@brief clears the contents2160021601Clears the content of a JSON value and resets it to the default value as21602if @ref basic_json(value_t) would have been called with the current value21603type from @ref type():2160421605Value type | initial value21606----------- | -------------21607null | `null`21608boolean | `false`21609string | `""`21610number | `0`21611binary | An empty byte vector21612object | `{}`21613array | `[]`2161421615@post Has the same effect as calling21616@code {.cpp}21617*this = basic_json(type());21618@endcode2161921620@liveexample{The example below shows the effect of `clear()` to different21621JSON types.,clear}2162221623@complexity Linear in the size of the JSON value.2162421625@iterators All iterators, pointers and references related to this container21626are invalidated.2162721628@exceptionsafety No-throw guarantee: this function never throws exceptions.2162921630@sa @ref basic_json(value_t) -- constructor that creates an object with the21631same value than calling `clear()`2163221633@since version 1.0.021634*/21635void clear() noexcept21636{21637switch (m_type)21638{21639case value_t::number_integer:21640{21641m_value.number_integer = 0;21642break;21643}2164421645case value_t::number_unsigned:21646{21647m_value.number_unsigned = 0;21648break;21649}2165021651case value_t::number_float:21652{21653m_value.number_float = 0.0;21654break;21655}2165621657case value_t::boolean:21658{21659m_value.boolean = false;21660break;21661}2166221663case value_t::string:21664{21665m_value.string->clear();21666break;21667}2166821669case value_t::binary:21670{21671m_value.binary->clear();21672break;21673}2167421675case value_t::array:21676{21677m_value.array->clear();21678break;21679}2168021681case value_t::object:21682{21683m_value.object->clear();21684break;21685}2168621687default:21688break;21689}21690}2169121692/*!21693@brief add an object to an array2169421695Appends the given element @a val to the end of the JSON value. If the21696function is called on a JSON null value, an empty array is created before21697appending @a val.2169821699@param[in] val the value to add to the JSON array2170021701@throw type_error.308 when called on a type other than JSON array or21702null; example: `"cannot use push_back() with number"`2170321704@complexity Amortized constant.2170521706@liveexample{The example shows how `push_back()` and `+=` can be used to21707add elements to a JSON array. Note how the `null` value was silently21708converted to a JSON array.,push_back}2170921710@since version 1.0.021711*/21712void push_back(basic_json&& val)21713{21714// push_back only works for null objects or arrays21715if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))21716{21717JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));21718}2171921720// transform null object into an array21721if (is_null())21722{21723m_type = value_t::array;21724m_value = value_t::array;21725assert_invariant();21726}2172721728// add element to array (move semantics)21729m_value.array->push_back(std::move(val));21730// if val is moved from, basic_json move constructor marks it null so we do not call the destructor21731}2173221733/*!21734@brief add an object to an array21735@copydoc push_back(basic_json&&)21736*/21737reference operator+=(basic_json&& val)21738{21739push_back(std::move(val));21740return *this;21741}2174221743/*!21744@brief add an object to an array21745@copydoc push_back(basic_json&&)21746*/21747void push_back(const basic_json& val)21748{21749// push_back only works for null objects or arrays21750if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))21751{21752JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));21753}2175421755// transform null object into an array21756if (is_null())21757{21758m_type = value_t::array;21759m_value = value_t::array;21760assert_invariant();21761}2176221763// add element to array21764m_value.array->push_back(val);21765}2176621767/*!21768@brief add an object to an array21769@copydoc push_back(basic_json&&)21770*/21771reference operator+=(const basic_json& val)21772{21773push_back(val);21774return *this;21775}2177621777/*!21778@brief add an object to an object2177921780Inserts the given element @a val to the JSON object. If the function is21781called on a JSON null value, an empty object is created before inserting21782@a val.2178321784@param[in] val the value to add to the JSON object2178521786@throw type_error.308 when called on a type other than JSON object or21787null; example: `"cannot use push_back() with number"`2178821789@complexity Logarithmic in the size of the container, O(log(`size()`)).2179021791@liveexample{The example shows how `push_back()` and `+=` can be used to21792add elements to a JSON object. Note how the `null` value was silently21793converted to a JSON object.,push_back__object_t__value}2179421795@since version 1.0.021796*/21797void push_back(const typename object_t::value_type& val)21798{21799// push_back only works for null objects or objects21800if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))21801{21802JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));21803}2180421805// transform null object into an object21806if (is_null())21807{21808m_type = value_t::object;21809m_value = value_t::object;21810assert_invariant();21811}2181221813// add element to array21814m_value.object->insert(val);21815}2181621817/*!21818@brief add an object to an object21819@copydoc push_back(const typename object_t::value_type&)21820*/21821reference operator+=(const typename object_t::value_type& val)21822{21823push_back(val);21824return *this;21825}2182621827/*!21828@brief add an object to an object2182921830This function allows to use `push_back` with an initializer list. In case21831218321. the current value is an object,218332. the initializer list @a init contains only two elements, and218343. the first element of @a init is a string,2183521836@a init is converted into an object element and added using21837@ref push_back(const typename object_t::value_type&). Otherwise, @a init21838is converted to a JSON value and added using @ref push_back(basic_json&&).2183921840@param[in] init an initializer list2184121842@complexity Linear in the size of the initializer list @a init.2184321844@note This function is required to resolve an ambiguous overload error,21845because pairs like `{"key", "value"}` can be both interpreted as21846`object_t::value_type` or `std::initializer_list<basic_json>`, see21847https://github.com/nlohmann/json/issues/235 for more information.2184821849@liveexample{The example shows how initializer lists are treated as21850objects when possible.,push_back__initializer_list}21851*/21852void push_back(initializer_list_t init)21853{21854if (is_object() && init.size() == 2 && (*init.begin())->is_string())21855{21856basic_json&& key = init.begin()->moved_or_copied();21857push_back(typename object_t::value_type(21858std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));21859}21860else21861{21862push_back(basic_json(init));21863}21864}2186521866/*!21867@brief add an object to an object21868@copydoc push_back(initializer_list_t)21869*/21870reference operator+=(initializer_list_t init)21871{21872push_back(init);21873return *this;21874}2187521876/*!21877@brief add an object to an array2187821879Creates a JSON value from the passed parameters @a args to the end of the21880JSON value. If the function is called on a JSON null value, an empty array21881is created before appending the value created from @a args.2188221883@param[in] args arguments to forward to a constructor of @ref basic_json21884@tparam Args compatible types to create a @ref basic_json object2188521886@return reference to the inserted element2188721888@throw type_error.311 when called on a type other than JSON array or21889null; example: `"cannot use emplace_back() with number"`2189021891@complexity Amortized constant.2189221893@liveexample{The example shows how `push_back()` can be used to add21894elements to a JSON array. Note how the `null` value was silently converted21895to a JSON array.,emplace_back}2189621897@since version 2.0.8, returns reference since 3.7.021898*/21899template<class... Args>21900reference emplace_back(Args&& ... args)21901{21902// emplace_back only works for null objects or arrays21903if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))21904{21905JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));21906}2190721908// transform null object into an array21909if (is_null())21910{21911m_type = value_t::array;21912m_value = value_t::array;21913assert_invariant();21914}2191521916// add element to array (perfect forwarding)21917#ifdef JSON_HAS_CPP_1721918return m_value.array->emplace_back(std::forward<Args>(args)...);21919#else21920m_value.array->emplace_back(std::forward<Args>(args)...);21921return m_value.array->back();21922#endif21923}2192421925/*!21926@brief add an object to an object if key does not exist2192721928Inserts a new element into a JSON object constructed in-place with the21929given @a args if there is no element with the key in the container. If the21930function is called on a JSON null value, an empty object is created before21931appending the value created from @a args.2193221933@param[in] args arguments to forward to a constructor of @ref basic_json21934@tparam Args compatible types to create a @ref basic_json object2193521936@return a pair consisting of an iterator to the inserted element, or the21937already-existing element if no insertion happened, and a bool21938denoting whether the insertion took place.2193921940@throw type_error.311 when called on a type other than JSON object or21941null; example: `"cannot use emplace() with number"`2194221943@complexity Logarithmic in the size of the container, O(log(`size()`)).2194421945@liveexample{The example shows how `emplace()` can be used to add elements21946to a JSON object. Note how the `null` value was silently converted to a21947JSON object. Further note how no value is added if there was already one21948value stored with the same key.,emplace}2194921950@since version 2.0.821951*/21952template<class... Args>21953std::pair<iterator, bool> emplace(Args&& ... args)21954{21955// emplace only works for null objects or arrays21956if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))21957{21958JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));21959}2196021961// transform null object into an object21962if (is_null())21963{21964m_type = value_t::object;21965m_value = value_t::object;21966assert_invariant();21967}2196821969// add element to array (perfect forwarding)21970auto res = m_value.object->emplace(std::forward<Args>(args)...);21971// create result iterator and set iterator to the result of emplace21972auto it = begin();21973it.m_it.object_iterator = res.first;2197421975// return pair of iterator and boolean21976return {it, res.second};21977}2197821979/// Helper for insertion of an iterator21980/// @note: This uses std::distance to support GCC 4.8,21981/// see https://github.com/nlohmann/json/pull/125721982template<typename... Args>21983iterator insert_iterator(const_iterator pos, Args&& ... args)21984{21985iterator result(this);21986JSON_ASSERT(m_value.array != nullptr);2198721988auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);21989m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);21990result.m_it.array_iterator = m_value.array->begin() + insert_pos;2199121992// This could have been written as:21993// result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);21994// but the return value of insert is missing in GCC 4.8, so it is written this way instead.2199521996return result;21997}2199821999/*!22000@brief inserts element2200122002Inserts element @a val before iterator @a pos.2200322004@param[in] pos iterator before which the content will be inserted; may be22005the end() iterator22006@param[in] val element to insert22007@return iterator pointing to the inserted @a val.2200822009@throw type_error.309 if called on JSON values other than arrays;22010example: `"cannot use insert() with string"`22011@throw invalid_iterator.202 if @a pos is not an iterator of *this;22012example: `"iterator does not fit current value"`2201322014@complexity Constant plus linear in the distance between @a pos and end of22015the container.2201622017@liveexample{The example shows how `insert()` is used.,insert}2201822019@since version 1.0.022020*/22021iterator insert(const_iterator pos, const basic_json& val)22022{22023// insert only works for arrays22024if (JSON_HEDLEY_LIKELY(is_array()))22025{22026// check if iterator pos fits to this JSON value22027if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))22028{22029JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));22030}2203122032// insert to array and return iterator22033return insert_iterator(pos, val);22034}2203522036JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));22037}2203822039/*!22040@brief inserts element22041@copydoc insert(const_iterator, const basic_json&)22042*/22043iterator insert(const_iterator pos, basic_json&& val)22044{22045return insert(pos, val);22046}2204722048/*!22049@brief inserts elements2205022051Inserts @a cnt copies of @a val before iterator @a pos.2205222053@param[in] pos iterator before which the content will be inserted; may be22054the end() iterator22055@param[in] cnt number of copies of @a val to insert22056@param[in] val element to insert22057@return iterator pointing to the first element inserted, or @a pos if22058`cnt==0`2205922060@throw type_error.309 if called on JSON values other than arrays; example:22061`"cannot use insert() with string"`22062@throw invalid_iterator.202 if @a pos is not an iterator of *this;22063example: `"iterator does not fit current value"`2206422065@complexity Linear in @a cnt plus linear in the distance between @a pos22066and end of the container.2206722068@liveexample{The example shows how `insert()` is used.,insert__count}2206922070@since version 1.0.022071*/22072iterator insert(const_iterator pos, size_type cnt, const basic_json& val)22073{22074// insert only works for arrays22075if (JSON_HEDLEY_LIKELY(is_array()))22076{22077// check if iterator pos fits to this JSON value22078if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))22079{22080JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));22081}2208222083// insert to array and return iterator22084return insert_iterator(pos, cnt, val);22085}2208622087JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));22088}2208922090/*!22091@brief inserts elements2209222093Inserts elements from range `[first, last)` before iterator @a pos.2209422095@param[in] pos iterator before which the content will be inserted; may be22096the end() iterator22097@param[in] first begin of the range of elements to insert22098@param[in] last end of the range of elements to insert2209922100@throw type_error.309 if called on JSON values other than arrays; example:22101`"cannot use insert() with string"`22102@throw invalid_iterator.202 if @a pos is not an iterator of *this;22103example: `"iterator does not fit current value"`22104@throw invalid_iterator.210 if @a first and @a last do not belong to the22105same JSON value; example: `"iterators do not fit"`22106@throw invalid_iterator.211 if @a first or @a last are iterators into22107container for which insert is called; example: `"passed iterators may not22108belong to container"`2210922110@return iterator pointing to the first element inserted, or @a pos if22111`first==last`2211222113@complexity Linear in `std::distance(first, last)` plus linear in the22114distance between @a pos and end of the container.2211522116@liveexample{The example shows how `insert()` is used.,insert__range}2211722118@since version 1.0.022119*/22120iterator insert(const_iterator pos, const_iterator first, const_iterator last)22121{22122// insert only works for arrays22123if (JSON_HEDLEY_UNLIKELY(!is_array()))22124{22125JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));22126}2212722128// check if iterator pos fits to this JSON value22129if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))22130{22131JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));22132}2213322134// check if range iterators belong to the same JSON object22135if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))22136{22137JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));22138}2213922140if (JSON_HEDLEY_UNLIKELY(first.m_object == this))22141{22142JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));22143}2214422145// insert to array and return iterator22146return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);22147}2214822149/*!22150@brief inserts elements2215122152Inserts elements from initializer list @a ilist before iterator @a pos.2215322154@param[in] pos iterator before which the content will be inserted; may be22155the end() iterator22156@param[in] ilist initializer list to insert the values from2215722158@throw type_error.309 if called on JSON values other than arrays; example:22159`"cannot use insert() with string"`22160@throw invalid_iterator.202 if @a pos is not an iterator of *this;22161example: `"iterator does not fit current value"`2216222163@return iterator pointing to the first element inserted, or @a pos if22164`ilist` is empty2216522166@complexity Linear in `ilist.size()` plus linear in the distance between22167@a pos and end of the container.2216822169@liveexample{The example shows how `insert()` is used.,insert__ilist}2217022171@since version 1.0.022172*/22173iterator insert(const_iterator pos, initializer_list_t ilist)22174{22175// insert only works for arrays22176if (JSON_HEDLEY_UNLIKELY(!is_array()))22177{22178JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));22179}2218022181// check if iterator pos fits to this JSON value22182if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))22183{22184JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));22185}2218622187// insert to array and return iterator22188return insert_iterator(pos, ilist.begin(), ilist.end());22189}2219022191/*!22192@brief inserts elements2219322194Inserts elements from range `[first, last)`.2219522196@param[in] first begin of the range of elements to insert22197@param[in] last end of the range of elements to insert2219822199@throw type_error.309 if called on JSON values other than objects; example:22200`"cannot use insert() with string"`22201@throw invalid_iterator.202 if iterator @a first or @a last does does not22202point to an object; example: `"iterators first and last must point to22203objects"`22204@throw invalid_iterator.210 if @a first and @a last do not belong to the22205same JSON value; example: `"iterators do not fit"`2220622207@complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number22208of elements to insert.2220922210@liveexample{The example shows how `insert()` is used.,insert__range_object}2221122212@since version 3.0.022213*/22214void insert(const_iterator first, const_iterator last)22215{22216// insert only works for objects22217if (JSON_HEDLEY_UNLIKELY(!is_object()))22218{22219JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));22220}2222122222// check if range iterators belong to the same JSON object22223if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))22224{22225JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));22226}2222722228// passed iterators must belong to objects22229if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))22230{22231JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));22232}2223322234m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);22235}2223622237/*!22238@brief updates a JSON object from another object, overwriting existing keys2223922240Inserts all values from JSON object @a j and overwrites existing keys.2224122242@param[in] j JSON object to read values from2224322244@throw type_error.312 if called on JSON values other than objects; example:22245`"cannot use update() with string"`2224622247@complexity O(N*log(size() + N)), where N is the number of elements to22248insert.2224922250@liveexample{The example shows how `update()` is used.,update}2225122252@sa https://docs.python.org/3.6/library/stdtypes.html#dict.update2225322254@since version 3.0.022255*/22256void update(const_reference j)22257{22258// implicitly convert null value to an empty object22259if (is_null())22260{22261m_type = value_t::object;22262m_value.object = create<object_t>();22263assert_invariant();22264}2226522266if (JSON_HEDLEY_UNLIKELY(!is_object()))22267{22268JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));22269}22270if (JSON_HEDLEY_UNLIKELY(!j.is_object()))22271{22272JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));22273}2227422275for (auto it = j.cbegin(); it != j.cend(); ++it)22276{22277m_value.object->operator[](it.key()) = it.value();22278}22279}2228022281/*!22282@brief updates a JSON object from another object, overwriting existing keys2228322284Inserts all values from from range `[first, last)` and overwrites existing22285keys.2228622287@param[in] first begin of the range of elements to insert22288@param[in] last end of the range of elements to insert2228922290@throw type_error.312 if called on JSON values other than objects; example:22291`"cannot use update() with string"`22292@throw invalid_iterator.202 if iterator @a first or @a last does does not22293point to an object; example: `"iterators first and last must point to22294objects"`22295@throw invalid_iterator.210 if @a first and @a last do not belong to the22296same JSON value; example: `"iterators do not fit"`2229722298@complexity O(N*log(size() + N)), where N is the number of elements to22299insert.2230022301@liveexample{The example shows how `update()` is used__range.,update}2230222303@sa https://docs.python.org/3.6/library/stdtypes.html#dict.update2230422305@since version 3.0.022306*/22307void update(const_iterator first, const_iterator last)22308{22309// implicitly convert null value to an empty object22310if (is_null())22311{22312m_type = value_t::object;22313m_value.object = create<object_t>();22314assert_invariant();22315}2231622317if (JSON_HEDLEY_UNLIKELY(!is_object()))22318{22319JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));22320}2232122322// check if range iterators belong to the same JSON object22323if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))22324{22325JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));22326}2232722328// passed iterators must belong to objects22329if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()22330|| !last.m_object->is_object()))22331{22332JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));22333}2233422335for (auto it = first; it != last; ++it)22336{22337m_value.object->operator[](it.key()) = it.value();22338}22339}2234022341/*!22342@brief exchanges the values2234322344Exchanges the contents of the JSON value with those of @a other. Does not22345invoke any move, copy, or swap operations on individual elements. All22346iterators and references remain valid. The past-the-end iterator is22347invalidated.2234822349@param[in,out] other JSON value to exchange the contents with2235022351@complexity Constant.2235222353@liveexample{The example below shows how JSON values can be swapped with22354`swap()`.,swap__reference}2235522356@since version 1.0.022357*/22358void swap(reference other) noexcept (22359std::is_nothrow_move_constructible<value_t>::value&&22360std::is_nothrow_move_assignable<value_t>::value&&22361std::is_nothrow_move_constructible<json_value>::value&&22362std::is_nothrow_move_assignable<json_value>::value22363)22364{22365std::swap(m_type, other.m_type);22366std::swap(m_value, other.m_value);22367assert_invariant();22368}2236922370/*!22371@brief exchanges the values2237222373Exchanges the contents of the JSON value from @a left with those of @a right. Does not22374invoke any move, copy, or swap operations on individual elements. All22375iterators and references remain valid. The past-the-end iterator is22376invalidated. implemented as a friend function callable via ADL.2237722378@param[in,out] left JSON value to exchange the contents with22379@param[in,out] right JSON value to exchange the contents with2238022381@complexity Constant.2238222383@liveexample{The example below shows how JSON values can be swapped with22384`swap()`.,swap__reference}2238522386@since version 1.0.022387*/22388friend void swap(reference left, reference right) noexcept (22389std::is_nothrow_move_constructible<value_t>::value&&22390std::is_nothrow_move_assignable<value_t>::value&&22391std::is_nothrow_move_constructible<json_value>::value&&22392std::is_nothrow_move_assignable<json_value>::value22393)22394{22395left.swap(right);22396}2239722398/*!22399@brief exchanges the values2240022401Exchanges the contents of a JSON array with those of @a other. Does not22402invoke any move, copy, or swap operations on individual elements. All22403iterators and references remain valid. The past-the-end iterator is22404invalidated.2240522406@param[in,out] other array to exchange the contents with2240722408@throw type_error.310 when JSON value is not an array; example: `"cannot22409use swap() with string"`2241022411@complexity Constant.2241222413@liveexample{The example below shows how arrays can be swapped with22414`swap()`.,swap__array_t}2241522416@since version 1.0.022417*/22418void swap(array_t& other)22419{22420// swap only works for arrays22421if (JSON_HEDLEY_LIKELY(is_array()))22422{22423std::swap(*(m_value.array), other);22424}22425else22426{22427JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));22428}22429}2243022431/*!22432@brief exchanges the values2243322434Exchanges the contents of a JSON object with those of @a other. Does not22435invoke any move, copy, or swap operations on individual elements. All22436iterators and references remain valid. The past-the-end iterator is22437invalidated.2243822439@param[in,out] other object to exchange the contents with2244022441@throw type_error.310 when JSON value is not an object; example:22442`"cannot use swap() with string"`2244322444@complexity Constant.2244522446@liveexample{The example below shows how objects can be swapped with22447`swap()`.,swap__object_t}2244822449@since version 1.0.022450*/22451void swap(object_t& other)22452{22453// swap only works for objects22454if (JSON_HEDLEY_LIKELY(is_object()))22455{22456std::swap(*(m_value.object), other);22457}22458else22459{22460JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));22461}22462}2246322464/*!22465@brief exchanges the values2246622467Exchanges the contents of a JSON string with those of @a other. Does not22468invoke any move, copy, or swap operations on individual elements. All22469iterators and references remain valid. The past-the-end iterator is22470invalidated.2247122472@param[in,out] other string to exchange the contents with2247322474@throw type_error.310 when JSON value is not a string; example: `"cannot22475use swap() with boolean"`2247622477@complexity Constant.2247822479@liveexample{The example below shows how strings can be swapped with22480`swap()`.,swap__string_t}2248122482@since version 1.0.022483*/22484void swap(string_t& other)22485{22486// swap only works for strings22487if (JSON_HEDLEY_LIKELY(is_string()))22488{22489std::swap(*(m_value.string), other);22490}22491else22492{22493JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));22494}22495}2249622497/*!22498@brief exchanges the values2249922500Exchanges the contents of a JSON string with those of @a other. Does not22501invoke any move, copy, or swap operations on individual elements. All22502iterators and references remain valid. The past-the-end iterator is22503invalidated.2250422505@param[in,out] other binary to exchange the contents with2250622507@throw type_error.310 when JSON value is not a string; example: `"cannot22508use swap() with boolean"`2250922510@complexity Constant.2251122512@liveexample{The example below shows how strings can be swapped with22513`swap()`.,swap__binary_t}2251422515@since version 3.8.022516*/22517void swap(binary_t& other)22518{22519// swap only works for strings22520if (JSON_HEDLEY_LIKELY(is_binary()))22521{22522std::swap(*(m_value.binary), other);22523}22524else22525{22526JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));22527}22528}2252922530/// @copydoc swap(binary_t)22531void swap(typename binary_t::container_type& other)22532{22533// swap only works for strings22534if (JSON_HEDLEY_LIKELY(is_binary()))22535{22536std::swap(*(m_value.binary), other);22537}22538else22539{22540JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));22541}22542}2254322544/// @}2254522546public:22547//////////////////////////////////////////22548// lexicographical comparison operators //22549//////////////////////////////////////////2255022551/// @name lexicographical comparison operators22552/// @{2255322554/*!22555@brief comparison: equal2255622557Compares two JSON values for equality according to the following rules:22558- Two JSON values are equal if (1) they are from the same type and (2)22559their stored values are the same according to their respective22560`operator==`.22561- Integer and floating-point numbers are automatically converted before22562comparison. Note that two NaN values are always treated as unequal.22563- Two JSON null values are equal.2256422565@note Floating-point inside JSON values numbers are compared with22566`json::number_float_t::operator==` which is `double::operator==` by22567default. To compare floating-point while respecting an epsilon, an alternative22568[comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)22569could be used, for instance22570@code {.cpp}22571template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>22572inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept22573{22574return std::abs(a - b) <= epsilon;22575}22576@endcode22577Or you can self-defined operator equal function like this:22578@code {.cpp}22579bool my_equal(const_reference lhs, const_reference rhs) {22580const auto lhs_type lhs.type();22581const auto rhs_type rhs.type();22582if (lhs_type == rhs_type) {22583switch(lhs_type)22584// self_defined case22585case value_t::number_float:22586return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();22587// other cases remain the same with the original22588...22589}22590...22591}22592@endcode2259322594@note NaN values never compare equal to themselves or to other NaN values.2259522596@param[in] lhs first JSON value to consider22597@param[in] rhs second JSON value to consider22598@return whether the values @a lhs and @a rhs are equal2259922600@exceptionsafety No-throw guarantee: this function never throws exceptions.2260122602@complexity Linear.2260322604@liveexample{The example demonstrates comparing several JSON22605types.,operator__equal}2260622607@since version 1.0.022608*/22609friend bool operator==(const_reference lhs, const_reference rhs) noexcept22610{22611const auto lhs_type = lhs.type();22612const auto rhs_type = rhs.type();2261322614if (lhs_type == rhs_type)22615{22616switch (lhs_type)22617{22618case value_t::array:22619return *lhs.m_value.array == *rhs.m_value.array;2262022621case value_t::object:22622return *lhs.m_value.object == *rhs.m_value.object;2262322624case value_t::null:22625return true;2262622627case value_t::string:22628return *lhs.m_value.string == *rhs.m_value.string;2262922630case value_t::boolean:22631return lhs.m_value.boolean == rhs.m_value.boolean;2263222633case value_t::number_integer:22634return lhs.m_value.number_integer == rhs.m_value.number_integer;2263522636case value_t::number_unsigned:22637return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;2263822639case value_t::number_float:22640return lhs.m_value.number_float == rhs.m_value.number_float;2264122642case value_t::binary:22643return *lhs.m_value.binary == *rhs.m_value.binary;2264422645default:22646return false;22647}22648}22649else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)22650{22651return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;22652}22653else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)22654{22655return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);22656}22657else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)22658{22659return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;22660}22661else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)22662{22663return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);22664}22665else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)22666{22667return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;22668}22669else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)22670{22671return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);22672}2267322674return false;22675}2267622677/*!22678@brief comparison: equal22679@copydoc operator==(const_reference, const_reference)22680*/22681template<typename ScalarType, typename std::enable_if<22682std::is_scalar<ScalarType>::value, int>::type = 0>22683friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept22684{22685return lhs == basic_json(rhs);22686}2268722688/*!22689@brief comparison: equal22690@copydoc operator==(const_reference, const_reference)22691*/22692template<typename ScalarType, typename std::enable_if<22693std::is_scalar<ScalarType>::value, int>::type = 0>22694friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept22695{22696return basic_json(lhs) == rhs;22697}2269822699/*!22700@brief comparison: not equal2270122702Compares two JSON values for inequality by calculating `not (lhs == rhs)`.2270322704@param[in] lhs first JSON value to consider22705@param[in] rhs second JSON value to consider22706@return whether the values @a lhs and @a rhs are not equal2270722708@complexity Linear.2270922710@exceptionsafety No-throw guarantee: this function never throws exceptions.2271122712@liveexample{The example demonstrates comparing several JSON22713types.,operator__notequal}2271422715@since version 1.0.022716*/22717friend bool operator!=(const_reference lhs, const_reference rhs) noexcept22718{22719return !(lhs == rhs);22720}2272122722/*!22723@brief comparison: not equal22724@copydoc operator!=(const_reference, const_reference)22725*/22726template<typename ScalarType, typename std::enable_if<22727std::is_scalar<ScalarType>::value, int>::type = 0>22728friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept22729{22730return lhs != basic_json(rhs);22731}2273222733/*!22734@brief comparison: not equal22735@copydoc operator!=(const_reference, const_reference)22736*/22737template<typename ScalarType, typename std::enable_if<22738std::is_scalar<ScalarType>::value, int>::type = 0>22739friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept22740{22741return basic_json(lhs) != rhs;22742}2274322744/*!22745@brief comparison: less than2274622747Compares whether one JSON value @a lhs is less than another JSON value @a22748rhs according to the following rules:22749- If @a lhs and @a rhs have the same type, the values are compared using22750the default `<` operator.22751- Integer and floating-point numbers are automatically converted before22752comparison22753- In case @a lhs and @a rhs have different types, the values are ignored22754and the order of the types is considered, see22755@ref operator<(const value_t, const value_t).2275622757@param[in] lhs first JSON value to consider22758@param[in] rhs second JSON value to consider22759@return whether @a lhs is less than @a rhs2276022761@complexity Linear.2276222763@exceptionsafety No-throw guarantee: this function never throws exceptions.2276422765@liveexample{The example demonstrates comparing several JSON22766types.,operator__less}2276722768@since version 1.0.022769*/22770friend bool operator<(const_reference lhs, const_reference rhs) noexcept22771{22772const auto lhs_type = lhs.type();22773const auto rhs_type = rhs.type();2277422775if (lhs_type == rhs_type)22776{22777switch (lhs_type)22778{22779case value_t::array:22780// note parentheses are necessary, see22781// https://github.com/nlohmann/json/issues/153022782return (*lhs.m_value.array) < (*rhs.m_value.array);2278322784case value_t::object:22785return (*lhs.m_value.object) < (*rhs.m_value.object);2278622787case value_t::null:22788return false;2278922790case value_t::string:22791return (*lhs.m_value.string) < (*rhs.m_value.string);2279222793case value_t::boolean:22794return (lhs.m_value.boolean) < (rhs.m_value.boolean);2279522796case value_t::number_integer:22797return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);2279822799case value_t::number_unsigned:22800return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);2280122802case value_t::number_float:22803return (lhs.m_value.number_float) < (rhs.m_value.number_float);2280422805case value_t::binary:22806return (*lhs.m_value.binary) < (*rhs.m_value.binary);2280722808default:22809return false;22810}22811}22812else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)22813{22814return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;22815}22816else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)22817{22818return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);22819}22820else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)22821{22822return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;22823}22824else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)22825{22826return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);22827}22828else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)22829{22830return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);22831}22832else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)22833{22834return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;22835}2283622837// We only reach this line if we cannot compare values. In that case,22838// we compare types. Note we have to call the operator explicitly,22839// because MSVC has problems otherwise.22840return operator<(lhs_type, rhs_type);22841}2284222843/*!22844@brief comparison: less than22845@copydoc operator<(const_reference, const_reference)22846*/22847template<typename ScalarType, typename std::enable_if<22848std::is_scalar<ScalarType>::value, int>::type = 0>22849friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept22850{22851return lhs < basic_json(rhs);22852}2285322854/*!22855@brief comparison: less than22856@copydoc operator<(const_reference, const_reference)22857*/22858template<typename ScalarType, typename std::enable_if<22859std::is_scalar<ScalarType>::value, int>::type = 0>22860friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept22861{22862return basic_json(lhs) < rhs;22863}2286422865/*!22866@brief comparison: less than or equal2286722868Compares whether one JSON value @a lhs is less than or equal to another22869JSON value by calculating `not (rhs < lhs)`.2287022871@param[in] lhs first JSON value to consider22872@param[in] rhs second JSON value to consider22873@return whether @a lhs is less than or equal to @a rhs2287422875@complexity Linear.2287622877@exceptionsafety No-throw guarantee: this function never throws exceptions.2287822879@liveexample{The example demonstrates comparing several JSON22880types.,operator__greater}2288122882@since version 1.0.022883*/22884friend bool operator<=(const_reference lhs, const_reference rhs) noexcept22885{22886return !(rhs < lhs);22887}2288822889/*!22890@brief comparison: less than or equal22891@copydoc operator<=(const_reference, const_reference)22892*/22893template<typename ScalarType, typename std::enable_if<22894std::is_scalar<ScalarType>::value, int>::type = 0>22895friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept22896{22897return lhs <= basic_json(rhs);22898}2289922900/*!22901@brief comparison: less than or equal22902@copydoc operator<=(const_reference, const_reference)22903*/22904template<typename ScalarType, typename std::enable_if<22905std::is_scalar<ScalarType>::value, int>::type = 0>22906friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept22907{22908return basic_json(lhs) <= rhs;22909}2291022911/*!22912@brief comparison: greater than2291322914Compares whether one JSON value @a lhs is greater than another22915JSON value by calculating `not (lhs <= rhs)`.2291622917@param[in] lhs first JSON value to consider22918@param[in] rhs second JSON value to consider22919@return whether @a lhs is greater than to @a rhs2292022921@complexity Linear.2292222923@exceptionsafety No-throw guarantee: this function never throws exceptions.2292422925@liveexample{The example demonstrates comparing several JSON22926types.,operator__lessequal}2292722928@since version 1.0.022929*/22930friend bool operator>(const_reference lhs, const_reference rhs) noexcept22931{22932return !(lhs <= rhs);22933}2293422935/*!22936@brief comparison: greater than22937@copydoc operator>(const_reference, const_reference)22938*/22939template<typename ScalarType, typename std::enable_if<22940std::is_scalar<ScalarType>::value, int>::type = 0>22941friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept22942{22943return lhs > basic_json(rhs);22944}2294522946/*!22947@brief comparison: greater than22948@copydoc operator>(const_reference, const_reference)22949*/22950template<typename ScalarType, typename std::enable_if<22951std::is_scalar<ScalarType>::value, int>::type = 0>22952friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept22953{22954return basic_json(lhs) > rhs;22955}2295622957/*!22958@brief comparison: greater than or equal2295922960Compares whether one JSON value @a lhs is greater than or equal to another22961JSON value by calculating `not (lhs < rhs)`.2296222963@param[in] lhs first JSON value to consider22964@param[in] rhs second JSON value to consider22965@return whether @a lhs is greater than or equal to @a rhs2296622967@complexity Linear.2296822969@exceptionsafety No-throw guarantee: this function never throws exceptions.2297022971@liveexample{The example demonstrates comparing several JSON22972types.,operator__greaterequal}2297322974@since version 1.0.022975*/22976friend bool operator>=(const_reference lhs, const_reference rhs) noexcept22977{22978return !(lhs < rhs);22979}2298022981/*!22982@brief comparison: greater than or equal22983@copydoc operator>=(const_reference, const_reference)22984*/22985template<typename ScalarType, typename std::enable_if<22986std::is_scalar<ScalarType>::value, int>::type = 0>22987friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept22988{22989return lhs >= basic_json(rhs);22990}2299122992/*!22993@brief comparison: greater than or equal22994@copydoc operator>=(const_reference, const_reference)22995*/22996template<typename ScalarType, typename std::enable_if<22997std::is_scalar<ScalarType>::value, int>::type = 0>22998friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept22999{23000return basic_json(lhs) >= rhs;23001}2300223003/// @}2300423005///////////////////23006// serialization //23007///////////////////2300823009/// @name serialization23010/// @{2301123012/*!23013@brief serialize to stream2301423015Serialize the given JSON value @a j to the output stream @a o. The JSON23016value will be serialized using the @ref dump member function.2301723018- The indentation of the output can be controlled with the member variable23019`width` of the output stream @a o. For instance, using the manipulator23020`std::setw(4)` on @a o sets the indentation level to `4` and the23021serialization result is the same as calling `dump(4)`.2302223023- The indentation character can be controlled with the member variable23024`fill` of the output stream @a o. For instance, the manipulator23025`std::setfill('\\t')` sets indentation to use a tab character rather than23026the default space character.2302723028@param[in,out] o stream to serialize to23029@param[in] j JSON value to serialize2303023031@return the stream @a o2303223033@throw type_error.316 if a string stored inside the JSON value is not23034UTF-8 encoded2303523036@complexity Linear.2303723038@liveexample{The example below shows the serialization with different23039parameters to `width` to adjust the indentation level.,operator_serialize}2304023041@since version 1.0.0; indentation character added in version 3.0.023042*/23043friend std::ostream& operator<<(std::ostream& o, const basic_json& j)23044{23045// read width member and use it as indentation parameter if nonzero23046const bool pretty_print = o.width() > 0;23047const auto indentation = pretty_print ? o.width() : 0;2304823049// reset width to 0 for subsequent calls to this stream23050o.width(0);2305123052// do the actual serialization23053serializer s(detail::output_adapter<char>(o), o.fill());23054s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));23055return o;23056}2305723058/*!23059@brief serialize to stream23060@deprecated This stream operator is deprecated and will be removed in23061future 4.0.0 of the library. Please use23062@ref operator<<(std::ostream&, const basic_json&)23063instead; that is, replace calls like `j >> o;` with `o << j;`.23064@since version 1.0.0; deprecated since version 3.0.023065*/23066JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))23067friend std::ostream& operator>>(const basic_json& j, std::ostream& o)23068{23069return o << j;23070}2307123072/// @}230732307423075/////////////////////23076// deserialization //23077/////////////////////2307823079/// @name deserialization23080/// @{2308123082/*!23083@brief deserialize from a compatible input2308423085@tparam InputType A compatible input, for instance23086- an std::istream object23087- a FILE pointer23088- a C-style array of characters23089- a pointer to a null-terminated string of single byte characters23090- an object obj for which begin(obj) and end(obj) produces a valid pair of23091iterators.2309223093@param[in] i input to read from23094@param[in] cb a parser callback function of type @ref parser_callback_t23095which is used to control the deserialization by filtering unwanted values23096(optional)23097@param[in] allow_exceptions whether to throw exceptions in case of a23098parse error (optional, true by default)23099@param[in] ignore_comments whether comments should be ignored and treated23100like whitespace (true) or yield a parse error (true); (optional, false by23101default)2310223103@return deserialized JSON value; in case of a parse error and23104@a allow_exceptions set to `false`, the return value will be23105value_t::discarded.2310623107@throw parse_error.101 if a parse error occurs; example: `""unexpected end23108of input; expected string literal""`23109@throw parse_error.102 if to_unicode fails or surrogate error23110@throw parse_error.103 if to_unicode fails2311123112@complexity Linear in the length of the input. The parser is a predictive23113LL(1) parser. The complexity can be higher if the parser callback function23114@a cb or reading from the input @a i has a super-linear complexity.2311523116@note A UTF-8 byte order mark is silently ignored.2311723118@liveexample{The example below demonstrates the `parse()` function reading23119from an array.,parse__array__parser_callback_t}2312023121@liveexample{The example below demonstrates the `parse()` function with23122and without callback function.,parse__string__parser_callback_t}2312323124@liveexample{The example below demonstrates the `parse()` function with23125and without callback function.,parse__istream__parser_callback_t}2312623127@liveexample{The example below demonstrates the `parse()` function reading23128from a contiguous container.,parse__contiguouscontainer__parser_callback_t}2312923130@since version 2.0.3 (contiguous containers); version 3.9.0 allowed to23131ignore comments.23132*/23133template<typename InputType>23134JSON_HEDLEY_WARN_UNUSED_RESULT23135static basic_json parse(InputType&& i,23136const parser_callback_t cb = nullptr,23137const bool allow_exceptions = true,23138const bool ignore_comments = false)23139{23140basic_json result;23141parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);23142return result;23143}2314423145/*!23146@brief deserialize from a pair of character iterators2314723148The value_type of the iterator must be a integral type with size of 1, 2 or231494 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.2315023151@param[in] first iterator to start of character range23152@param[in] last iterator to end of character range23153@param[in] cb a parser callback function of type @ref parser_callback_t23154which is used to control the deserialization by filtering unwanted values23155(optional)23156@param[in] allow_exceptions whether to throw exceptions in case of a23157parse error (optional, true by default)23158@param[in] ignore_comments whether comments should be ignored and treated23159like whitespace (true) or yield a parse error (true); (optional, false by23160default)2316123162@return deserialized JSON value; in case of a parse error and23163@a allow_exceptions set to `false`, the return value will be23164value_t::discarded.2316523166@throw parse_error.101 if a parse error occurs; example: `""unexpected end23167of input; expected string literal""`23168@throw parse_error.102 if to_unicode fails or surrogate error23169@throw parse_error.103 if to_unicode fails23170*/23171template<typename IteratorType>23172JSON_HEDLEY_WARN_UNUSED_RESULT23173static basic_json parse(IteratorType first,23174IteratorType last,23175const parser_callback_t cb = nullptr,23176const bool allow_exceptions = true,23177const bool ignore_comments = false)23178{23179basic_json result;23180parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);23181return result;23182}2318323184JSON_HEDLEY_WARN_UNUSED_RESULT23185JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))23186static basic_json parse(detail::span_input_adapter&& i,23187const parser_callback_t cb = nullptr,23188const bool allow_exceptions = true,23189const bool ignore_comments = false)23190{23191basic_json result;23192parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);23193return result;23194}2319523196/*!23197@brief check if the input is valid JSON2319823199Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)23200function, this function neither throws an exception in case of invalid JSON23201input (i.e., a parse error) nor creates diagnostic information.2320223203@tparam InputType A compatible input, for instance23204- an std::istream object23205- a FILE pointer23206- a C-style array of characters23207- a pointer to a null-terminated string of single byte characters23208- an object obj for which begin(obj) and end(obj) produces a valid pair of23209iterators.2321023211@param[in] i input to read from23212@param[in] ignore_comments whether comments should be ignored and treated23213like whitespace (true) or yield a parse error (true); (optional, false by23214default)2321523216@return Whether the input read from @a i is valid JSON.2321723218@complexity Linear in the length of the input. The parser is a predictive23219LL(1) parser.2322023221@note A UTF-8 byte order mark is silently ignored.2322223223@liveexample{The example below demonstrates the `accept()` function reading23224from a string.,accept__string}23225*/23226template<typename InputType>23227static bool accept(InputType&& i,23228const bool ignore_comments = false)23229{23230return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);23231}2323223233template<typename IteratorType>23234static bool accept(IteratorType first, IteratorType last,23235const bool ignore_comments = false)23236{23237return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);23238}2323923240JSON_HEDLEY_WARN_UNUSED_RESULT23241JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))23242static bool accept(detail::span_input_adapter&& i,23243const bool ignore_comments = false)23244{23245return parser(i.get(), nullptr, false, ignore_comments).accept(true);23246}2324723248/*!23249@brief generate SAX events2325023251The SAX event lister must follow the interface of @ref json_sax.2325223253This function reads from a compatible input. Examples are:23254- an std::istream object23255- a FILE pointer23256- a C-style array of characters23257- a pointer to a null-terminated string of single byte characters23258- an object obj for which begin(obj) and end(obj) produces a valid pair of23259iterators.2326023261@param[in] i input to read from23262@param[in,out] sax SAX event listener23263@param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)23264@param[in] strict whether the input has to be consumed completely23265@param[in] ignore_comments whether comments should be ignored and treated23266like whitespace (true) or yield a parse error (true); (optional, false by23267default); only applies to the JSON file format.2326823269@return return value of the last processed SAX event2327023271@throw parse_error.101 if a parse error occurs; example: `""unexpected end23272of input; expected string literal""`23273@throw parse_error.102 if to_unicode fails or surrogate error23274@throw parse_error.103 if to_unicode fails2327523276@complexity Linear in the length of the input. The parser is a predictive23277LL(1) parser. The complexity can be higher if the SAX consumer @a sax has23278a super-linear complexity.2327923280@note A UTF-8 byte order mark is silently ignored.2328123282@liveexample{The example below demonstrates the `sax_parse()` function23283reading from string and processing the events with a user-defined SAX23284event consumer.,sax_parse}2328523286@since version 3.2.023287*/23288template <typename InputType, typename SAX>23289JSON_HEDLEY_NON_NULL(2)23290static bool sax_parse(InputType&& i, SAX* sax,23291input_format_t format = input_format_t::json,23292const bool strict = true,23293const bool ignore_comments = false)23294{23295auto ia = detail::input_adapter(std::forward<InputType>(i));23296return format == input_format_t::json23297? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)23298: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);23299}2330023301template<class IteratorType, class SAX>23302JSON_HEDLEY_NON_NULL(3)23303static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,23304input_format_t format = input_format_t::json,23305const bool strict = true,23306const bool ignore_comments = false)23307{23308auto ia = detail::input_adapter(std::move(first), std::move(last));23309return format == input_format_t::json23310? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)23311: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);23312}2331323314template <typename SAX>23315JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))23316JSON_HEDLEY_NON_NULL(2)23317static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,23318input_format_t format = input_format_t::json,23319const bool strict = true,23320const bool ignore_comments = false)23321{23322auto ia = i.get();23323return format == input_format_t::json23324? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)23325: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);23326}2332723328/*!23329@brief deserialize from stream23330@deprecated This stream operator is deprecated and will be removed in23331version 4.0.0 of the library. Please use23332@ref operator>>(std::istream&, basic_json&)23333instead; that is, replace calls like `j << i;` with `i >> j;`.23334@since version 1.0.0; deprecated since version 3.0.023335*/23336JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))23337friend std::istream& operator<<(basic_json& j, std::istream& i)23338{23339return operator>>(i, j);23340}2334123342/*!23343@brief deserialize from stream2334423345Deserializes an input stream to a JSON value.2334623347@param[in,out] i input stream to read a serialized JSON value from23348@param[in,out] j JSON value to write the deserialized input to2334923350@throw parse_error.101 in case of an unexpected token23351@throw parse_error.102 if to_unicode fails or surrogate error23352@throw parse_error.103 if to_unicode fails2335323354@complexity Linear in the length of the input. The parser is a predictive23355LL(1) parser.2335623357@note A UTF-8 byte order mark is silently ignored.2335823359@liveexample{The example below shows how a JSON value is constructed by23360reading a serialization from a stream.,operator_deserialize}2336123362@sa parse(std::istream&, const parser_callback_t) for a variant with a23363parser callback function to filter values while parsing2336423365@since version 1.0.023366*/23367friend std::istream& operator>>(std::istream& i, basic_json& j)23368{23369parser(detail::input_adapter(i)).parse(false, j);23370return i;23371}2337223373/// @}2337423375///////////////////////////23376// convenience functions //23377///////////////////////////2337823379/*!23380@brief return the type as string2338123382Returns the type name as string to be used in error messages - usually to23383indicate that a function was called on a wrong JSON type.2338423385@return a string representation of a the @a m_type member:23386Value type | return value23387----------- | -------------23388null | `"null"`23389boolean | `"boolean"`23390string | `"string"`23391number | `"number"` (for all number types)23392object | `"object"`23393array | `"array"`23394binary | `"binary"`23395discarded | `"discarded"`2339623397@exceptionsafety No-throw guarantee: this function never throws exceptions.2339823399@complexity Constant.2340023401@liveexample{The following code exemplifies `type_name()` for all JSON23402types.,type_name}2340323404@sa @ref type() -- return the type of the JSON value23405@sa @ref operator value_t() -- return the type of the JSON value (implicit)2340623407@since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`23408since 3.0.023409*/23410JSON_HEDLEY_RETURNS_NON_NULL23411const char* type_name() const noexcept23412{23413{23414switch (m_type)23415{23416case value_t::null:23417return "null";23418case value_t::object:23419return "object";23420case value_t::array:23421return "array";23422case value_t::string:23423return "string";23424case value_t::boolean:23425return "boolean";23426case value_t::binary:23427return "binary";23428case value_t::discarded:23429return "discarded";23430default:23431return "number";23432}23433}23434}234352343623437private:23438//////////////////////23439// member variables //23440//////////////////////2344123442/// the type of the current element23443value_t m_type = value_t::null;2344423445/// the value of the current element23446json_value m_value = {};2344723448//////////////////////////////////////////23449// binary serialization/deserialization //23450//////////////////////////////////////////2345123452/// @name binary serialization/deserialization support23453/// @{2345423455public:23456/*!23457@brief create a CBOR serialization of a given JSON value2345823459Serializes a given JSON value @a j to a byte vector using the CBOR (Concise23460Binary Object Representation) serialization format. CBOR is a binary23461serialization format which aims to be more compact than JSON itself, yet23462more efficient to parse.2346323464The library uses the following mapping from JSON values types to23465CBOR types according to the CBOR specification (RFC 7049):2346623467JSON value type | value/range | CBOR type | first byte23468--------------- | ------------------------------------------ | ---------------------------------- | ---------------23469null | `null` | Null | 0xF623470boolean | `true` | True | 0xF523471boolean | `false` | False | 0xF423472number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B23473number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A23474number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x3923475number_integer | -128..-25 | Negative integer (1 byte follow) | 0x3823476number_integer | -24..-1 | Negative integer | 0x20..0x3723477number_integer | 0..23 | Integer | 0x00..0x1723478number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x1823479number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x1923480number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A23481number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B23482number_unsigned | 0..23 | Integer | 0x00..0x1723483number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x1823484number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x1923485number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A23486number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B23487number_float | *any value representable by a float* | Single-Precision Float | 0xFA23488number_float | *any value NOT representable by a float* | Double-Precision Float | 0xFB23489string | *length*: 0..23 | UTF-8 string | 0x60..0x7723490string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x7823491string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x7923492string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A23493string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B23494array | *size*: 0..23 | array | 0x80..0x9723495array | *size*: 23..255 | array (1 byte follow) | 0x9823496array | *size*: 256..65535 | array (2 bytes follow) | 0x9923497array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A23498array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B23499object | *size*: 0..23 | map | 0xA0..0xB723500object | *size*: 23..255 | map (1 byte follow) | 0xB823501object | *size*: 256..65535 | map (2 bytes follow) | 0xB923502object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA23503object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB23504binary | *size*: 0..23 | byte string | 0x40..0x5723505binary | *size*: 23..255 | byte string (1 byte follow) | 0x5823506binary | *size*: 256..65535 | byte string (2 bytes follow) | 0x5923507binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A23508binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B2350923510@note The mapping is **complete** in the sense that any JSON value type23511can be converted to a CBOR value.2351223513@note If NaN or Infinity are stored inside a JSON number, they are23514serialized properly. This behavior differs from the @ref dump()23515function which serializes NaN or Infinity to `null`.2351623517@note The following CBOR types are not used in the conversion:23518- UTF-8 strings terminated by "break" (0x7F)23519- arrays terminated by "break" (0x9F)23520- maps terminated by "break" (0xBF)23521- byte strings terminated by "break" (0x5F)23522- date/time (0xC0..0xC1)23523- bignum (0xC2..0xC3)23524- decimal fraction (0xC4)23525- bigfloat (0xC5)23526- expected conversions (0xD5..0xD7)23527- simple values (0xE0..0xF3, 0xF8)23528- undefined (0xF7)23529- half-precision floats (0xF9)23530- break (0xFF)2353123532@param[in] j JSON value to serialize23533@return CBOR serialization as byte vector2353423535@complexity Linear in the size of the JSON value @a j.2353623537@liveexample{The example shows the serialization of a JSON value to a byte23538vector in CBOR format.,to_cbor}2353923540@sa http://cbor.io23541@sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the23542analogous deserialization23543@sa @ref to_msgpack(const basic_json&) for the related MessagePack format23544@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the23545related UBJSON format2354623547@since version 2.0.9; compact representation of floating-point numbers23548since version 3.8.023549*/23550static std::vector<uint8_t> to_cbor(const basic_json& j)23551{23552std::vector<uint8_t> result;23553to_cbor(j, result);23554return result;23555}2355623557static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)23558{23559binary_writer<uint8_t>(o).write_cbor(j);23560}2356123562static void to_cbor(const basic_json& j, detail::output_adapter<char> o)23563{23564binary_writer<char>(o).write_cbor(j);23565}2356623567/*!23568@brief create a MessagePack serialization of a given JSON value2356923570Serializes a given JSON value @a j to a byte vector using the MessagePack23571serialization format. MessagePack is a binary serialization format which23572aims to be more compact than JSON itself, yet more efficient to parse.2357323574The library uses the following mapping from JSON values types to23575MessagePack types according to the MessagePack specification:2357623577JSON value type | value/range | MessagePack type | first byte23578--------------- | --------------------------------- | ---------------- | ----------23579null | `null` | nil | 0xC023580boolean | `true` | true | 0xC323581boolean | `false` | false | 0xC223582number_integer | -9223372036854775808..-2147483649 | int64 | 0xD323583number_integer | -2147483648..-32769 | int32 | 0xD223584number_integer | -32768..-129 | int16 | 0xD123585number_integer | -128..-33 | int8 | 0xD023586number_integer | -32..-1 | negative fixint | 0xE0..0xFF23587number_integer | 0..127 | positive fixint | 0x00..0x7F23588number_integer | 128..255 | uint 8 | 0xCC23589number_integer | 256..65535 | uint 16 | 0xCD23590number_integer | 65536..4294967295 | uint 32 | 0xCE23591number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF23592number_unsigned | 0..127 | positive fixint | 0x00..0x7F23593number_unsigned | 128..255 | uint 8 | 0xCC23594number_unsigned | 256..65535 | uint 16 | 0xCD23595number_unsigned | 65536..4294967295 | uint 32 | 0xCE23596number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF23597number_float | *any value representable by a float* | float 32 | 0xCA23598number_float | *any value NOT representable by a float* | float 64 | 0xCB23599string | *length*: 0..31 | fixstr | 0xA0..0xBF23600string | *length*: 32..255 | str 8 | 0xD923601string | *length*: 256..65535 | str 16 | 0xDA23602string | *length*: 65536..4294967295 | str 32 | 0xDB23603array | *size*: 0..15 | fixarray | 0x90..0x9F23604array | *size*: 16..65535 | array 16 | 0xDC23605array | *size*: 65536..4294967295 | array 32 | 0xDD23606object | *size*: 0..15 | fix map | 0x80..0x8F23607object | *size*: 16..65535 | map 16 | 0xDE23608object | *size*: 65536..4294967295 | map 32 | 0xDF23609binary | *size*: 0..255 | bin 8 | 0xC423610binary | *size*: 256..65535 | bin 16 | 0xC523611binary | *size*: 65536..4294967295 | bin 32 | 0xC62361223613@note The mapping is **complete** in the sense that any JSON value type23614can be converted to a MessagePack value.2361523616@note The following values can **not** be converted to a MessagePack value:23617- strings with more than 4294967295 bytes23618- byte strings with more than 4294967295 bytes23619- arrays with more than 4294967295 elements23620- objects with more than 4294967295 elements2362123622@note Any MessagePack output created @ref to_msgpack can be successfully23623parsed by @ref from_msgpack.2362423625@note If NaN or Infinity are stored inside a JSON number, they are23626serialized properly. This behavior differs from the @ref dump()23627function which serializes NaN or Infinity to `null`.2362823629@param[in] j JSON value to serialize23630@return MessagePack serialization as byte vector2363123632@complexity Linear in the size of the JSON value @a j.2363323634@liveexample{The example shows the serialization of a JSON value to a byte23635vector in MessagePack format.,to_msgpack}2363623637@sa http://msgpack.org23638@sa @ref from_msgpack for the analogous deserialization23639@sa @ref to_cbor(const basic_json& for the related CBOR format23640@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the23641related UBJSON format2364223643@since version 2.0.923644*/23645static std::vector<uint8_t> to_msgpack(const basic_json& j)23646{23647std::vector<uint8_t> result;23648to_msgpack(j, result);23649return result;23650}2365123652static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)23653{23654binary_writer<uint8_t>(o).write_msgpack(j);23655}2365623657static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)23658{23659binary_writer<char>(o).write_msgpack(j);23660}2366123662/*!23663@brief create a UBJSON serialization of a given JSON value2366423665Serializes a given JSON value @a j to a byte vector using the UBJSON23666(Universal Binary JSON) serialization format. UBJSON aims to be more compact23667than JSON itself, yet more efficient to parse.2366823669The library uses the following mapping from JSON values types to23670UBJSON types according to the UBJSON specification:2367123672JSON value type | value/range | UBJSON type | marker23673--------------- | --------------------------------- | ----------- | ------23674null | `null` | null | `Z`23675boolean | `true` | true | `T`23676boolean | `false` | false | `F`23677number_integer | -9223372036854775808..-2147483649 | int64 | `L`23678number_integer | -2147483648..-32769 | int32 | `l`23679number_integer | -32768..-129 | int16 | `I`23680number_integer | -128..127 | int8 | `i`23681number_integer | 128..255 | uint8 | `U`23682number_integer | 256..32767 | int16 | `I`23683number_integer | 32768..2147483647 | int32 | `l`23684number_integer | 2147483648..9223372036854775807 | int64 | `L`23685number_unsigned | 0..127 | int8 | `i`23686number_unsigned | 128..255 | uint8 | `U`23687number_unsigned | 256..32767 | int16 | `I`23688number_unsigned | 32768..2147483647 | int32 | `l`23689number_unsigned | 2147483648..9223372036854775807 | int64 | `L`23690number_unsigned | 2147483649..18446744073709551615 | high-precision | `H`23691number_float | *any value* | float64 | `D`23692string | *with shortest length indicator* | string | `S`23693array | *see notes on optimized format* | array | `[`23694object | *see notes on optimized format* | map | `{`2369523696@note The mapping is **complete** in the sense that any JSON value type23697can be converted to a UBJSON value.2369823699@note The following values can **not** be converted to a UBJSON value:23700- strings with more than 9223372036854775807 bytes (theoretical)2370123702@note The following markers are not used in the conversion:23703- `Z`: no-op values are not created.23704- `C`: single-byte strings are serialized with `S` markers.2370523706@note Any UBJSON output created @ref to_ubjson can be successfully parsed23707by @ref from_ubjson.2370823709@note If NaN or Infinity are stored inside a JSON number, they are23710serialized properly. This behavior differs from the @ref dump()23711function which serializes NaN or Infinity to `null`.2371223713@note The optimized formats for containers are supported: Parameter23714@a use_size adds size information to the beginning of a container and23715removes the closing marker. Parameter @a use_type further checks23716whether all elements of a container have the same type and adds the23717type marker to the beginning of the container. The @a use_type23718parameter must only be used together with @a use_size = true. Note23719that @a use_size = true alone may result in larger representations -23720the benefit of this parameter is that the receiving side is23721immediately informed on the number of elements of the container.2372223723@note If the JSON data contains the binary type, the value stored is a list23724of integers, as suggested by the UBJSON documentation. In particular,23725this means that serialization and the deserialization of a JSON23726containing binary values into UBJSON and back will result in a23727different JSON object.2372823729@param[in] j JSON value to serialize23730@param[in] use_size whether to add size annotations to container types23731@param[in] use_type whether to add type annotations to container types23732(must be combined with @a use_size = true)23733@return UBJSON serialization as byte vector2373423735@complexity Linear in the size of the JSON value @a j.2373623737@liveexample{The example shows the serialization of a JSON value to a byte23738vector in UBJSON format.,to_ubjson}2373923740@sa http://ubjson.org23741@sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the23742analogous deserialization23743@sa @ref to_cbor(const basic_json& for the related CBOR format23744@sa @ref to_msgpack(const basic_json&) for the related MessagePack format2374523746@since version 3.1.023747*/23748static std::vector<uint8_t> to_ubjson(const basic_json& j,23749const bool use_size = false,23750const bool use_type = false)23751{23752std::vector<uint8_t> result;23753to_ubjson(j, result, use_size, use_type);23754return result;23755}2375623757static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,23758const bool use_size = false, const bool use_type = false)23759{23760binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);23761}2376223763static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,23764const bool use_size = false, const bool use_type = false)23765{23766binary_writer<char>(o).write_ubjson(j, use_size, use_type);23767}237682376923770/*!23771@brief Serializes the given JSON object `j` to BSON and returns a vector23772containing the corresponding BSON-representation.2377323774BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are23775stored as a single entity (a so-called document).2377623777The library uses the following mapping from JSON values types to BSON types:2377823779JSON value type | value/range | BSON type | marker23780--------------- | --------------------------------- | ----------- | ------23781null | `null` | null | 0x0A23782boolean | `true`, `false` | boolean | 0x0823783number_integer | -9223372036854775808..-2147483649 | int64 | 0x1223784number_integer | -2147483648..2147483647 | int32 | 0x1023785number_integer | 2147483648..9223372036854775807 | int64 | 0x1223786number_unsigned | 0..2147483647 | int32 | 0x1023787number_unsigned | 2147483648..9223372036854775807 | int64 | 0x1223788number_unsigned | 9223372036854775808..18446744073709551615| -- | --23789number_float | *any value* | double | 0x0123790string | *any value* | string | 0x0223791array | *any value* | document | 0x0423792object | *any value* | document | 0x0323793binary | *any value* | binary | 0x052379423795@warning The mapping is **incomplete**, since only JSON-objects (and things23796contained therein) can be serialized to BSON.23797Also, integers larger than 9223372036854775807 cannot be serialized to BSON,23798and the keys may not contain U+0000, since they are serialized a23799zero-terminated c-strings.2380023801@throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`23802@throw out_of_range.409 if a key in `j` contains a NULL (U+0000)23803@throw type_error.317 if `!j.is_object()`2380423805@pre The input `j` is required to be an object: `j.is_object() == true`.2380623807@note Any BSON output created via @ref to_bson can be successfully parsed23808by @ref from_bson.2380923810@param[in] j JSON value to serialize23811@return BSON serialization as byte vector2381223813@complexity Linear in the size of the JSON value @a j.2381423815@liveexample{The example shows the serialization of a JSON value to a byte23816vector in BSON format.,to_bson}2381723818@sa http://bsonspec.org/spec.html23819@sa @ref from_bson(detail::input_adapter&&, const bool strict) for the23820analogous deserialization23821@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the23822related UBJSON format23823@sa @ref to_cbor(const basic_json&) for the related CBOR format23824@sa @ref to_msgpack(const basic_json&) for the related MessagePack format23825*/23826static std::vector<uint8_t> to_bson(const basic_json& j)23827{23828std::vector<uint8_t> result;23829to_bson(j, result);23830return result;23831}2383223833/*!23834@brief Serializes the given JSON object `j` to BSON and forwards the23835corresponding BSON-representation to the given output_adapter `o`.23836@param j The JSON object to convert to BSON.23837@param o The output adapter that receives the binary BSON representation.23838@pre The input `j` shall be an object: `j.is_object() == true`23839@sa @ref to_bson(const basic_json&)23840*/23841static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)23842{23843binary_writer<uint8_t>(o).write_bson(j);23844}2384523846/*!23847@copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)23848*/23849static void to_bson(const basic_json& j, detail::output_adapter<char> o)23850{23851binary_writer<char>(o).write_bson(j);23852}238532385423855/*!23856@brief create a JSON value from an input in CBOR format2385723858Deserializes a given input @a i to a JSON value using the CBOR (Concise23859Binary Object Representation) serialization format.2386023861The library maps CBOR types to JSON value types as follows:2386223863CBOR type | JSON value type | first byte23864---------------------- | --------------- | ----------23865Integer | number_unsigned | 0x00..0x1723866Unsigned integer | number_unsigned | 0x1823867Unsigned integer | number_unsigned | 0x1923868Unsigned integer | number_unsigned | 0x1A23869Unsigned integer | number_unsigned | 0x1B23870Negative integer | number_integer | 0x20..0x3723871Negative integer | number_integer | 0x3823872Negative integer | number_integer | 0x3923873Negative integer | number_integer | 0x3A23874Negative integer | number_integer | 0x3B23875Byte string | binary | 0x40..0x5723876Byte string | binary | 0x5823877Byte string | binary | 0x5923878Byte string | binary | 0x5A23879Byte string | binary | 0x5B23880UTF-8 string | string | 0x60..0x7723881UTF-8 string | string | 0x7823882UTF-8 string | string | 0x7923883UTF-8 string | string | 0x7A23884UTF-8 string | string | 0x7B23885UTF-8 string | string | 0x7F23886array | array | 0x80..0x9723887array | array | 0x9823888array | array | 0x9923889array | array | 0x9A23890array | array | 0x9B23891array | array | 0x9F23892map | object | 0xA0..0xB723893map | object | 0xB823894map | object | 0xB923895map | object | 0xBA23896map | object | 0xBB23897map | object | 0xBF23898False | `false` | 0xF423899True | `true` | 0xF523900Null | `null` | 0xF623901Half-Precision Float | number_float | 0xF923902Single-Precision Float | number_float | 0xFA23903Double-Precision Float | number_float | 0xFB2390423905@warning The mapping is **incomplete** in the sense that not all CBOR23906types can be converted to a JSON value. The following CBOR types23907are not supported and will yield parse errors (parse_error.112):23908- date/time (0xC0..0xC1)23909- bignum (0xC2..0xC3)23910- decimal fraction (0xC4)23911- bigfloat (0xC5)23912- expected conversions (0xD5..0xD7)23913- simple values (0xE0..0xF3, 0xF8)23914- undefined (0xF7)2391523916@warning CBOR allows map keys of any type, whereas JSON only allows23917strings as keys in object values. Therefore, CBOR maps with keys23918other than UTF-8 strings are rejected (parse_error.113).2391923920@note Any CBOR output created @ref to_cbor can be successfully parsed by23921@ref from_cbor.2392223923@param[in] i an input in CBOR format convertible to an input adapter23924@param[in] strict whether to expect the input to be consumed until EOF23925(true by default)23926@param[in] allow_exceptions whether to throw exceptions in case of a23927parse error (optional, true by default)23928@param[in] tag_handler how to treat CBOR tags (optional, error by default)2392923930@return deserialized JSON value; in case of a parse error and23931@a allow_exceptions set to `false`, the return value will be23932value_t::discarded.2393323934@throw parse_error.110 if the given input ends prematurely or the end of23935file was not reached when @a strict was set to true23936@throw parse_error.112 if unsupported features from CBOR were23937used in the given input @a v or if the input is not valid CBOR23938@throw parse_error.113 if a string was expected as map key, but not found2393923940@complexity Linear in the size of the input @a i.2394123942@liveexample{The example shows the deserialization of a byte vector in CBOR23943format to a JSON value.,from_cbor}2394423945@sa http://cbor.io23946@sa @ref to_cbor(const basic_json&) for the analogous serialization23947@sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the23948related MessagePack format23949@sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the23950related UBJSON format2395123952@since version 2.0.9; parameter @a start_index since 2.1.1; changed to23953consume input adapters, removed start_index parameter, and added23954@a strict parameter since 3.0.0; added @a allow_exceptions parameter23955since 3.2.0; added @a tag_handler parameter since 3.9.0.23956*/23957template<typename InputType>23958JSON_HEDLEY_WARN_UNUSED_RESULT23959static basic_json from_cbor(InputType&& i,23960const bool strict = true,23961const bool allow_exceptions = true,23962const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)23963{23964basic_json result;23965detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23966auto ia = detail::input_adapter(std::forward<InputType>(i));23967const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);23968return res ? result : basic_json(value_t::discarded);23969}2397023971/*!23972@copydoc from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t)23973*/23974template<typename IteratorType>23975JSON_HEDLEY_WARN_UNUSED_RESULT23976static basic_json from_cbor(IteratorType first, IteratorType last,23977const bool strict = true,23978const bool allow_exceptions = true,23979const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)23980{23981basic_json result;23982detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);23983auto ia = detail::input_adapter(std::move(first), std::move(last));23984const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);23985return res ? result : basic_json(value_t::discarded);23986}2398723988template<typename T>23989JSON_HEDLEY_WARN_UNUSED_RESULT23990JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))23991static basic_json from_cbor(const T* ptr, std::size_t len,23992const bool strict = true,23993const bool allow_exceptions = true,23994const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)23995{23996return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);23997}239982399924000JSON_HEDLEY_WARN_UNUSED_RESULT24001JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))24002static basic_json from_cbor(detail::span_input_adapter&& i,24003const bool strict = true,24004const bool allow_exceptions = true,24005const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)24006{24007basic_json result;24008detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);24009auto ia = i.get();24010const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);24011return res ? result : basic_json(value_t::discarded);24012}2401324014/*!24015@brief create a JSON value from an input in MessagePack format2401624017Deserializes a given input @a i to a JSON value using the MessagePack24018serialization format.2401924020The library maps MessagePack types to JSON value types as follows:2402124022MessagePack type | JSON value type | first byte24023---------------- | --------------- | ----------24024positive fixint | number_unsigned | 0x00..0x7F24025fixmap | object | 0x80..0x8F24026fixarray | array | 0x90..0x9F24027fixstr | string | 0xA0..0xBF24028nil | `null` | 0xC024029false | `false` | 0xC224030true | `true` | 0xC324031float 32 | number_float | 0xCA24032float 64 | number_float | 0xCB24033uint 8 | number_unsigned | 0xCC24034uint 16 | number_unsigned | 0xCD24035uint 32 | number_unsigned | 0xCE24036uint 64 | number_unsigned | 0xCF24037int 8 | number_integer | 0xD024038int 16 | number_integer | 0xD124039int 32 | number_integer | 0xD224040int 64 | number_integer | 0xD324041str 8 | string | 0xD924042str 16 | string | 0xDA24043str 32 | string | 0xDB24044array 16 | array | 0xDC24045array 32 | array | 0xDD24046map 16 | object | 0xDE24047map 32 | object | 0xDF24048bin 8 | binary | 0xC424049bin 16 | binary | 0xC524050bin 32 | binary | 0xC624051ext 8 | binary | 0xC724052ext 16 | binary | 0xC824053ext 32 | binary | 0xC924054fixext 1 | binary | 0xD424055fixext 2 | binary | 0xD524056fixext 4 | binary | 0xD624057fixext 8 | binary | 0xD724058fixext 16 | binary | 0xD824059negative fixint | number_integer | 0xE0-0xFF2406024061@note Any MessagePack output created @ref to_msgpack can be successfully24062parsed by @ref from_msgpack.2406324064@param[in] i an input in MessagePack format convertible to an input24065adapter24066@param[in] strict whether to expect the input to be consumed until EOF24067(true by default)24068@param[in] allow_exceptions whether to throw exceptions in case of a24069parse error (optional, true by default)2407024071@return deserialized JSON value; in case of a parse error and24072@a allow_exceptions set to `false`, the return value will be24073value_t::discarded.2407424075@throw parse_error.110 if the given input ends prematurely or the end of24076file was not reached when @a strict was set to true24077@throw parse_error.112 if unsupported features from MessagePack were24078used in the given input @a i or if the input is not valid MessagePack24079@throw parse_error.113 if a string was expected as map key, but not found2408024081@complexity Linear in the size of the input @a i.2408224083@liveexample{The example shows the deserialization of a byte vector in24084MessagePack format to a JSON value.,from_msgpack}2408524086@sa http://msgpack.org24087@sa @ref to_msgpack(const basic_json&) for the analogous serialization24088@sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the24089related CBOR format24090@sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for24091the related UBJSON format24092@sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for24093the related BSON format2409424095@since version 2.0.9; parameter @a start_index since 2.1.1; changed to24096consume input adapters, removed start_index parameter, and added24097@a strict parameter since 3.0.0; added @a allow_exceptions parameter24098since 3.2.024099*/24100template<typename InputType>24101JSON_HEDLEY_WARN_UNUSED_RESULT24102static basic_json from_msgpack(InputType&& i,24103const bool strict = true,24104const bool allow_exceptions = true)24105{24106basic_json result;24107detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);24108auto ia = detail::input_adapter(std::forward<InputType>(i));24109const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);24110return res ? result : basic_json(value_t::discarded);24111}2411224113/*!24114@copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)24115*/24116template<typename IteratorType>24117JSON_HEDLEY_WARN_UNUSED_RESULT24118static basic_json from_msgpack(IteratorType first, IteratorType last,24119const bool strict = true,24120const bool allow_exceptions = true)24121{24122basic_json result;24123detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);24124auto ia = detail::input_adapter(std::move(first), std::move(last));24125const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);24126return res ? result : basic_json(value_t::discarded);24127}241282412924130template<typename T>24131JSON_HEDLEY_WARN_UNUSED_RESULT24132JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))24133static basic_json from_msgpack(const T* ptr, std::size_t len,24134const bool strict = true,24135const bool allow_exceptions = true)24136{24137return from_msgpack(ptr, ptr + len, strict, allow_exceptions);24138}2413924140JSON_HEDLEY_WARN_UNUSED_RESULT24141JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))24142static basic_json from_msgpack(detail::span_input_adapter&& i,24143const bool strict = true,24144const bool allow_exceptions = true)24145{24146basic_json result;24147detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);24148auto ia = i.get();24149const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);24150return res ? result : basic_json(value_t::discarded);24151}241522415324154/*!24155@brief create a JSON value from an input in UBJSON format2415624157Deserializes a given input @a i to a JSON value using the UBJSON (Universal24158Binary JSON) serialization format.2415924160The library maps UBJSON types to JSON value types as follows:2416124162UBJSON type | JSON value type | marker24163----------- | --------------------------------------- | ------24164no-op | *no value, next value is read* | `N`24165null | `null` | `Z`24166false | `false` | `F`24167true | `true` | `T`24168float32 | number_float | `d`24169float64 | number_float | `D`24170uint8 | number_unsigned | `U`24171int8 | number_integer | `i`24172int16 | number_integer | `I`24173int32 | number_integer | `l`24174int64 | number_integer | `L`24175high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'24176string | string | `S`24177char | string | `C`24178array | array (optimized values are supported) | `[`24179object | object (optimized values are supported) | `{`2418024181@note The mapping is **complete** in the sense that any UBJSON value can24182be converted to a JSON value.2418324184@param[in] i an input in UBJSON format convertible to an input adapter24185@param[in] strict whether to expect the input to be consumed until EOF24186(true by default)24187@param[in] allow_exceptions whether to throw exceptions in case of a24188parse error (optional, true by default)2418924190@return deserialized JSON value; in case of a parse error and24191@a allow_exceptions set to `false`, the return value will be24192value_t::discarded.2419324194@throw parse_error.110 if the given input ends prematurely or the end of24195file was not reached when @a strict was set to true24196@throw parse_error.112 if a parse error occurs24197@throw parse_error.113 if a string could not be parsed successfully2419824199@complexity Linear in the size of the input @a i.2420024201@liveexample{The example shows the deserialization of a byte vector in24202UBJSON format to a JSON value.,from_ubjson}2420324204@sa http://ubjson.org24205@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the24206analogous serialization24207@sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the24208related CBOR format24209@sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for24210the related MessagePack format24211@sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for24212the related BSON format2421324214@since version 3.1.0; added @a allow_exceptions parameter since 3.2.024215*/24216template<typename InputType>24217JSON_HEDLEY_WARN_UNUSED_RESULT24218static basic_json from_ubjson(InputType&& i,24219const bool strict = true,24220const bool allow_exceptions = true)24221{24222basic_json result;24223detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);24224auto ia = detail::input_adapter(std::forward<InputType>(i));24225const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);24226return res ? result : basic_json(value_t::discarded);24227}2422824229/*!24230@copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)24231*/24232template<typename IteratorType>24233JSON_HEDLEY_WARN_UNUSED_RESULT24234static basic_json from_ubjson(IteratorType first, IteratorType last,24235const bool strict = true,24236const bool allow_exceptions = true)24237{24238basic_json result;24239detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);24240auto ia = detail::input_adapter(std::move(first), std::move(last));24241const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);24242return res ? result : basic_json(value_t::discarded);24243}2424424245template<typename T>24246JSON_HEDLEY_WARN_UNUSED_RESULT24247JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))24248static basic_json from_ubjson(const T* ptr, std::size_t len,24249const bool strict = true,24250const bool allow_exceptions = true)24251{24252return from_ubjson(ptr, ptr + len, strict, allow_exceptions);24253}2425424255JSON_HEDLEY_WARN_UNUSED_RESULT24256JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))24257static basic_json from_ubjson(detail::span_input_adapter&& i,24258const bool strict = true,24259const bool allow_exceptions = true)24260{24261basic_json result;24262detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);24263auto ia = i.get();24264const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);24265return res ? result : basic_json(value_t::discarded);24266}242672426824269/*!24270@brief Create a JSON value from an input in BSON format2427124272Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)24273serialization format.2427424275The library maps BSON record types to JSON value types as follows:2427624277BSON type | BSON marker byte | JSON value type24278--------------- | ---------------- | ---------------------------24279double | 0x01 | number_float24280string | 0x02 | string24281document | 0x03 | object24282array | 0x04 | array24283binary | 0x05 | still unsupported24284undefined | 0x06 | still unsupported24285ObjectId | 0x07 | still unsupported24286boolean | 0x08 | boolean24287UTC Date-Time | 0x09 | still unsupported24288null | 0x0A | null24289Regular Expr. | 0x0B | still unsupported24290DB Pointer | 0x0C | still unsupported24291JavaScript Code | 0x0D | still unsupported24292Symbol | 0x0E | still unsupported24293JavaScript Code | 0x0F | still unsupported24294int32 | 0x10 | number_integer24295Timestamp | 0x11 | still unsupported24296128-bit decimal float | 0x13 | still unsupported24297Max Key | 0x7F | still unsupported24298Min Key | 0xFF | still unsupported2429924300@warning The mapping is **incomplete**. The unsupported mappings24301are indicated in the table above.2430224303@param[in] i an input in BSON format convertible to an input adapter24304@param[in] strict whether to expect the input to be consumed until EOF24305(true by default)24306@param[in] allow_exceptions whether to throw exceptions in case of a24307parse error (optional, true by default)2430824309@return deserialized JSON value; in case of a parse error and24310@a allow_exceptions set to `false`, the return value will be24311value_t::discarded.2431224313@throw parse_error.114 if an unsupported BSON record type is encountered2431424315@complexity Linear in the size of the input @a i.2431624317@liveexample{The example shows the deserialization of a byte vector in24318BSON format to a JSON value.,from_bson}2431924320@sa http://bsonspec.org/spec.html24321@sa @ref to_bson(const basic_json&) for the analogous serialization24322@sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the24323related CBOR format24324@sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for24325the related MessagePack format24326@sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the24327related UBJSON format24328*/24329template<typename InputType>24330JSON_HEDLEY_WARN_UNUSED_RESULT24331static basic_json from_bson(InputType&& i,24332const bool strict = true,24333const bool allow_exceptions = true)24334{24335basic_json result;24336detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);24337auto ia = detail::input_adapter(std::forward<InputType>(i));24338const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);24339return res ? result : basic_json(value_t::discarded);24340}2434124342/*!24343@copydoc from_bson(detail::input_adapter&&, const bool, const bool)24344*/24345template<typename IteratorType>24346JSON_HEDLEY_WARN_UNUSED_RESULT24347static basic_json from_bson(IteratorType first, IteratorType last,24348const bool strict = true,24349const bool allow_exceptions = true)24350{24351basic_json result;24352detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);24353auto ia = detail::input_adapter(std::move(first), std::move(last));24354const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);24355return res ? result : basic_json(value_t::discarded);24356}2435724358template<typename T>24359JSON_HEDLEY_WARN_UNUSED_RESULT24360JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))24361static basic_json from_bson(const T* ptr, std::size_t len,24362const bool strict = true,24363const bool allow_exceptions = true)24364{24365return from_bson(ptr, ptr + len, strict, allow_exceptions);24366}2436724368JSON_HEDLEY_WARN_UNUSED_RESULT24369JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))24370static basic_json from_bson(detail::span_input_adapter&& i,24371const bool strict = true,24372const bool allow_exceptions = true)24373{24374basic_json result;24375detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);24376auto ia = i.get();24377const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);24378return res ? result : basic_json(value_t::discarded);24379}24380/// @}2438124382//////////////////////////24383// JSON Pointer support //24384//////////////////////////2438524386/// @name JSON Pointer functions24387/// @{2438824389/*!24390@brief access specified element via JSON Pointer2439124392Uses a JSON pointer to retrieve a reference to the respective JSON value.24393No bound checking is performed. Similar to @ref operator[](const typename24394object_t::key_type&), `null` values are created in arrays and objects if24395necessary.2439624397In particular:24398- If the JSON pointer points to an object key that does not exist, it24399is created an filled with a `null` value before a reference to it24400is returned.24401- If the JSON pointer points to an array index that does not exist, it24402is created an filled with a `null` value before a reference to it24403is returned. All indices between the current maximum and the given24404index are also filled with `null`.24405- The special value `-` is treated as a synonym for the index past the24406end.2440724408@param[in] ptr a JSON pointer2440924410@return reference to the element pointed to by @a ptr2441124412@complexity Constant.2441324414@throw parse_error.106 if an array index begins with '0'24415@throw parse_error.109 if an array index was not a number24416@throw out_of_range.404 if the JSON pointer can not be resolved2441724418@liveexample{The behavior is shown in the example.,operatorjson_pointer}2441924420@since version 2.0.024421*/24422reference operator[](const json_pointer& ptr)24423{24424return ptr.get_unchecked(this);24425}2442624427/*!24428@brief access specified element via JSON Pointer2442924430Uses a JSON pointer to retrieve a reference to the respective JSON value.24431No bound checking is performed. The function does not change the JSON24432value; no `null` values are created. In particular, the special value24433`-` yields an exception.2443424435@param[in] ptr JSON pointer to the desired element2443624437@return const reference to the element pointed to by @a ptr2443824439@complexity Constant.2444024441@throw parse_error.106 if an array index begins with '0'24442@throw parse_error.109 if an array index was not a number24443@throw out_of_range.402 if the array index '-' is used24444@throw out_of_range.404 if the JSON pointer can not be resolved2444524446@liveexample{The behavior is shown in the example.,operatorjson_pointer_const}2444724448@since version 2.0.024449*/24450const_reference operator[](const json_pointer& ptr) const24451{24452return ptr.get_unchecked(this);24453}2445424455/*!24456@brief access specified element via JSON Pointer2445724458Returns a reference to the element at with specified JSON pointer @a ptr,24459with bounds checking.2446024461@param[in] ptr JSON pointer to the desired element2446224463@return reference to the element pointed to by @a ptr2446424465@throw parse_error.106 if an array index in the passed JSON pointer @a ptr24466begins with '0'. See example below.2446724468@throw parse_error.109 if an array index in the passed JSON pointer @a ptr24469is not a number. See example below.2447024471@throw out_of_range.401 if an array index in the passed JSON pointer @a ptr24472is out of range. See example below.2447324474@throw out_of_range.402 if the array index '-' is used in the passed JSON24475pointer @a ptr. As `at` provides checked access (and no elements are24476implicitly inserted), the index '-' is always invalid. See example below.2447724478@throw out_of_range.403 if the JSON pointer describes a key of an object24479which cannot be found. See example below.2448024481@throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.24482See example below.2448324484@exceptionsafety Strong guarantee: if an exception is thrown, there are no24485changes in the JSON value.2448624487@complexity Constant.2448824489@since version 2.0.02449024491@liveexample{The behavior is shown in the example.,at_json_pointer}24492*/24493reference at(const json_pointer& ptr)24494{24495return ptr.get_checked(this);24496}2449724498/*!24499@brief access specified element via JSON Pointer2450024501Returns a const reference to the element at with specified JSON pointer @a24502ptr, with bounds checking.2450324504@param[in] ptr JSON pointer to the desired element2450524506@return reference to the element pointed to by @a ptr2450724508@throw parse_error.106 if an array index in the passed JSON pointer @a ptr24509begins with '0'. See example below.2451024511@throw parse_error.109 if an array index in the passed JSON pointer @a ptr24512is not a number. See example below.2451324514@throw out_of_range.401 if an array index in the passed JSON pointer @a ptr24515is out of range. See example below.2451624517@throw out_of_range.402 if the array index '-' is used in the passed JSON24518pointer @a ptr. As `at` provides checked access (and no elements are24519implicitly inserted), the index '-' is always invalid. See example below.2452024521@throw out_of_range.403 if the JSON pointer describes a key of an object24522which cannot be found. See example below.2452324524@throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.24525See example below.2452624527@exceptionsafety Strong guarantee: if an exception is thrown, there are no24528changes in the JSON value.2452924530@complexity Constant.2453124532@since version 2.0.02453324534@liveexample{The behavior is shown in the example.,at_json_pointer_const}24535*/24536const_reference at(const json_pointer& ptr) const24537{24538return ptr.get_checked(this);24539}2454024541/*!24542@brief return flattened JSON value2454324544The function creates a JSON object whose keys are JSON pointers (see [RFC245456901](https://tools.ietf.org/html/rfc6901)) and whose values are all24546primitive. The original JSON value can be restored using the @ref24547unflatten() function.2454824549@return an object that maps JSON pointers to primitive values2455024551@note Empty objects and arrays are flattened to `null` and will not be24552reconstructed correctly by the @ref unflatten() function.2455324554@complexity Linear in the size the JSON value.2455524556@liveexample{The following code shows how a JSON object is flattened to an24557object whose keys consist of JSON pointers.,flatten}2455824559@sa @ref unflatten() for the reverse function2456024561@since version 2.0.024562*/24563basic_json flatten() const24564{24565basic_json result(value_t::object);24566json_pointer::flatten("", *this, result);24567return result;24568}2456924570/*!24571@brief unflatten a previously flattened JSON value2457224573The function restores the arbitrary nesting of a JSON value that has been24574flattened before using the @ref flatten() function. The JSON value must24575meet certain constraints:245761. The value must be an object.245772. The keys must be JSON pointers (see24578[RFC 6901](https://tools.ietf.org/html/rfc6901))245793. The mapped values must be primitive JSON types.2458024581@return the original JSON from a flattened version2458224583@note Empty objects and arrays are flattened by @ref flatten() to `null`24584values and can not unflattened to their original type. Apart from24585this example, for a JSON value `j`, the following is always true:24586`j == j.flatten().unflatten()`.2458724588@complexity Linear in the size the JSON value.2458924590@throw type_error.314 if value is not an object24591@throw type_error.315 if object values are not primitive2459224593@liveexample{The following code shows how a flattened JSON object is24594unflattened into the original nested JSON object.,unflatten}2459524596@sa @ref flatten() for the reverse function2459724598@since version 2.0.024599*/24600basic_json unflatten() const24601{24602return json_pointer::unflatten(*this);24603}2460424605/// @}2460624607//////////////////////////24608// JSON Patch functions //24609//////////////////////////2461024611/// @name JSON Patch functions24612/// @{2461324614/*!24615@brief applies a JSON patch2461624617[JSON Patch](http://jsonpatch.com) defines a JSON document structure for24618expressing a sequence of operations to apply to a JSON) document. With24619this function, a JSON Patch is applied to the current JSON value by24620executing all operations from the patch.2462124622@param[in] json_patch JSON patch document24623@return patched document2462424625@note The application of a patch is atomic: Either all operations succeed24626and the patched document is returned or an exception is thrown. In24627any case, the original value is not changed: the patch is applied24628to a copy of the value.2462924630@throw parse_error.104 if the JSON patch does not consist of an array of24631objects2463224633@throw parse_error.105 if the JSON patch is malformed (e.g., mandatory24634attributes are missing); example: `"operation add must have member path"`2463524636@throw out_of_range.401 if an array index is out of range.2463724638@throw out_of_range.403 if a JSON pointer inside the patch could not be24639resolved successfully in the current JSON value; example: `"key baz not24640found"`2464124642@throw out_of_range.405 if JSON pointer has no parent ("add", "remove",24643"move")2464424645@throw other_error.501 if "test" operation was unsuccessful2464624647@complexity Linear in the size of the JSON value and the length of the24648JSON patch. As usually only a fraction of the JSON value is affected by24649the patch, the complexity can usually be neglected.2465024651@liveexample{The following code shows how a JSON patch is applied to a24652value.,patch}2465324654@sa @ref diff -- create a JSON patch by comparing two JSON values2465524656@sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)24657@sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)2465824659@since version 2.0.024660*/24661basic_json patch(const basic_json& json_patch) const24662{24663// make a working copy to apply the patch to24664basic_json result = *this;2466524666// the valid JSON Patch operations24667enum class patch_operations {add, remove, replace, move, copy, test, invalid};2466824669const auto get_op = [](const std::string & op)24670{24671if (op == "add")24672{24673return patch_operations::add;24674}24675if (op == "remove")24676{24677return patch_operations::remove;24678}24679if (op == "replace")24680{24681return patch_operations::replace;24682}24683if (op == "move")24684{24685return patch_operations::move;24686}24687if (op == "copy")24688{24689return patch_operations::copy;24690}24691if (op == "test")24692{24693return patch_operations::test;24694}2469524696return patch_operations::invalid;24697};2469824699// wrapper for "add" operation; add value at ptr24700const auto operation_add = [&result](json_pointer & ptr, basic_json val)24701{24702// adding to the root of the target document means replacing it24703if (ptr.empty())24704{24705result = val;24706return;24707}2470824709// make sure the top element of the pointer exists24710json_pointer top_pointer = ptr.top();24711if (top_pointer != ptr)24712{24713result.at(top_pointer);24714}2471524716// get reference to parent of JSON pointer ptr24717const auto last_path = ptr.back();24718ptr.pop_back();24719basic_json& parent = result[ptr];2472024721switch (parent.m_type)24722{24723case value_t::null:24724case value_t::object:24725{24726// use operator[] to add value24727parent[last_path] = val;24728break;24729}2473024731case value_t::array:24732{24733if (last_path == "-")24734{24735// special case: append to back24736parent.push_back(val);24737}24738else24739{24740const auto idx = json_pointer::array_index(last_path);24741if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))24742{24743// avoid undefined behavior24744JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));24745}2474624747// default case: insert add offset24748parent.insert(parent.begin() + static_cast<difference_type>(idx), val);24749}24750break;24751}2475224753// if there exists a parent it cannot be primitive24754default: // LCOV_EXCL_LINE24755JSON_ASSERT(false); // LCOV_EXCL_LINE24756}24757};2475824759// wrapper for "remove" operation; remove value at ptr24760const auto operation_remove = [&result](json_pointer & ptr)24761{24762// get reference to parent of JSON pointer ptr24763const auto last_path = ptr.back();24764ptr.pop_back();24765basic_json& parent = result.at(ptr);2476624767// remove child24768if (parent.is_object())24769{24770// perform range check24771auto it = parent.find(last_path);24772if (JSON_HEDLEY_LIKELY(it != parent.end()))24773{24774parent.erase(it);24775}24776else24777{24778JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));24779}24780}24781else if (parent.is_array())24782{24783// note erase performs range check24784parent.erase(json_pointer::array_index(last_path));24785}24786};2478724788// type check: top level value must be an array24789if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))24790{24791JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));24792}2479324794// iterate and apply the operations24795for (const auto& val : json_patch)24796{24797// wrapper to get a value for an operation24798const auto get_value = [&val](const std::string & op,24799const std::string & member,24800bool string_type) -> basic_json &24801{24802// find value24803auto it = val.m_value.object->find(member);2480424805// context-sensitive error message24806const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";2480724808// check if desired value is present24809if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))24810{24811JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));24812}2481324814// check if result is of type string24815if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))24816{24817JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));24818}2481924820// no error: return value24821return it->second;24822};2482324824// type check: every element of the array must be an object24825if (JSON_HEDLEY_UNLIKELY(!val.is_object()))24826{24827JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));24828}2482924830// collect mandatory members24831const auto op = get_value("op", "op", true).template get<std::string>();24832const auto path = get_value(op, "path", true).template get<std::string>();24833json_pointer ptr(path);2483424835switch (get_op(op))24836{24837case patch_operations::add:24838{24839operation_add(ptr, get_value("add", "value", false));24840break;24841}2484224843case patch_operations::remove:24844{24845operation_remove(ptr);24846break;24847}2484824849case patch_operations::replace:24850{24851// the "path" location must exist - use at()24852result.at(ptr) = get_value("replace", "value", false);24853break;24854}2485524856case patch_operations::move:24857{24858const auto from_path = get_value("move", "from", true).template get<std::string>();24859json_pointer from_ptr(from_path);2486024861// the "from" location must exist - use at()24862basic_json v = result.at(from_ptr);2486324864// The move operation is functionally identical to a24865// "remove" operation on the "from" location, followed24866// immediately by an "add" operation at the target24867// location with the value that was just removed.24868operation_remove(from_ptr);24869operation_add(ptr, v);24870break;24871}2487224873case patch_operations::copy:24874{24875const auto from_path = get_value("copy", "from", true).template get<std::string>();24876const json_pointer from_ptr(from_path);2487724878// the "from" location must exist - use at()24879basic_json v = result.at(from_ptr);2488024881// The copy is functionally identical to an "add"24882// operation at the target location using the value24883// specified in the "from" member.24884operation_add(ptr, v);24885break;24886}2488724888case patch_operations::test:24889{24890bool success = false;24891JSON_TRY24892{24893// check if "value" matches the one at "path"24894// the "path" location must exist - use at()24895success = (result.at(ptr) == get_value("test", "value", false));24896}24897JSON_INTERNAL_CATCH (out_of_range&)24898{24899// ignore out of range errors: success remains false24900}2490124902// throw an exception if test fails24903if (JSON_HEDLEY_UNLIKELY(!success))24904{24905JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));24906}2490724908break;24909}2491024911default:24912{24913// op must be "add", "remove", "replace", "move", "copy", or24914// "test"24915JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));24916}24917}24918}2491924920return result;24921}2492224923/*!24924@brief creates a diff as a JSON patch2492524926Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can24927be changed into the value @a target by calling @ref patch function.2492824929@invariant For two JSON values @a source and @a target, the following code24930yields always `true`:24931@code {.cpp}24932source.patch(diff(source, target)) == target;24933@endcode2493424935@note Currently, only `remove`, `add`, and `replace` operations are24936generated.2493724938@param[in] source JSON value to compare from24939@param[in] target JSON value to compare against24940@param[in] path helper value to create JSON pointers2494124942@return a JSON patch to convert the @a source to @a target2494324944@complexity Linear in the lengths of @a source and @a target.2494524946@liveexample{The following code shows how a JSON patch is created as a24947diff for two JSON values.,diff}2494824949@sa @ref patch -- apply a JSON patch24950@sa @ref merge_patch -- apply a JSON Merge Patch2495124952@sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)2495324954@since version 2.0.024955*/24956JSON_HEDLEY_WARN_UNUSED_RESULT24957static basic_json diff(const basic_json& source, const basic_json& target,24958const std::string& path = "")24959{24960// the patch24961basic_json result(value_t::array);2496224963// if the values are the same, return empty patch24964if (source == target)24965{24966return result;24967}2496824969if (source.type() != target.type())24970{24971// different types: replace value24972result.push_back(24973{24974{"op", "replace"}, {"path", path}, {"value", target}24975});24976return result;24977}2497824979switch (source.type())24980{24981case value_t::array:24982{24983// first pass: traverse common elements24984std::size_t i = 0;24985while (i < source.size() && i < target.size())24986{24987// recursive call to compare array values at index i24988auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));24989result.insert(result.end(), temp_diff.begin(), temp_diff.end());24990++i;24991}2499224993// i now reached the end of at least one array24994// in a second pass, traverse the remaining elements2499524996// remove my remaining elements24997const auto end_index = static_cast<difference_type>(result.size());24998while (i < source.size())24999{25000// add operations in reverse order to avoid invalid25001// indices25002result.insert(result.begin() + end_index, object(25003{25004{"op", "remove"},25005{"path", path + "/" + std::to_string(i)}25006}));25007++i;25008}2500925010// add other remaining elements25011while (i < target.size())25012{25013result.push_back(25014{25015{"op", "add"},25016{"path", path + "/-"},25017{"value", target[i]}25018});25019++i;25020}2502125022break;25023}2502425025case value_t::object:25026{25027// first pass: traverse this object's elements25028for (auto it = source.cbegin(); it != source.cend(); ++it)25029{25030// escape the key name to be used in a JSON patch25031const auto key = json_pointer::escape(it.key());2503225033if (target.find(it.key()) != target.end())25034{25035// recursive call to compare object values at key it25036auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);25037result.insert(result.end(), temp_diff.begin(), temp_diff.end());25038}25039else25040{25041// found a key that is not in o -> remove it25042result.push_back(object(25043{25044{"op", "remove"}, {"path", path + "/" + key}25045}));25046}25047}2504825049// second pass: traverse other object's elements25050for (auto it = target.cbegin(); it != target.cend(); ++it)25051{25052if (source.find(it.key()) == source.end())25053{25054// found a key that is not in this -> add it25055const auto key = json_pointer::escape(it.key());25056result.push_back(25057{25058{"op", "add"}, {"path", path + "/" + key},25059{"value", it.value()}25060});25061}25062}2506325064break;25065}2506625067default:25068{25069// both primitive type: replace value25070result.push_back(25071{25072{"op", "replace"}, {"path", path}, {"value", target}25073});25074break;25075}25076}2507725078return result;25079}2508025081/// @}2508225083////////////////////////////////25084// JSON Merge Patch functions //25085////////////////////////////////2508625087/// @name JSON Merge Patch functions25088/// @{2508925090/*!25091@brief applies a JSON Merge Patch2509225093The merge patch format is primarily intended for use with the HTTP PATCH25094method as a means of describing a set of modifications to a target25095resource's content. This function applies a merge patch to the current25096JSON value.2509725098The function implements the following algorithm from Section 2 of25099[RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):2510025101```25102define MergePatch(Target, Patch):25103if Patch is an Object:25104if Target is not an Object:25105Target = {} // Ignore the contents and set it to an empty Object25106for each Name/Value pair in Patch:25107if Value is null:25108if Name exists in Target:25109remove the Name/Value pair from Target25110else:25111Target[Name] = MergePatch(Target[Name], Value)25112return Target25113else:25114return Patch25115```2511625117Thereby, `Target` is the current object; that is, the patch is applied to25118the current value.2511925120@param[in] apply_patch the patch to apply2512125122@complexity Linear in the lengths of @a patch.2512325124@liveexample{The following code shows how a JSON Merge Patch is applied to25125a JSON document.,merge_patch}2512625127@sa @ref patch -- apply a JSON patch25128@sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)2512925130@since version 3.0.025131*/25132void merge_patch(const basic_json& apply_patch)25133{25134if (apply_patch.is_object())25135{25136if (!is_object())25137{25138*this = object();25139}25140for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)25141{25142if (it.value().is_null())25143{25144erase(it.key());25145}25146else25147{25148operator[](it.key()).merge_patch(it.value());25149}25150}25151}25152else25153{25154*this = apply_patch;25155}25156}2515725158/// @}25159};2516025161/*!25162@brief user-defined to_string function for JSON values2516325164This function implements a user-defined to_string for JSON objects.2516525166@param[in] j a JSON object25167@return a std::string object25168*/2516925170NLOHMANN_BASIC_JSON_TPL_DECLARATION25171std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)25172{25173return j.dump();25174}25175} // namespace nlohmann2517625177///////////////////////25178// nonmember support //25179///////////////////////2518025181// specialization of std::swap, and std::hash25182namespace std25183{2518425185/// hash value for JSON objects25186template<>25187struct hash<nlohmann::json>25188{25189/*!25190@brief return a hash value for a JSON object2519125192@since version 1.0.025193*/25194std::size_t operator()(const nlohmann::json& j) const25195{25196return nlohmann::detail::hash(j);25197}25198};2519925200/// specialization for std::less<value_t>25201/// @note: do not remove the space after '<',25202/// see https://github.com/nlohmann/json/pull/67925203template<>25204struct less<::nlohmann::detail::value_t>25205{25206/*!25207@brief compare two value_t enum values25208@since version 3.0.025209*/25210bool operator()(nlohmann::detail::value_t lhs,25211nlohmann::detail::value_t rhs) const noexcept25212{25213return nlohmann::detail::operator<(lhs, rhs);25214}25215};2521625217// C++20 prohibit function specialization in the std namespace.25218#ifndef JSON_HAS_CPP_202521925220/*!25221@brief exchanges the values of two JSON objects2522225223@since version 1.0.025224*/25225template<>25226inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(25227is_nothrow_move_constructible<nlohmann::json>::value&&25228is_nothrow_move_assignable<nlohmann::json>::value25229)25230{25231j1.swap(j2);25232}2523325234#endif2523525236} // namespace std2523725238/*!25239@brief user-defined string literal for JSON values2524025241This operator implements a user-defined string literal for JSON objects. It25242can be used by adding `"_json"` to a string literal and returns a JSON object25243if no parse error occurred.2524425245@param[in] s a string representation of a JSON object25246@param[in] n the length of string @a s25247@return a JSON object2524825249@since version 1.0.025250*/25251JSON_HEDLEY_NON_NULL(1)25252inline nlohmann::json operator "" _json(const char* s, std::size_t n)25253{25254return nlohmann::json::parse(s, s + n);25255}2525625257/*!25258@brief user-defined string literal for JSON pointer2525925260This operator implements a user-defined string literal for JSON Pointers. It25261can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer25262object if no parse error occurred.2526325264@param[in] s a string representation of a JSON Pointer25265@param[in] n the length of string @a s25266@return a JSON pointer object2526725268@since version 2.0.025269*/25270JSON_HEDLEY_NON_NULL(1)25271inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)25272{25273return nlohmann::json::json_pointer(std::string(s, n));25274}2527525276// #include <nlohmann/detail/macro_unscope.hpp>252772527825279// restore GCC/clang diagnostic settings25280#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)25281#pragma GCC diagnostic pop25282#endif25283#if defined(__clang__)25284#pragma GCC diagnostic pop25285#endif2528625287// clean up25288#undef JSON_ASSERT25289#undef JSON_INTERNAL_CATCH25290#undef JSON_CATCH25291#undef JSON_THROW25292#undef JSON_TRY25293#undef JSON_HAS_CPP_1425294#undef JSON_HAS_CPP_1725295#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION25296#undef NLOHMANN_BASIC_JSON_TPL25297#undef JSON_EXPLICIT2529825299// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>25300#undef JSON_HEDLEY_ALWAYS_INLINE25301#undef JSON_HEDLEY_ARM_VERSION25302#undef JSON_HEDLEY_ARM_VERSION_CHECK25303#undef JSON_HEDLEY_ARRAY_PARAM25304#undef JSON_HEDLEY_ASSUME25305#undef JSON_HEDLEY_BEGIN_C_DECLS25306#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE25307#undef JSON_HEDLEY_CLANG_HAS_BUILTIN25308#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE25309#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE25310#undef JSON_HEDLEY_CLANG_HAS_EXTENSION25311#undef JSON_HEDLEY_CLANG_HAS_FEATURE25312#undef JSON_HEDLEY_CLANG_HAS_WARNING25313#undef JSON_HEDLEY_COMPCERT_VERSION25314#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK25315#undef JSON_HEDLEY_CONCAT25316#undef JSON_HEDLEY_CONCAT325317#undef JSON_HEDLEY_CONCAT3_EX25318#undef JSON_HEDLEY_CONCAT_EX25319#undef JSON_HEDLEY_CONST25320#undef JSON_HEDLEY_CONSTEXPR25321#undef JSON_HEDLEY_CONST_CAST25322#undef JSON_HEDLEY_CPP_CAST25323#undef JSON_HEDLEY_CRAY_VERSION25324#undef JSON_HEDLEY_CRAY_VERSION_CHECK25325#undef JSON_HEDLEY_C_DECL25326#undef JSON_HEDLEY_DEPRECATED25327#undef JSON_HEDLEY_DEPRECATED_FOR25328#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL25329#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_25330#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED25331#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES25332#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS25333#undef JSON_HEDLEY_DIAGNOSTIC_POP25334#undef JSON_HEDLEY_DIAGNOSTIC_PUSH25335#undef JSON_HEDLEY_DMC_VERSION25336#undef JSON_HEDLEY_DMC_VERSION_CHECK25337#undef JSON_HEDLEY_EMPTY_BASES25338#undef JSON_HEDLEY_EMSCRIPTEN_VERSION25339#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK25340#undef JSON_HEDLEY_END_C_DECLS25341#undef JSON_HEDLEY_FLAGS25342#undef JSON_HEDLEY_FLAGS_CAST25343#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE25344#undef JSON_HEDLEY_GCC_HAS_BUILTIN25345#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE25346#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE25347#undef JSON_HEDLEY_GCC_HAS_EXTENSION25348#undef JSON_HEDLEY_GCC_HAS_FEATURE25349#undef JSON_HEDLEY_GCC_HAS_WARNING25350#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK25351#undef JSON_HEDLEY_GCC_VERSION25352#undef JSON_HEDLEY_GCC_VERSION_CHECK25353#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE25354#undef JSON_HEDLEY_GNUC_HAS_BUILTIN25355#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE25356#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE25357#undef JSON_HEDLEY_GNUC_HAS_EXTENSION25358#undef JSON_HEDLEY_GNUC_HAS_FEATURE25359#undef JSON_HEDLEY_GNUC_HAS_WARNING25360#undef JSON_HEDLEY_GNUC_VERSION25361#undef JSON_HEDLEY_GNUC_VERSION_CHECK25362#undef JSON_HEDLEY_HAS_ATTRIBUTE25363#undef JSON_HEDLEY_HAS_BUILTIN25364#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE25365#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS25366#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE25367#undef JSON_HEDLEY_HAS_EXTENSION25368#undef JSON_HEDLEY_HAS_FEATURE25369#undef JSON_HEDLEY_HAS_WARNING25370#undef JSON_HEDLEY_IAR_VERSION25371#undef JSON_HEDLEY_IAR_VERSION_CHECK25372#undef JSON_HEDLEY_IBM_VERSION25373#undef JSON_HEDLEY_IBM_VERSION_CHECK25374#undef JSON_HEDLEY_IMPORT25375#undef JSON_HEDLEY_INLINE25376#undef JSON_HEDLEY_INTEL_VERSION25377#undef JSON_HEDLEY_INTEL_VERSION_CHECK25378#undef JSON_HEDLEY_IS_CONSTANT25379#undef JSON_HEDLEY_IS_CONSTEXPR_25380#undef JSON_HEDLEY_LIKELY25381#undef JSON_HEDLEY_MALLOC25382#undef JSON_HEDLEY_MESSAGE25383#undef JSON_HEDLEY_MSVC_VERSION25384#undef JSON_HEDLEY_MSVC_VERSION_CHECK25385#undef JSON_HEDLEY_NEVER_INLINE25386#undef JSON_HEDLEY_NON_NULL25387#undef JSON_HEDLEY_NO_ESCAPE25388#undef JSON_HEDLEY_NO_RETURN25389#undef JSON_HEDLEY_NO_THROW25390#undef JSON_HEDLEY_NULL25391#undef JSON_HEDLEY_PELLES_VERSION25392#undef JSON_HEDLEY_PELLES_VERSION_CHECK25393#undef JSON_HEDLEY_PGI_VERSION25394#undef JSON_HEDLEY_PGI_VERSION_CHECK25395#undef JSON_HEDLEY_PREDICT25396#undef JSON_HEDLEY_PRINTF_FORMAT25397#undef JSON_HEDLEY_PRIVATE25398#undef JSON_HEDLEY_PUBLIC25399#undef JSON_HEDLEY_PURE25400#undef JSON_HEDLEY_REINTERPRET_CAST25401#undef JSON_HEDLEY_REQUIRE25402#undef JSON_HEDLEY_REQUIRE_CONSTEXPR25403#undef JSON_HEDLEY_REQUIRE_MSG25404#undef JSON_HEDLEY_RESTRICT25405#undef JSON_HEDLEY_RETURNS_NON_NULL25406#undef JSON_HEDLEY_SENTINEL25407#undef JSON_HEDLEY_STATIC_ASSERT25408#undef JSON_HEDLEY_STATIC_CAST25409#undef JSON_HEDLEY_STRINGIFY25410#undef JSON_HEDLEY_STRINGIFY_EX25411#undef JSON_HEDLEY_SUNPRO_VERSION25412#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK25413#undef JSON_HEDLEY_TINYC_VERSION25414#undef JSON_HEDLEY_TINYC_VERSION_CHECK25415#undef JSON_HEDLEY_TI_ARMCL_VERSION25416#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK25417#undef JSON_HEDLEY_TI_CL2000_VERSION25418#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK25419#undef JSON_HEDLEY_TI_CL430_VERSION25420#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK25421#undef JSON_HEDLEY_TI_CL6X_VERSION25422#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK25423#undef JSON_HEDLEY_TI_CL7X_VERSION25424#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK25425#undef JSON_HEDLEY_TI_CLPRU_VERSION25426#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK25427#undef JSON_HEDLEY_TI_VERSION25428#undef JSON_HEDLEY_TI_VERSION_CHECK25429#undef JSON_HEDLEY_UNAVAILABLE25430#undef JSON_HEDLEY_UNLIKELY25431#undef JSON_HEDLEY_UNPREDICTABLE25432#undef JSON_HEDLEY_UNREACHABLE25433#undef JSON_HEDLEY_UNREACHABLE_RETURN25434#undef JSON_HEDLEY_VERSION25435#undef JSON_HEDLEY_VERSION_DECODE_MAJOR25436#undef JSON_HEDLEY_VERSION_DECODE_MINOR25437#undef JSON_HEDLEY_VERSION_DECODE_REVISION25438#undef JSON_HEDLEY_VERSION_ENCODE25439#undef JSON_HEDLEY_WARNING25440#undef JSON_HEDLEY_WARN_UNUSED_RESULT25441#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG25442#undef JSON_HEDLEY_FALL_THROUGH25443254442544525446#endif // INCLUDE_NLOHMANN_JSON_HPP_254472544825449