LCOV - code coverage report
Current view: top level - src/foreign/nlohmann - json.hpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 41.3 % 1084 448
Test Date: 2024-10-24 15:46:30 Functions: 59.0 % 117 69

            Line data    Source code
       1              : /*
       2              :     __ _____ _____ _____
       3              :  __|  |   __|     |   | |  JSON for Modern C++
       4              : |  |  |__   |  |  | | | |  version 3.10.5
       5              : |_____|_____|_____|_|___|  https://github.com/nlohmann/json
       6              : 
       7              : Licensed under the MIT License <http://opensource.org/licenses/MIT>.
       8              : SPDX-License-Identifier: MIT
       9              : Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
      10              : 
      11              : Permission is hereby  granted, free of charge, to any  person obtaining a copy
      12              : of this software and associated  documentation files (the "Software"), to deal
      13              : in the Software  without restriction, including without  limitation the rights
      14              : to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
      15              : copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
      16              : furnished to do so, subject to the following conditions:
      17              : 
      18              : The above copyright notice and this permission notice shall be included in all
      19              : copies or substantial portions of the Software.
      20              : 
      21              : THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
      22              : IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
      23              : FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
      24              : AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
      25              : LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      26              : OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
      27              : SOFTWARE.
      28              : */
      29              : 
      30              : /****************************************************************************\
      31              :  * Note on documentation: The source files contain links to the online      *
      32              :  * documentation of the public API at https://json.nlohmann.me. This URL    *
      33              :  * contains the most recent documentation and should also be applicable to  *
      34              :  * previous versions; documentation for deprecated functions is not         *
      35              :  * removed, but marked deprecated. See "Generate documentation" section in  *
      36              :  * file doc/README.md.                                                      *
      37              : \****************************************************************************/
      38              : 
      39              : #ifndef INCLUDE_NLOHMANN_JSON_HPP_
      40              : #define INCLUDE_NLOHMANN_JSON_HPP_
      41              : 
      42              : #define NLOHMANN_JSON_VERSION_MAJOR 3
      43              : #define NLOHMANN_JSON_VERSION_MINOR 10
      44              : #define NLOHMANN_JSON_VERSION_PATCH 5
      45              : 
      46              : #include <algorithm> // all_of, find, for_each
      47              : #include <cstddef> // nullptr_t, ptrdiff_t, size_t
      48              : #include <functional> // hash, less
      49              : #include <initializer_list> // initializer_list
      50              : #ifndef JSON_NO_IO
      51              :     #include <iosfwd> // istream, ostream
      52              : #endif  // JSON_NO_IO
      53              : #include <iterator> // random_access_iterator_tag
      54              : #include <memory> // unique_ptr
      55              : #include <numeric> // accumulate
      56              : #include <string> // string, stoi, to_string
      57              : #include <utility> // declval, forward, move, pair, swap
      58              : #include <vector> // vector
      59              : 
      60              : // #include <nlohmann/adl_serializer.hpp>
      61              : 
      62              : 
      63              : #include <type_traits>
      64              : #include <utility>
      65              : 
      66              : // #include <nlohmann/detail/conversions/from_json.hpp>
      67              : 
      68              : 
      69              : #include <algorithm> // transform
      70              : #include <array> // array
      71              : #include <forward_list> // forward_list
      72              : #include <iterator> // inserter, front_inserter, end
      73              : #include <map> // map
      74              : #include <string> // string
      75              : #include <tuple> // tuple, make_tuple
      76              : #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
      77              : #include <unordered_map> // unordered_map
      78              : #include <utility> // pair, declval
      79              : #include <valarray> // valarray
      80              : 
      81              : // #include <nlohmann/detail/exceptions.hpp>
      82              : 
      83              : 
      84              : #include <exception> // exception
      85              : #include <stdexcept> // runtime_error
      86              : #include <string> // to_string
      87              : #include <vector> // vector
      88              : 
      89              : // #include <nlohmann/detail/value_t.hpp>
      90              : 
      91              : 
      92              : #include <array> // array
      93              : #include <cstddef> // size_t
      94              : #include <cstdint> // uint8_t
      95              : #include <string> // string
      96              : 
      97              : namespace nlohmann
      98              : {
      99              : namespace detail
     100              : {
     101              : ///////////////////////////
     102              : // JSON type enumeration //
     103              : ///////////////////////////
     104              : 
     105              : /*!
     106              : @brief the JSON type enumeration
     107              : 
     108              : This enumeration collects the different JSON types. It is internally used to
     109              : distinguish the stored values, and the functions @ref basic_json::is_null(),
     110              : @ref basic_json::is_object(), @ref basic_json::is_array(),
     111              : @ref basic_json::is_string(), @ref basic_json::is_boolean(),
     112              : @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
     113              : @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
     114              : @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
     115              : @ref basic_json::is_structured() rely on it.
     116              : 
     117              : @note There are three enumeration entries (number_integer, number_unsigned, and
     118              : number_float), because the library distinguishes these three types for numbers:
     119              : @ref basic_json::number_unsigned_t is used for unsigned integers,
     120              : @ref basic_json::number_integer_t is used for signed integers, and
     121              : @ref basic_json::number_float_t is used for floating-point numbers or to
     122              : approximate integers which do not fit in the limits of their respective type.
     123              : 
     124              : @sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON
     125              : value with the default value for a given type
     126              : 
     127              : @since version 1.0.0
     128              : */
     129              : enum class value_t : std::uint8_t
     130              : {
     131              :     null,             ///< null value
     132              :     object,           ///< object (unordered set of name/value pairs)
     133              :     array,            ///< array (ordered collection of values)
     134              :     string,           ///< string value
     135              :     boolean,          ///< boolean value
     136              :     number_integer,   ///< number value (signed integer)
     137              :     number_unsigned,  ///< number value (unsigned integer)
     138              :     number_float,     ///< number value (floating-point)
     139              :     binary,           ///< binary array (ordered collection of bytes)
     140              :     discarded         ///< discarded by the parser callback function
     141              : };
     142              : 
     143              : /*!
     144              : @brief comparison operator for JSON types
     145              : 
     146              : Returns an ordering that is similar to Python:
     147              : - order: null < boolean < number < object < array < string < binary
     148              : - furthermore, each type is not smaller than itself
     149              : - discarded values are not comparable
     150              : - binary is represented as a b"" string in python and directly comparable to a
     151              :   string; however, making a binary array directly comparable with a string would
     152              :   be surprising behavior in a JSON file.
     153              : 
     154              : @since version 1.0.0
     155              : */
     156              : inline bool operator<(const value_t lhs, const value_t rhs) noexcept
     157              : {
     158              :     static constexpr std::array<std::uint8_t, 9> order = {{
     159              :             0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
     160              :             1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
     161              :             6 /* binary */
     162              :         }
     163              :     };
     164              : 
     165            0 :     const auto l_index = static_cast<std::size_t>(lhs);
     166            0 :     const auto r_index = static_cast<std::size_t>(rhs);
     167            0 :     return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
     168              : }
     169              : }  // namespace detail
     170              : }  // namespace nlohmann
     171              : 
     172              : // #include <nlohmann/detail/string_escape.hpp>
     173              : 
     174              : 
     175              : #include <string>
     176              : // #include <nlohmann/detail/macro_scope.hpp>
     177              : 
     178              : 
     179              : #include <utility> // declval, pair
     180              : // #include <nlohmann/thirdparty/hedley/hedley.hpp>
     181              : 
     182              : 
     183              : /* Hedley - https://nemequ.github.io/hedley
     184              :  * Created by Evan Nemerson <evan@nemerson.com>
     185              :  *
     186              :  * To the extent possible under law, the author(s) have dedicated all
     187              :  * copyright and related and neighboring rights to this software to
     188              :  * the public domain worldwide. This software is distributed without
     189              :  * any warranty.
     190              :  *
     191              :  * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
     192              :  * SPDX-License-Identifier: CC0-1.0
     193              :  */
     194              : 
     195              : #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
     196              : #if defined(JSON_HEDLEY_VERSION)
     197              :     #undef JSON_HEDLEY_VERSION
     198              : #endif
     199              : #define JSON_HEDLEY_VERSION 15
     200              : 
     201              : #if defined(JSON_HEDLEY_STRINGIFY_EX)
     202              :     #undef JSON_HEDLEY_STRINGIFY_EX
     203              : #endif
     204              : #define JSON_HEDLEY_STRINGIFY_EX(x) #x
     205              : 
     206              : #if defined(JSON_HEDLEY_STRINGIFY)
     207              :     #undef JSON_HEDLEY_STRINGIFY
     208              : #endif
     209              : #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
     210              : 
     211              : #if defined(JSON_HEDLEY_CONCAT_EX)
     212              :     #undef JSON_HEDLEY_CONCAT_EX
     213              : #endif
     214              : #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
     215              : 
     216              : #if defined(JSON_HEDLEY_CONCAT)
     217              :     #undef JSON_HEDLEY_CONCAT
     218              : #endif
     219              : #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
     220              : 
     221              : #if defined(JSON_HEDLEY_CONCAT3_EX)
     222              :     #undef JSON_HEDLEY_CONCAT3_EX
     223              : #endif
     224              : #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
     225              : 
     226              : #if defined(JSON_HEDLEY_CONCAT3)
     227              :     #undef JSON_HEDLEY_CONCAT3
     228              : #endif
     229              : #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
     230              : 
     231              : #if defined(JSON_HEDLEY_VERSION_ENCODE)
     232              :     #undef JSON_HEDLEY_VERSION_ENCODE
     233              : #endif
     234              : #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
     235              : 
     236              : #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
     237              :     #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
     238              : #endif
     239              : #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
     240              : 
     241              : #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
     242              :     #undef JSON_HEDLEY_VERSION_DECODE_MINOR
     243              : #endif
     244              : #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
     245              : 
     246              : #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
     247              :     #undef JSON_HEDLEY_VERSION_DECODE_REVISION
     248              : #endif
     249              : #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
     250              : 
     251              : #if defined(JSON_HEDLEY_GNUC_VERSION)
     252              :     #undef JSON_HEDLEY_GNUC_VERSION
     253              : #endif
     254              : #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
     255              :     #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
     256              : #elif defined(__GNUC__)
     257              :     #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
     258              : #endif
     259              : 
     260              : #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
     261              :     #undef JSON_HEDLEY_GNUC_VERSION_CHECK
     262              : #endif
     263              : #if defined(JSON_HEDLEY_GNUC_VERSION)
     264              :     #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     265              : #else
     266              :     #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
     267              : #endif
     268              : 
     269              : #if defined(JSON_HEDLEY_MSVC_VERSION)
     270              :     #undef JSON_HEDLEY_MSVC_VERSION
     271              : #endif
     272              : #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
     273              :     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
     274              : #elif defined(_MSC_FULL_VER) && !defined(__ICL)
     275              :     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
     276              : #elif defined(_MSC_VER) && !defined(__ICL)
     277              :     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
     278              : #endif
     279              : 
     280              : #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
     281              :     #undef JSON_HEDLEY_MSVC_VERSION_CHECK
     282              : #endif
     283              : #if !defined(JSON_HEDLEY_MSVC_VERSION)
     284              :     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
     285              : #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
     286              :     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
     287              : #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
     288              :     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
     289              : #else
     290              :     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
     291              : #endif
     292              : 
     293              : #if defined(JSON_HEDLEY_INTEL_VERSION)
     294              :     #undef JSON_HEDLEY_INTEL_VERSION
     295              : #endif
     296              : #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
     297              :     #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
     298              : #elif defined(__INTEL_COMPILER) && !defined(__ICL)
     299              :     #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
     300              : #endif
     301              : 
     302              : #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
     303              :     #undef JSON_HEDLEY_INTEL_VERSION_CHECK
     304              : #endif
     305              : #if defined(JSON_HEDLEY_INTEL_VERSION)
     306              :     #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     307              : #else
     308              :     #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
     309              : #endif
     310              : 
     311              : #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
     312              :     #undef JSON_HEDLEY_INTEL_CL_VERSION
     313              : #endif
     314              : #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
     315              :     #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
     316              : #endif
     317              : 
     318              : #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
     319              :     #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
     320              : #endif
     321              : #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
     322              :     #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     323              : #else
     324              :     #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
     325              : #endif
     326              : 
     327              : #if defined(JSON_HEDLEY_PGI_VERSION)
     328              :     #undef JSON_HEDLEY_PGI_VERSION
     329              : #endif
     330              : #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
     331              :     #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
     332              : #endif
     333              : 
     334              : #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
     335              :     #undef JSON_HEDLEY_PGI_VERSION_CHECK
     336              : #endif
     337              : #if defined(JSON_HEDLEY_PGI_VERSION)
     338              :     #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     339              : #else
     340              :     #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
     341              : #endif
     342              : 
     343              : #if defined(JSON_HEDLEY_SUNPRO_VERSION)
     344              :     #undef JSON_HEDLEY_SUNPRO_VERSION
     345              : #endif
     346              : #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
     347              :     #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)
     348              : #elif defined(__SUNPRO_C)
     349              :     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
     350              : #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
     351              :     #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)
     352              : #elif defined(__SUNPRO_CC)
     353              :     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
     354              : #endif
     355              : 
     356              : #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
     357              :     #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
     358              : #endif
     359              : #if defined(JSON_HEDLEY_SUNPRO_VERSION)
     360              :     #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     361              : #else
     362              :     #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
     363              : #endif
     364              : 
     365              : #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
     366              :     #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
     367              : #endif
     368              : #if defined(__EMSCRIPTEN__)
     369              :     #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
     370              : #endif
     371              : 
     372              : #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
     373              :     #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
     374              : #endif
     375              : #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
     376              :     #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     377              : #else
     378              :     #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
     379              : #endif
     380              : 
     381              : #if defined(JSON_HEDLEY_ARM_VERSION)
     382              :     #undef JSON_HEDLEY_ARM_VERSION
     383              : #endif
     384              : #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
     385              :     #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
     386              : #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
     387              :     #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
     388              : #endif
     389              : 
     390              : #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
     391              :     #undef JSON_HEDLEY_ARM_VERSION_CHECK
     392              : #endif
     393              : #if defined(JSON_HEDLEY_ARM_VERSION)
     394              :     #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     395              : #else
     396              :     #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
     397              : #endif
     398              : 
     399              : #if defined(JSON_HEDLEY_IBM_VERSION)
     400              :     #undef JSON_HEDLEY_IBM_VERSION
     401              : #endif
     402              : #if defined(__ibmxl__)
     403              :     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
     404              : #elif defined(__xlC__) && defined(__xlC_ver__)
     405              :     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
     406              : #elif defined(__xlC__)
     407              :     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
     408              : #endif
     409              : 
     410              : #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
     411              :     #undef JSON_HEDLEY_IBM_VERSION_CHECK
     412              : #endif
     413              : #if defined(JSON_HEDLEY_IBM_VERSION)
     414              :     #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     415              : #else
     416              :     #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
     417              : #endif
     418              : 
     419              : #if defined(JSON_HEDLEY_TI_VERSION)
     420              :     #undef JSON_HEDLEY_TI_VERSION
     421              : #endif
     422              : #if \
     423              :     defined(__TI_COMPILER_VERSION__) && \
     424              :     ( \
     425              :       defined(__TMS470__) || defined(__TI_ARM__) || \
     426              :       defined(__MSP430__) || \
     427              :       defined(__TMS320C2000__) \
     428              :     )
     429              : #if (__TI_COMPILER_VERSION__ >= 16000000)
     430              :     #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
     431              : #endif
     432              : #endif
     433              : 
     434              : #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
     435              :     #undef JSON_HEDLEY_TI_VERSION_CHECK
     436              : #endif
     437              : #if defined(JSON_HEDLEY_TI_VERSION)
     438              :     #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     439              : #else
     440              :     #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
     441              : #endif
     442              : 
     443              : #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
     444              :     #undef JSON_HEDLEY_TI_CL2000_VERSION
     445              : #endif
     446              : #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
     447              :     #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
     448              : #endif
     449              : 
     450              : #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
     451              :     #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
     452              : #endif
     453              : #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
     454              :     #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     455              : #else
     456              :     #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
     457              : #endif
     458              : 
     459              : #if defined(JSON_HEDLEY_TI_CL430_VERSION)
     460              :     #undef JSON_HEDLEY_TI_CL430_VERSION
     461              : #endif
     462              : #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
     463              :     #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
     464              : #endif
     465              : 
     466              : #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
     467              :     #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
     468              : #endif
     469              : #if defined(JSON_HEDLEY_TI_CL430_VERSION)
     470              :     #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     471              : #else
     472              :     #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
     473              : #endif
     474              : 
     475              : #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
     476              :     #undef JSON_HEDLEY_TI_ARMCL_VERSION
     477              : #endif
     478              : #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
     479              :     #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
     480              : #endif
     481              : 
     482              : #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
     483              :     #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
     484              : #endif
     485              : #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
     486              :     #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     487              : #else
     488              :     #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
     489              : #endif
     490              : 
     491              : #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
     492              :     #undef JSON_HEDLEY_TI_CL6X_VERSION
     493              : #endif
     494              : #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
     495              :     #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
     496              : #endif
     497              : 
     498              : #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
     499              :     #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
     500              : #endif
     501              : #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
     502              :     #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     503              : #else
     504              :     #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
     505              : #endif
     506              : 
     507              : #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
     508              :     #undef JSON_HEDLEY_TI_CL7X_VERSION
     509              : #endif
     510              : #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
     511              :     #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
     512              : #endif
     513              : 
     514              : #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
     515              :     #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
     516              : #endif
     517              : #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
     518              :     #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     519              : #else
     520              :     #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
     521              : #endif
     522              : 
     523              : #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
     524              :     #undef JSON_HEDLEY_TI_CLPRU_VERSION
     525              : #endif
     526              : #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
     527              :     #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
     528              : #endif
     529              : 
     530              : #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
     531              :     #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
     532              : #endif
     533              : #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
     534              :     #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     535              : #else
     536              :     #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
     537              : #endif
     538              : 
     539              : #if defined(JSON_HEDLEY_CRAY_VERSION)
     540              :     #undef JSON_HEDLEY_CRAY_VERSION
     541              : #endif
     542              : #if defined(_CRAYC)
     543              :     #if defined(_RELEASE_PATCHLEVEL)
     544              :         #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
     545              :     #else
     546              :         #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
     547              :     #endif
     548              : #endif
     549              : 
     550              : #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
     551              :     #undef JSON_HEDLEY_CRAY_VERSION_CHECK
     552              : #endif
     553              : #if defined(JSON_HEDLEY_CRAY_VERSION)
     554              :     #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     555              : #else
     556              :     #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
     557              : #endif
     558              : 
     559              : #if defined(JSON_HEDLEY_IAR_VERSION)
     560              :     #undef JSON_HEDLEY_IAR_VERSION
     561              : #endif
     562              : #if defined(__IAR_SYSTEMS_ICC__)
     563              :     #if __VER__ > 1000
     564              :         #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
     565              :     #else
     566              :         #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
     567              :     #endif
     568              : #endif
     569              : 
     570              : #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
     571              :     #undef JSON_HEDLEY_IAR_VERSION_CHECK
     572              : #endif
     573              : #if defined(JSON_HEDLEY_IAR_VERSION)
     574              :     #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     575              : #else
     576              :     #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
     577              : #endif
     578              : 
     579              : #if defined(JSON_HEDLEY_TINYC_VERSION)
     580              :     #undef JSON_HEDLEY_TINYC_VERSION
     581              : #endif
     582              : #if defined(__TINYC__)
     583              :     #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
     584              : #endif
     585              : 
     586              : #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
     587              :     #undef JSON_HEDLEY_TINYC_VERSION_CHECK
     588              : #endif
     589              : #if defined(JSON_HEDLEY_TINYC_VERSION)
     590              :     #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     591              : #else
     592              :     #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
     593              : #endif
     594              : 
     595              : #if defined(JSON_HEDLEY_DMC_VERSION)
     596              :     #undef JSON_HEDLEY_DMC_VERSION
     597              : #endif
     598              : #if defined(__DMC__)
     599              :     #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
     600              : #endif
     601              : 
     602              : #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
     603              :     #undef JSON_HEDLEY_DMC_VERSION_CHECK
     604              : #endif
     605              : #if defined(JSON_HEDLEY_DMC_VERSION)
     606              :     #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     607              : #else
     608              :     #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
     609              : #endif
     610              : 
     611              : #if defined(JSON_HEDLEY_COMPCERT_VERSION)
     612              :     #undef JSON_HEDLEY_COMPCERT_VERSION
     613              : #endif
     614              : #if defined(__COMPCERT_VERSION__)
     615              :     #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
     616              : #endif
     617              : 
     618              : #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
     619              :     #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
     620              : #endif
     621              : #if defined(JSON_HEDLEY_COMPCERT_VERSION)
     622              :     #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     623              : #else
     624              :     #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
     625              : #endif
     626              : 
     627              : #if defined(JSON_HEDLEY_PELLES_VERSION)
     628              :     #undef JSON_HEDLEY_PELLES_VERSION
     629              : #endif
     630              : #if defined(__POCC__)
     631              :     #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
     632              : #endif
     633              : 
     634              : #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
     635              :     #undef JSON_HEDLEY_PELLES_VERSION_CHECK
     636              : #endif
     637              : #if defined(JSON_HEDLEY_PELLES_VERSION)
     638              :     #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     639              : #else
     640              :     #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
     641              : #endif
     642              : 
     643              : #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
     644              :     #undef JSON_HEDLEY_MCST_LCC_VERSION
     645              : #endif
     646              : #if defined(__LCC__) && defined(__LCC_MINOR__)
     647              :     #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
     648              : #endif
     649              : 
     650              : #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
     651              :     #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
     652              : #endif
     653              : #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
     654              :     #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     655              : #else
     656              :     #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
     657              : #endif
     658              : 
     659              : #if defined(JSON_HEDLEY_GCC_VERSION)
     660              :     #undef JSON_HEDLEY_GCC_VERSION
     661              : #endif
     662              : #if \
     663              :     defined(JSON_HEDLEY_GNUC_VERSION) && \
     664              :     !defined(__clang__) && \
     665              :     !defined(JSON_HEDLEY_INTEL_VERSION) && \
     666              :     !defined(JSON_HEDLEY_PGI_VERSION) && \
     667              :     !defined(JSON_HEDLEY_ARM_VERSION) && \
     668              :     !defined(JSON_HEDLEY_CRAY_VERSION) && \
     669              :     !defined(JSON_HEDLEY_TI_VERSION) && \
     670              :     !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
     671              :     !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
     672              :     !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
     673              :     !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
     674              :     !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
     675              :     !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
     676              :     !defined(__COMPCERT__) && \
     677              :     !defined(JSON_HEDLEY_MCST_LCC_VERSION)
     678              :     #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
     679              : #endif
     680              : 
     681              : #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
     682              :     #undef JSON_HEDLEY_GCC_VERSION_CHECK
     683              : #endif
     684              : #if defined(JSON_HEDLEY_GCC_VERSION)
     685              :     #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
     686              : #else
     687              :     #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
     688              : #endif
     689              : 
     690              : #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
     691              :     #undef JSON_HEDLEY_HAS_ATTRIBUTE
     692              : #endif
     693              : #if \
     694              :   defined(__has_attribute) && \
     695              :   ( \
     696              :     (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
     697              :   )
     698              : #  define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
     699              : #else
     700              : #  define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
     701              : #endif
     702              : 
     703              : #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
     704              :     #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
     705              : #endif
     706              : #if defined(__has_attribute)
     707              :     #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
     708              : #else
     709              :     #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
     710              : #endif
     711              : 
     712              : #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
     713              :     #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
     714              : #endif
     715              : #if defined(__has_attribute)
     716              :     #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
     717              : #else
     718              :     #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
     719              : #endif
     720              : 
     721              : #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
     722              :     #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
     723              : #endif
     724              : #if \
     725              :     defined(__has_cpp_attribute) && \
     726              :     defined(__cplusplus) && \
     727              :     (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
     728              :     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
     729              : #else
     730              :     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
     731              : #endif
     732              : 
     733              : #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
     734              :     #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
     735              : #endif
     736              : #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
     737              :     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
     738              : #elif \
     739              :     !defined(JSON_HEDLEY_PGI_VERSION) && \
     740              :     !defined(JSON_HEDLEY_IAR_VERSION) && \
     741              :     (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
     742              :     (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
     743              :     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
     744              : #else
     745              :     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
     746              : #endif
     747              : 
     748              : #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
     749              :     #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
     750              : #endif
     751              : #if defined(__has_cpp_attribute) && defined(__cplusplus)
     752              :     #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
     753              : #else
     754              :     #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
     755              : #endif
     756              : 
     757              : #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
     758              :     #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
     759              : #endif
     760              : #if defined(__has_cpp_attribute) && defined(__cplusplus)
     761              :     #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
     762              : #else
     763              :     #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
     764              : #endif
     765              : 
     766              : #if defined(JSON_HEDLEY_HAS_BUILTIN)
     767              :     #undef JSON_HEDLEY_HAS_BUILTIN
     768              : #endif
     769              : #if defined(__has_builtin)
     770              :     #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
     771              : #else
     772              :     #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
     773              : #endif
     774              : 
     775              : #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
     776              :     #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
     777              : #endif
     778              : #if defined(__has_builtin)
     779              :     #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
     780              : #else
     781              :     #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
     782              : #endif
     783              : 
     784              : #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
     785              :     #undef JSON_HEDLEY_GCC_HAS_BUILTIN
     786              : #endif
     787              : #if defined(__has_builtin)
     788              :     #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
     789              : #else
     790              :     #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
     791              : #endif
     792              : 
     793              : #if defined(JSON_HEDLEY_HAS_FEATURE)
     794              :     #undef JSON_HEDLEY_HAS_FEATURE
     795              : #endif
     796              : #if defined(__has_feature)
     797              :     #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
     798              : #else
     799              :     #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
     800              : #endif
     801              : 
     802              : #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
     803              :     #undef JSON_HEDLEY_GNUC_HAS_FEATURE
     804              : #endif
     805              : #if defined(__has_feature)
     806              :     #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
     807              : #else
     808              :     #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
     809              : #endif
     810              : 
     811              : #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
     812              :     #undef JSON_HEDLEY_GCC_HAS_FEATURE
     813              : #endif
     814              : #if defined(__has_feature)
     815              :     #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
     816              : #else
     817              :     #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
     818              : #endif
     819              : 
     820              : #if defined(JSON_HEDLEY_HAS_EXTENSION)
     821              :     #undef JSON_HEDLEY_HAS_EXTENSION
     822              : #endif
     823              : #if defined(__has_extension)
     824              :     #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
     825              : #else
     826              :     #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
     827              : #endif
     828              : 
     829              : #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
     830              :     #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
     831              : #endif
     832              : #if defined(__has_extension)
     833              :     #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
     834              : #else
     835              :     #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
     836              : #endif
     837              : 
     838              : #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
     839              :     #undef JSON_HEDLEY_GCC_HAS_EXTENSION
     840              : #endif
     841              : #if defined(__has_extension)
     842              :     #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
     843              : #else
     844              :     #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
     845              : #endif
     846              : 
     847              : #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
     848              :     #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
     849              : #endif
     850              : #if defined(__has_declspec_attribute)
     851              :     #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
     852              : #else
     853              :     #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
     854              : #endif
     855              : 
     856              : #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
     857              :     #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
     858              : #endif
     859              : #if defined(__has_declspec_attribute)
     860              :     #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
     861              : #else
     862              :     #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
     863              : #endif
     864              : 
     865              : #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
     866              :     #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
     867              : #endif
     868              : #if defined(__has_declspec_attribute)
     869              :     #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
     870              : #else
     871              :     #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
     872              : #endif
     873              : 
     874              : #if defined(JSON_HEDLEY_HAS_WARNING)
     875              :     #undef JSON_HEDLEY_HAS_WARNING
     876              : #endif
     877              : #if defined(__has_warning)
     878              :     #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
     879              : #else
     880              :     #define JSON_HEDLEY_HAS_WARNING(warning) (0)
     881              : #endif
     882              : 
     883              : #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
     884              :     #undef JSON_HEDLEY_GNUC_HAS_WARNING
     885              : #endif
     886              : #if defined(__has_warning)
     887              :     #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
     888              : #else
     889              :     #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
     890              : #endif
     891              : 
     892              : #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
     893              :     #undef JSON_HEDLEY_GCC_HAS_WARNING
     894              : #endif
     895              : #if defined(__has_warning)
     896              :     #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
     897              : #else
     898              :     #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
     899              : #endif
     900              : 
     901              : #if \
     902              :     (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
     903              :     defined(__clang__) || \
     904              :     JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
     905              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
     906              :     JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
     907              :     JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
     908              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
     909              :     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
     910              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
     911              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
     912              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
     913              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
     914              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
     915              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
     916              :     JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
     917              :     JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
     918              :     JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
     919              :     (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
     920              :     #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
     921              : #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
     922              :     #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
     923              : #else
     924              :     #define JSON_HEDLEY_PRAGMA(value)
     925              : #endif
     926              : 
     927              : #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
     928              :     #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
     929              : #endif
     930              : #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
     931              :     #undef JSON_HEDLEY_DIAGNOSTIC_POP
     932              : #endif
     933              : #if defined(__clang__)
     934              :     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
     935              :     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
     936              : #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
     937              :     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
     938              :     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
     939              : #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
     940              :     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
     941              :     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
     942              : #elif \
     943              :     JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
     944              :     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
     945              :     #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
     946              :     #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
     947              : #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
     948              :     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
     949              :     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
     950              : #elif \
     951              :     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
     952              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
     953              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
     954              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
     955              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
     956              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
     957              :     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
     958              :     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
     959              : #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
     960              :     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
     961              :     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
     962              : #else
     963              :     #define JSON_HEDLEY_DIAGNOSTIC_PUSH
     964              :     #define JSON_HEDLEY_DIAGNOSTIC_POP
     965              : #endif
     966              : 
     967              : /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
     968              :    HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
     969              : #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
     970              :     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
     971              : #endif
     972              : #if defined(__cplusplus)
     973              : #  if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
     974              : #    if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
     975              : #      if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
     976              : #        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
     977              :     JSON_HEDLEY_DIAGNOSTIC_PUSH \
     978              :     _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
     979              :     _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
     980              :     _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
     981              :     xpr \
     982              :     JSON_HEDLEY_DIAGNOSTIC_POP
     983              : #      else
     984              : #        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
     985              :     JSON_HEDLEY_DIAGNOSTIC_PUSH \
     986              :     _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
     987              :     _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
     988              :     xpr \
     989              :     JSON_HEDLEY_DIAGNOSTIC_POP
     990              : #      endif
     991              : #    else
     992              : #      define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
     993              :     JSON_HEDLEY_DIAGNOSTIC_PUSH \
     994              :     _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
     995              :     xpr \
     996              :     JSON_HEDLEY_DIAGNOSTIC_POP
     997              : #    endif
     998              : #  endif
     999              : #endif
    1000              : #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
    1001              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
    1002              : #endif
    1003              : 
    1004              : #if defined(JSON_HEDLEY_CONST_CAST)
    1005              :     #undef JSON_HEDLEY_CONST_CAST
    1006              : #endif
    1007              : #if defined(__cplusplus)
    1008              : #  define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
    1009              : #elif \
    1010              :   JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
    1011              :   JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
    1012              :   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    1013              : #  define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
    1014              :         JSON_HEDLEY_DIAGNOSTIC_PUSH \
    1015              :         JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
    1016              :         ((T) (expr)); \
    1017              :         JSON_HEDLEY_DIAGNOSTIC_POP \
    1018              :     }))
    1019              : #else
    1020              : #  define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
    1021              : #endif
    1022              : 
    1023              : #if defined(JSON_HEDLEY_REINTERPRET_CAST)
    1024              :     #undef JSON_HEDLEY_REINTERPRET_CAST
    1025              : #endif
    1026              : #if defined(__cplusplus)
    1027              :     #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
    1028              : #else
    1029              :     #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
    1030              : #endif
    1031              : 
    1032              : #if defined(JSON_HEDLEY_STATIC_CAST)
    1033              :     #undef JSON_HEDLEY_STATIC_CAST
    1034              : #endif
    1035              : #if defined(__cplusplus)
    1036              :     #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
    1037              : #else
    1038              :     #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
    1039              : #endif
    1040              : 
    1041              : #if defined(JSON_HEDLEY_CPP_CAST)
    1042              :     #undef JSON_HEDLEY_CPP_CAST
    1043              : #endif
    1044              : #if defined(__cplusplus)
    1045              : #  if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
    1046              : #    define JSON_HEDLEY_CPP_CAST(T, expr) \
    1047              :     JSON_HEDLEY_DIAGNOSTIC_PUSH \
    1048              :     _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
    1049              :     ((T) (expr)) \
    1050              :     JSON_HEDLEY_DIAGNOSTIC_POP
    1051              : #  elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
    1052              : #    define JSON_HEDLEY_CPP_CAST(T, expr) \
    1053              :     JSON_HEDLEY_DIAGNOSTIC_PUSH \
    1054              :     _Pragma("diag_suppress=Pe137") \
    1055              :     JSON_HEDLEY_DIAGNOSTIC_POP
    1056              : #  else
    1057              : #    define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
    1058              : #  endif
    1059              : #else
    1060              : #  define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
    1061              : #endif
    1062              : 
    1063              : #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
    1064              :     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
    1065              : #endif
    1066              : #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
    1067              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
    1068              : #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    1069              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
    1070              : #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    1071              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
    1072              : #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
    1073              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
    1074              : #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
    1075              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
    1076              : #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
    1077              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
    1078              : #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
    1079              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
    1080              : #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1081              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
    1082              : #elif \
    1083              :     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    1084              :     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1085              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    1086              :     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1087              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    1088              :     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1089              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1090              :     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1091              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    1092              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1093              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
    1094              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
    1095              : #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
    1096              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
    1097              : #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
    1098              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
    1099              : #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    1100              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
    1101              : #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
    1102              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
    1103              : #else
    1104              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
    1105              : #endif
    1106              : 
    1107              : #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
    1108              :     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
    1109              : #endif
    1110              : #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
    1111              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
    1112              : #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    1113              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
    1114              : #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    1115              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
    1116              : #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
    1117              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
    1118              : #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
    1119              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
    1120              : #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
    1121              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
    1122              : #elif \
    1123              :     JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
    1124              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
    1125              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1126              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
    1127              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
    1128              : #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
    1129              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
    1130              : #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    1131              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
    1132              : #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1133              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
    1134              : #else
    1135              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
    1136              : #endif
    1137              : 
    1138              : #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
    1139              :     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
    1140              : #endif
    1141              : #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
    1142              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
    1143              : #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
    1144              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
    1145              : #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
    1146              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
    1147              : #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    1148              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
    1149              : #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
    1150              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
    1151              : #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
    1152              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
    1153              : #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
    1154              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
    1155              : #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
    1156              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
    1157              : #elif \
    1158              :     JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
    1159              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
    1160              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
    1161              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
    1162              : #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    1163              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
    1164              : #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1165              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
    1166              : #else
    1167              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
    1168              : #endif
    1169              : 
    1170              : #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
    1171              :     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
    1172              : #endif
    1173              : #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
    1174              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
    1175              : #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    1176              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
    1177              : #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
    1178              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
    1179              : #else
    1180              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
    1181              : #endif
    1182              : 
    1183              : #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
    1184              :     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
    1185              : #endif
    1186              : #if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
    1187              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
    1188              : #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
    1189              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
    1190              : #elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
    1191              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
    1192              : #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1193              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
    1194              : #else
    1195              :     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
    1196              : #endif
    1197              : 
    1198              : #if defined(JSON_HEDLEY_DEPRECATED)
    1199              :     #undef JSON_HEDLEY_DEPRECATED
    1200              : #endif
    1201              : #if defined(JSON_HEDLEY_DEPRECATED_FOR)
    1202              :     #undef JSON_HEDLEY_DEPRECATED_FOR
    1203              : #endif
    1204              : #if \
    1205              :     JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
    1206              :     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    1207              :     #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
    1208              :     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
    1209              : #elif \
    1210              :     (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
    1211              :     JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
    1212              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1213              :     JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
    1214              :     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
    1215              :     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
    1216              :     JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
    1217              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
    1218              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
    1219              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1220              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
    1221              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1222              :     #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
    1223              :     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
    1224              : #elif defined(__cplusplus) && (__cplusplus >= 201402L)
    1225              :     #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
    1226              :     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
    1227              : #elif \
    1228              :     JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
    1229              :     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
    1230              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1231              :     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    1232              :     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1233              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    1234              :     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1235              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    1236              :     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1237              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1238              :     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1239              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    1240              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1241              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    1242              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
    1243              :     JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
    1244              :     #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
    1245              :     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
    1246              : #elif \
    1247              :     JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
    1248              :     JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
    1249              :     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    1250              :     #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
    1251              :     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
    1252              : #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    1253              :     #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
    1254              :     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
    1255              : #else
    1256              :     #define JSON_HEDLEY_DEPRECATED(since)
    1257              :     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
    1258              : #endif
    1259              : 
    1260              : #if defined(JSON_HEDLEY_UNAVAILABLE)
    1261              :     #undef JSON_HEDLEY_UNAVAILABLE
    1262              : #endif
    1263              : #if \
    1264              :     JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
    1265              :     JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
    1266              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1267              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1268              :     #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
    1269              : #else
    1270              :     #define JSON_HEDLEY_UNAVAILABLE(available_since)
    1271              : #endif
    1272              : 
    1273              : #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
    1274              :     #undef JSON_HEDLEY_WARN_UNUSED_RESULT
    1275              : #endif
    1276              : #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
    1277              :     #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
    1278              : #endif
    1279              : #if \
    1280              :     JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
    1281              :     JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
    1282              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1283              :     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    1284              :     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1285              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    1286              :     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1287              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    1288              :     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1289              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1290              :     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1291              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    1292              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1293              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    1294              :     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
    1295              :     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
    1296              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1297              :     #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
    1298              :     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
    1299              : #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
    1300              :     #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
    1301              :     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
    1302              : #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
    1303              :     #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
    1304              :     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
    1305              : #elif defined(_Check_return_) /* SAL */
    1306              :     #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
    1307              :     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
    1308              : #else
    1309              :     #define JSON_HEDLEY_WARN_UNUSED_RESULT
    1310              :     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
    1311              : #endif
    1312              : 
    1313              : #if defined(JSON_HEDLEY_SENTINEL)
    1314              :     #undef JSON_HEDLEY_SENTINEL
    1315              : #endif
    1316              : #if \
    1317              :     JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
    1318              :     JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
    1319              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1320              :     JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
    1321              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1322              :     #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
    1323              : #else
    1324              :     #define JSON_HEDLEY_SENTINEL(position)
    1325              : #endif
    1326              : 
    1327              : #if defined(JSON_HEDLEY_NO_RETURN)
    1328              :     #undef JSON_HEDLEY_NO_RETURN
    1329              : #endif
    1330              : #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    1331              :     #define JSON_HEDLEY_NO_RETURN __noreturn
    1332              : #elif \
    1333              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1334              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1335              :     #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
    1336              : #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
    1337              :     #define JSON_HEDLEY_NO_RETURN _Noreturn
    1338              : #elif defined(__cplusplus) && (__cplusplus >= 201103L)
    1339              :     #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
    1340              : #elif \
    1341              :     JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
    1342              :     JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
    1343              :     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
    1344              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1345              :     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
    1346              :     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    1347              :     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1348              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    1349              :     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1350              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    1351              :     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1352              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1353              :     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1354              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    1355              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1356              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    1357              :     JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
    1358              :     #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
    1359              : #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
    1360              :     #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
    1361              : #elif \
    1362              :     JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
    1363              :     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    1364              :     #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
    1365              : #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
    1366              :     #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
    1367              : #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
    1368              :     #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
    1369              : #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
    1370              :     #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
    1371              : #else
    1372              :     #define JSON_HEDLEY_NO_RETURN
    1373              : #endif
    1374              : 
    1375              : #if defined(JSON_HEDLEY_NO_ESCAPE)
    1376              :     #undef JSON_HEDLEY_NO_ESCAPE
    1377              : #endif
    1378              : #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
    1379              :     #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
    1380              : #else
    1381              :     #define JSON_HEDLEY_NO_ESCAPE
    1382              : #endif
    1383              : 
    1384              : #if defined(JSON_HEDLEY_UNREACHABLE)
    1385              :     #undef JSON_HEDLEY_UNREACHABLE
    1386              : #endif
    1387              : #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
    1388              :     #undef JSON_HEDLEY_UNREACHABLE_RETURN
    1389              : #endif
    1390              : #if defined(JSON_HEDLEY_ASSUME)
    1391              :     #undef JSON_HEDLEY_ASSUME
    1392              : #endif
    1393              : #if \
    1394              :     JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
    1395              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1396              :     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    1397              :     #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
    1398              : #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
    1399              :     #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
    1400              : #elif \
    1401              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
    1402              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
    1403              :     #if defined(__cplusplus)
    1404              :         #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
    1405              :     #else
    1406              :         #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
    1407              :     #endif
    1408              : #endif
    1409              : #if \
    1410              :     (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
    1411              :     JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
    1412              :     JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
    1413              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1414              :     JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
    1415              :     JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
    1416              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1417              :     #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
    1418              : #elif defined(JSON_HEDLEY_ASSUME)
    1419              :     #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
    1420              : #endif
    1421              : #if !defined(JSON_HEDLEY_ASSUME)
    1422              :     #if defined(JSON_HEDLEY_UNREACHABLE)
    1423              :         #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
    1424              :     #else
    1425              :         #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
    1426              :     #endif
    1427              : #endif
    1428              : #if defined(JSON_HEDLEY_UNREACHABLE)
    1429              :     #if  \
    1430              :         JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
    1431              :         JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
    1432              :         #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
    1433              :     #else
    1434              :         #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
    1435              :     #endif
    1436              : #else
    1437              :     #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
    1438              : #endif
    1439              : #if !defined(JSON_HEDLEY_UNREACHABLE)
    1440              :     #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
    1441              : #endif
    1442              : 
    1443              : JSON_HEDLEY_DIAGNOSTIC_PUSH
    1444              : #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
    1445              :     #pragma clang diagnostic ignored "-Wpedantic"
    1446              : #endif
    1447              : #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
    1448              :     #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
    1449              : #endif
    1450              : #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
    1451              :     #if defined(__clang__)
    1452              :         #pragma clang diagnostic ignored "-Wvariadic-macros"
    1453              :     #elif defined(JSON_HEDLEY_GCC_VERSION)
    1454              :         #pragma GCC diagnostic ignored "-Wvariadic-macros"
    1455              :     #endif
    1456              : #endif
    1457              : #if defined(JSON_HEDLEY_NON_NULL)
    1458              :     #undef JSON_HEDLEY_NON_NULL
    1459              : #endif
    1460              : #if \
    1461              :     JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
    1462              :     JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
    1463              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1464              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
    1465              :     #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
    1466              : #else
    1467              :     #define JSON_HEDLEY_NON_NULL(...)
    1468              : #endif
    1469              : JSON_HEDLEY_DIAGNOSTIC_POP
    1470              : 
    1471              : #if defined(JSON_HEDLEY_PRINTF_FORMAT)
    1472              :     #undef JSON_HEDLEY_PRINTF_FORMAT
    1473              : #endif
    1474              : #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
    1475              :     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
    1476              : #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
    1477              :     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
    1478              : #elif \
    1479              :     JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
    1480              :     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
    1481              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1482              :     JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
    1483              :     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
    1484              :     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    1485              :     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1486              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    1487              :     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1488              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    1489              :     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1490              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1491              :     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1492              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    1493              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1494              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    1495              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1496              :     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
    1497              : #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
    1498              :     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
    1499              : #else
    1500              :     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
    1501              : #endif
    1502              : 
    1503              : #if defined(JSON_HEDLEY_CONSTEXPR)
    1504              :     #undef JSON_HEDLEY_CONSTEXPR
    1505              : #endif
    1506              : #if defined(__cplusplus)
    1507              :     #if __cplusplus >= 201103L
    1508              :         #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
    1509              :     #endif
    1510              : #endif
    1511              : #if !defined(JSON_HEDLEY_CONSTEXPR)
    1512              :     #define JSON_HEDLEY_CONSTEXPR
    1513              : #endif
    1514              : 
    1515              : #if defined(JSON_HEDLEY_PREDICT)
    1516              :     #undef JSON_HEDLEY_PREDICT
    1517              : #endif
    1518              : #if defined(JSON_HEDLEY_LIKELY)
    1519              :     #undef JSON_HEDLEY_LIKELY
    1520              : #endif
    1521              : #if defined(JSON_HEDLEY_UNLIKELY)
    1522              :     #undef JSON_HEDLEY_UNLIKELY
    1523              : #endif
    1524              : #if defined(JSON_HEDLEY_UNPREDICTABLE)
    1525              :     #undef JSON_HEDLEY_UNPREDICTABLE
    1526              : #endif
    1527              : #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
    1528              :     #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
    1529              : #endif
    1530              : #if \
    1531              :   (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
    1532              :   JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
    1533              :   JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1534              : #  define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(  (expr), (value), (probability))
    1535              : #  define JSON_HEDLEY_PREDICT_TRUE(expr, probability)   __builtin_expect_with_probability(!!(expr),    1   , (probability))
    1536              : #  define JSON_HEDLEY_PREDICT_FALSE(expr, probability)  __builtin_expect_with_probability(!!(expr),    0   , (probability))
    1537              : #  define JSON_HEDLEY_LIKELY(expr)                      __builtin_expect                 (!!(expr),    1                  )
    1538              : #  define JSON_HEDLEY_UNLIKELY(expr)                    __builtin_expect                 (!!(expr),    0                  )
    1539              : #elif \
    1540              :   (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
    1541              :   JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
    1542              :   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1543              :   (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
    1544              :   JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1545              :   JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
    1546              :   JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    1547              :   JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
    1548              :   JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
    1549              :   JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
    1550              :   JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
    1551              :   JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1552              :   JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    1553              :   JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
    1554              :   JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
    1555              :   JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1556              : #  define JSON_HEDLEY_PREDICT(expr, expected, probability) \
    1557              :     (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
    1558              : #  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
    1559              :     (__extension__ ({ \
    1560              :         double hedley_probability_ = (probability); \
    1561              :         ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
    1562              :     }))
    1563              : #  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
    1564              :     (__extension__ ({ \
    1565              :         double hedley_probability_ = (probability); \
    1566              :         ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
    1567              :     }))
    1568              : #  define JSON_HEDLEY_LIKELY(expr)   __builtin_expect(!!(expr), 1)
    1569              : #  define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
    1570              : #else
    1571              : #  define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
    1572              : #  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
    1573              : #  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
    1574              : #  define JSON_HEDLEY_LIKELY(expr) (!!(expr))
    1575              : #  define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
    1576              : #endif
    1577              : #if !defined(JSON_HEDLEY_UNPREDICTABLE)
    1578              :     #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
    1579              : #endif
    1580              : 
    1581              : #if defined(JSON_HEDLEY_MALLOC)
    1582              :     #undef JSON_HEDLEY_MALLOC
    1583              : #endif
    1584              : #if \
    1585              :     JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
    1586              :     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
    1587              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1588              :     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
    1589              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1590              :     JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
    1591              :     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    1592              :     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1593              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    1594              :     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1595              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    1596              :     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1597              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1598              :     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1599              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    1600              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1601              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    1602              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1603              :     #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
    1604              : #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
    1605              :     #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
    1606              : #elif \
    1607              :     JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
    1608              :     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    1609              :     #define JSON_HEDLEY_MALLOC __declspec(restrict)
    1610              : #else
    1611              :     #define JSON_HEDLEY_MALLOC
    1612              : #endif
    1613              : 
    1614              : #if defined(JSON_HEDLEY_PURE)
    1615              :     #undef JSON_HEDLEY_PURE
    1616              : #endif
    1617              : #if \
    1618              :   JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
    1619              :   JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
    1620              :   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1621              :   JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
    1622              :   JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1623              :   JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
    1624              :   JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    1625              :   (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1626              :   JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    1627              :   (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1628              :   JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    1629              :   (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1630              :   JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1631              :   (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1632              :   JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    1633              :   JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1634              :   JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    1635              :   JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
    1636              :   JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1637              : #  define JSON_HEDLEY_PURE __attribute__((__pure__))
    1638              : #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
    1639              : #  define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
    1640              : #elif defined(__cplusplus) && \
    1641              :     ( \
    1642              :       JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
    1643              :       JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
    1644              :       JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
    1645              :     )
    1646              : #  define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
    1647              : #else
    1648              : #  define JSON_HEDLEY_PURE
    1649              : #endif
    1650              : 
    1651              : #if defined(JSON_HEDLEY_CONST)
    1652              :     #undef JSON_HEDLEY_CONST
    1653              : #endif
    1654              : #if \
    1655              :     JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
    1656              :     JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
    1657              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1658              :     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
    1659              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1660              :     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
    1661              :     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    1662              :     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1663              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    1664              :     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1665              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    1666              :     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1667              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1668              :     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1669              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    1670              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1671              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    1672              :     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
    1673              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1674              :     #define JSON_HEDLEY_CONST __attribute__((__const__))
    1675              : #elif \
    1676              :     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
    1677              :     #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
    1678              : #else
    1679              :     #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
    1680              : #endif
    1681              : 
    1682              : #if defined(JSON_HEDLEY_RESTRICT)
    1683              :     #undef JSON_HEDLEY_RESTRICT
    1684              : #endif
    1685              : #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
    1686              :     #define JSON_HEDLEY_RESTRICT restrict
    1687              : #elif \
    1688              :     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
    1689              :     JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
    1690              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1691              :     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
    1692              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1693              :     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
    1694              :     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
    1695              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1696              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
    1697              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
    1698              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1699              :     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
    1700              :     JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
    1701              :     defined(__clang__) || \
    1702              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1703              :     #define JSON_HEDLEY_RESTRICT __restrict
    1704              : #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
    1705              :     #define JSON_HEDLEY_RESTRICT _Restrict
    1706              : #else
    1707              :     #define JSON_HEDLEY_RESTRICT
    1708              : #endif
    1709              : 
    1710              : #if defined(JSON_HEDLEY_INLINE)
    1711              :     #undef JSON_HEDLEY_INLINE
    1712              : #endif
    1713              : #if \
    1714              :     (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
    1715              :     (defined(__cplusplus) && (__cplusplus >= 199711L))
    1716              :     #define JSON_HEDLEY_INLINE inline
    1717              : #elif \
    1718              :     defined(JSON_HEDLEY_GCC_VERSION) || \
    1719              :     JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
    1720              :     #define JSON_HEDLEY_INLINE __inline__
    1721              : #elif \
    1722              :     JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
    1723              :     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
    1724              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1725              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
    1726              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
    1727              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
    1728              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
    1729              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1730              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    1731              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1732              :     #define JSON_HEDLEY_INLINE __inline
    1733              : #else
    1734              :     #define JSON_HEDLEY_INLINE
    1735              : #endif
    1736              : 
    1737              : #if defined(JSON_HEDLEY_ALWAYS_INLINE)
    1738              :     #undef JSON_HEDLEY_ALWAYS_INLINE
    1739              : #endif
    1740              : #if \
    1741              :   JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
    1742              :   JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
    1743              :   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1744              :   JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
    1745              :   JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1746              :   JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
    1747              :   JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    1748              :   (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1749              :   JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    1750              :   (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1751              :   JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    1752              :   (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1753              :   JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1754              :   (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1755              :   JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    1756              :   JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1757              :   JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    1758              :   JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
    1759              :   JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
    1760              : #  define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
    1761              : #elif \
    1762              :   JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
    1763              :   JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    1764              : #  define JSON_HEDLEY_ALWAYS_INLINE __forceinline
    1765              : #elif defined(__cplusplus) && \
    1766              :     ( \
    1767              :       JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    1768              :       JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1769              :       JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    1770              :       JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
    1771              :       JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1772              :       JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
    1773              :     )
    1774              : #  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
    1775              : #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    1776              : #  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
    1777              : #else
    1778              : #  define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
    1779              : #endif
    1780              : 
    1781              : #if defined(JSON_HEDLEY_NEVER_INLINE)
    1782              :     #undef JSON_HEDLEY_NEVER_INLINE
    1783              : #endif
    1784              : #if \
    1785              :     JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
    1786              :     JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
    1787              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1788              :     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
    1789              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1790              :     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
    1791              :     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    1792              :     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1793              :     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    1794              :     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1795              :     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    1796              :     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1797              :     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    1798              :     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1799              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    1800              :     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    1801              :     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    1802              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
    1803              :     JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
    1804              :     #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
    1805              : #elif \
    1806              :     JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
    1807              :     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    1808              :     #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
    1809              : #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
    1810              :     #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
    1811              : #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
    1812              :     #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
    1813              : #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    1814              :     #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
    1815              : #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
    1816              :     #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
    1817              : #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
    1818              :     #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
    1819              : #else
    1820              :     #define JSON_HEDLEY_NEVER_INLINE
    1821              : #endif
    1822              : 
    1823              : #if defined(JSON_HEDLEY_PRIVATE)
    1824              :     #undef JSON_HEDLEY_PRIVATE
    1825              : #endif
    1826              : #if defined(JSON_HEDLEY_PUBLIC)
    1827              :     #undef JSON_HEDLEY_PUBLIC
    1828              : #endif
    1829              : #if defined(JSON_HEDLEY_IMPORT)
    1830              :     #undef JSON_HEDLEY_IMPORT
    1831              : #endif
    1832              : #if defined(_WIN32) || defined(__CYGWIN__)
    1833              : #  define JSON_HEDLEY_PRIVATE
    1834              : #  define JSON_HEDLEY_PUBLIC   __declspec(dllexport)
    1835              : #  define JSON_HEDLEY_IMPORT   __declspec(dllimport)
    1836              : #else
    1837              : #  if \
    1838              :     JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
    1839              :     JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
    1840              :     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
    1841              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1842              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1843              :     JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
    1844              :     ( \
    1845              :       defined(__TI_EABI__) && \
    1846              :       ( \
    1847              :         (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    1848              :         JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
    1849              :       ) \
    1850              :     ) || \
    1851              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1852              : #    define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
    1853              : #    define JSON_HEDLEY_PUBLIC  __attribute__((__visibility__("default")))
    1854              : #  else
    1855              : #    define JSON_HEDLEY_PRIVATE
    1856              : #    define JSON_HEDLEY_PUBLIC
    1857              : #  endif
    1858              : #  define JSON_HEDLEY_IMPORT    extern
    1859              : #endif
    1860              : 
    1861              : #if defined(JSON_HEDLEY_NO_THROW)
    1862              :     #undef JSON_HEDLEY_NO_THROW
    1863              : #endif
    1864              : #if \
    1865              :     JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
    1866              :     JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
    1867              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1868              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1869              :     #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
    1870              : #elif \
    1871              :     JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
    1872              :     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
    1873              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
    1874              :     #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
    1875              : #else
    1876              :     #define JSON_HEDLEY_NO_THROW
    1877              : #endif
    1878              : 
    1879              : #if defined(JSON_HEDLEY_FALL_THROUGH)
    1880              :     #undef JSON_HEDLEY_FALL_THROUGH
    1881              : #endif
    1882              : #if \
    1883              :     JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
    1884              :     JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
    1885              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1886              :     #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
    1887              : #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
    1888              :     #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
    1889              : #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
    1890              :     #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
    1891              : #elif defined(__fallthrough) /* SAL */
    1892              :     #define JSON_HEDLEY_FALL_THROUGH __fallthrough
    1893              : #else
    1894              :     #define JSON_HEDLEY_FALL_THROUGH
    1895              : #endif
    1896              : 
    1897              : #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
    1898              :     #undef JSON_HEDLEY_RETURNS_NON_NULL
    1899              : #endif
    1900              : #if \
    1901              :     JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
    1902              :     JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
    1903              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1904              :     #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
    1905              : #elif defined(_Ret_notnull_) /* SAL */
    1906              :     #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
    1907              : #else
    1908              :     #define JSON_HEDLEY_RETURNS_NON_NULL
    1909              : #endif
    1910              : 
    1911              : #if defined(JSON_HEDLEY_ARRAY_PARAM)
    1912              :     #undef JSON_HEDLEY_ARRAY_PARAM
    1913              : #endif
    1914              : #if \
    1915              :     defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
    1916              :     !defined(__STDC_NO_VLA__) && \
    1917              :     !defined(__cplusplus) && \
    1918              :     !defined(JSON_HEDLEY_PGI_VERSION) && \
    1919              :     !defined(JSON_HEDLEY_TINYC_VERSION)
    1920              :     #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
    1921              : #else
    1922              :     #define JSON_HEDLEY_ARRAY_PARAM(name)
    1923              : #endif
    1924              : 
    1925              : #if defined(JSON_HEDLEY_IS_CONSTANT)
    1926              :     #undef JSON_HEDLEY_IS_CONSTANT
    1927              : #endif
    1928              : #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
    1929              :     #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
    1930              : #endif
    1931              : /* JSON_HEDLEY_IS_CONSTEXPR_ is for
    1932              :    HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
    1933              : #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
    1934              :     #undef JSON_HEDLEY_IS_CONSTEXPR_
    1935              : #endif
    1936              : #if \
    1937              :     JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
    1938              :     JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
    1939              :     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1940              :     JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
    1941              :     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    1942              :     JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
    1943              :     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
    1944              :     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
    1945              :     JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
    1946              :     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
    1947              :     #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
    1948              : #endif
    1949              : #if !defined(__cplusplus)
    1950              : #  if \
    1951              :        JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
    1952              :        JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
    1953              :        JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    1954              :        JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
    1955              :        JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
    1956              :        JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
    1957              :        JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
    1958              : #if defined(__INTPTR_TYPE__)
    1959              :     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
    1960              : #else
    1961              :     #include <stdint.h>
    1962              :     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
    1963              : #endif
    1964              : #  elif \
    1965              :        ( \
    1966              :           defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
    1967              :           !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
    1968              :           !defined(JSON_HEDLEY_PGI_VERSION) && \
    1969              :           !defined(JSON_HEDLEY_IAR_VERSION)) || \
    1970              :        (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
    1971              :        JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
    1972              :        JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
    1973              :        JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
    1974              :        JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
    1975              : #if defined(__INTPTR_TYPE__)
    1976              :     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
    1977              : #else
    1978              :     #include <stdint.h>
    1979              :     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
    1980              : #endif
    1981              : #  elif \
    1982              :        defined(JSON_HEDLEY_GCC_VERSION) || \
    1983              :        defined(JSON_HEDLEY_INTEL_VERSION) || \
    1984              :        defined(JSON_HEDLEY_TINYC_VERSION) || \
    1985              :        defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
    1986              :        JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
    1987              :        defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
    1988              :        defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
    1989              :        defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
    1990              :        defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
    1991              :        defined(__clang__)
    1992              : #    define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
    1993              :         sizeof(void) != \
    1994              :         sizeof(*( \
    1995              :                   1 ? \
    1996              :                   ((void*) ((expr) * 0L) ) : \
    1997              : ((struct { char v[sizeof(void) * 2]; } *) 1) \
    1998              :                 ) \
    1999              :               ) \
    2000              :                                             )
    2001              : #  endif
    2002              : #endif
    2003              : #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
    2004              :     #if !defined(JSON_HEDLEY_IS_CONSTANT)
    2005              :         #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
    2006              :     #endif
    2007              :     #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
    2008              : #else
    2009              :     #if !defined(JSON_HEDLEY_IS_CONSTANT)
    2010              :         #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
    2011              :     #endif
    2012              :     #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
    2013              : #endif
    2014              : 
    2015              : #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
    2016              :     #undef JSON_HEDLEY_BEGIN_C_DECLS
    2017              : #endif
    2018              : #if defined(JSON_HEDLEY_END_C_DECLS)
    2019              :     #undef JSON_HEDLEY_END_C_DECLS
    2020              : #endif
    2021              : #if defined(JSON_HEDLEY_C_DECL)
    2022              :     #undef JSON_HEDLEY_C_DECL
    2023              : #endif
    2024              : #if defined(__cplusplus)
    2025              :     #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
    2026              :     #define JSON_HEDLEY_END_C_DECLS }
    2027              :     #define JSON_HEDLEY_C_DECL extern "C"
    2028              : #else
    2029              :     #define JSON_HEDLEY_BEGIN_C_DECLS
    2030              :     #define JSON_HEDLEY_END_C_DECLS
    2031              :     #define JSON_HEDLEY_C_DECL
    2032              : #endif
    2033              : 
    2034              : #if defined(JSON_HEDLEY_STATIC_ASSERT)
    2035              :     #undef JSON_HEDLEY_STATIC_ASSERT
    2036              : #endif
    2037              : #if \
    2038              :   !defined(__cplusplus) && ( \
    2039              :       (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
    2040              :       (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
    2041              :       JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
    2042              :       JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    2043              :       defined(_Static_assert) \
    2044              :     )
    2045              : #  define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
    2046              : #elif \
    2047              :   (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
    2048              :   JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
    2049              :   JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    2050              : #  define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
    2051              : #else
    2052              : #  define JSON_HEDLEY_STATIC_ASSERT(expr, message)
    2053              : #endif
    2054              : 
    2055              : #if defined(JSON_HEDLEY_NULL)
    2056              :     #undef JSON_HEDLEY_NULL
    2057              : #endif
    2058              : #if defined(__cplusplus)
    2059              :     #if __cplusplus >= 201103L
    2060              :         #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
    2061              :     #elif defined(NULL)
    2062              :         #define JSON_HEDLEY_NULL NULL
    2063              :     #else
    2064              :         #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
    2065              :     #endif
    2066              : #elif defined(NULL)
    2067              :     #define JSON_HEDLEY_NULL NULL
    2068              : #else
    2069              :     #define JSON_HEDLEY_NULL ((void*) 0)
    2070              : #endif
    2071              : 
    2072              : #if defined(JSON_HEDLEY_MESSAGE)
    2073              :     #undef JSON_HEDLEY_MESSAGE
    2074              : #endif
    2075              : #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
    2076              : #  define JSON_HEDLEY_MESSAGE(msg) \
    2077              :     JSON_HEDLEY_DIAGNOSTIC_PUSH \
    2078              :     JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
    2079              :     JSON_HEDLEY_PRAGMA(message msg) \
    2080              :     JSON_HEDLEY_DIAGNOSTIC_POP
    2081              : #elif \
    2082              :   JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
    2083              :   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    2084              : #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
    2085              : #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
    2086              : #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
    2087              : #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    2088              : #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
    2089              : #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
    2090              : #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
    2091              : #else
    2092              : #  define JSON_HEDLEY_MESSAGE(msg)
    2093              : #endif
    2094              : 
    2095              : #if defined(JSON_HEDLEY_WARNING)
    2096              :     #undef JSON_HEDLEY_WARNING
    2097              : #endif
    2098              : #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
    2099              : #  define JSON_HEDLEY_WARNING(msg) \
    2100              :     JSON_HEDLEY_DIAGNOSTIC_PUSH \
    2101              :     JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
    2102              :     JSON_HEDLEY_PRAGMA(clang warning msg) \
    2103              :     JSON_HEDLEY_DIAGNOSTIC_POP
    2104              : #elif \
    2105              :   JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
    2106              :   JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
    2107              :   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    2108              : #  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
    2109              : #elif \
    2110              :   JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
    2111              :   JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    2112              : #  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
    2113              : #else
    2114              : #  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
    2115              : #endif
    2116              : 
    2117              : #if defined(JSON_HEDLEY_REQUIRE)
    2118              :     #undef JSON_HEDLEY_REQUIRE
    2119              : #endif
    2120              : #if defined(JSON_HEDLEY_REQUIRE_MSG)
    2121              :     #undef JSON_HEDLEY_REQUIRE_MSG
    2122              : #endif
    2123              : #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
    2124              : #  if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
    2125              : #    define JSON_HEDLEY_REQUIRE(expr) \
    2126              :     JSON_HEDLEY_DIAGNOSTIC_PUSH \
    2127              :     _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
    2128              :     __attribute__((diagnose_if(!(expr), #expr, "error"))) \
    2129              :     JSON_HEDLEY_DIAGNOSTIC_POP
    2130              : #    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
    2131              :     JSON_HEDLEY_DIAGNOSTIC_PUSH \
    2132              :     _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
    2133              :     __attribute__((diagnose_if(!(expr), msg, "error"))) \
    2134              :     JSON_HEDLEY_DIAGNOSTIC_POP
    2135              : #  else
    2136              : #    define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
    2137              : #    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
    2138              : #  endif
    2139              : #else
    2140              : #  define JSON_HEDLEY_REQUIRE(expr)
    2141              : #  define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
    2142              : #endif
    2143              : 
    2144              : #if defined(JSON_HEDLEY_FLAGS)
    2145              :     #undef JSON_HEDLEY_FLAGS
    2146              : #endif
    2147              : #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
    2148              :     #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
    2149              : #else
    2150              :     #define JSON_HEDLEY_FLAGS
    2151              : #endif
    2152              : 
    2153              : #if defined(JSON_HEDLEY_FLAGS_CAST)
    2154              :     #undef JSON_HEDLEY_FLAGS_CAST
    2155              : #endif
    2156              : #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
    2157              : #  define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
    2158              :         JSON_HEDLEY_DIAGNOSTIC_PUSH \
    2159              :         _Pragma("warning(disable:188)") \
    2160              :         ((T) (expr)); \
    2161              :         JSON_HEDLEY_DIAGNOSTIC_POP \
    2162              :     }))
    2163              : #else
    2164              : #  define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
    2165              : #endif
    2166              : 
    2167              : #if defined(JSON_HEDLEY_EMPTY_BASES)
    2168              :     #undef JSON_HEDLEY_EMPTY_BASES
    2169              : #endif
    2170              : #if \
    2171              :     (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
    2172              :     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    2173              :     #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
    2174              : #else
    2175              :     #define JSON_HEDLEY_EMPTY_BASES
    2176              : #endif
    2177              : 
    2178              : /* Remaining macros are deprecated. */
    2179              : 
    2180              : #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
    2181              :     #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
    2182              : #endif
    2183              : #if defined(__clang__)
    2184              :     #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
    2185              : #else
    2186              :     #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
    2187              : #endif
    2188              : 
    2189              : #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
    2190              :     #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
    2191              : #endif
    2192              : #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
    2193              : 
    2194              : #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
    2195              :     #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
    2196              : #endif
    2197              : #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
    2198              : 
    2199              : #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
    2200              :     #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
    2201              : #endif
    2202              : #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
    2203              : 
    2204              : #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
    2205              :     #undef JSON_HEDLEY_CLANG_HAS_FEATURE
    2206              : #endif
    2207              : #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
    2208              : 
    2209              : #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
    2210              :     #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
    2211              : #endif
    2212              : #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
    2213              : 
    2214              : #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
    2215              :     #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
    2216              : #endif
    2217              : #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
    2218              : 
    2219              : #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
    2220              :     #undef JSON_HEDLEY_CLANG_HAS_WARNING
    2221              : #endif
    2222              : #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
    2223              : 
    2224              : #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
    2225              : 
    2226              : // #include <nlohmann/detail/meta/detected.hpp>
    2227              : 
    2228              : 
    2229              : #include <type_traits>
    2230              : 
    2231              : // #include <nlohmann/detail/meta/void_t.hpp>
    2232              : 
    2233              : 
    2234              : namespace nlohmann
    2235              : {
    2236              : namespace detail
    2237              : {
    2238              : template<typename ...Ts> struct make_void
    2239              : {
    2240              :     using type = void;
    2241              : };
    2242              : template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
    2243              : } // namespace detail
    2244              : }  // namespace nlohmann
    2245              : 
    2246              : 
    2247              : // https://en.cppreference.com/w/cpp/experimental/is_detected
    2248              : namespace nlohmann
    2249              : {
    2250              : namespace detail
    2251              : {
    2252              : struct nonesuch
    2253              : {
    2254              :     nonesuch() = delete;
    2255              :     ~nonesuch() = delete;
    2256              :     nonesuch(nonesuch const&) = delete;
    2257              :     nonesuch(nonesuch const&&) = delete;
    2258              :     void operator=(nonesuch const&) = delete;
    2259              :     void operator=(nonesuch&&) = delete;
    2260              : };
    2261              : 
    2262              : template<class Default,
    2263              :          class AlwaysVoid,
    2264              :          template<class...> class Op,
    2265              :          class... Args>
    2266              : struct detector
    2267              : {
    2268              :     using value_t = std::false_type;
    2269              :     using type = Default;
    2270              : };
    2271              : 
    2272              : template<class Default, template<class...> class Op, class... Args>
    2273              : struct detector<Default, void_t<Op<Args...>>, Op, Args...>
    2274              : {
    2275              :     using value_t = std::true_type;
    2276              :     using type = Op<Args...>;
    2277              : };
    2278              : 
    2279              : template<template<class...> class Op, class... Args>
    2280              : using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
    2281              : 
    2282              : template<template<class...> class Op, class... Args>
    2283              : struct is_detected_lazy : is_detected<Op, Args...> { };
    2284              : 
    2285              : template<template<class...> class Op, class... Args>
    2286              : using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
    2287              : 
    2288              : template<class Default, template<class...> class Op, class... Args>
    2289              : using detected_or = detector<Default, void, Op, Args...>;
    2290              : 
    2291              : template<class Default, template<class...> class Op, class... Args>
    2292              : using detected_or_t = typename detected_or<Default, Op, Args...>::type;
    2293              : 
    2294              : template<class Expected, template<class...> class Op, class... Args>
    2295              : using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
    2296              : 
    2297              : template<class To, template<class...> class Op, class... Args>
    2298              : using is_detected_convertible =
    2299              :     std::is_convertible<detected_t<Op, Args...>, To>;
    2300              : }  // namespace detail
    2301              : }  // namespace nlohmann
    2302              : 
    2303              : 
    2304              : // This file contains all internal macro definitions
    2305              : // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
    2306              : 
    2307              : // exclude unsupported compilers
    2308              : #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
    2309              :     #if defined(__clang__)
    2310              :         #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
    2311              :             #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
    2312              :         #endif
    2313              :     #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
    2314              :         #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
    2315              :             #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
    2316              :         #endif
    2317              :     #endif
    2318              : #endif
    2319              : 
    2320              : // C++ language standard detection
    2321              : // if the user manually specified the used c++ version this is skipped
    2322              : #if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
    2323              :     #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
    2324              :         #define JSON_HAS_CPP_20
    2325              :         #define JSON_HAS_CPP_17
    2326              :         #define JSON_HAS_CPP_14
    2327              :     #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
    2328              :         #define JSON_HAS_CPP_17
    2329              :         #define JSON_HAS_CPP_14
    2330              :     #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
    2331              :         #define JSON_HAS_CPP_14
    2332              :     #endif
    2333              :     // the cpp 11 flag is always specified because it is the minimal required version
    2334              :     #define JSON_HAS_CPP_11
    2335              : #endif
    2336              : 
    2337              : #if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
    2338              :     #ifdef JSON_HAS_CPP_17
    2339              :         #if defined(__cpp_lib_filesystem)
    2340              :             #define JSON_HAS_FILESYSTEM 1
    2341              :         #elif defined(__cpp_lib_experimental_filesystem)
    2342              :             #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
    2343              :         #elif !defined(__has_include)
    2344              :             #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
    2345              :         #elif __has_include(<filesystem>)
    2346              :             #define JSON_HAS_FILESYSTEM 1
    2347              :         #elif __has_include(<experimental/filesystem>)
    2348              :             #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
    2349              :         #endif
    2350              : 
    2351              :         // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
    2352              :         #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
    2353              :             #undef JSON_HAS_FILESYSTEM
    2354              :             #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
    2355              :         #endif
    2356              : 
    2357              :         // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
    2358              :         #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
    2359              :             #undef JSON_HAS_FILESYSTEM
    2360              :             #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
    2361              :         #endif
    2362              : 
    2363              :         // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
    2364              :         #if defined(__clang_major__) && __clang_major__ < 7
    2365              :             #undef JSON_HAS_FILESYSTEM
    2366              :             #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
    2367              :         #endif
    2368              : 
    2369              :         // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
    2370              :         #if defined(_MSC_VER) && _MSC_VER < 1940
    2371              :             #undef JSON_HAS_FILESYSTEM
    2372              :             #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
    2373              :         #endif
    2374              : 
    2375              :         // no filesystem support before iOS 13
    2376              :         #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
    2377              :             #undef JSON_HAS_FILESYSTEM
    2378              :             #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
    2379              :         #endif
    2380              : 
    2381              :         // no filesystem support before macOS Catalina
    2382              :         #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
    2383              :             #undef JSON_HAS_FILESYSTEM
    2384              :             #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
    2385              :         #endif
    2386              :     #endif
    2387              : #endif
    2388              : 
    2389              : #ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
    2390              :     #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
    2391              : #endif
    2392              : 
    2393              : #ifndef JSON_HAS_FILESYSTEM
    2394              :     #define JSON_HAS_FILESYSTEM 0
    2395              : #endif
    2396              : 
    2397              : // disable documentation warnings on clang
    2398              : #if defined(__clang__)
    2399              :     #pragma clang diagnostic push
    2400              :     #pragma clang diagnostic ignored "-Wdocumentation"
    2401              :     #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
    2402              : #endif
    2403              : 
    2404              : // allow disabling exceptions
    2405              : #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
    2406              :     #define JSON_THROW(exception) throw exception
    2407              :     #define JSON_TRY try
    2408              :     #define JSON_CATCH(exception) catch(exception)
    2409              :     #define JSON_INTERNAL_CATCH(exception) catch(exception)
    2410              : #else
    2411              :     #include <cstdlib>
    2412              :     #define JSON_THROW(exception) std::abort()
    2413              :     #define JSON_TRY if(true)
    2414              :     #define JSON_CATCH(exception) if(false)
    2415              :     #define JSON_INTERNAL_CATCH(exception) if(false)
    2416              : #endif
    2417              : 
    2418              : // override exception macros
    2419              : #if defined(JSON_THROW_USER)
    2420              :     #undef JSON_THROW
    2421              :     #define JSON_THROW JSON_THROW_USER
    2422              : #endif
    2423              : #if defined(JSON_TRY_USER)
    2424              :     #undef JSON_TRY
    2425              :     #define JSON_TRY JSON_TRY_USER
    2426              : #endif
    2427              : #if defined(JSON_CATCH_USER)
    2428              :     #undef JSON_CATCH
    2429              :     #define JSON_CATCH JSON_CATCH_USER
    2430              :     #undef JSON_INTERNAL_CATCH
    2431              :     #define JSON_INTERNAL_CATCH JSON_CATCH_USER
    2432              : #endif
    2433              : #if defined(JSON_INTERNAL_CATCH_USER)
    2434              :     #undef JSON_INTERNAL_CATCH
    2435              :     #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
    2436              : #endif
    2437              : 
    2438              : // allow overriding assert
    2439              : #if !defined(JSON_ASSERT)
    2440              :     #include <cassert> // assert
    2441              :     #define JSON_ASSERT(x) assert(x)
    2442              : #endif
    2443              : 
    2444              : // allow to access some private functions (needed by the test suite)
    2445              : #if defined(JSON_TESTS_PRIVATE)
    2446              :     #define JSON_PRIVATE_UNLESS_TESTED public
    2447              : #else
    2448              :     #define JSON_PRIVATE_UNLESS_TESTED private
    2449              : #endif
    2450              : 
    2451              : /*!
    2452              : @brief macro to briefly define a mapping between an enum and JSON
    2453              : @def NLOHMANN_JSON_SERIALIZE_ENUM
    2454              : @since version 3.4.0
    2455              : */
    2456              : #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                            \
    2457              :     template<typename BasicJsonType>                                                            \
    2458              :     inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                   \
    2459              :     {                                                                                           \
    2460              :         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
    2461              :         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
    2462              :         auto it = std::find_if(std::begin(m), std::end(m),                                      \
    2463              :                                [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool  \
    2464              :         {                                                                                       \
    2465              :             return ej_pair.first == e;                                                          \
    2466              :         });                                                                                     \
    2467              :         j = ((it != std::end(m)) ? it : std::begin(m))->second;                                 \
    2468              :     }                                                                                           \
    2469              :     template<typename BasicJsonType>                                                            \
    2470              :     inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                 \
    2471              :     {                                                                                           \
    2472              :         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
    2473              :         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
    2474              :         auto it = std::find_if(std::begin(m), std::end(m),                                      \
    2475              :                                [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
    2476              :         {                                                                                       \
    2477              :             return ej_pair.second == j;                                                         \
    2478              :         });                                                                                     \
    2479              :         e = ((it != std::end(m)) ? it : std::begin(m))->first;                                  \
    2480              :     }
    2481              : 
    2482              : // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
    2483              : // may be removed in the future once the class is split.
    2484              : 
    2485              : #define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
    2486              :     template<template<typename, typename, typename...> class ObjectType,   \
    2487              :              template<typename, typename...> class ArrayType,              \
    2488              :              class StringType, class BooleanType, class NumberIntegerType, \
    2489              :              class NumberUnsignedType, class NumberFloatType,              \
    2490              :              template<typename> class AllocatorType,                       \
    2491              :              template<typename, typename = void> class JSONSerializer,     \
    2492              :              class BinaryType>
    2493              : 
    2494              : #define NLOHMANN_BASIC_JSON_TPL                                            \
    2495              :     basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
    2496              :     NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
    2497              :     AllocatorType, JSONSerializer, BinaryType>
    2498              : 
    2499              : // Macros to simplify conversion from/to types
    2500              : 
    2501              : #define NLOHMANN_JSON_EXPAND( x ) x
    2502              : #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
    2503              : #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
    2504              :         NLOHMANN_JSON_PASTE64, \
    2505              :         NLOHMANN_JSON_PASTE63, \
    2506              :         NLOHMANN_JSON_PASTE62, \
    2507              :         NLOHMANN_JSON_PASTE61, \
    2508              :         NLOHMANN_JSON_PASTE60, \
    2509              :         NLOHMANN_JSON_PASTE59, \
    2510              :         NLOHMANN_JSON_PASTE58, \
    2511              :         NLOHMANN_JSON_PASTE57, \
    2512              :         NLOHMANN_JSON_PASTE56, \
    2513              :         NLOHMANN_JSON_PASTE55, \
    2514              :         NLOHMANN_JSON_PASTE54, \
    2515              :         NLOHMANN_JSON_PASTE53, \
    2516              :         NLOHMANN_JSON_PASTE52, \
    2517              :         NLOHMANN_JSON_PASTE51, \
    2518              :         NLOHMANN_JSON_PASTE50, \
    2519              :         NLOHMANN_JSON_PASTE49, \
    2520              :         NLOHMANN_JSON_PASTE48, \
    2521              :         NLOHMANN_JSON_PASTE47, \
    2522              :         NLOHMANN_JSON_PASTE46, \
    2523              :         NLOHMANN_JSON_PASTE45, \
    2524              :         NLOHMANN_JSON_PASTE44, \
    2525              :         NLOHMANN_JSON_PASTE43, \
    2526              :         NLOHMANN_JSON_PASTE42, \
    2527              :         NLOHMANN_JSON_PASTE41, \
    2528              :         NLOHMANN_JSON_PASTE40, \
    2529              :         NLOHMANN_JSON_PASTE39, \
    2530              :         NLOHMANN_JSON_PASTE38, \
    2531              :         NLOHMANN_JSON_PASTE37, \
    2532              :         NLOHMANN_JSON_PASTE36, \
    2533              :         NLOHMANN_JSON_PASTE35, \
    2534              :         NLOHMANN_JSON_PASTE34, \
    2535              :         NLOHMANN_JSON_PASTE33, \
    2536              :         NLOHMANN_JSON_PASTE32, \
    2537              :         NLOHMANN_JSON_PASTE31, \
    2538              :         NLOHMANN_JSON_PASTE30, \
    2539              :         NLOHMANN_JSON_PASTE29, \
    2540              :         NLOHMANN_JSON_PASTE28, \
    2541              :         NLOHMANN_JSON_PASTE27, \
    2542              :         NLOHMANN_JSON_PASTE26, \
    2543              :         NLOHMANN_JSON_PASTE25, \
    2544              :         NLOHMANN_JSON_PASTE24, \
    2545              :         NLOHMANN_JSON_PASTE23, \
    2546              :         NLOHMANN_JSON_PASTE22, \
    2547              :         NLOHMANN_JSON_PASTE21, \
    2548              :         NLOHMANN_JSON_PASTE20, \
    2549              :         NLOHMANN_JSON_PASTE19, \
    2550              :         NLOHMANN_JSON_PASTE18, \
    2551              :         NLOHMANN_JSON_PASTE17, \
    2552              :         NLOHMANN_JSON_PASTE16, \
    2553              :         NLOHMANN_JSON_PASTE15, \
    2554              :         NLOHMANN_JSON_PASTE14, \
    2555              :         NLOHMANN_JSON_PASTE13, \
    2556              :         NLOHMANN_JSON_PASTE12, \
    2557              :         NLOHMANN_JSON_PASTE11, \
    2558              :         NLOHMANN_JSON_PASTE10, \
    2559              :         NLOHMANN_JSON_PASTE9, \
    2560              :         NLOHMANN_JSON_PASTE8, \
    2561              :         NLOHMANN_JSON_PASTE7, \
    2562              :         NLOHMANN_JSON_PASTE6, \
    2563              :         NLOHMANN_JSON_PASTE5, \
    2564              :         NLOHMANN_JSON_PASTE4, \
    2565              :         NLOHMANN_JSON_PASTE3, \
    2566              :         NLOHMANN_JSON_PASTE2, \
    2567              :         NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
    2568              : #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
    2569              : #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
    2570              : #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
    2571              : #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
    2572              : #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
    2573              : #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)
    2574              : #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)
    2575              : #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)
    2576              : #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)
    2577              : #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)
    2578              : #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)
    2579              : #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)
    2580              : #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)
    2581              : #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)
    2582              : #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)
    2583              : #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)
    2584              : #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)
    2585              : #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)
    2586              : #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)
    2587              : #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)
    2588              : #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)
    2589              : #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)
    2590              : #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)
    2591              : #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)
    2592              : #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)
    2593              : #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)
    2594              : #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)
    2595              : #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)
    2596              : #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)
    2597              : #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)
    2598              : #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)
    2599              : #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)
    2600              : #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)
    2601              : #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)
    2602              : #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)
    2603              : #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)
    2604              : #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)
    2605              : #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)
    2606              : #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)
    2607              : #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)
    2608              : #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)
    2609              : #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)
    2610              : #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)
    2611              : #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)
    2612              : #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)
    2613              : #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)
    2614              : #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)
    2615              : #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)
    2616              : #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)
    2617              : #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)
    2618              : #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)
    2619              : #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)
    2620              : #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)
    2621              : #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)
    2622              : #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)
    2623              : #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)
    2624              : #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)
    2625              : #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)
    2626              : #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)
    2627              : #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)
    2628              : #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)
    2629              : #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)
    2630              : #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)
    2631              : 
    2632              : #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
    2633              : #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
    2634              : 
    2635              : /*!
    2636              : @brief macro
    2637              : @def NLOHMANN_DEFINE_TYPE_INTRUSIVE
    2638              : @since version 3.9.0
    2639              : */
    2640              : #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)  \
    2641              :     friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
    2642              :     friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
    2643              : 
    2644              : /*!
    2645              : @brief macro
    2646              : @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
    2647              : @since version 3.9.0
    2648              : */
    2649              : #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)  \
    2650              :     inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
    2651              :     inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
    2652              : 
    2653              : 
    2654              : // inspired from https://stackoverflow.com/a/26745591
    2655              : // allows to call any std function as if (e.g. with begin):
    2656              : // using std::begin; begin(x);
    2657              : //
    2658              : // it allows using the detected idiom to retrieve the return type
    2659              : // of such an expression
    2660              : #define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)                                 \
    2661              :     namespace detail {                                                            \
    2662              :     using std::std_name;                                                          \
    2663              :     \
    2664              :     template<typename... T>                                                       \
    2665              :     using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \
    2666              :     }                                                                             \
    2667              :     \
    2668              :     namespace detail2 {                                                           \
    2669              :     struct std_name##_tag                                                         \
    2670              :     {                                                                             \
    2671              :     };                                                                            \
    2672              :     \
    2673              :     template<typename... T>                                                       \
    2674              :     std_name##_tag std_name(T&&...);                                              \
    2675              :     \
    2676              :     template<typename... T>                                                       \
    2677              :     using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \
    2678              :     \
    2679              :     template<typename... T>                                                       \
    2680              :     struct would_call_std_##std_name                                              \
    2681              :     {                                                                             \
    2682              :         static constexpr auto const value = ::nlohmann::detail::                  \
    2683              :                                             is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
    2684              :     };                                                                            \
    2685              :     } /* namespace detail2 */ \
    2686              :     \
    2687              :     template<typename... T>                                                       \
    2688              :     struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...>   \
    2689              :     {                                                                             \
    2690              :     }
    2691              : 
    2692              : #ifndef JSON_USE_IMPLICIT_CONVERSIONS
    2693              :     #define JSON_USE_IMPLICIT_CONVERSIONS 1
    2694              : #endif
    2695              : 
    2696              : #if JSON_USE_IMPLICIT_CONVERSIONS
    2697              :     #define JSON_EXPLICIT
    2698              : #else
    2699              :     #define JSON_EXPLICIT explicit
    2700              : #endif
    2701              : 
    2702              : #ifndef JSON_DIAGNOSTICS
    2703              :     #define JSON_DIAGNOSTICS 0
    2704              : #endif
    2705              : 
    2706              : 
    2707              : namespace nlohmann
    2708              : {
    2709              : namespace detail
    2710              : {
    2711              : 
    2712              : /*!
    2713              : @brief replace all occurrences of a substring by another string
    2714              : 
    2715              : @param[in,out] s  the string to manipulate; changed so that all
    2716              :                occurrences of @a f are replaced with @a t
    2717              : @param[in]     f  the substring to replace with @a t
    2718              : @param[in]     t  the string to replace @a f
    2719              : 
    2720              : @pre The search string @a f must not be empty. **This precondition is
    2721              : enforced with an assertion.**
    2722              : 
    2723              : @since version 2.0.0
    2724              : */
    2725              : inline void replace_substring(std::string& s, const std::string& f,
    2726              :                               const std::string& t)
    2727              : {
    2728              :     JSON_ASSERT(!f.empty());
    2729              :     for (auto pos = s.find(f);                // find first occurrence of f
    2730              :             pos != std::string::npos;         // make sure f was found
    2731              :             s.replace(pos, f.size(), t),      // replace with t, and
    2732              :             pos = s.find(f, pos + t.size()))  // find next occurrence of f
    2733              :     {}
    2734              : }
    2735              : 
    2736              : /*!
    2737              :  * @brief string escaping as described in RFC 6901 (Sect. 4)
    2738              :  * @param[in] s string to escape
    2739              :  * @return    escaped string
    2740              :  *
    2741              :  * Note the order of escaping "~" to "~0" and "/" to "~1" is important.
    2742              :  */
    2743              : inline std::string escape(std::string s)
    2744              : {
    2745              :     replace_substring(s, "~", "~0");
    2746              :     replace_substring(s, "/", "~1");
    2747              :     return s;
    2748              : }
    2749              : 
    2750              : /*!
    2751              :  * @brief string unescaping as described in RFC 6901 (Sect. 4)
    2752              :  * @param[in] s string to unescape
    2753              :  * @return    unescaped string
    2754              :  *
    2755              :  * Note the order of escaping "~1" to "/" and "~0" to "~" is important.
    2756              :  */
    2757              : static void unescape(std::string& s)
    2758              : {
    2759              :     replace_substring(s, "~1", "/");
    2760              :     replace_substring(s, "~0", "~");
    2761              : }
    2762              : 
    2763              : } // namespace detail
    2764              : } // namespace nlohmann
    2765              : 
    2766              : // #include <nlohmann/detail/input/position_t.hpp>
    2767              : 
    2768              : 
    2769              : #include <cstddef> // size_t
    2770              : 
    2771              : namespace nlohmann
    2772              : {
    2773              : namespace detail
    2774              : {
    2775              : /// struct to capture the start position of the current token
    2776              : struct position_t
    2777              : {
    2778              :     /// the total number of characters read
    2779              :     std::size_t chars_read_total = 0;
    2780              :     /// the number of characters read in the current line
    2781              :     std::size_t chars_read_current_line = 0;
    2782              :     /// the number of lines read
    2783              :     std::size_t lines_read = 0;
    2784              : 
    2785              :     /// conversion to size_t to preserve SAX interface
    2786              :     constexpr operator size_t() const
    2787              :     {
    2788              :         return chars_read_total;
    2789              :     }
    2790              : };
    2791              : 
    2792              : } // namespace detail
    2793              : } // namespace nlohmann
    2794              : 
    2795              : // #include <nlohmann/detail/macro_scope.hpp>
    2796              : 
    2797              : 
    2798              : namespace nlohmann
    2799              : {
    2800              : namespace detail
    2801              : {
    2802              : ////////////////
    2803              : // exceptions //
    2804              : ////////////////
    2805              : 
    2806              : /// @brief general exception of the @ref basic_json class
    2807              : /// @sa https://json.nlohmann.me/api/basic_json/exception/
    2808            0 : class exception : public std::exception
    2809              : {
    2810              :   public:
    2811              :     /// returns the explanatory string
    2812            0 :     const char* what() const noexcept override
    2813              :     {
    2814            0 :         return m.what();
    2815              :     }
    2816              : 
    2817              :     /// the id of the exception
    2818              :     const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
    2819              : 
    2820              :   protected:
    2821              :     JSON_HEDLEY_NON_NULL(3)
    2822            0 :     exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
    2823              : 
    2824            0 :     static std::string name(const std::string& ename, int id_)
    2825              :     {
    2826            0 :         return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
    2827              :     }
    2828              : 
    2829              :     template<typename BasicJsonType>
    2830              :     static std::string diagnostics(const BasicJsonType& leaf_element)
    2831              :     {
    2832              : #if JSON_DIAGNOSTICS
    2833              :         std::vector<std::string> tokens;
    2834              :         for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
    2835              :         {
    2836              :             switch (current->m_parent->type())
    2837              :             {
    2838              :                 case value_t::array:
    2839              :                 {
    2840              :                     for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
    2841              :                     {
    2842              :                         if (&current->m_parent->m_value.array->operator[](i) == current)
    2843              :                         {
    2844              :                             tokens.emplace_back(std::to_string(i));
    2845              :                             break;
    2846              :                         }
    2847              :                     }
    2848              :                     break;
    2849              :                 }
    2850              : 
    2851              :                 case value_t::object:
    2852              :                 {
    2853              :                     for (const auto& element : *current->m_parent->m_value.object)
    2854              :                     {
    2855              :                         if (&element.second == current)
    2856              :                         {
    2857              :                             tokens.emplace_back(element.first.c_str());
    2858              :                             break;
    2859              :                         }
    2860              :                     }
    2861              :                     break;
    2862              :                 }
    2863              : 
    2864              :                 case value_t::null: // LCOV_EXCL_LINE
    2865              :                 case value_t::string: // LCOV_EXCL_LINE
    2866              :                 case value_t::boolean: // LCOV_EXCL_LINE
    2867              :                 case value_t::number_integer: // LCOV_EXCL_LINE
    2868              :                 case value_t::number_unsigned: // LCOV_EXCL_LINE
    2869              :                 case value_t::number_float: // LCOV_EXCL_LINE
    2870              :                 case value_t::binary: // LCOV_EXCL_LINE
    2871              :                 case value_t::discarded: // LCOV_EXCL_LINE
    2872              :                 default:   // LCOV_EXCL_LINE
    2873              :                     break; // LCOV_EXCL_LINE
    2874              :             }
    2875              :         }
    2876              : 
    2877              :         if (tokens.empty())
    2878              :         {
    2879              :             return "";
    2880              :         }
    2881              : 
    2882              :         return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
    2883              :                                      [](const std::string & a, const std::string & b)
    2884              :         {
    2885              :             return a + "/" + detail::escape(b);
    2886              :         }) + ") ";
    2887              : #else
    2888              :         static_cast<void>(leaf_element);
    2889            0 :         return "";
    2890              : #endif
    2891              :     }
    2892              : 
    2893              :   private:
    2894              :     /// an exception object as storage for error messages
    2895              :     std::runtime_error m;
    2896              : };
    2897              : 
    2898              : /// @brief exception indicating a parse error
    2899              : /// @sa https://json.nlohmann.me/api/basic_json/parse_error/
    2900            0 : class parse_error : public exception
    2901              : {
    2902              :   public:
    2903              :     /*!
    2904              :     @brief create a parse error exception
    2905              :     @param[in] id_       the id of the exception
    2906              :     @param[in] pos       the position where the error occurred (or with
    2907              :                          chars_read_total=0 if the position cannot be
    2908              :                          determined)
    2909              :     @param[in] what_arg  the explanatory string
    2910              :     @return parse_error object
    2911              :     */
    2912              :     template<typename BasicJsonType>
    2913            0 :     static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
    2914              :     {
    2915            0 :         std::string w = exception::name("parse_error", id_) + "parse error" +
    2916              :                         position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
    2917            0 :         return {id_, pos.chars_read_total, w.c_str()};
    2918              :     }
    2919              : 
    2920              :     template<typename BasicJsonType>
    2921              :     static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
    2922              :     {
    2923              :         std::string w = exception::name("parse_error", id_) + "parse error" +
    2924              :                         (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
    2925              :                         ": " + exception::diagnostics(context) + what_arg;
    2926              :         return {id_, byte_, w.c_str()};
    2927              :     }
    2928              : 
    2929              :     /*!
    2930              :     @brief byte index of the parse error
    2931              : 
    2932              :     The byte index of the last read character in the input file.
    2933              : 
    2934              :     @note For an input with n bytes, 1 is the index of the first character and
    2935              :           n+1 is the index of the terminating null byte or the end of file.
    2936              :           This also holds true when reading a byte vector (CBOR or MessagePack).
    2937              :     */
    2938              :     const std::size_t byte;
    2939              : 
    2940              :   private:
    2941              :     parse_error(int id_, std::size_t byte_, const char* what_arg)
    2942            0 :         : exception(id_, what_arg), byte(byte_) {}
    2943              : 
    2944            0 :     static std::string position_string(const position_t& pos)
    2945              :     {
    2946            0 :         return " at line " + std::to_string(pos.lines_read + 1) +
    2947            0 :                ", column " + std::to_string(pos.chars_read_current_line);
    2948              :     }
    2949              : };
    2950              : 
    2951              : /// @brief exception indicating errors with iterators
    2952              : /// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/
    2953              : class invalid_iterator : public exception
    2954              : {
    2955              :   public:
    2956              :     template<typename BasicJsonType>
    2957            0 :     static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
    2958              :     {
    2959            0 :         std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
    2960            0 :         return {id_, w.c_str()};
    2961              :     }
    2962              : 
    2963              :   private:
    2964              :     JSON_HEDLEY_NON_NULL(3)
    2965            0 :     invalid_iterator(int id_, const char* what_arg)
    2966            0 :         : exception(id_, what_arg) {}
    2967              : };
    2968              : 
    2969              : /// @brief exception indicating executing a member function with a wrong type
    2970              : /// @sa https://json.nlohmann.me/api/basic_json/type_error/
    2971              : class type_error : public exception
    2972              : {
    2973              :   public:
    2974              :     template<typename BasicJsonType>
    2975            0 :     static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
    2976              :     {
    2977            0 :         std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
    2978            0 :         return {id_, w.c_str()};
    2979              :     }
    2980              : 
    2981              :   private:
    2982              :     JSON_HEDLEY_NON_NULL(3)
    2983            0 :     type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
    2984              : };
    2985              : 
    2986              : /// @brief exception indicating access out of the defined range
    2987              : /// @sa https://json.nlohmann.me/api/basic_json/out_of_range/
    2988            0 : class out_of_range : public exception
    2989              : {
    2990              :   public:
    2991              :     template<typename BasicJsonType>
    2992            0 :     static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
    2993              :     {
    2994            0 :         std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
    2995            0 :         return {id_, w.c_str()};
    2996              :     }
    2997              : 
    2998              :   private:
    2999              :     JSON_HEDLEY_NON_NULL(3)
    3000            0 :     out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
    3001              : };
    3002              : 
    3003              : /// @brief exception indicating other library errors
    3004              : /// @sa https://json.nlohmann.me/api/basic_json/other_error/
    3005              : class other_error : public exception
    3006              : {
    3007              :   public:
    3008              :     template<typename BasicJsonType>
    3009              :     static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
    3010              :     {
    3011              :         std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
    3012              :         return {id_, w.c_str()};
    3013              :     }
    3014              : 
    3015              :   private:
    3016              :     JSON_HEDLEY_NON_NULL(3)
    3017              :     other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
    3018              : };
    3019              : 
    3020              : }  // namespace detail
    3021              : }  // namespace nlohmann
    3022              : 
    3023              : // #include <nlohmann/detail/macro_scope.hpp>
    3024              : 
    3025              : // #include <nlohmann/detail/meta/cpp_future.hpp>
    3026              : 
    3027              : 
    3028              : #include <cstddef> // size_t
    3029              : #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
    3030              : #include <utility> // index_sequence, make_index_sequence, index_sequence_for
    3031              : 
    3032              : // #include <nlohmann/detail/macro_scope.hpp>
    3033              : 
    3034              : 
    3035              : namespace nlohmann
    3036              : {
    3037              : namespace detail
    3038              : {
    3039              : 
    3040              : template<typename T>
    3041              : using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
    3042              : 
    3043              : #ifdef JSON_HAS_CPP_14
    3044              : 
    3045              : // the following utilities are natively available in C++14
    3046              : using std::enable_if_t;
    3047              : using std::index_sequence;
    3048              : using std::make_index_sequence;
    3049              : using std::index_sequence_for;
    3050              : 
    3051              : #else
    3052              : 
    3053              : // alias templates to reduce boilerplate
    3054              : template<bool B, typename T = void>
    3055              : using enable_if_t = typename std::enable_if<B, T>::type;
    3056              : 
    3057              : // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
    3058              : // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
    3059              : 
    3060              : //// START OF CODE FROM GOOGLE ABSEIL
    3061              : 
    3062              : // integer_sequence
    3063              : //
    3064              : // Class template representing a compile-time integer sequence. An instantiation
    3065              : // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
    3066              : // type through its template arguments (which is a common need when
    3067              : // working with C++11 variadic templates). `absl::integer_sequence` is designed
    3068              : // to be a drop-in replacement for C++14's `std::integer_sequence`.
    3069              : //
    3070              : // Example:
    3071              : //
    3072              : //   template< class T, T... Ints >
    3073              : //   void user_function(integer_sequence<T, Ints...>);
    3074              : //
    3075              : //   int main()
    3076              : //   {
    3077              : //     // user_function's `T` will be deduced to `int` and `Ints...`
    3078              : //     // will be deduced to `0, 1, 2, 3, 4`.
    3079              : //     user_function(make_integer_sequence<int, 5>());
    3080              : //   }
    3081              : template <typename T, T... Ints>
    3082              : struct integer_sequence
    3083              : {
    3084              :     using value_type = T;
    3085              :     static constexpr std::size_t size() noexcept
    3086              :     {
    3087              :         return sizeof...(Ints);
    3088              :     }
    3089              : };
    3090              : 
    3091              : // index_sequence
    3092              : //
    3093              : // A helper template for an `integer_sequence` of `size_t`,
    3094              : // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
    3095              : // `std::index_sequence`.
    3096              : template <size_t... Ints>
    3097              : using index_sequence = integer_sequence<size_t, Ints...>;
    3098              : 
    3099              : namespace utility_internal
    3100              : {
    3101              : 
    3102              : template <typename Seq, size_t SeqSize, size_t Rem>
    3103              : struct Extend;
    3104              : 
    3105              : // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
    3106              : template <typename T, T... Ints, size_t SeqSize>
    3107              : struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
    3108              : {
    3109              :     using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
    3110              : };
    3111              : 
    3112              : template <typename T, T... Ints, size_t SeqSize>
    3113              : struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
    3114              : {
    3115              :     using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
    3116              : };
    3117              : 
    3118              : // Recursion helper for 'make_integer_sequence<T, N>'.
    3119              : // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
    3120              : template <typename T, size_t N>
    3121              : struct Gen
    3122              : {
    3123              :     using type =
    3124              :         typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
    3125              : };
    3126              : 
    3127              : template <typename T>
    3128              : struct Gen<T, 0>
    3129              : {
    3130              :     using type = integer_sequence<T>;
    3131              : };
    3132              : 
    3133              : }  // namespace utility_internal
    3134              : 
    3135              : // Compile-time sequences of integers
    3136              : 
    3137              : // make_integer_sequence
    3138              : //
    3139              : // This template alias is equivalent to
    3140              : // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
    3141              : // replacement for C++14's `std::make_integer_sequence`.
    3142              : template <typename T, T N>
    3143              : using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
    3144              : 
    3145              : // make_index_sequence
    3146              : //
    3147              : // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
    3148              : // and is designed to be a drop-in replacement for C++14's
    3149              : // `std::make_index_sequence`.
    3150              : template <size_t N>
    3151              : using make_index_sequence = make_integer_sequence<size_t, N>;
    3152              : 
    3153              : // index_sequence_for
    3154              : //
    3155              : // Converts a typename pack into an index sequence of the same length, and
    3156              : // is designed to be a drop-in replacement for C++14's
    3157              : // `std::index_sequence_for()`
    3158              : template <typename... Ts>
    3159              : using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
    3160              : 
    3161              : //// END OF CODE FROM GOOGLE ABSEIL
    3162              : 
    3163              : #endif
    3164              : 
    3165              : // dispatch utility (taken from ranges-v3)
    3166              : template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
    3167              : template<> struct priority_tag<0> {};
    3168              : 
    3169              : // taken from ranges-v3
    3170              : template<typename T>
    3171              : struct static_const
    3172              : {
    3173              :     static constexpr T value{};
    3174              : };
    3175              : 
    3176              : template<typename T>
    3177              : constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
    3178              : 
    3179              : }  // namespace detail
    3180              : }  // namespace nlohmann
    3181              : 
    3182              : // #include <nlohmann/detail/meta/identity_tag.hpp>
    3183              : 
    3184              : 
    3185              : namespace nlohmann
    3186              : {
    3187              : namespace detail
    3188              : {
    3189              : // dispatching helper struct
    3190              : template <class T> struct identity_tag {};
    3191              : }  // namespace detail
    3192              : }  // namespace nlohmann
    3193              : 
    3194              : // #include <nlohmann/detail/meta/type_traits.hpp>
    3195              : 
    3196              : 
    3197              : #include <limits> // numeric_limits
    3198              : #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
    3199              : #include <utility> // declval
    3200              : #include <tuple> // tuple
    3201              : 
    3202              : // #include <nlohmann/detail/macro_scope.hpp>
    3203              : 
    3204              : 
    3205              : // #include <nlohmann/detail/iterators/iterator_traits.hpp>
    3206              : 
    3207              : 
    3208              : #include <iterator> // random_access_iterator_tag
    3209              : 
    3210              : // #include <nlohmann/detail/meta/void_t.hpp>
    3211              : 
    3212              : // #include <nlohmann/detail/meta/cpp_future.hpp>
    3213              : 
    3214              : 
    3215              : namespace nlohmann
    3216              : {
    3217              : namespace detail
    3218              : {
    3219              : template<typename It, typename = void>
    3220              : struct iterator_types {};
    3221              : 
    3222              : template<typename It>
    3223              : struct iterator_types <
    3224              :     It,
    3225              :     void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
    3226              :     typename It::reference, typename It::iterator_category >>
    3227              : {
    3228              :     using difference_type = typename It::difference_type;
    3229              :     using value_type = typename It::value_type;
    3230              :     using pointer = typename It::pointer;
    3231              :     using reference = typename It::reference;
    3232              :     using iterator_category = typename It::iterator_category;
    3233              : };
    3234              : 
    3235              : // This is required as some compilers implement std::iterator_traits in a way that
    3236              : // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
    3237              : template<typename T, typename = void>
    3238              : struct iterator_traits
    3239              : {
    3240              : };
    3241              : 
    3242              : template<typename T>
    3243              : struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
    3244              :             : iterator_types<T>
    3245              : {
    3246              : };
    3247              : 
    3248              : template<typename T>
    3249              : struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
    3250              : {
    3251              :     using iterator_category = std::random_access_iterator_tag;
    3252              :     using value_type = T;
    3253              :     using difference_type = ptrdiff_t;
    3254              :     using pointer = T*;
    3255              :     using reference = T&;
    3256              : };
    3257              : } // namespace detail
    3258              : } // namespace nlohmann
    3259              : 
    3260              : // #include <nlohmann/detail/meta/call_std/begin.hpp>
    3261              : 
    3262              : 
    3263              : // #include <nlohmann/detail/macro_scope.hpp>
    3264              : 
    3265              : 
    3266              : namespace nlohmann
    3267              : {
    3268              : NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin);
    3269              : } // namespace nlohmann
    3270              : 
    3271              : // #include <nlohmann/detail/meta/call_std/end.hpp>
    3272              : 
    3273              : 
    3274              : // #include <nlohmann/detail/macro_scope.hpp>
    3275              : 
    3276              : 
    3277              : namespace nlohmann
    3278              : {
    3279              : NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end);
    3280              : }  // namespace nlohmann
    3281              : 
    3282              : // #include <nlohmann/detail/meta/cpp_future.hpp>
    3283              : 
    3284              : // #include <nlohmann/detail/meta/detected.hpp>
    3285              : 
    3286              : // #include <nlohmann/json_fwd.hpp>
    3287              : #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
    3288              : #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
    3289              : 
    3290              : #include <cstdint> // int64_t, uint64_t
    3291              : #include <map> // map
    3292              : #include <memory> // allocator
    3293              : #include <string> // string
    3294              : #include <vector> // vector
    3295              : 
    3296              : /*!
    3297              : @brief namespace for Niels Lohmann
    3298              : @see https://github.com/nlohmann
    3299              : @since version 1.0.0
    3300              : */
    3301              : namespace nlohmann
    3302              : {
    3303              : /*!
    3304              : @brief default JSONSerializer template argument
    3305              : 
    3306              : This serializer ignores the template arguments and uses ADL
    3307              : ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
    3308              : for serialization.
    3309              : */
    3310              : template<typename T = void, typename SFINAE = void>
    3311              : struct adl_serializer;
    3312              : 
    3313              : /// a class to store JSON values
    3314              : /// @sa https://json.nlohmann.me/api/basic_json/
    3315              : template<template<typename U, typename V, typename... Args> class ObjectType =
    3316              :          std::map,
    3317              :          template<typename U, typename... Args> class ArrayType = std::vector,
    3318              :          class StringType = std::string, class BooleanType = bool,
    3319              :          class NumberIntegerType = std::int64_t,
    3320              :          class NumberUnsignedType = std::uint64_t,
    3321              :          class NumberFloatType = double,
    3322              :          template<typename U> class AllocatorType = std::allocator,
    3323              :          template<typename T, typename SFINAE = void> class JSONSerializer =
    3324              :          adl_serializer,
    3325              :          class BinaryType = std::vector<std::uint8_t>>
    3326              : class basic_json;
    3327              : 
    3328              : /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
    3329              : /// @sa https://json.nlohmann.me/api/json_pointer/
    3330              : template<typename BasicJsonType>
    3331              : class json_pointer;
    3332              : 
    3333              : /*!
    3334              : @brief default specialization
    3335              : @sa https://json.nlohmann.me/api/json/
    3336              : */
    3337              : using json = basic_json<>;
    3338              : 
    3339              : /// @brief a minimal map-like container that preserves insertion order
    3340              : /// @sa https://json.nlohmann.me/api/ordered_map/
    3341              : template<class Key, class T, class IgnoredLess, class Allocator>
    3342              : struct ordered_map;
    3343              : 
    3344              : /// @brief specialization that maintains the insertion order of object keys
    3345              : /// @sa https://json.nlohmann.me/api/ordered_json/
    3346              : using ordered_json = basic_json<nlohmann::ordered_map>;
    3347              : 
    3348              : }  // namespace nlohmann
    3349              : 
    3350              : #endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
    3351              : 
    3352              : 
    3353              : namespace nlohmann
    3354              : {
    3355              : /*!
    3356              : @brief detail namespace with internal helper functions
    3357              : 
    3358              : This namespace collects functions that should not be exposed,
    3359              : implementations of some @ref basic_json methods, and meta-programming helpers.
    3360              : 
    3361              : @since version 2.1.0
    3362              : */
    3363              : namespace detail
    3364              : {
    3365              : /////////////
    3366              : // helpers //
    3367              : /////////////
    3368              : 
    3369              : // Note to maintainers:
    3370              : //
    3371              : // Every trait in this file expects a non CV-qualified type.
    3372              : // The only exceptions are in the 'aliases for detected' section
    3373              : // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
    3374              : //
    3375              : // In this case, T has to be properly CV-qualified to constraint the function arguments
    3376              : // (e.g. to_json(BasicJsonType&, const T&))
    3377              : 
    3378              : template<typename> struct is_basic_json : std::false_type {};
    3379              : 
    3380              : NLOHMANN_BASIC_JSON_TPL_DECLARATION
    3381              : struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
    3382              : 
    3383              : //////////////////////
    3384              : // json_ref helpers //
    3385              : //////////////////////
    3386              : 
    3387              : template<typename>
    3388              : class json_ref;
    3389              : 
    3390              : template<typename>
    3391              : struct is_json_ref : std::false_type {};
    3392              : 
    3393              : template<typename T>
    3394              : struct is_json_ref<json_ref<T>> : std::true_type {};
    3395              : 
    3396              : //////////////////////////
    3397              : // aliases for detected //
    3398              : //////////////////////////
    3399              : 
    3400              : template<typename T>
    3401              : using mapped_type_t = typename T::mapped_type;
    3402              : 
    3403              : template<typename T>
    3404              : using key_type_t = typename T::key_type;
    3405              : 
    3406              : template<typename T>
    3407              : using value_type_t = typename T::value_type;
    3408              : 
    3409              : template<typename T>
    3410              : using difference_type_t = typename T::difference_type;
    3411              : 
    3412              : template<typename T>
    3413              : using pointer_t = typename T::pointer;
    3414              : 
    3415              : template<typename T>
    3416              : using reference_t = typename T::reference;
    3417              : 
    3418              : template<typename T>
    3419              : using iterator_category_t = typename T::iterator_category;
    3420              : 
    3421              : template<typename T, typename... Args>
    3422              : using to_json_function = decltype(T::to_json(std::declval<Args>()...));
    3423              : 
    3424              : template<typename T, typename... Args>
    3425              : using from_json_function = decltype(T::from_json(std::declval<Args>()...));
    3426              : 
    3427              : template<typename T, typename U>
    3428              : using get_template_function = decltype(std::declval<T>().template get<U>());
    3429              : 
    3430              : // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
    3431              : template<typename BasicJsonType, typename T, typename = void>
    3432              : struct has_from_json : std::false_type {};
    3433              : 
    3434              : // trait checking if j.get<T> is valid
    3435              : // use this trait instead of std::is_constructible or std::is_convertible,
    3436              : // both rely on, or make use of implicit conversions, and thus fail when T
    3437              : // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
    3438              : template <typename BasicJsonType, typename T>
    3439              : struct is_getable
    3440              : {
    3441              :     static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
    3442              : };
    3443              : 
    3444              : template<typename BasicJsonType, typename T>
    3445              : struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
    3446              : {
    3447              :     using serializer = typename BasicJsonType::template json_serializer<T, void>;
    3448              : 
    3449              :     static constexpr bool value =
    3450              :         is_detected_exact<void, from_json_function, serializer,
    3451              :         const BasicJsonType&, T&>::value;
    3452              : };
    3453              : 
    3454              : // This trait checks if JSONSerializer<T>::from_json(json const&) exists
    3455              : // this overload is used for non-default-constructible user-defined-types
    3456              : template<typename BasicJsonType, typename T, typename = void>
    3457              : struct has_non_default_from_json : std::false_type {};
    3458              : 
    3459              : template<typename BasicJsonType, typename T>
    3460              : struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
    3461              : {
    3462              :     using serializer = typename BasicJsonType::template json_serializer<T, void>;
    3463              : 
    3464              :     static constexpr bool value =
    3465              :         is_detected_exact<T, from_json_function, serializer,
    3466              :         const BasicJsonType&>::value;
    3467              : };
    3468              : 
    3469              : // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
    3470              : // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
    3471              : template<typename BasicJsonType, typename T, typename = void>
    3472              : struct has_to_json : std::false_type {};
    3473              : 
    3474              : template<typename BasicJsonType, typename T>
    3475              : struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
    3476              : {
    3477              :     using serializer = typename BasicJsonType::template json_serializer<T, void>;
    3478              : 
    3479              :     static constexpr bool value =
    3480              :         is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
    3481              :         T>::value;
    3482              : };
    3483              : 
    3484              : 
    3485              : ///////////////////
    3486              : // is_ functions //
    3487              : ///////////////////
    3488              : 
    3489              : // https://en.cppreference.com/w/cpp/types/conjunction
    3490              : template<class...> struct conjunction : std::true_type { };
    3491              : template<class B1> struct conjunction<B1> : B1 { };
    3492              : template<class B1, class... Bn>
    3493              : struct conjunction<B1, Bn...>
    3494              : : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
    3495              : 
    3496              : // https://en.cppreference.com/w/cpp/types/negation
    3497              : template<class B> struct negation : std::integral_constant < bool, !B::value > { };
    3498              : 
    3499              : // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
    3500              : // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
    3501              : // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
    3502              : template <typename T>
    3503              : struct is_default_constructible : std::is_default_constructible<T> {};
    3504              : 
    3505              : template <typename T1, typename T2>
    3506              : struct is_default_constructible<std::pair<T1, T2>>
    3507              :             : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
    3508              : 
    3509              : template <typename T1, typename T2>
    3510              : struct is_default_constructible<const std::pair<T1, T2>>
    3511              :             : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
    3512              : 
    3513              : template <typename... Ts>
    3514              : struct is_default_constructible<std::tuple<Ts...>>
    3515              :             : conjunction<is_default_constructible<Ts>...> {};
    3516              : 
    3517              : template <typename... Ts>
    3518              : struct is_default_constructible<const std::tuple<Ts...>>
    3519              :             : conjunction<is_default_constructible<Ts>...> {};
    3520              : 
    3521              : 
    3522              : template <typename T, typename... Args>
    3523              : struct is_constructible : std::is_constructible<T, Args...> {};
    3524              : 
    3525              : template <typename T1, typename T2>
    3526              : struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
    3527              : 
    3528              : template <typename T1, typename T2>
    3529              : struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
    3530              : 
    3531              : template <typename... Ts>
    3532              : struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
    3533              : 
    3534              : template <typename... Ts>
    3535              : struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
    3536              : 
    3537              : 
    3538              : template<typename T, typename = void>
    3539              : struct is_iterator_traits : std::false_type {};
    3540              : 
    3541              : template<typename T>
    3542              : struct is_iterator_traits<iterator_traits<T>>
    3543              : {
    3544              :   private:
    3545              :     using traits = iterator_traits<T>;
    3546              : 
    3547              :   public:
    3548              :     static constexpr auto value =
    3549              :         is_detected<value_type_t, traits>::value &&
    3550              :         is_detected<difference_type_t, traits>::value &&
    3551              :         is_detected<pointer_t, traits>::value &&
    3552              :         is_detected<iterator_category_t, traits>::value &&
    3553              :         is_detected<reference_t, traits>::value;
    3554              : };
    3555              : 
    3556              : template<typename T>
    3557              : struct is_range
    3558              : {
    3559              :   private:
    3560              :     using t_ref = typename std::add_lvalue_reference<T>::type;
    3561              : 
    3562              :     using iterator = detected_t<result_of_begin, t_ref>;
    3563              :     using sentinel = detected_t<result_of_end, t_ref>;
    3564              : 
    3565              :     // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
    3566              :     // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
    3567              :     // but reimplementing these would be too much work, as a lot of other concepts are used underneath
    3568              :     static constexpr auto is_iterator_begin =
    3569              :         is_iterator_traits<iterator_traits<iterator>>::value;
    3570              : 
    3571              :   public:
    3572              :     static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
    3573              : };
    3574              : 
    3575              : template<typename R>
    3576              : using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
    3577              : 
    3578              : template<typename T>
    3579              : using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;
    3580              : 
    3581              : // The following implementation of is_complete_type is taken from
    3582              : // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
    3583              : // and is written by Xiang Fan who agreed to using it in this library.
    3584              : 
    3585              : template<typename T, typename = void>
    3586              : struct is_complete_type : std::false_type {};
    3587              : 
    3588              : template<typename T>
    3589              : struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
    3590              : 
    3591              : template<typename BasicJsonType, typename CompatibleObjectType,
    3592              :          typename = void>
    3593              : struct is_compatible_object_type_impl : std::false_type {};
    3594              : 
    3595              : template<typename BasicJsonType, typename CompatibleObjectType>
    3596              : struct is_compatible_object_type_impl <
    3597              :     BasicJsonType, CompatibleObjectType,
    3598              :     enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
    3599              :     is_detected<key_type_t, CompatibleObjectType>::value >>
    3600              : {
    3601              :     using object_t = typename BasicJsonType::object_t;
    3602              : 
    3603              :     // macOS's is_constructible does not play well with nonesuch...
    3604              :     static constexpr bool value =
    3605              :         is_constructible<typename object_t::key_type,
    3606              :         typename CompatibleObjectType::key_type>::value &&
    3607              :         is_constructible<typename object_t::mapped_type,
    3608              :         typename CompatibleObjectType::mapped_type>::value;
    3609              : };
    3610              : 
    3611              : template<typename BasicJsonType, typename CompatibleObjectType>
    3612              : struct is_compatible_object_type
    3613              :     : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
    3614              : 
    3615              : template<typename BasicJsonType, typename ConstructibleObjectType,
    3616              :          typename = void>
    3617              : struct is_constructible_object_type_impl : std::false_type {};
    3618              : 
    3619              : template<typename BasicJsonType, typename ConstructibleObjectType>
    3620              : struct is_constructible_object_type_impl <
    3621              :     BasicJsonType, ConstructibleObjectType,
    3622              :     enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
    3623              :     is_detected<key_type_t, ConstructibleObjectType>::value >>
    3624              : {
    3625              :     using object_t = typename BasicJsonType::object_t;
    3626              : 
    3627              :     static constexpr bool value =
    3628              :         (is_default_constructible<ConstructibleObjectType>::value &&
    3629              :          (std::is_move_assignable<ConstructibleObjectType>::value ||
    3630              :           std::is_copy_assignable<ConstructibleObjectType>::value) &&
    3631              :          (is_constructible<typename ConstructibleObjectType::key_type,
    3632              :           typename object_t::key_type>::value &&
    3633              :           std::is_same <
    3634              :           typename object_t::mapped_type,
    3635              :           typename ConstructibleObjectType::mapped_type >::value)) ||
    3636              :         (has_from_json<BasicJsonType,
    3637              :          typename ConstructibleObjectType::mapped_type>::value ||
    3638              :          has_non_default_from_json <
    3639              :          BasicJsonType,
    3640              :          typename ConstructibleObjectType::mapped_type >::value);
    3641              : };
    3642              : 
    3643              : template<typename BasicJsonType, typename ConstructibleObjectType>
    3644              : struct is_constructible_object_type
    3645              :     : is_constructible_object_type_impl<BasicJsonType,
    3646              :       ConstructibleObjectType> {};
    3647              : 
    3648              : template<typename BasicJsonType, typename CompatibleStringType>
    3649              : struct is_compatible_string_type
    3650              : {
    3651              :     static constexpr auto value =
    3652              :         is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
    3653              : };
    3654              : 
    3655              : template<typename BasicJsonType, typename ConstructibleStringType>
    3656              : struct is_constructible_string_type
    3657              : {
    3658              :     static constexpr auto value =
    3659              :         is_constructible<ConstructibleStringType,
    3660              :         typename BasicJsonType::string_t>::value;
    3661              : };
    3662              : 
    3663              : template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
    3664              : struct is_compatible_array_type_impl : std::false_type {};
    3665              : 
    3666              : template<typename BasicJsonType, typename CompatibleArrayType>
    3667              : struct is_compatible_array_type_impl <
    3668              :     BasicJsonType, CompatibleArrayType,
    3669              :     enable_if_t <
    3670              :     is_detected<iterator_t, CompatibleArrayType>::value&&
    3671              :     is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
    3672              : // special case for types like std::filesystem::path whose iterator's value_type are themselves
    3673              : // c.f. https://github.com/nlohmann/json/pull/3073
    3674              :     !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
    3675              : {
    3676              :     static constexpr bool value =
    3677              :         is_constructible<BasicJsonType,
    3678              :         range_value_t<CompatibleArrayType>>::value;
    3679              : };
    3680              : 
    3681              : template<typename BasicJsonType, typename CompatibleArrayType>
    3682              : struct is_compatible_array_type
    3683              :     : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
    3684              : 
    3685              : template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
    3686              : struct is_constructible_array_type_impl : std::false_type {};
    3687              : 
    3688              : template<typename BasicJsonType, typename ConstructibleArrayType>
    3689              : struct is_constructible_array_type_impl <
    3690              :     BasicJsonType, ConstructibleArrayType,
    3691              :     enable_if_t<std::is_same<ConstructibleArrayType,
    3692              :     typename BasicJsonType::value_type>::value >>
    3693              :             : std::true_type {};
    3694              : 
    3695              : template<typename BasicJsonType, typename ConstructibleArrayType>
    3696              : struct is_constructible_array_type_impl <
    3697              :     BasicJsonType, ConstructibleArrayType,
    3698              :     enable_if_t < !std::is_same<ConstructibleArrayType,
    3699              :     typename BasicJsonType::value_type>::value&&
    3700              :     !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
    3701              :     is_default_constructible<ConstructibleArrayType>::value&&
    3702              : (std::is_move_assignable<ConstructibleArrayType>::value ||
    3703              :  std::is_copy_assignable<ConstructibleArrayType>::value)&&
    3704              : is_detected<iterator_t, ConstructibleArrayType>::value&&
    3705              : is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
    3706              : is_detected<range_value_t, ConstructibleArrayType>::value&&
    3707              : // special case for types like std::filesystem::path whose iterator's value_type are themselves
    3708              : // c.f. https://github.com/nlohmann/json/pull/3073
    3709              : !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
    3710              :         is_complete_type <
    3711              :         detected_t<range_value_t, ConstructibleArrayType >>::value >>
    3712              : {
    3713              :     using value_type = range_value_t<ConstructibleArrayType>;
    3714              : 
    3715              :     static constexpr bool value =
    3716              :         std::is_same<value_type,
    3717              :         typename BasicJsonType::array_t::value_type>::value ||
    3718              :         has_from_json<BasicJsonType,
    3719              :         value_type>::value ||
    3720              :         has_non_default_from_json <
    3721              :         BasicJsonType,
    3722              :         value_type >::value;
    3723              : };
    3724              : 
    3725              : template<typename BasicJsonType, typename ConstructibleArrayType>
    3726              : struct is_constructible_array_type
    3727              :     : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
    3728              : 
    3729              : template<typename RealIntegerType, typename CompatibleNumberIntegerType,
    3730              :          typename = void>
    3731              : struct is_compatible_integer_type_impl : std::false_type {};
    3732              : 
    3733              : template<typename RealIntegerType, typename CompatibleNumberIntegerType>
    3734              : struct is_compatible_integer_type_impl <
    3735              :     RealIntegerType, CompatibleNumberIntegerType,
    3736              :     enable_if_t < std::is_integral<RealIntegerType>::value&&
    3737              :     std::is_integral<CompatibleNumberIntegerType>::value&&
    3738              :     !std::is_same<bool, CompatibleNumberIntegerType>::value >>
    3739              : {
    3740              :     // is there an assert somewhere on overflows?
    3741              :     using RealLimits = std::numeric_limits<RealIntegerType>;
    3742              :     using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
    3743              : 
    3744              :     static constexpr auto value =
    3745              :         is_constructible<RealIntegerType,
    3746              :         CompatibleNumberIntegerType>::value &&
    3747              :         CompatibleLimits::is_integer &&
    3748              :         RealLimits::is_signed == CompatibleLimits::is_signed;
    3749              : };
    3750              : 
    3751              : template<typename RealIntegerType, typename CompatibleNumberIntegerType>
    3752              : struct is_compatible_integer_type
    3753              :     : is_compatible_integer_type_impl<RealIntegerType,
    3754              :       CompatibleNumberIntegerType> {};
    3755              : 
    3756              : template<typename BasicJsonType, typename CompatibleType, typename = void>
    3757              : struct is_compatible_type_impl: std::false_type {};
    3758              : 
    3759              : template<typename BasicJsonType, typename CompatibleType>
    3760              : struct is_compatible_type_impl <
    3761              :     BasicJsonType, CompatibleType,
    3762              :     enable_if_t<is_complete_type<CompatibleType>::value >>
    3763              : {
    3764              :     static constexpr bool value =
    3765              :         has_to_json<BasicJsonType, CompatibleType>::value;
    3766              : };
    3767              : 
    3768              : template<typename BasicJsonType, typename CompatibleType>
    3769              : struct is_compatible_type
    3770              :     : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
    3771              : 
    3772              : template<typename T1, typename T2>
    3773              : struct is_constructible_tuple : std::false_type {};
    3774              : 
    3775              : template<typename T1, typename... Args>
    3776              : struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
    3777              : 
    3778              : // a naive helper to check if a type is an ordered_map (exploits the fact that
    3779              : // ordered_map inherits capacity() from std::vector)
    3780              : template <typename T>
    3781              : struct is_ordered_map
    3782              : {
    3783              :     using one = char;
    3784              : 
    3785              :     struct two
    3786              :     {
    3787              :         char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
    3788              :     };
    3789              : 
    3790              :     template <typename C> static one test( decltype(&C::capacity) ) ;
    3791              :     template <typename C> static two test(...);
    3792              : 
    3793              :     enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
    3794              : };
    3795              : 
    3796              : // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
    3797              : template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
    3798              : T conditional_static_cast(U value)
    3799              : {
    3800              :     return static_cast<T>(value);
    3801              : }
    3802              : 
    3803              : template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
    3804              : T conditional_static_cast(U value)
    3805              : {
    3806              :     return value;
    3807              : }
    3808              : 
    3809              : }  // namespace detail
    3810              : }  // namespace nlohmann
    3811              : 
    3812              : // #include <nlohmann/detail/value_t.hpp>
    3813              : 
    3814              : 
    3815              : #if JSON_HAS_EXPERIMENTAL_FILESYSTEM
    3816              : #include <experimental/filesystem>
    3817              : namespace nlohmann::detail
    3818              : {
    3819              : namespace std_fs = std::experimental::filesystem;
    3820              : } // namespace nlohmann::detail
    3821              : #elif JSON_HAS_FILESYSTEM
    3822              : #include <filesystem>
    3823              : namespace nlohmann::detail
    3824              : {
    3825              : namespace std_fs = std::filesystem;
    3826              : } // namespace nlohmann::detail
    3827              : #endif
    3828              : 
    3829              : namespace nlohmann
    3830              : {
    3831              : namespace detail
    3832              : {
    3833              : template<typename BasicJsonType>
    3834              : void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
    3835              : {
    3836              :     if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
    3837              :     {
    3838              :         JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
    3839              :     }
    3840              :     n = nullptr;
    3841              : }
    3842              : 
    3843              : // overloads for basic_json template parameters
    3844              : template < typename BasicJsonType, typename ArithmeticType,
    3845              :            enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
    3846              :                          !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
    3847              :                          int > = 0 >
    3848         2391 : void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
    3849              : {
    3850         2391 :     switch (static_cast<value_t>(j))
    3851              :     {
    3852              :         case value_t::number_unsigned:
    3853              :         {
    3854           31 :             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
    3855           31 :             break;
    3856              :         }
    3857              :         case value_t::number_integer:
    3858              :         {
    3859            0 :             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
    3860            0 :             break;
    3861              :         }
    3862              :         case value_t::number_float:
    3863              :         {
    3864         2360 :             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
    3865         2360 :             break;
    3866              :         }
    3867              : 
    3868            0 :         case value_t::null:
    3869              :         case value_t::object:
    3870              :         case value_t::array:
    3871              :         case value_t::string:
    3872              :         case value_t::boolean:
    3873              :         case value_t::binary:
    3874              :         case value_t::discarded:
    3875              :         default:
    3876            0 :             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
    3877              :     }
    3878         2391 : }
    3879              : 
    3880              : template<typename BasicJsonType>
    3881              : void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
    3882              : {
    3883              :     if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
    3884              :     {
    3885              :         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
    3886              :     }
    3887              :     b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
    3888              : }
    3889              : 
    3890              : template<typename BasicJsonType>
    3891           81 : void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
    3892              : {
    3893           81 :     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
    3894              :     {
    3895            0 :         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
    3896              :     }
    3897              :     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
    3898           81 : }
    3899              : 
    3900              : template <
    3901              :     typename BasicJsonType, typename ConstructibleStringType,
    3902              :     enable_if_t <
    3903              :         is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
    3904              :         !std::is_same<typename BasicJsonType::string_t,
    3905              :                       ConstructibleStringType>::value,
    3906              :         int > = 0 >
    3907              : void from_json(const BasicJsonType& j, ConstructibleStringType& s)
    3908              : {
    3909              :     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
    3910              :     {
    3911              :         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
    3912              :     }
    3913              : 
    3914              :     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
    3915              : }
    3916              : 
    3917              : template<typename BasicJsonType>
    3918              : void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
    3919              : {
    3920         2391 :     get_arithmetic_value(j, val);
    3921              : }
    3922              : 
    3923              : template<typename BasicJsonType>
    3924              : void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
    3925              : {
    3926              :     get_arithmetic_value(j, val);
    3927              : }
    3928              : 
    3929              : template<typename BasicJsonType>
    3930              : void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
    3931              : {
    3932              :     get_arithmetic_value(j, val);
    3933              : }
    3934              : 
    3935              : template<typename BasicJsonType, typename EnumType,
    3936              :          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
    3937              : void from_json(const BasicJsonType& j, EnumType& e)
    3938              : {
    3939              :     typename std::underlying_type<EnumType>::type val;
    3940              :     get_arithmetic_value(j, val);
    3941              :     e = static_cast<EnumType>(val);
    3942              : }
    3943              : 
    3944              : // forward_list doesn't have an insert method
    3945              : template<typename BasicJsonType, typename T, typename Allocator,
    3946              :          enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
    3947              : void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
    3948              : {
    3949              :     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
    3950              :     {
    3951              :         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
    3952              :     }
    3953              :     l.clear();
    3954              :     std::transform(j.rbegin(), j.rend(),
    3955              :                    std::front_inserter(l), [](const BasicJsonType & i)
    3956              :     {
    3957              :         return i.template get<T>();
    3958              :     });
    3959              : }
    3960              : 
    3961              : // valarray doesn't have an insert method
    3962              : template<typename BasicJsonType, typename T,
    3963              :          enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
    3964              : void from_json(const BasicJsonType& j, std::valarray<T>& l)
    3965              : {
    3966              :     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
    3967              :     {
    3968              :         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
    3969              :     }
    3970              :     l.resize(j.size());
    3971              :     std::transform(j.begin(), j.end(), std::begin(l),
    3972              :                    [](const BasicJsonType & elem)
    3973              :     {
    3974              :         return elem.template get<T>();
    3975              :     });
    3976              : }
    3977              : 
    3978              : template<typename BasicJsonType, typename T, std::size_t N>
    3979              : auto from_json(const BasicJsonType& j, T (&arr)[N])  // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
    3980              : -> decltype(j.template get<T>(), void())
    3981              : {
    3982              :     for (std::size_t i = 0; i < N; ++i)
    3983              :     {
    3984              :         arr[i] = j.at(i).template get<T>();
    3985              :     }
    3986              : }
    3987              : 
    3988              : template<typename BasicJsonType>
    3989              : void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
    3990              : {
    3991              :     arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
    3992              : }
    3993              : 
    3994              : template<typename BasicJsonType, typename T, std::size_t N>
    3995              : auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
    3996              :                           priority_tag<2> /*unused*/)
    3997              : -> decltype(j.template get<T>(), void())
    3998              : {
    3999              :     for (std::size_t i = 0; i < N; ++i)
    4000              :     {
    4001              :         arr[i] = j.at(i).template get<T>();
    4002              :     }
    4003              : }
    4004              : 
    4005              : template<typename BasicJsonType, typename ConstructibleArrayType,
    4006              :          enable_if_t<
    4007              :              std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
    4008              :              int> = 0>
    4009          147 : auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
    4010              : -> decltype(
    4011              :     arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
    4012              :     j.template get<typename ConstructibleArrayType::value_type>(),
    4013              :     void())
    4014              : {
    4015              :     using std::end;
    4016              : 
    4017              :     ConstructibleArrayType ret;
    4018          147 :     ret.reserve(j.size());
    4019          294 :     std::transform(j.begin(), j.end(),
    4020              :                    std::inserter(ret, end(ret)), [](const BasicJsonType & i)
    4021              :     {
    4022              :         // get<BasicJsonType>() returns *this, this won't call a from_json
    4023              :         // method when value_type is BasicJsonType
    4024              :         return i.template get<typename ConstructibleArrayType::value_type>();
    4025              :     });
    4026          147 :     arr = std::move(ret);
    4027          147 : }
    4028              : 
    4029              : template<typename BasicJsonType, typename ConstructibleArrayType,
    4030              :          enable_if_t<
    4031              :              std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
    4032              :              int> = 0>
    4033              : void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
    4034              :                           priority_tag<0> /*unused*/)
    4035              : {
    4036              :     using std::end;
    4037              : 
    4038              :     ConstructibleArrayType ret;
    4039              :     std::transform(
    4040              :         j.begin(), j.end(), std::inserter(ret, end(ret)),
    4041              :         [](const BasicJsonType & i)
    4042              :     {
    4043              :         // get<BasicJsonType>() returns *this, this won't call a from_json
    4044              :         // method when value_type is BasicJsonType
    4045              :         return i.template get<typename ConstructibleArrayType::value_type>();
    4046              :     });
    4047              :     arr = std::move(ret);
    4048              : }
    4049              : 
    4050              : template < typename BasicJsonType, typename ConstructibleArrayType,
    4051              :            enable_if_t <
    4052              :                is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
    4053              :                !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
    4054              :                !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
    4055              :                !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
    4056              :                !is_basic_json<ConstructibleArrayType>::value,
    4057              :                int > = 0 >
    4058          147 : auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
    4059              : -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
    4060              : j.template get<typename ConstructibleArrayType::value_type>(),
    4061              : void())
    4062              : {
    4063          147 :     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
    4064              :     {
    4065            0 :         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
    4066              :     }
    4067              : 
    4068          147 :     from_json_array_impl(j, arr, priority_tag<3> {});
    4069          147 : }
    4070              : 
    4071              : template < typename BasicJsonType, typename T, std::size_t... Idx >
    4072              : std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
    4073              :         identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
    4074              : {
    4075              :     return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
    4076              : }
    4077              : 
    4078              : template < typename BasicJsonType, typename T, std::size_t N >
    4079              : auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
    4080              : -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
    4081              : {
    4082              :     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
    4083              :     {
    4084              :         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
    4085              :     }
    4086              : 
    4087              :     return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
    4088              : }
    4089              : 
    4090              : template<typename BasicJsonType>
    4091              : void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
    4092              : {
    4093              :     if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
    4094              :     {
    4095              :         JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
    4096              :     }
    4097              : 
    4098              :     bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
    4099              : }
    4100              : 
    4101              : template<typename BasicJsonType, typename ConstructibleObjectType,
    4102              :          enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
    4103           54 : void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
    4104              : {
    4105           54 :     if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
    4106              :     {
    4107            0 :         JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
    4108              :     }
    4109              : 
    4110              :     ConstructibleObjectType ret;
    4111              :     const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
    4112              :     using value_type = typename ConstructibleObjectType::value_type;
    4113           54 :     std::transform(
    4114              :         inner_object->begin(), inner_object->end(),
    4115              :         std::inserter(ret, ret.begin()),
    4116          135 :         [](typename BasicJsonType::object_t::value_type const & p)
    4117              :     {
    4118          135 :         return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
    4119              :     });
    4120              :     obj = std::move(ret);
    4121           54 : }
    4122              : 
    4123              : // overload for arithmetic types, not chosen for basic_json template arguments
    4124              : // (BooleanType, etc..); note: Is it really necessary to provide explicit
    4125              : // overloads for boolean_t etc. in case of a custom BooleanType which is not
    4126              : // an arithmetic type?
    4127              : template < typename BasicJsonType, typename ArithmeticType,
    4128              :            enable_if_t <
    4129              :                std::is_arithmetic<ArithmeticType>::value&&
    4130              :                !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
    4131              :                !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
    4132              :                !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
    4133              :                !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
    4134              :                int > = 0 >
    4135              : void from_json(const BasicJsonType& j, ArithmeticType& val)
    4136              : {
    4137              :     switch (static_cast<value_t>(j))
    4138              :     {
    4139              :         case value_t::number_unsigned:
    4140              :         {
    4141              :             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
    4142              :             break;
    4143              :         }
    4144              :         case value_t::number_integer:
    4145              :         {
    4146              :             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
    4147              :             break;
    4148              :         }
    4149              :         case value_t::number_float:
    4150              :         {
    4151              :             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
    4152              :             break;
    4153              :         }
    4154              :         case value_t::boolean:
    4155              :         {
    4156              :             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
    4157              :             break;
    4158              :         }
    4159              : 
    4160              :         case value_t::null:
    4161              :         case value_t::object:
    4162              :         case value_t::array:
    4163              :         case value_t::string:
    4164              :         case value_t::binary:
    4165              :         case value_t::discarded:
    4166              :         default:
    4167              :             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
    4168              :     }
    4169              : }
    4170              : 
    4171              : template<typename BasicJsonType, typename... Args, std::size_t... Idx>
    4172              : std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
    4173              : {
    4174              :     return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
    4175              : }
    4176              : 
    4177              : template < typename BasicJsonType, class A1, class A2 >
    4178              : std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
    4179              : {
    4180              :     return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
    4181              :             std::forward<BasicJsonType>(j).at(1).template get<A2>()};
    4182              : }
    4183              : 
    4184              : template<typename BasicJsonType, typename A1, typename A2>
    4185              : void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
    4186              : {
    4187              :     p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
    4188              : }
    4189              : 
    4190              : template<typename BasicJsonType, typename... Args>
    4191              : std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
    4192              : {
    4193              :     return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
    4194              : }
    4195              : 
    4196              : template<typename BasicJsonType, typename... Args>
    4197              : void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
    4198              : {
    4199              :     t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
    4200              : }
    4201              : 
    4202              : template<typename BasicJsonType, typename TupleRelated>
    4203              : auto from_json(BasicJsonType&& j, TupleRelated&& t)
    4204              : -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
    4205              : {
    4206              :     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
    4207              :     {
    4208              :         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
    4209              :     }
    4210              : 
    4211              :     return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
    4212              : }
    4213              : 
    4214              : template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
    4215              :            typename = enable_if_t < !std::is_constructible <
    4216              :                                         typename BasicJsonType::string_t, Key >::value >>
    4217              : void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
    4218              : {
    4219              :     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
    4220              :     {
    4221              :         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
    4222              :     }
    4223              :     m.clear();
    4224              :     for (const auto& p : j)
    4225              :     {
    4226              :         if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
    4227              :         {
    4228              :             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
    4229              :         }
    4230              :         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
    4231              :     }
    4232              : }
    4233              : 
    4234              : template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
    4235              :            typename = enable_if_t < !std::is_constructible <
    4236              :                                         typename BasicJsonType::string_t, Key >::value >>
    4237              : void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
    4238              : {
    4239              :     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
    4240              :     {
    4241              :         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
    4242              :     }
    4243              :     m.clear();
    4244              :     for (const auto& p : j)
    4245              :     {
    4246              :         if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
    4247              :         {
    4248              :             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
    4249              :         }
    4250              :         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
    4251              :     }
    4252              : }
    4253              : 
    4254              : #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
    4255              : template<typename BasicJsonType>
    4256              : void from_json(const BasicJsonType& j, std_fs::path& p)
    4257              : {
    4258              :     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
    4259              :     {
    4260              :         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
    4261              :     }
    4262              :     p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
    4263              : }
    4264              : #endif
    4265              : 
    4266              : struct from_json_fn
    4267              : {
    4268              :     template<typename BasicJsonType, typename T>
    4269              :     auto operator()(const BasicJsonType& j, T&& val) const
    4270              :     noexcept(noexcept(from_json(j, std::forward<T>(val))))
    4271              :     -> decltype(from_json(j, std::forward<T>(val)))
    4272              :     {
    4273          147 :         return from_json(j, std::forward<T>(val));
    4274              :     }
    4275              : };
    4276              : }  // namespace detail
    4277              : 
    4278              : /// namespace to hold default `from_json` function
    4279              : /// to see why this is required:
    4280              : /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
    4281              : namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
    4282              : {
    4283              : constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
    4284              : } // namespace
    4285              : } // namespace nlohmann
    4286              : 
    4287              : // #include <nlohmann/detail/conversions/to_json.hpp>
    4288              : 
    4289              : 
    4290              : #include <algorithm> // copy
    4291              : #include <iterator> // begin, end
    4292              : #include <string> // string
    4293              : #include <tuple> // tuple, get
    4294              : #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
    4295              : #include <utility> // move, forward, declval, pair
    4296              : #include <valarray> // valarray
    4297              : #include <vector> // vector
    4298              : 
    4299              : // #include <nlohmann/detail/macro_scope.hpp>
    4300              : 
    4301              : // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
    4302              : 
    4303              : 
    4304              : #include <cstddef> // size_t
    4305              : #include <iterator> // input_iterator_tag
    4306              : #include <string> // string, to_string
    4307              : #include <tuple> // tuple_size, get, tuple_element
    4308              : #include <utility> // move
    4309              : 
    4310              : // #include <nlohmann/detail/meta/type_traits.hpp>
    4311              : 
    4312              : // #include <nlohmann/detail/value_t.hpp>
    4313              : 
    4314              : 
    4315              : namespace nlohmann
    4316              : {
    4317              : namespace detail
    4318              : {
    4319              : template<typename string_type>
    4320            0 : void int_to_string( string_type& target, std::size_t value )
    4321              : {
    4322              :     // For ADL
    4323              :     using std::to_string;
    4324            0 :     target = to_string(value);
    4325            0 : }
    4326            4 : template<typename IteratorType> class iteration_proxy_value
    4327              : {
    4328              :   public:
    4329              :     using difference_type = std::ptrdiff_t;
    4330              :     using value_type = iteration_proxy_value;
    4331              :     using pointer = value_type * ;
    4332              :     using reference = value_type & ;
    4333              :     using iterator_category = std::input_iterator_tag;
    4334              :     using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
    4335              : 
    4336              :   private:
    4337              :     /// the iterator
    4338              :     IteratorType anchor;
    4339              :     /// an index for arrays (used to create key names)
    4340              :     std::size_t array_index = 0;
    4341              :     /// last stringified array index
    4342              :     mutable std::size_t array_index_last = 0;
    4343              :     /// a string representation of the array index
    4344              :     mutable string_type array_index_str = "0";
    4345              :     /// an empty string (to return a reference for primitive values)
    4346              :     const string_type empty_str{};
    4347              : 
    4348              :   public:
    4349              :     explicit iteration_proxy_value(IteratorType it) noexcept
    4350            8 :         : anchor(std::move(it))
    4351              :     {}
    4352              : 
    4353              :     /// dereference operator (needed for range-based for)
    4354              :     iteration_proxy_value& operator*()
    4355              :     {
    4356              :         return *this;
    4357              :     }
    4358              : 
    4359              :     /// increment operator (needed for range-based for)
    4360              :     iteration_proxy_value& operator++()
    4361              :     {
    4362            6 :         ++anchor;
    4363            6 :         ++array_index;
    4364              : 
    4365            6 :         return *this;
    4366              :     }
    4367              : 
    4368              :     /// equality operator (needed for InputIterator)
    4369              :     bool operator==(const iteration_proxy_value& o) const
    4370              :     {
    4371              :         return anchor == o.anchor;
    4372              :     }
    4373              : 
    4374              :     /// inequality operator (needed for range-based for)
    4375              :     bool operator!=(const iteration_proxy_value& o) const
    4376              :     {
    4377              :         return anchor != o.anchor;
    4378              :     }
    4379              : 
    4380              :     /// return key of the iterator
    4381            6 :     const string_type& key() const
    4382              :     {
    4383              :         JSON_ASSERT(anchor.m_object != nullptr);
    4384              : 
    4385            6 :         switch (anchor.m_object->type())
    4386              :         {
    4387              :             // use integer array index as key
    4388            0 :             case value_t::array:
    4389              :             {
    4390            0 :                 if (array_index != array_index_last)
    4391              :                 {
    4392            0 :                     int_to_string( array_index_str, array_index );
    4393            0 :                     array_index_last = array_index;
    4394              :                 }
    4395            0 :                 return array_index_str;
    4396              :             }
    4397              : 
    4398              :             // use key from the object
    4399            6 :             case value_t::object:
    4400            6 :                 return anchor.key();
    4401              : 
    4402              :             // use an empty key for all primitive types
    4403            0 :             case value_t::null:
    4404              :             case value_t::string:
    4405              :             case value_t::boolean:
    4406              :             case value_t::number_integer:
    4407              :             case value_t::number_unsigned:
    4408              :             case value_t::number_float:
    4409              :             case value_t::binary:
    4410              :             case value_t::discarded:
    4411              :             default:
    4412            0 :                 return empty_str;
    4413              :         }
    4414              :     }
    4415              : 
    4416              :     /// return value of the iterator
    4417              :     typename IteratorType::reference value() const
    4418              :     {
    4419              :         return anchor.value();
    4420              :     }
    4421              : };
    4422              : 
    4423              : /// proxy class for the items() function
    4424              : template<typename IteratorType> class iteration_proxy
    4425              : {
    4426              :   private:
    4427              :     /// the container to iterate
    4428              :     typename IteratorType::reference container;
    4429              : 
    4430              :   public:
    4431              :     /// construct iteration proxy from a container
    4432              :     explicit iteration_proxy(typename IteratorType::reference cont) noexcept
    4433              :         : container(cont) {}
    4434              : 
    4435              :     /// return iterator begin (needed for range-based for)
    4436            2 :     iteration_proxy_value<IteratorType> begin() noexcept
    4437              :     {
    4438            2 :         return iteration_proxy_value<IteratorType>(container.begin());
    4439              :     }
    4440              : 
    4441              :     /// return iterator end (needed for range-based for)
    4442            2 :     iteration_proxy_value<IteratorType> end() noexcept
    4443              :     {
    4444            2 :         return iteration_proxy_value<IteratorType>(container.end());
    4445              :     }
    4446              : };
    4447              : // Structured Bindings Support
    4448              : // For further reference see https://blog.tartanllama.xyz/structured-bindings/
    4449              : // And see https://github.com/nlohmann/json/pull/1391
    4450              : template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
    4451              : auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
    4452              : {
    4453              :     return i.key();
    4454              : }
    4455              : // Structured Bindings Support
    4456              : // For further reference see https://blog.tartanllama.xyz/structured-bindings/
    4457              : // And see https://github.com/nlohmann/json/pull/1391
    4458              : template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
    4459              : auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
    4460              : {
    4461              :     return i.value();
    4462              : }
    4463              : }  // namespace detail
    4464              : }  // namespace nlohmann
    4465              : 
    4466              : // The Addition to the STD Namespace is required to add
    4467              : // Structured Bindings Support to the iteration_proxy_value class
    4468              : // For further reference see https://blog.tartanllama.xyz/structured-bindings/
    4469              : // And see https://github.com/nlohmann/json/pull/1391
    4470              : namespace std
    4471              : {
    4472              : #if defined(__clang__)
    4473              :     // Fix: https://github.com/nlohmann/json/issues/1401
    4474              :     #pragma clang diagnostic push
    4475              :     #pragma clang diagnostic ignored "-Wmismatched-tags"
    4476              : #endif
    4477              : template<typename IteratorType>
    4478              : class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
    4479              :             : public std::integral_constant<std::size_t, 2> {};
    4480              : 
    4481              : template<std::size_t N, typename IteratorType>
    4482              : class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
    4483              : {
    4484              :   public:
    4485              :     using type = decltype(
    4486              :                      get<N>(std::declval <
    4487              :                             ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
    4488              : };
    4489              : #if defined(__clang__)
    4490              :     #pragma clang diagnostic pop
    4491              : #endif
    4492              : } // namespace std
    4493              : 
    4494              : // #include <nlohmann/detail/meta/cpp_future.hpp>
    4495              : 
    4496              : // #include <nlohmann/detail/meta/type_traits.hpp>
    4497              : 
    4498              : // #include <nlohmann/detail/value_t.hpp>
    4499              : 
    4500              : 
    4501              : #if JSON_HAS_EXPERIMENTAL_FILESYSTEM
    4502              : #include <experimental/filesystem>
    4503              : namespace nlohmann::detail
    4504              : {
    4505              : namespace std_fs = std::experimental::filesystem;
    4506              : } // namespace nlohmann::detail
    4507              : #elif JSON_HAS_FILESYSTEM
    4508              : #include <filesystem>
    4509              : namespace nlohmann::detail
    4510              : {
    4511              : namespace std_fs = std::filesystem;
    4512              : } // namespace nlohmann::detail
    4513              : #endif
    4514              : 
    4515              : namespace nlohmann
    4516              : {
    4517              : namespace detail
    4518              : {
    4519              : //////////////////
    4520              : // constructors //
    4521              : //////////////////
    4522              : 
    4523              : /*
    4524              :  * Note all external_constructor<>::construct functions need to call
    4525              :  * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
    4526              :  * allocated value (e.g., a string). See bug issue
    4527              :  * https://github.com/nlohmann/json/issues/2865 for more information.
    4528              :  */
    4529              : 
    4530              : template<value_t> struct external_constructor;
    4531              : 
    4532              : template<>
    4533              : struct external_constructor<value_t::boolean>
    4534              : {
    4535              :     template<typename BasicJsonType>
    4536              :     static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
    4537              :     {
    4538            0 :         j.m_value.destroy(j.m_type);
    4539            0 :         j.m_type = value_t::boolean;
    4540            0 :         j.m_value = b;
    4541              :         j.assert_invariant();
    4542              :     }
    4543              : };
    4544              : 
    4545              : template<>
    4546              : struct external_constructor<value_t::string>
    4547              : {
    4548              :     template<typename BasicJsonType>
    4549          147 :     static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
    4550              :     {
    4551          147 :         j.m_value.destroy(j.m_type);
    4552          147 :         j.m_type = value_t::string;
    4553          147 :         j.m_value = s;
    4554              :         j.assert_invariant();
    4555          147 :     }
    4556              : 
    4557              :     template<typename BasicJsonType>
    4558              :     static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
    4559              :     {
    4560              :         j.m_value.destroy(j.m_type);
    4561              :         j.m_type = value_t::string;
    4562              :         j.m_value = std::move(s);
    4563              :         j.assert_invariant();
    4564              :     }
    4565              : 
    4566              :     template < typename BasicJsonType, typename CompatibleStringType,
    4567              :                enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
    4568              :                              int > = 0 >
    4569              :     static void construct(BasicJsonType& j, const CompatibleStringType& str)
    4570              :     {
    4571              :         j.m_value.destroy(j.m_type);
    4572              :         j.m_type = value_t::string;
    4573              :         j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
    4574              :         j.assert_invariant();
    4575              :     }
    4576              : };
    4577              : 
    4578              : template<>
    4579              : struct external_constructor<value_t::binary>
    4580              : {
    4581              :     template<typename BasicJsonType>
    4582              :     static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
    4583              :     {
    4584              :         j.m_value.destroy(j.m_type);
    4585              :         j.m_type = value_t::binary;
    4586              :         j.m_value = typename BasicJsonType::binary_t(b);
    4587              :         j.assert_invariant();
    4588              :     }
    4589              : 
    4590              :     template<typename BasicJsonType>
    4591              :     static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
    4592              :     {
    4593              :         j.m_value.destroy(j.m_type);
    4594              :         j.m_type = value_t::binary;
    4595              :         j.m_value = typename BasicJsonType::binary_t(std::move(b));
    4596              :         j.assert_invariant();
    4597              :     }
    4598              : };
    4599              : 
    4600              : template<>
    4601              : struct external_constructor<value_t::number_float>
    4602              : {
    4603              :     template<typename BasicJsonType>
    4604              :     static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
    4605              :     {
    4606         4249 :         j.m_value.destroy(j.m_type);
    4607         3607 :         j.m_type = value_t::number_float;
    4608         4249 :         j.m_value = val;
    4609              :         j.assert_invariant();
    4610              :     }
    4611              : };
    4612              : 
    4613              : template<>
    4614              : struct external_constructor<value_t::number_unsigned>
    4615              : {
    4616              :     template<typename BasicJsonType>
    4617              :     static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
    4618              :     {
    4619          200 :         j.m_value.destroy(j.m_type);
    4620          200 :         j.m_type = value_t::number_unsigned;
    4621          200 :         j.m_value = val;
    4622              :         j.assert_invariant();
    4623              :     }
    4624              : };
    4625              : 
    4626              : template<>
    4627              : struct external_constructor<value_t::number_integer>
    4628              : {
    4629              :     template<typename BasicJsonType>
    4630              :     static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
    4631              :     {
    4632            8 :         j.m_value.destroy(j.m_type);
    4633            8 :         j.m_type = value_t::number_integer;
    4634            8 :         j.m_value = val;
    4635              :         j.assert_invariant();
    4636              :     }
    4637              : };
    4638              : 
    4639              : template<>
    4640              : struct external_constructor<value_t::array>
    4641              : {
    4642              :     template<typename BasicJsonType>
    4643              :     static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
    4644              :     {
    4645              :         j.m_value.destroy(j.m_type);
    4646              :         j.m_type = value_t::array;
    4647              :         j.m_value = arr;
    4648              :         j.set_parents();
    4649              :         j.assert_invariant();
    4650              :     }
    4651              : 
    4652              :     template<typename BasicJsonType>
    4653              :     static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
    4654              :     {
    4655              :         j.m_value.destroy(j.m_type);
    4656              :         j.m_type = value_t::array;
    4657              :         j.m_value = std::move(arr);
    4658              :         j.set_parents();
    4659              :         j.assert_invariant();
    4660              :     }
    4661              : 
    4662              :     template < typename BasicJsonType, typename CompatibleArrayType,
    4663              :                enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
    4664              :                              int > = 0 >
    4665              :     static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
    4666              :     {
    4667              :         using std::begin;
    4668              :         using std::end;
    4669              : 
    4670              :         j.m_value.destroy(j.m_type);
    4671              :         j.m_type = value_t::array;
    4672              :         j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
    4673              :         j.set_parents();
    4674              :         j.assert_invariant();
    4675              :     }
    4676              : 
    4677              :     template<typename BasicJsonType>
    4678              :     static void construct(BasicJsonType& j, const std::vector<bool>& arr)
    4679              :     {
    4680              :         j.m_value.destroy(j.m_type);
    4681              :         j.m_type = value_t::array;
    4682              :         j.m_value = value_t::array;
    4683              :         j.m_value.array->reserve(arr.size());
    4684              :         for (const bool x : arr)
    4685              :         {
    4686              :             j.m_value.array->push_back(x);
    4687              :             j.set_parent(j.m_value.array->back());
    4688              :         }
    4689              :         j.assert_invariant();
    4690              :     }
    4691              : 
    4692              :     template<typename BasicJsonType, typename T,
    4693              :              enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
    4694              :     static void construct(BasicJsonType& j, const std::valarray<T>& arr)
    4695              :     {
    4696              :         j.m_value.destroy(j.m_type);
    4697              :         j.m_type = value_t::array;
    4698              :         j.m_value = value_t::array;
    4699              :         j.m_value.array->resize(arr.size());
    4700              :         if (arr.size() > 0)
    4701              :         {
    4702              :             std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
    4703              :         }
    4704              :         j.set_parents();
    4705              :         j.assert_invariant();
    4706              :     }
    4707              : };
    4708              : 
    4709              : template<>
    4710              : struct external_constructor<value_t::object>
    4711              : {
    4712              :     template<typename BasicJsonType>
    4713              :     static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
    4714              :     {
    4715              :         j.m_value.destroy(j.m_type);
    4716              :         j.m_type = value_t::object;
    4717              :         j.m_value = obj;
    4718              :         j.set_parents();
    4719              :         j.assert_invariant();
    4720              :     }
    4721              : 
    4722              :     template<typename BasicJsonType>
    4723              :     static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
    4724              :     {
    4725              :         j.m_value.destroy(j.m_type);
    4726              :         j.m_type = value_t::object;
    4727              :         j.m_value = std::move(obj);
    4728              :         j.set_parents();
    4729              :         j.assert_invariant();
    4730              :     }
    4731              : 
    4732              :     template < typename BasicJsonType, typename CompatibleObjectType,
    4733              :                enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
    4734              :     static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
    4735              :     {
    4736              :         using std::begin;
    4737              :         using std::end;
    4738              : 
    4739              :         j.m_value.destroy(j.m_type);
    4740              :         j.m_type = value_t::object;
    4741              :         j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
    4742              :         j.set_parents();
    4743              :         j.assert_invariant();
    4744              :     }
    4745              : };
    4746              : 
    4747              : /////////////
    4748              : // to_json //
    4749              : /////////////
    4750              : 
    4751              : template<typename BasicJsonType, typename T,
    4752              :          enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
    4753              : void to_json(BasicJsonType& j, T b) noexcept
    4754              : {
    4755              :     external_constructor<value_t::boolean>::construct(j, b);
    4756              : }
    4757              : 
    4758              : template<typename BasicJsonType, typename CompatibleString,
    4759              :          enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
    4760              : void to_json(BasicJsonType& j, const CompatibleString& s)
    4761              : {
    4762          147 :     external_constructor<value_t::string>::construct(j, s);
    4763              : }
    4764              : 
    4765              : template<typename BasicJsonType>
    4766              : void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
    4767              : {
    4768              :     external_constructor<value_t::string>::construct(j, std::move(s));
    4769              : }
    4770              : 
    4771              : template<typename BasicJsonType, typename FloatType,
    4772              :          enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
    4773              : void to_json(BasicJsonType& j, FloatType val) noexcept
    4774              : {
    4775              :     external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
    4776              : }
    4777              : 
    4778              : template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
    4779              :          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
    4780              : void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
    4781              : {
    4782              :     external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
    4783              : }
    4784              : 
    4785              : template<typename BasicJsonType, typename CompatibleNumberIntegerType,
    4786              :          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
    4787              : void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
    4788              : {
    4789              :     external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
    4790              : }
    4791              : 
    4792              : template<typename BasicJsonType, typename EnumType,
    4793              :          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
    4794              : void to_json(BasicJsonType& j, EnumType e) noexcept
    4795              : {
    4796              :     using underlying_type = typename std::underlying_type<EnumType>::type;
    4797              :     external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
    4798              : }
    4799              : 
    4800              : template<typename BasicJsonType>
    4801              : void to_json(BasicJsonType& j, const std::vector<bool>& e)
    4802              : {
    4803              :     external_constructor<value_t::array>::construct(j, e);
    4804              : }
    4805              : 
    4806              : template < typename BasicJsonType, typename CompatibleArrayType,
    4807              :            enable_if_t < is_compatible_array_type<BasicJsonType,
    4808              :                          CompatibleArrayType>::value&&
    4809              :                          !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
    4810              :                          !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
    4811              :                          !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
    4812              :                          !is_basic_json<CompatibleArrayType>::value,
    4813              :                          int > = 0 >
    4814              : void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
    4815              : {
    4816              :     external_constructor<value_t::array>::construct(j, arr);
    4817              : }
    4818              : 
    4819              : template<typename BasicJsonType>
    4820              : void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
    4821              : {
    4822              :     external_constructor<value_t::binary>::construct(j, bin);
    4823              : }
    4824              : 
    4825              : template<typename BasicJsonType, typename T,
    4826              :          enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
    4827              : void to_json(BasicJsonType& j, const std::valarray<T>& arr)
    4828              : {
    4829              :     external_constructor<value_t::array>::construct(j, std::move(arr));
    4830              : }
    4831              : 
    4832              : template<typename BasicJsonType>
    4833              : void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
    4834              : {
    4835              :     external_constructor<value_t::array>::construct(j, std::move(arr));
    4836              : }
    4837              : 
    4838              : template < typename BasicJsonType, typename CompatibleObjectType,
    4839              :            enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
    4840              : void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
    4841              : {
    4842              :     external_constructor<value_t::object>::construct(j, obj);
    4843              : }
    4844              : 
    4845              : template<typename BasicJsonType>
    4846              : void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
    4847              : {
    4848              :     external_constructor<value_t::object>::construct(j, std::move(obj));
    4849              : }
    4850              : 
    4851              : template <
    4852              :     typename BasicJsonType, typename T, std::size_t N,
    4853              :     enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
    4854              :                   const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
    4855              :                   int > = 0 >
    4856              : void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
    4857              : {
    4858              :     external_constructor<value_t::array>::construct(j, arr);
    4859              : }
    4860              : 
    4861              : template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
    4862              : void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
    4863              : {
    4864              :     j = { p.first, p.second };
    4865              : }
    4866              : 
    4867              : // for https://github.com/nlohmann/json/pull/1134
    4868              : template<typename BasicJsonType, typename T,
    4869              :          enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
    4870              : void to_json(BasicJsonType& j, const T& b)
    4871              : {
    4872              :     j = { {b.key(), b.value()} };
    4873              : }
    4874              : 
    4875              : template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
    4876              : void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
    4877              : {
    4878              :     j = { std::get<Idx>(t)... };
    4879              : }
    4880              : 
    4881              : template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
    4882              : void to_json(BasicJsonType& j, const T& t)
    4883              : {
    4884              :     to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
    4885              : }
    4886              : 
    4887              : #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
    4888              : template<typename BasicJsonType>
    4889              : void to_json(BasicJsonType& j, const std_fs::path& p)
    4890              : {
    4891              :     j = p.string();
    4892              : }
    4893              : #endif
    4894              : 
    4895              : struct to_json_fn
    4896              : {
    4897              :     template<typename BasicJsonType, typename T>
    4898              :     auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
    4899              :     -> decltype(to_json(j, std::forward<T>(val)), void())
    4900              :     {
    4901         4456 :         return to_json(j, std::forward<T>(val));
    4902              :     }
    4903              : };
    4904              : }  // namespace detail
    4905              : 
    4906              : /// namespace to hold default `to_json` function
    4907              : /// to see why this is required:
    4908              : /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
    4909              : namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
    4910              : {
    4911              : constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
    4912              : } // namespace
    4913              : } // namespace nlohmann
    4914              : 
    4915              : // #include <nlohmann/detail/meta/identity_tag.hpp>
    4916              : 
    4917              : // #include <nlohmann/detail/meta/type_traits.hpp>
    4918              : 
    4919              : 
    4920              : namespace nlohmann
    4921              : {
    4922              : 
    4923              : /// @sa https://json.nlohmann.me/api/adl_serializer/
    4924              : template<typename ValueType, typename>
    4925              : struct adl_serializer
    4926              : {
    4927              :     /// @brief convert a JSON value to any value type
    4928              :     /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
    4929              :     template<typename BasicJsonType, typename TargetType = ValueType>
    4930              :     static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
    4931              :         noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
    4932              :     -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
    4933              :     {
    4934              :         ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
    4935          282 :     }
    4936              : 
    4937              :     /// @brief convert a JSON value to any value type
    4938              :     /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
    4939              :     template<typename BasicJsonType, typename TargetType = ValueType>
    4940              :     static auto from_json(BasicJsonType && j) noexcept(
    4941              :     noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
    4942              :     -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
    4943              :     {
    4944              :         return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
    4945              :     }
    4946              : 
    4947              :     /// @brief convert any value type to a JSON value
    4948              :     /// @sa https://json.nlohmann.me/api/adl_serializer/to_json/
    4949              :     template<typename BasicJsonType, typename TargetType = ValueType>
    4950              :     static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
    4951              :         noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
    4952              :     -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
    4953              :     {
    4954              :         ::nlohmann::to_json(j, std::forward<TargetType>(val));
    4955              :     }
    4956              : };
    4957              : }  // namespace nlohmann
    4958              : 
    4959              : // #include <nlohmann/byte_container_with_subtype.hpp>
    4960              : 
    4961              : 
    4962              : #include <cstdint> // uint8_t, uint64_t
    4963              : #include <tuple> // tie
    4964              : #include <utility> // move
    4965              : 
    4966              : namespace nlohmann
    4967              : {
    4968              : 
    4969              : /// @brief an internal type for a backed binary type
    4970              : /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/
    4971              : template<typename BinaryType>
    4972            0 : class byte_container_with_subtype : public BinaryType
    4973              : {
    4974              :   public:
    4975              :     using container_type = BinaryType;
    4976              :     using subtype_type = std::uint64_t;
    4977              : 
    4978              :     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
    4979            0 :     byte_container_with_subtype() noexcept(noexcept(container_type()))
    4980            0 :         : container_type()
    4981              :     {}
    4982              : 
    4983              :     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
    4984              :     byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
    4985              :         : container_type(b)
    4986              :     {}
    4987              : 
    4988              :     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
    4989              :     byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
    4990              :         : container_type(std::move(b))
    4991              :     {}
    4992              : 
    4993              :     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
    4994              :     byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
    4995              :         : container_type(b)
    4996              :         , m_subtype(subtype_)
    4997              :         , m_has_subtype(true)
    4998              :     {}
    4999              : 
    5000              :     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
    5001              :     byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
    5002              :         : container_type(std::move(b))
    5003              :         , m_subtype(subtype_)
    5004              :         , m_has_subtype(true)
    5005              :     {}
    5006              : 
    5007              :     bool operator==(const byte_container_with_subtype& rhs) const
    5008              :     {
    5009              :         return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
    5010              :                std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
    5011              :     }
    5012              : 
    5013              :     bool operator!=(const byte_container_with_subtype& rhs) const
    5014              :     {
    5015              :         return !(rhs == *this);
    5016              :     }
    5017              : 
    5018              :     /// @brief sets the binary subtype
    5019              :     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/
    5020              :     void set_subtype(subtype_type subtype_) noexcept
    5021              :     {
    5022              :         m_subtype = subtype_;
    5023              :         m_has_subtype = true;
    5024              :     }
    5025              : 
    5026              :     /// @brief return the binary subtype
    5027              :     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/subtype/
    5028              :     constexpr subtype_type subtype() const noexcept
    5029              :     {
    5030              :         return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
    5031              :     }
    5032              : 
    5033              :     /// @brief return whether the value has a subtype
    5034              :     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/
    5035              :     constexpr bool has_subtype() const noexcept
    5036              :     {
    5037              :         return m_has_subtype;
    5038              :     }
    5039              : 
    5040              :     /// @brief clears the binary subtype
    5041              :     /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/
    5042              :     void clear_subtype() noexcept
    5043              :     {
    5044              :         m_subtype = 0;
    5045              :         m_has_subtype = false;
    5046              :     }
    5047              : 
    5048              :   private:
    5049              :     subtype_type m_subtype = 0;
    5050              :     bool m_has_subtype = false;
    5051              : };
    5052              : 
    5053              : }  // namespace nlohmann
    5054              : 
    5055              : // #include <nlohmann/detail/conversions/from_json.hpp>
    5056              : 
    5057              : // #include <nlohmann/detail/conversions/to_json.hpp>
    5058              : 
    5059              : // #include <nlohmann/detail/exceptions.hpp>
    5060              : 
    5061              : // #include <nlohmann/detail/hash.hpp>
    5062              : 
    5063              : 
    5064              : #include <cstdint> // uint8_t
    5065              : #include <cstddef> // size_t
    5066              : #include <functional> // hash
    5067              : 
    5068              : // #include <nlohmann/detail/macro_scope.hpp>
    5069              : 
    5070              : // #include <nlohmann/detail/value_t.hpp>
    5071              : 
    5072              : 
    5073              : namespace nlohmann
    5074              : {
    5075              : namespace detail
    5076              : {
    5077              : 
    5078              : // boost::hash_combine
    5079              : inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
    5080              : {
    5081              :     seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
    5082              :     return seed;
    5083              : }
    5084              : 
    5085              : /*!
    5086              : @brief hash a JSON value
    5087              : 
    5088              : The hash function tries to rely on std::hash where possible. Furthermore, the
    5089              : type of the JSON value is taken into account to have different hash values for
    5090              : null, 0, 0U, and false, etc.
    5091              : 
    5092              : @tparam BasicJsonType basic_json specialization
    5093              : @param j JSON value to hash
    5094              : @return hash value of j
    5095              : */
    5096              : template<typename BasicJsonType>
    5097              : std::size_t hash(const BasicJsonType& j)
    5098              : {
    5099              :     using string_t = typename BasicJsonType::string_t;
    5100              :     using number_integer_t = typename BasicJsonType::number_integer_t;
    5101              :     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
    5102              :     using number_float_t = typename BasicJsonType::number_float_t;
    5103              : 
    5104              :     const auto type = static_cast<std::size_t>(j.type());
    5105              :     switch (j.type())
    5106              :     {
    5107              :         case BasicJsonType::value_t::null:
    5108              :         case BasicJsonType::value_t::discarded:
    5109              :         {
    5110              :             return combine(type, 0);
    5111              :         }
    5112              : 
    5113              :         case BasicJsonType::value_t::object:
    5114              :         {
    5115              :             auto seed = combine(type, j.size());
    5116              :             for (const auto& element : j.items())
    5117              :             {
    5118              :                 const auto h = std::hash<string_t> {}(element.key());
    5119              :                 seed = combine(seed, h);
    5120              :                 seed = combine(seed, hash(element.value()));
    5121              :             }
    5122              :             return seed;
    5123              :         }
    5124              : 
    5125              :         case BasicJsonType::value_t::array:
    5126              :         {
    5127              :             auto seed = combine(type, j.size());
    5128              :             for (const auto& element : j)
    5129              :             {
    5130              :                 seed = combine(seed, hash(element));
    5131              :             }
    5132              :             return seed;
    5133              :         }
    5134              : 
    5135              :         case BasicJsonType::value_t::string:
    5136              :         {
    5137              :             const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
    5138              :             return combine(type, h);
    5139              :         }
    5140              : 
    5141              :         case BasicJsonType::value_t::boolean:
    5142              :         {
    5143              :             const auto h = std::hash<bool> {}(j.template get<bool>());
    5144              :             return combine(type, h);
    5145              :         }
    5146              : 
    5147              :         case BasicJsonType::value_t::number_integer:
    5148              :         {
    5149              :             const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
    5150              :             return combine(type, h);
    5151              :         }
    5152              : 
    5153              :         case BasicJsonType::value_t::number_unsigned:
    5154              :         {
    5155              :             const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
    5156              :             return combine(type, h);
    5157              :         }
    5158              : 
    5159              :         case BasicJsonType::value_t::number_float:
    5160              :         {
    5161              :             const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
    5162              :             return combine(type, h);
    5163              :         }
    5164              : 
    5165              :         case BasicJsonType::value_t::binary:
    5166              :         {
    5167              :             auto seed = combine(type, j.get_binary().size());
    5168              :             const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
    5169              :             seed = combine(seed, h);
    5170              :             seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
    5171              :             for (const auto byte : j.get_binary())
    5172              :             {
    5173              :                 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
    5174              :             }
    5175              :             return seed;
    5176              :         }
    5177              : 
    5178              :         default:                   // LCOV_EXCL_LINE
    5179              :             JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
    5180              :             return 0;              // LCOV_EXCL_LINE
    5181              :     }
    5182              : }
    5183              : 
    5184              : }  // namespace detail
    5185              : }  // namespace nlohmann
    5186              : 
    5187              : // #include <nlohmann/detail/input/binary_reader.hpp>
    5188              : 
    5189              : 
    5190              : #include <algorithm> // generate_n
    5191              : #include <array> // array
    5192              : #include <cmath> // ldexp
    5193              : #include <cstddef> // size_t
    5194              : #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
    5195              : #include <cstdio> // snprintf
    5196              : #include <cstring> // memcpy
    5197              : #include <iterator> // back_inserter
    5198              : #include <limits> // numeric_limits
    5199              : #include <string> // char_traits, string
    5200              : #include <utility> // make_pair, move
    5201              : #include <vector> // vector
    5202              : 
    5203              : // #include <nlohmann/detail/exceptions.hpp>
    5204              : 
    5205              : // #include <nlohmann/detail/input/input_adapters.hpp>
    5206              : 
    5207              : 
    5208              : #include <array> // array
    5209              : #include <cstddef> // size_t
    5210              : #include <cstring> // strlen
    5211              : #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
    5212              : #include <memory> // shared_ptr, make_shared, addressof
    5213              : #include <numeric> // accumulate
    5214              : #include <string> // string, char_traits
    5215              : #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
    5216              : #include <utility> // pair, declval
    5217              : 
    5218              : #ifndef JSON_NO_IO
    5219              :     #include <cstdio>   // FILE *
    5220              :     #include <istream>  // istream
    5221              : #endif                  // JSON_NO_IO
    5222              : 
    5223              : // #include <nlohmann/detail/iterators/iterator_traits.hpp>
    5224              : 
    5225              : // #include <nlohmann/detail/macro_scope.hpp>
    5226              : 
    5227              : 
    5228              : namespace nlohmann
    5229              : {
    5230              : namespace detail
    5231              : {
    5232              : /// the supported input formats
    5233              : enum class input_format_t { json, cbor, msgpack, ubjson, bson };
    5234              : 
    5235              : ////////////////////
    5236              : // input adapters //
    5237              : ////////////////////
    5238              : 
    5239              : #ifndef JSON_NO_IO
    5240              : /*!
    5241              : Input adapter for stdio file access. This adapter read only 1 byte and do not use any
    5242              :  buffer. This adapter is a very low level adapter.
    5243              : */
    5244              : class file_input_adapter
    5245              : {
    5246              :   public:
    5247              :     using char_type = char;
    5248              : 
    5249              :     JSON_HEDLEY_NON_NULL(2)
    5250              :     explicit file_input_adapter(std::FILE* f) noexcept
    5251              :         : m_file(f)
    5252              :     {}
    5253              : 
    5254              :     // make class move-only
    5255              :     file_input_adapter(const file_input_adapter&) = delete;
    5256              :     file_input_adapter(file_input_adapter&&) noexcept = default;
    5257              :     file_input_adapter& operator=(const file_input_adapter&) = delete;
    5258              :     file_input_adapter& operator=(file_input_adapter&&) = delete;
    5259              :     ~file_input_adapter() = default;
    5260              : 
    5261              :     std::char_traits<char>::int_type get_character() noexcept
    5262              :     {
    5263              :         return std::fgetc(m_file);
    5264              :     }
    5265              : 
    5266              :   private:
    5267              :     /// the file pointer to read from
    5268              :     std::FILE* m_file;
    5269              : };
    5270              : 
    5271              : 
    5272              : /*!
    5273              : Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
    5274              : beginning of input. Does not support changing the underlying std::streambuf
    5275              : in mid-input. Maintains underlying std::istream and std::streambuf to support
    5276              : subsequent use of standard std::istream operations to process any input
    5277              : characters following those used in parsing the JSON input.  Clears the
    5278              : std::istream flags; any input errors (e.g., EOF) will be detected by the first
    5279              : subsequent call for input from the std::istream.
    5280              : */
    5281              : class input_stream_adapter
    5282              : {
    5283              :   public:
    5284              :     using char_type = char;
    5285              : 
    5286           66 :     ~input_stream_adapter()
    5287              :     {
    5288              :         // clear stream flags; we use underlying streambuf I/O, do not
    5289              :         // maintain ifstream flags, except eof
    5290           66 :         if (is != nullptr)
    5291              :         {
    5292           33 :             is->clear(is->rdstate() & std::ios::eofbit);
    5293              :         }
    5294           66 :     }
    5295              : 
    5296              :     explicit input_stream_adapter(std::istream& i)
    5297           33 :         : is(&i), sb(i.rdbuf())
    5298              :     {}
    5299              : 
    5300              :     // delete because of pointer members
    5301              :     input_stream_adapter(const input_stream_adapter&) = delete;
    5302              :     input_stream_adapter& operator=(input_stream_adapter&) = delete;
    5303              :     input_stream_adapter& operator=(input_stream_adapter&&) = delete;
    5304              : 
    5305              :     input_stream_adapter(input_stream_adapter&& rhs) noexcept
    5306           33 :         : is(rhs.is), sb(rhs.sb)
    5307              :     {
    5308           33 :         rhs.is = nullptr;
    5309           33 :         rhs.sb = nullptr;
    5310              :     }
    5311              : 
    5312              :     // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
    5313              :     // ensure that std::char_traits<char>::eof() and the character 0xFF do not
    5314              :     // end up as the same value, e.g. 0xFFFFFFFF.
    5315       101635 :     std::char_traits<char>::int_type get_character()
    5316              :     {
    5317       101635 :         auto res = sb->sbumpc();
    5318              :         // set eof manually, as we don't use the istream interface.
    5319       101635 :         if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
    5320              :         {
    5321            0 :             is->clear(is->rdstate() | std::ios::eofbit);
    5322              :         }
    5323       101635 :         return res;
    5324              :     }
    5325              : 
    5326              :   private:
    5327              :     /// the associated input stream
    5328              :     std::istream* is = nullptr;
    5329              :     std::streambuf* sb = nullptr;
    5330              : };
    5331              : #endif  // JSON_NO_IO
    5332              : 
    5333              : // General-purpose iterator-based adapter. It might not be as fast as
    5334              : // theoretically possible for some containers, but it is extremely versatile.
    5335              : template<typename IteratorType>
    5336              : class iterator_input_adapter
    5337              : {
    5338              :   public:
    5339              :     using char_type = typename std::iterator_traits<IteratorType>::value_type;
    5340              : 
    5341              :     iterator_input_adapter(IteratorType first, IteratorType last)
    5342              :         : current(std::move(first)), end(std::move(last))
    5343              :     {}
    5344              : 
    5345              :     typename std::char_traits<char_type>::int_type get_character()
    5346              :     {
    5347              :         if (JSON_HEDLEY_LIKELY(current != end))
    5348              :         {
    5349              :             auto result = std::char_traits<char_type>::to_int_type(*current);
    5350              :             std::advance(current, 1);
    5351              :             return result;
    5352              :         }
    5353              : 
    5354              :         return std::char_traits<char_type>::eof();
    5355              :     }
    5356              : 
    5357              :   private:
    5358              :     IteratorType current;
    5359              :     IteratorType end;
    5360              : 
    5361              :     template<typename BaseInputAdapter, size_t T>
    5362              :     friend struct wide_string_input_helper;
    5363              : 
    5364              :     bool empty() const
    5365              :     {
    5366              :         return current == end;
    5367              :     }
    5368              : };
    5369              : 
    5370              : 
    5371              : template<typename BaseInputAdapter, size_t T>
    5372              : struct wide_string_input_helper;
    5373              : 
    5374              : template<typename BaseInputAdapter>
    5375              : struct wide_string_input_helper<BaseInputAdapter, 4>
    5376              : {
    5377              :     // UTF-32
    5378              :     static void fill_buffer(BaseInputAdapter& input,
    5379              :                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
    5380              :                             size_t& utf8_bytes_index,
    5381              :                             size_t& utf8_bytes_filled)
    5382              :     {
    5383              :         utf8_bytes_index = 0;
    5384              : 
    5385              :         if (JSON_HEDLEY_UNLIKELY(input.empty()))
    5386              :         {
    5387              :             utf8_bytes[0] = std::char_traits<char>::eof();
    5388              :             utf8_bytes_filled = 1;
    5389              :         }
    5390              :         else
    5391              :         {
    5392              :             // get the current character
    5393              :             const auto wc = input.get_character();
    5394              : 
    5395              :             // UTF-32 to UTF-8 encoding
    5396              :             if (wc < 0x80)
    5397              :             {
    5398              :                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
    5399              :                 utf8_bytes_filled = 1;
    5400              :             }
    5401              :             else if (wc <= 0x7FF)
    5402              :             {
    5403              :                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
    5404              :                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
    5405              :                 utf8_bytes_filled = 2;
    5406              :             }
    5407              :             else if (wc <= 0xFFFF)
    5408              :             {
    5409              :                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
    5410              :                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
    5411              :                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
    5412              :                 utf8_bytes_filled = 3;
    5413              :             }
    5414              :             else if (wc <= 0x10FFFF)
    5415              :             {
    5416              :                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
    5417              :                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
    5418              :                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
    5419              :                 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
    5420              :                 utf8_bytes_filled = 4;
    5421              :             }
    5422              :             else
    5423              :             {
    5424              :                 // unknown character
    5425              :                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
    5426              :                 utf8_bytes_filled = 1;
    5427              :             }
    5428              :         }
    5429              :     }
    5430              : };
    5431              : 
    5432              : template<typename BaseInputAdapter>
    5433              : struct wide_string_input_helper<BaseInputAdapter, 2>
    5434              : {
    5435              :     // UTF-16
    5436              :     static void fill_buffer(BaseInputAdapter& input,
    5437              :                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
    5438              :                             size_t& utf8_bytes_index,
    5439              :                             size_t& utf8_bytes_filled)
    5440              :     {
    5441              :         utf8_bytes_index = 0;
    5442              : 
    5443              :         if (JSON_HEDLEY_UNLIKELY(input.empty()))
    5444              :         {
    5445              :             utf8_bytes[0] = std::char_traits<char>::eof();
    5446              :             utf8_bytes_filled = 1;
    5447              :         }
    5448              :         else
    5449              :         {
    5450              :             // get the current character
    5451              :             const auto wc = input.get_character();
    5452              : 
    5453              :             // UTF-16 to UTF-8 encoding
    5454              :             if (wc < 0x80)
    5455              :             {
    5456              :                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
    5457              :                 utf8_bytes_filled = 1;
    5458              :             }
    5459              :             else if (wc <= 0x7FF)
    5460              :             {
    5461              :                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
    5462              :                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
    5463              :                 utf8_bytes_filled = 2;
    5464              :             }
    5465              :             else if (0xD800 > wc || wc >= 0xE000)
    5466              :             {
    5467              :                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
    5468              :                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
    5469              :                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
    5470              :                 utf8_bytes_filled = 3;
    5471              :             }
    5472              :             else
    5473              :             {
    5474              :                 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
    5475              :                 {
    5476              :                     const auto wc2 = static_cast<unsigned int>(input.get_character());
    5477              :                     const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
    5478              :                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
    5479              :                     utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
    5480              :                     utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
    5481              :                     utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
    5482              :                     utf8_bytes_filled = 4;
    5483              :                 }
    5484              :                 else
    5485              :                 {
    5486              :                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
    5487              :                     utf8_bytes_filled = 1;
    5488              :                 }
    5489              :             }
    5490              :         }
    5491              :     }
    5492              : };
    5493              : 
    5494              : // Wraps another input apdater to convert wide character types into individual bytes.
    5495              : template<typename BaseInputAdapter, typename WideCharType>
    5496              : class wide_string_input_adapter
    5497              : {
    5498              :   public:
    5499              :     using char_type = char;
    5500              : 
    5501              :     wide_string_input_adapter(BaseInputAdapter base)
    5502              :         : base_adapter(base) {}
    5503              : 
    5504              :     typename std::char_traits<char>::int_type get_character() noexcept
    5505              :     {
    5506              :         // check if buffer needs to be filled
    5507              :         if (utf8_bytes_index == utf8_bytes_filled)
    5508              :         {
    5509              :             fill_buffer<sizeof(WideCharType)>();
    5510              : 
    5511              :             JSON_ASSERT(utf8_bytes_filled > 0);
    5512              :             JSON_ASSERT(utf8_bytes_index == 0);
    5513              :         }
    5514              : 
    5515              :         // use buffer
    5516              :         JSON_ASSERT(utf8_bytes_filled > 0);
    5517              :         JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
    5518              :         return utf8_bytes[utf8_bytes_index++];
    5519              :     }
    5520              : 
    5521              :   private:
    5522              :     BaseInputAdapter base_adapter;
    5523              : 
    5524              :     template<size_t T>
    5525              :     void fill_buffer()
    5526              :     {
    5527              :         wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
    5528              :     }
    5529              : 
    5530              :     /// a buffer for UTF-8 bytes
    5531              :     std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
    5532              : 
    5533              :     /// index to the utf8_codes array for the next valid byte
    5534              :     std::size_t utf8_bytes_index = 0;
    5535              :     /// number of valid bytes in the utf8_codes array
    5536              :     std::size_t utf8_bytes_filled = 0;
    5537              : };
    5538              : 
    5539              : 
    5540              : template<typename IteratorType, typename Enable = void>
    5541              : struct iterator_input_adapter_factory
    5542              : {
    5543              :     using iterator_type = IteratorType;
    5544              :     using char_type = typename std::iterator_traits<iterator_type>::value_type;
    5545              :     using adapter_type = iterator_input_adapter<iterator_type>;
    5546              : 
    5547              :     static adapter_type create(IteratorType first, IteratorType last)
    5548              :     {
    5549              :         return adapter_type(std::move(first), std::move(last));
    5550              :     }
    5551              : };
    5552              : 
    5553              : template<typename T>
    5554              : struct is_iterator_of_multibyte
    5555              : {
    5556              :     using value_type = typename std::iterator_traits<T>::value_type;
    5557              :     enum
    5558              :     {
    5559              :         value = sizeof(value_type) > 1
    5560              :     };
    5561              : };
    5562              : 
    5563              : template<typename IteratorType>
    5564              : struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
    5565              : {
    5566              :     using iterator_type = IteratorType;
    5567              :     using char_type = typename std::iterator_traits<iterator_type>::value_type;
    5568              :     using base_adapter_type = iterator_input_adapter<iterator_type>;
    5569              :     using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
    5570              : 
    5571              :     static adapter_type create(IteratorType first, IteratorType last)
    5572              :     {
    5573              :         return adapter_type(base_adapter_type(std::move(first), std::move(last)));
    5574              :     }
    5575              : };
    5576              : 
    5577              : // General purpose iterator-based input
    5578              : template<typename IteratorType>
    5579              : typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
    5580              : {
    5581              :     using factory_type = iterator_input_adapter_factory<IteratorType>;
    5582              :     return factory_type::create(first, last);
    5583              : }
    5584              : 
    5585              : // Convenience shorthand from container to iterator
    5586              : // Enables ADL on begin(container) and end(container)
    5587              : // Encloses the using declarations in namespace for not to leak them to outside scope
    5588              : 
    5589              : namespace container_input_adapter_factory_impl
    5590              : {
    5591              : 
    5592              : using std::begin;
    5593              : using std::end;
    5594              : 
    5595              : template<typename ContainerType, typename Enable = void>
    5596              : struct container_input_adapter_factory {};
    5597              : 
    5598              : template<typename ContainerType>
    5599              : struct container_input_adapter_factory< ContainerType,
    5600              :        void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
    5601              :        {
    5602              :            using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
    5603              : 
    5604              :            static adapter_type create(const ContainerType& container)
    5605              : {
    5606              :     return input_adapter(begin(container), end(container));
    5607              : }
    5608              :        };
    5609              : 
    5610              : } // namespace container_input_adapter_factory_impl
    5611              : 
    5612              : template<typename ContainerType>
    5613              : typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
    5614              : {
    5615              :     return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
    5616              : }
    5617              : 
    5618              : #ifndef JSON_NO_IO
    5619              : // Special cases with fast paths
    5620              : inline file_input_adapter input_adapter(std::FILE* file)
    5621              : {
    5622              :     return file_input_adapter(file);
    5623              : }
    5624              : 
    5625              : inline input_stream_adapter input_adapter(std::istream& stream)
    5626              : {
    5627              :     return input_stream_adapter(stream);
    5628              : }
    5629              : 
    5630              : inline input_stream_adapter input_adapter(std::istream&& stream)
    5631              : {
    5632              :     return input_stream_adapter(stream);
    5633              : }
    5634              : #endif  // JSON_NO_IO
    5635              : 
    5636              : using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
    5637              : 
    5638              : // Null-delimited strings, and the like.
    5639              : template < typename CharT,
    5640              :            typename std::enable_if <
    5641              :                std::is_pointer<CharT>::value&&
    5642              :                !std::is_array<CharT>::value&&
    5643              :                std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
    5644              :                sizeof(typename std::remove_pointer<CharT>::type) == 1,
    5645              :                int >::type = 0 >
    5646              : contiguous_bytes_input_adapter input_adapter(CharT b)
    5647              : {
    5648              :     auto length = std::strlen(reinterpret_cast<const char*>(b));
    5649              :     const auto* ptr = reinterpret_cast<const char*>(b);
    5650              :     return input_adapter(ptr, ptr + length);
    5651              : }
    5652              : 
    5653              : template<typename T, std::size_t N>
    5654              : auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
    5655              : {
    5656              :     return input_adapter(array, array + N);
    5657              : }
    5658              : 
    5659              : // This class only handles inputs of input_buffer_adapter type.
    5660              : // It's required so that expressions like {ptr, len} can be implicitly cast
    5661              : // to the correct adapter.
    5662              : class span_input_adapter
    5663              : {
    5664              :   public:
    5665              :     template < typename CharT,
    5666              :                typename std::enable_if <
    5667              :                    std::is_pointer<CharT>::value&&
    5668              :                    std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
    5669              :                    sizeof(typename std::remove_pointer<CharT>::type) == 1,
    5670              :                    int >::type = 0 >
    5671              :     span_input_adapter(CharT b, std::size_t l)
    5672              :         : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
    5673              : 
    5674              :     template<class IteratorType,
    5675              :              typename std::enable_if<
    5676              :                  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
    5677              :                  int>::type = 0>
    5678              :     span_input_adapter(IteratorType first, IteratorType last)
    5679              :         : ia(input_adapter(first, last)) {}
    5680              : 
    5681              :     contiguous_bytes_input_adapter&& get()
    5682              :     {
    5683              :         return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
    5684              :     }
    5685              : 
    5686              :   private:
    5687              :     contiguous_bytes_input_adapter ia;
    5688              : };
    5689              : }  // namespace detail
    5690              : }  // namespace nlohmann
    5691              : 
    5692              : // #include <nlohmann/detail/input/json_sax.hpp>
    5693              : 
    5694              : 
    5695              : #include <cstddef>
    5696              : #include <string> // string
    5697              : #include <utility> // move
    5698              : #include <vector> // vector
    5699              : 
    5700              : // #include <nlohmann/detail/exceptions.hpp>
    5701              : 
    5702              : // #include <nlohmann/detail/macro_scope.hpp>
    5703              : 
    5704              : 
    5705              : namespace nlohmann
    5706              : {
    5707              : 
    5708              : /*!
    5709              : @brief SAX interface
    5710              : 
    5711              : This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
    5712              : Each function is called in different situations while the input is parsed. The
    5713              : boolean return value informs the parser whether to continue processing the
    5714              : input.
    5715              : */
    5716              : template<typename BasicJsonType>
    5717              : struct json_sax
    5718              : {
    5719              :     using number_integer_t = typename BasicJsonType::number_integer_t;
    5720              :     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
    5721              :     using number_float_t = typename BasicJsonType::number_float_t;
    5722              :     using string_t = typename BasicJsonType::string_t;
    5723              :     using binary_t = typename BasicJsonType::binary_t;
    5724              : 
    5725              :     /*!
    5726              :     @brief a null value was read
    5727              :     @return whether parsing should proceed
    5728              :     */
    5729              :     virtual bool null() = 0;
    5730              : 
    5731              :     /*!
    5732              :     @brief a boolean value was read
    5733              :     @param[in] val  boolean value
    5734              :     @return whether parsing should proceed
    5735              :     */
    5736              :     virtual bool boolean(bool val) = 0;
    5737              : 
    5738              :     /*!
    5739              :     @brief an integer number was read
    5740              :     @param[in] val  integer value
    5741              :     @return whether parsing should proceed
    5742              :     */
    5743              :     virtual bool number_integer(number_integer_t val) = 0;
    5744              : 
    5745              :     /*!
    5746              :     @brief an unsigned integer number was read
    5747              :     @param[in] val  unsigned integer value
    5748              :     @return whether parsing should proceed
    5749              :     */
    5750              :     virtual bool number_unsigned(number_unsigned_t val) = 0;
    5751              : 
    5752              :     /*!
    5753              :     @brief a floating-point number was read
    5754              :     @param[in] val  floating-point value
    5755              :     @param[in] s    raw token value
    5756              :     @return whether parsing should proceed
    5757              :     */
    5758              :     virtual bool number_float(number_float_t val, const string_t& s) = 0;
    5759              : 
    5760              :     /*!
    5761              :     @brief a string value was read
    5762              :     @param[in] val  string value
    5763              :     @return whether parsing should proceed
    5764              :     @note It is safe to move the passed string value.
    5765              :     */
    5766              :     virtual bool string(string_t& val) = 0;
    5767              : 
    5768              :     /*!
    5769              :     @brief a binary value was read
    5770              :     @param[in] val  binary value
    5771              :     @return whether parsing should proceed
    5772              :     @note It is safe to move the passed binary value.
    5773              :     */
    5774              :     virtual bool binary(binary_t& val) = 0;
    5775              : 
    5776              :     /*!
    5777              :     @brief the beginning of an object was read
    5778              :     @param[in] elements  number of object elements or -1 if unknown
    5779              :     @return whether parsing should proceed
    5780              :     @note binary formats may report the number of elements
    5781              :     */
    5782              :     virtual bool start_object(std::size_t elements) = 0;
    5783              : 
    5784              :     /*!
    5785              :     @brief an object key was read
    5786              :     @param[in] val  object key
    5787              :     @return whether parsing should proceed
    5788              :     @note It is safe to move the passed string.
    5789              :     */
    5790              :     virtual bool key(string_t& val) = 0;
    5791              : 
    5792              :     /*!
    5793              :     @brief the end of an object was read
    5794              :     @return whether parsing should proceed
    5795              :     */
    5796              :     virtual bool end_object() = 0;
    5797              : 
    5798              :     /*!
    5799              :     @brief the beginning of an array was read
    5800              :     @param[in] elements  number of array elements or -1 if unknown
    5801              :     @return whether parsing should proceed
    5802              :     @note binary formats may report the number of elements
    5803              :     */
    5804              :     virtual bool start_array(std::size_t elements) = 0;
    5805              : 
    5806              :     /*!
    5807              :     @brief the end of an array was read
    5808              :     @return whether parsing should proceed
    5809              :     */
    5810              :     virtual bool end_array() = 0;
    5811              : 
    5812              :     /*!
    5813              :     @brief a parse error occurred
    5814              :     @param[in] position    the position in the input where the error occurs
    5815              :     @param[in] last_token  the last read token
    5816              :     @param[in] ex          an exception object describing the error
    5817              :     @return whether parsing should proceed (must return false)
    5818              :     */
    5819              :     virtual bool parse_error(std::size_t position,
    5820              :                              const std::string& last_token,
    5821              :                              const detail::exception& ex) = 0;
    5822              : 
    5823              :     json_sax() = default;
    5824              :     json_sax(const json_sax&) = default;
    5825              :     json_sax(json_sax&&) noexcept = default;
    5826              :     json_sax& operator=(const json_sax&) = default;
    5827              :     json_sax& operator=(json_sax&&) noexcept = default;
    5828              :     virtual ~json_sax() = default;
    5829              : };
    5830              : 
    5831              : 
    5832              : namespace detail
    5833              : {
    5834              : /*!
    5835              : @brief SAX implementation to create a JSON value from SAX events
    5836              : 
    5837              : This class implements the @ref json_sax interface and processes the SAX events
    5838              : to create a JSON value which makes it basically a DOM parser. The structure or
    5839              : hierarchy of the JSON value is managed by the stack `ref_stack` which contains
    5840              : a pointer to the respective array or object for each recursion depth.
    5841              : 
    5842              : After successful parsing, the value that is passed by reference to the
    5843              : constructor contains the parsed value.
    5844              : 
    5845              : @tparam BasicJsonType  the JSON type
    5846              : */
    5847              : template<typename BasicJsonType>
    5848              : class json_sax_dom_parser
    5849              : {
    5850              :   public:
    5851              :     using number_integer_t = typename BasicJsonType::number_integer_t;
    5852              :     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
    5853              :     using number_float_t = typename BasicJsonType::number_float_t;
    5854              :     using string_t = typename BasicJsonType::string_t;
    5855              :     using binary_t = typename BasicJsonType::binary_t;
    5856              : 
    5857              :     /*!
    5858              :     @param[in,out] r  reference to a JSON value that is manipulated while
    5859              :                        parsing
    5860              :     @param[in] allow_exceptions_  whether parse errors yield exceptions
    5861              :     */
    5862           33 :     explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
    5863           33 :         : root(r), allow_exceptions(allow_exceptions_)
    5864              :     {}
    5865              : 
    5866              :     // make class move-only
    5867              :     json_sax_dom_parser(const json_sax_dom_parser&) = delete;
    5868              :     json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
    5869              :     json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
    5870              :     json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
    5871           33 :     ~json_sax_dom_parser() = default;
    5872              : 
    5873              :     bool null()
    5874              :     {
    5875            0 :         handle_value(nullptr);
    5876              :         return true;
    5877              :     }
    5878              : 
    5879              :     bool boolean(bool val)
    5880              :     {
    5881            0 :         handle_value(val);
    5882              :         return true;
    5883              :     }
    5884              : 
    5885              :     bool number_integer(number_integer_t val)
    5886              :     {
    5887            8 :         handle_value(val);
    5888              :         return true;
    5889              :     }
    5890              : 
    5891              :     bool number_unsigned(number_unsigned_t val)
    5892              :     {
    5893          200 :         handle_value(val);
    5894              :         return true;
    5895              :     }
    5896              : 
    5897              :     bool number_float(number_float_t val, const string_t& /*unused*/)
    5898              :     {
    5899         4248 :         handle_value(val);
    5900              :         return true;
    5901              :     }
    5902              : 
    5903              :     bool string(string_t& val)
    5904              :     {
    5905          147 :         handle_value(val);
    5906              :         return true;
    5907              :     }
    5908              : 
    5909              :     bool binary(binary_t& val)
    5910              :     {
    5911              :         handle_value(std::move(val));
    5912              :         return true;
    5913              :     }
    5914              : 
    5915          585 :     bool start_object(std::size_t len)
    5916              :     {
    5917          585 :         ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
    5918              : 
    5919          585 :         if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
    5920              :         {
    5921            0 :             JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
    5922              :         }
    5923              : 
    5924          585 :         return true;
    5925              :     }
    5926              : 
    5927              :     bool key(string_t& val)
    5928              :     {
    5929              :         // add null at given key and store the reference for later
    5930         1956 :         object_element = &(ref_stack.back()->m_value.object->operator[](val));
    5931              :         return true;
    5932              :     }
    5933              : 
    5934              :     bool end_object()
    5935              :     {
    5936              :         ref_stack.back()->set_parents();
    5937              :         ref_stack.pop_back();
    5938              :         return true;
    5939              :     }
    5940              : 
    5941          615 :     bool start_array(std::size_t len)
    5942              :     {
    5943          615 :         ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
    5944              : 
    5945          615 :         if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
    5946              :         {
    5947            0 :             JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
    5948              :         }
    5949              : 
    5950          615 :         return true;
    5951              :     }
    5952              : 
    5953              :     bool end_array()
    5954              :     {
    5955              :         ref_stack.back()->set_parents();
    5956              :         ref_stack.pop_back();
    5957              :         return true;
    5958              :     }
    5959              : 
    5960              :     template<class Exception>
    5961            0 :     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
    5962              :                      const Exception& ex)
    5963              :     {
    5964            0 :         errored = true;
    5965              :         static_cast<void>(ex);
    5966            0 :         if (allow_exceptions)
    5967              :         {
    5968            0 :             JSON_THROW(ex);
    5969              :         }
    5970            0 :         return false;
    5971              :     }
    5972              : 
    5973              :     constexpr bool is_errored() const
    5974              :     {
    5975           33 :         return errored;
    5976              :     }
    5977              : 
    5978              :   private:
    5979              :     /*!
    5980              :     @invariant If the ref stack is empty, then the passed value will be the new
    5981              :                root.
    5982              :     @invariant If the ref stack contains a value, then it is an array or an
    5983              :                object to which we can add elements
    5984              :     */
    5985              :     template<typename Value>
    5986              :     JSON_HEDLEY_RETURNS_NON_NULL
    5987         5803 :     BasicJsonType* handle_value(Value&& v)
    5988              :     {
    5989         5803 :         if (ref_stack.empty())
    5990              :         {
    5991           33 :             root = BasicJsonType(std::forward<Value>(v));
    5992           33 :             return &root;
    5993              :         }
    5994              : 
    5995              :         JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
    5996              : 
    5997         5770 :         if (ref_stack.back()->is_array())
    5998              :         {
    5999         3814 :             ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
    6000         3814 :             return &(ref_stack.back()->m_value.array->back());
    6001              :         }
    6002              : 
    6003              :         JSON_ASSERT(ref_stack.back()->is_object());
    6004              :         JSON_ASSERT(object_element);
    6005         1956 :         *object_element = BasicJsonType(std::forward<Value>(v));
    6006         1956 :         return object_element;
    6007              :     }
    6008              : 
    6009              :     /// the parsed JSON value
    6010              :     BasicJsonType& root;
    6011              :     /// stack to model hierarchy of values
    6012              :     std::vector<BasicJsonType*> ref_stack {};
    6013              :     /// helper to hold the reference for the next object element
    6014              :     BasicJsonType* object_element = nullptr;
    6015              :     /// whether a syntax error occurred
    6016              :     bool errored = false;
    6017              :     /// whether to throw exceptions in case of errors
    6018              :     const bool allow_exceptions = true;
    6019              : };
    6020              : 
    6021              : template<typename BasicJsonType>
    6022              : class json_sax_dom_callback_parser
    6023              : {
    6024              :   public:
    6025              :     using number_integer_t = typename BasicJsonType::number_integer_t;
    6026              :     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
    6027              :     using number_float_t = typename BasicJsonType::number_float_t;
    6028              :     using string_t = typename BasicJsonType::string_t;
    6029              :     using binary_t = typename BasicJsonType::binary_t;
    6030              :     using parser_callback_t = typename BasicJsonType::parser_callback_t;
    6031              :     using parse_event_t = typename BasicJsonType::parse_event_t;
    6032              : 
    6033            0 :     json_sax_dom_callback_parser(BasicJsonType& r,
    6034              :                                  const parser_callback_t cb,
    6035              :                                  const bool allow_exceptions_ = true)
    6036            0 :         : root(r), callback(cb), allow_exceptions(allow_exceptions_)
    6037              :     {
    6038            0 :         keep_stack.push_back(true);
    6039            0 :     }
    6040              : 
    6041              :     // make class move-only
    6042              :     json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
    6043              :     json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
    6044              :     json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
    6045              :     json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
    6046            0 :     ~json_sax_dom_callback_parser() = default;
    6047              : 
    6048              :     bool null()
    6049              :     {
    6050            0 :         handle_value(nullptr);
    6051              :         return true;
    6052              :     }
    6053              : 
    6054              :     bool boolean(bool val)
    6055              :     {
    6056            0 :         handle_value(val);
    6057              :         return true;
    6058              :     }
    6059              : 
    6060              :     bool number_integer(number_integer_t val)
    6061              :     {
    6062            0 :         handle_value(val);
    6063              :         return true;
    6064              :     }
    6065              : 
    6066              :     bool number_unsigned(number_unsigned_t val)
    6067              :     {
    6068            0 :         handle_value(val);
    6069              :         return true;
    6070              :     }
    6071              : 
    6072              :     bool number_float(number_float_t val, const string_t& /*unused*/)
    6073              :     {
    6074            0 :         handle_value(val);
    6075              :         return true;
    6076              :     }
    6077              : 
    6078              :     bool string(string_t& val)
    6079              :     {
    6080            0 :         handle_value(val);
    6081              :         return true;
    6082              :     }
    6083              : 
    6084              :     bool binary(binary_t& val)
    6085              :     {
    6086              :         handle_value(std::move(val));
    6087              :         return true;
    6088              :     }
    6089              : 
    6090            0 :     bool start_object(std::size_t len)
    6091              :     {
    6092              :         // check callback for object start
    6093            0 :         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
    6094            0 :         keep_stack.push_back(keep);
    6095              : 
    6096            0 :         auto val = handle_value(BasicJsonType::value_t::object, true);
    6097            0 :         ref_stack.push_back(val.second);
    6098              : 
    6099              :         // check object limit
    6100            0 :         if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
    6101              :         {
    6102            0 :             JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
    6103              :         }
    6104              : 
    6105            0 :         return true;
    6106              :     }
    6107              : 
    6108            0 :     bool key(string_t& val)
    6109              :     {
    6110              :         BasicJsonType k = BasicJsonType(val);
    6111              : 
    6112              :         // check callback for key
    6113            0 :         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
    6114            0 :         key_keep_stack.push_back(keep);
    6115              : 
    6116              :         // add discarded value at given key and store the reference for later
    6117            0 :         if (keep && ref_stack.back())
    6118              :         {
    6119            0 :             object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
    6120              :         }
    6121              : 
    6122            0 :         return true;
    6123              :     }
    6124              : 
    6125            0 :     bool end_object()
    6126              :     {
    6127            0 :         if (ref_stack.back())
    6128              :         {
    6129            0 :             if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
    6130              :             {
    6131              :                 // discard object
    6132            0 :                 *ref_stack.back() = discarded;
    6133              :             }
    6134              :             else
    6135              :             {
    6136              :                 ref_stack.back()->set_parents();
    6137              :             }
    6138              :         }
    6139              : 
    6140              :         JSON_ASSERT(!ref_stack.empty());
    6141              :         JSON_ASSERT(!keep_stack.empty());
    6142              :         ref_stack.pop_back();
    6143              :         keep_stack.pop_back();
    6144              : 
    6145            0 :         if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
    6146              :         {
    6147              :             // remove discarded value
    6148            0 :             for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
    6149              :             {
    6150            0 :                 if (it->is_discarded())
    6151              :                 {
    6152            0 :                     ref_stack.back()->erase(it);
    6153            0 :                     break;
    6154              :                 }
    6155              :             }
    6156              :         }
    6157              : 
    6158            0 :         return true;
    6159              :     }
    6160              : 
    6161            0 :     bool start_array(std::size_t len)
    6162              :     {
    6163            0 :         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
    6164            0 :         keep_stack.push_back(keep);
    6165              : 
    6166            0 :         auto val = handle_value(BasicJsonType::value_t::array, true);
    6167            0 :         ref_stack.push_back(val.second);
    6168              : 
    6169              :         // check array limit
    6170            0 :         if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
    6171              :         {
    6172            0 :             JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
    6173              :         }
    6174              : 
    6175            0 :         return true;
    6176              :     }
    6177              : 
    6178            0 :     bool end_array()
    6179              :     {
    6180              :         bool keep = true;
    6181              : 
    6182            0 :         if (ref_stack.back())
    6183              :         {
    6184            0 :             keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
    6185            0 :             if (keep)
    6186              :             {
    6187              :                 ref_stack.back()->set_parents();
    6188              :             }
    6189              :             else
    6190              :             {
    6191              :                 // discard array
    6192            0 :                 *ref_stack.back() = discarded;
    6193              :             }
    6194              :         }
    6195              : 
    6196              :         JSON_ASSERT(!ref_stack.empty());
    6197              :         JSON_ASSERT(!keep_stack.empty());
    6198              :         ref_stack.pop_back();
    6199              :         keep_stack.pop_back();
    6200              : 
    6201              :         // remove discarded value
    6202            0 :         if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
    6203              :         {
    6204            0 :             ref_stack.back()->m_value.array->pop_back();
    6205              :         }
    6206              : 
    6207            0 :         return true;
    6208              :     }
    6209              : 
    6210              :     template<class Exception>
    6211            0 :     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
    6212              :                      const Exception& ex)
    6213              :     {
    6214            0 :         errored = true;
    6215              :         static_cast<void>(ex);
    6216            0 :         if (allow_exceptions)
    6217              :         {
    6218            0 :             JSON_THROW(ex);
    6219              :         }
    6220            0 :         return false;
    6221              :     }
    6222              : 
    6223              :     constexpr bool is_errored() const
    6224              :     {
    6225            0 :         return errored;
    6226              :     }
    6227              : 
    6228              :   private:
    6229              :     /*!
    6230              :     @param[in] v  value to add to the JSON value we build during parsing
    6231              :     @param[in] skip_callback  whether we should skip calling the callback
    6232              :                function; this is required after start_array() and
    6233              :                start_object() SAX events, because otherwise we would call the
    6234              :                callback function with an empty array or object, respectively.
    6235              : 
    6236              :     @invariant If the ref stack is empty, then the passed value will be the new
    6237              :                root.
    6238              :     @invariant If the ref stack contains a value, then it is an array or an
    6239              :                object to which we can add elements
    6240              : 
    6241              :     @return pair of boolean (whether value should be kept) and pointer (to the
    6242              :             passed value in the ref_stack hierarchy; nullptr if not kept)
    6243              :     */
    6244              :     template<typename Value>
    6245            0 :     std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
    6246              :     {
    6247              :         JSON_ASSERT(!keep_stack.empty());
    6248              : 
    6249              :         // do not handle this value if we know it would be added to a discarded
    6250              :         // container
    6251            0 :         if (!keep_stack.back())
    6252              :         {
    6253            0 :             return {false, nullptr};
    6254              :         }
    6255              : 
    6256              :         // create value
    6257            0 :         auto value = BasicJsonType(std::forward<Value>(v));
    6258              : 
    6259              :         // check callback
    6260            0 :         const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
    6261              : 
    6262              :         // do not handle this value if we just learnt it shall be discarded
    6263              :         if (!keep)
    6264              :         {
    6265            0 :             return {false, nullptr};
    6266              :         }
    6267              : 
    6268            0 :         if (ref_stack.empty())
    6269              :         {
    6270            0 :             root = std::move(value);
    6271            0 :             return {true, &root};
    6272              :         }
    6273              : 
    6274              :         // skip this value if we already decided to skip the parent
    6275              :         // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
    6276            0 :         if (!ref_stack.back())
    6277              :         {
    6278            0 :             return {false, nullptr};
    6279              :         }
    6280              : 
    6281              :         // we now only expect arrays and objects
    6282              :         JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
    6283              : 
    6284              :         // array
    6285            0 :         if (ref_stack.back()->is_array())
    6286              :         {
    6287            0 :             ref_stack.back()->m_value.array->emplace_back(std::move(value));
    6288            0 :             return {true, &(ref_stack.back()->m_value.array->back())};
    6289              :         }
    6290              : 
    6291              :         // object
    6292              :         JSON_ASSERT(ref_stack.back()->is_object());
    6293              :         // check if we should store an element for the current key
    6294              :         JSON_ASSERT(!key_keep_stack.empty());
    6295              :         const bool store_element = key_keep_stack.back();
    6296              :         key_keep_stack.pop_back();
    6297              : 
    6298            0 :         if (!store_element)
    6299              :         {
    6300            0 :             return {false, nullptr};
    6301              :         }
    6302              : 
    6303              :         JSON_ASSERT(object_element);
    6304            0 :         *object_element = std::move(value);
    6305            0 :         return {true, object_element};
    6306              :     }
    6307              : 
    6308              :     /// the parsed JSON value
    6309              :     BasicJsonType& root;
    6310              :     /// stack to model hierarchy of values
    6311              :     std::vector<BasicJsonType*> ref_stack {};
    6312              :     /// stack to manage which values to keep
    6313              :     std::vector<bool> keep_stack {};
    6314              :     /// stack to manage which object keys to keep
    6315              :     std::vector<bool> key_keep_stack {};
    6316              :     /// helper to hold the reference for the next object element
    6317              :     BasicJsonType* object_element = nullptr;
    6318              :     /// whether a syntax error occurred
    6319              :     bool errored = false;
    6320              :     /// callback function
    6321              :     const parser_callback_t callback = nullptr;
    6322              :     /// whether to throw exceptions in case of errors
    6323              :     const bool allow_exceptions = true;
    6324              :     /// a discarded value for the callback
    6325              :     BasicJsonType discarded = BasicJsonType::value_t::discarded;
    6326              : };
    6327              : 
    6328              : template<typename BasicJsonType>
    6329              : class json_sax_acceptor
    6330              : {
    6331              :   public:
    6332              :     using number_integer_t = typename BasicJsonType::number_integer_t;
    6333              :     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
    6334              :     using number_float_t = typename BasicJsonType::number_float_t;
    6335              :     using string_t = typename BasicJsonType::string_t;
    6336              :     using binary_t = typename BasicJsonType::binary_t;
    6337              : 
    6338              :     bool null()
    6339              :     {
    6340              :         return true;
    6341              :     }
    6342              : 
    6343              :     bool boolean(bool /*unused*/)
    6344              :     {
    6345              :         return true;
    6346              :     }
    6347              : 
    6348              :     bool number_integer(number_integer_t /*unused*/)
    6349              :     {
    6350              :         return true;
    6351              :     }
    6352              : 
    6353              :     bool number_unsigned(number_unsigned_t /*unused*/)
    6354              :     {
    6355              :         return true;
    6356              :     }
    6357              : 
    6358              :     bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
    6359              :     {
    6360              :         return true;
    6361              :     }
    6362              : 
    6363              :     bool string(string_t& /*unused*/)
    6364              :     {
    6365              :         return true;
    6366              :     }
    6367              : 
    6368              :     bool binary(binary_t& /*unused*/)
    6369              :     {
    6370              :         return true;
    6371              :     }
    6372              : 
    6373              :     bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
    6374              :     {
    6375              :         return true;
    6376              :     }
    6377              : 
    6378              :     bool key(string_t& /*unused*/)
    6379              :     {
    6380              :         return true;
    6381              :     }
    6382              : 
    6383              :     bool end_object()
    6384              :     {
    6385              :         return true;
    6386              :     }
    6387              : 
    6388              :     bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
    6389              :     {
    6390              :         return true;
    6391              :     }
    6392              : 
    6393              :     bool end_array()
    6394              :     {
    6395              :         return true;
    6396              :     }
    6397              : 
    6398              :     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
    6399              :     {
    6400              :         return false;
    6401              :     }
    6402              : };
    6403              : }  // namespace detail
    6404              : 
    6405              : }  // namespace nlohmann
    6406              : 
    6407              : // #include <nlohmann/detail/input/lexer.hpp>
    6408              : 
    6409              : 
    6410              : #include <array> // array
    6411              : #include <clocale> // localeconv
    6412              : #include <cstddef> // size_t
    6413              : #include <cstdio> // snprintf
    6414              : #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
    6415              : #include <initializer_list> // initializer_list
    6416              : #include <string> // char_traits, string
    6417              : #include <utility> // move
    6418              : #include <vector> // vector
    6419              : 
    6420              : // #include <nlohmann/detail/input/input_adapters.hpp>
    6421              : 
    6422              : // #include <nlohmann/detail/input/position_t.hpp>
    6423              : 
    6424              : // #include <nlohmann/detail/macro_scope.hpp>
    6425              : 
    6426              : 
    6427              : namespace nlohmann
    6428              : {
    6429              : namespace detail
    6430              : {
    6431              : ///////////
    6432              : // lexer //
    6433              : ///////////
    6434              : 
    6435              : template<typename BasicJsonType>
    6436              : class lexer_base
    6437              : {
    6438              :   public:
    6439              :     /// token types for the parser
    6440              :     enum class token_type
    6441              :     {
    6442              :         uninitialized,    ///< indicating the scanner is uninitialized
    6443              :         literal_true,     ///< the `true` literal
    6444              :         literal_false,    ///< the `false` literal
    6445              :         literal_null,     ///< the `null` literal
    6446              :         value_string,     ///< a string -- use get_string() for actual value
    6447              :         value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
    6448              :         value_integer,    ///< a signed integer -- use get_number_integer() for actual value
    6449              :         value_float,      ///< an floating point number -- use get_number_float() for actual value
    6450              :         begin_array,      ///< the character for array begin `[`
    6451              :         begin_object,     ///< the character for object begin `{`
    6452              :         end_array,        ///< the character for array end `]`
    6453              :         end_object,       ///< the character for object end `}`
    6454              :         name_separator,   ///< the name separator `:`
    6455              :         value_separator,  ///< the value separator `,`
    6456              :         parse_error,      ///< indicating a parse error
    6457              :         end_of_input,     ///< indicating the end of the input buffer
    6458              :         literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
    6459              :     };
    6460              : 
    6461              :     /// return name of values of type token_type (only used for errors)
    6462              :     JSON_HEDLEY_RETURNS_NON_NULL
    6463              :     JSON_HEDLEY_CONST
    6464            0 :     static const char* token_type_name(const token_type t) noexcept
    6465              :     {
    6466            0 :         switch (t)
    6467              :         {
    6468              :             case token_type::uninitialized:
    6469              :                 return "<uninitialized>";
    6470            0 :             case token_type::literal_true:
    6471            0 :                 return "true literal";
    6472            0 :             case token_type::literal_false:
    6473            0 :                 return "false literal";
    6474            0 :             case token_type::literal_null:
    6475            0 :                 return "null literal";
    6476            0 :             case token_type::value_string:
    6477            0 :                 return "string literal";
    6478            0 :             case token_type::value_unsigned:
    6479              :             case token_type::value_integer:
    6480              :             case token_type::value_float:
    6481            0 :                 return "number literal";
    6482            0 :             case token_type::begin_array:
    6483            0 :                 return "'['";
    6484            0 :             case token_type::begin_object:
    6485            0 :                 return "'{'";
    6486            0 :             case token_type::end_array:
    6487            0 :                 return "']'";
    6488            0 :             case token_type::end_object:
    6489            0 :                 return "'}'";
    6490            0 :             case token_type::name_separator:
    6491            0 :                 return "':'";
    6492            0 :             case token_type::value_separator:
    6493            0 :                 return "','";
    6494            0 :             case token_type::parse_error:
    6495            0 :                 return "<parse error>";
    6496            0 :             case token_type::end_of_input:
    6497            0 :                 return "end of input";
    6498            0 :             case token_type::literal_or_value:
    6499            0 :                 return "'[', '{', or a literal";
    6500              :             // LCOV_EXCL_START
    6501              :             default: // catch non-enum values
    6502              :                 return "unknown token";
    6503              :                 // LCOV_EXCL_STOP
    6504              :         }
    6505              :     }
    6506              : };
    6507              : /*!
    6508              : @brief lexical analysis
    6509              : 
    6510              : This class organizes the lexical analysis during JSON deserialization.
    6511              : */
    6512              : template<typename BasicJsonType, typename InputAdapterType>
    6513              : class lexer : public lexer_base<BasicJsonType>
    6514              : {
    6515              :     using number_integer_t = typename BasicJsonType::number_integer_t;
    6516              :     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
    6517              :     using number_float_t = typename BasicJsonType::number_float_t;
    6518              :     using string_t = typename BasicJsonType::string_t;
    6519              :     using char_type = typename InputAdapterType::char_type;
    6520              :     using char_int_type = typename std::char_traits<char_type>::int_type;
    6521              : 
    6522              :   public:
    6523              :     using token_type = typename lexer_base<BasicJsonType>::token_type;
    6524              : 
    6525           33 :     explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
    6526              :         : ia(std::move(adapter))
    6527           33 :         , ignore_comments(ignore_comments_)
    6528           33 :         , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
    6529           33 :     {}
    6530              : 
    6531              :     // delete because of pointer members
    6532              :     lexer(const lexer&) = delete;
    6533              :     lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
    6534              :     lexer& operator=(lexer&) = delete;
    6535              :     lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
    6536           33 :     ~lexer() = default;
    6537              : 
    6538              :   private:
    6539              :     /////////////////////
    6540              :     // locales
    6541              :     /////////////////////
    6542              : 
    6543              :     /// return the locale-dependent decimal point
    6544              :     JSON_HEDLEY_PURE
    6545              :     static char get_decimal_point() noexcept
    6546              :     {
    6547           33 :         const auto* loc = localeconv();
    6548              :         JSON_ASSERT(loc != nullptr);
    6549           33 :         return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
    6550              :     }
    6551              : 
    6552              :     /////////////////////
    6553              :     // scan functions
    6554              :     /////////////////////
    6555              : 
    6556              :     /*!
    6557              :     @brief get codepoint from 4 hex characters following `\u`
    6558              : 
    6559              :     For input "\u c1 c2 c3 c4" the codepoint is:
    6560              :       (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
    6561              :     = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
    6562              : 
    6563              :     Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
    6564              :     must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
    6565              :     conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
    6566              :     between the ASCII value of the character and the desired integer value.
    6567              : 
    6568              :     @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
    6569              :             non-hex character)
    6570              :     */
    6571            0 :     int get_codepoint()
    6572              :     {
    6573              :         // this function only makes sense after reading `\u`
    6574              :         JSON_ASSERT(current == 'u');
    6575              :         int codepoint = 0;
    6576              : 
    6577            0 :         const auto factors = { 12u, 8u, 4u, 0u };
    6578            0 :         for (const auto factor : factors)
    6579              :         {
    6580            0 :             get();
    6581              : 
    6582            0 :             if (current >= '0' && current <= '9')
    6583              :             {
    6584            0 :                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
    6585              :             }
    6586            0 :             else if (current >= 'A' && current <= 'F')
    6587              :             {
    6588            0 :                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
    6589              :             }
    6590            0 :             else if (current >= 'a' && current <= 'f')
    6591              :             {
    6592            0 :                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
    6593              :             }
    6594              :             else
    6595              :             {
    6596              :                 return -1;
    6597              :             }
    6598              :         }
    6599              : 
    6600              :         JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
    6601              :         return codepoint;
    6602              :     }
    6603              : 
    6604              :     /*!
    6605              :     @brief check if the next byte(s) are inside a given range
    6606              : 
    6607              :     Adds the current byte and, for each passed range, reads a new byte and
    6608              :     checks if it is inside the range. If a violation was detected, set up an
    6609              :     error message and return false. Otherwise, return true.
    6610              : 
    6611              :     @param[in] ranges  list of integers; interpreted as list of pairs of
    6612              :                        inclusive lower and upper bound, respectively
    6613              : 
    6614              :     @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
    6615              :          1, 2, or 3 pairs. This precondition is enforced by an assertion.
    6616              : 
    6617              :     @return true if and only if no range violation was detected
    6618              :     */
    6619            0 :     bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
    6620              :     {
    6621              :         JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
    6622            0 :         add(current);
    6623              : 
    6624            0 :         for (auto range = ranges.begin(); range != ranges.end(); ++range)
    6625              :         {
    6626            0 :             get();
    6627            0 :             if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
    6628              :             {
    6629              :                 add(current);
    6630              :             }
    6631              :             else
    6632              :             {
    6633            0 :                 error_message = "invalid string: ill-formed UTF-8 byte";
    6634            0 :                 return false;
    6635              :             }
    6636              :         }
    6637              : 
    6638              :         return true;
    6639              :     }
    6640              : 
    6641              :     /*!
    6642              :     @brief scan a string literal
    6643              : 
    6644              :     This function scans a string according to Sect. 7 of RFC 8259. While
    6645              :     scanning, bytes are escaped and copied into buffer token_buffer. Then the
    6646              :     function returns successfully, token_buffer is *not* null-terminated (as it
    6647              :     may contain \0 bytes), and token_buffer.size() is the number of bytes in the
    6648              :     string.
    6649              : 
    6650              :     @return token_type::value_string if string could be successfully scanned,
    6651              :             token_type::parse_error otherwise
    6652              : 
    6653              :     @note In case of errors, variable error_message contains a textual
    6654              :           description.
    6655              :     */
    6656         2103 :     token_type scan_string()
    6657              :     {
    6658              :         // reset token_buffer (ignore opening quote)
    6659         2103 :         reset();
    6660              : 
    6661              :         // we entered the function by reading an open quote
    6662              :         JSON_ASSERT(current == '\"');
    6663              : 
    6664              :         while (true)
    6665              :         {
    6666              :             // get next character
    6667        16515 :             switch (get())
    6668              :             {
    6669              :                 // end of file while parsing string
    6670            0 :                 case std::char_traits<char_type>::eof():
    6671              :                 {
    6672            0 :                     error_message = "invalid string: missing closing quote";
    6673            0 :                     return token_type::parse_error;
    6674              :                 }
    6675              : 
    6676              :                 // closing quote
    6677              :                 case '\"':
    6678              :                 {
    6679              :                     return token_type::value_string;
    6680              :                 }
    6681              : 
    6682              :                 // escapes
    6683            0 :                 case '\\':
    6684              :                 {
    6685            0 :                     switch (get())
    6686              :                     {
    6687              :                         // quotation mark
    6688              :                         case '\"':
    6689              :                             add('\"');
    6690              :                             break;
    6691              :                         // reverse solidus
    6692              :                         case '\\':
    6693              :                             add('\\');
    6694              :                             break;
    6695              :                         // solidus
    6696              :                         case '/':
    6697              :                             add('/');
    6698              :                             break;
    6699              :                         // backspace
    6700              :                         case 'b':
    6701              :                             add('\b');
    6702              :                             break;
    6703              :                         // form feed
    6704              :                         case 'f':
    6705              :                             add('\f');
    6706              :                             break;
    6707              :                         // line feed
    6708              :                         case 'n':
    6709              :                             add('\n');
    6710              :                             break;
    6711              :                         // carriage return
    6712              :                         case 'r':
    6713              :                             add('\r');
    6714              :                             break;
    6715              :                         // tab
    6716              :                         case 't':
    6717              :                             add('\t');
    6718              :                             break;
    6719              : 
    6720              :                         // unicode escapes
    6721            0 :                         case 'u':
    6722              :                         {
    6723            0 :                             const int codepoint1 = get_codepoint();
    6724              :                             int codepoint = codepoint1; // start with codepoint1
    6725              : 
    6726            0 :                             if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
    6727              :                             {
    6728            0 :                                 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
    6729            0 :                                 return token_type::parse_error;
    6730              :                             }
    6731              : 
    6732              :                             // check if code point is a high surrogate
    6733            0 :                             if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
    6734              :                             {
    6735              :                                 // expect next \uxxxx entry
    6736            0 :                                 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
    6737              :                                 {
    6738            0 :                                     const int codepoint2 = get_codepoint();
    6739              : 
    6740            0 :                                     if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
    6741              :                                     {
    6742            0 :                                         error_message = "invalid string: '\\u' must be followed by 4 hex digits";
    6743            0 :                                         return token_type::parse_error;
    6744              :                                     }
    6745              : 
    6746              :                                     // check if codepoint2 is a low surrogate
    6747            0 :                                     if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
    6748              :                                     {
    6749              :                                         // overwrite codepoint
    6750            0 :                                         codepoint = static_cast<int>(
    6751              :                                                         // high surrogate occupies the most significant 22 bits
    6752            0 :                                                         (static_cast<unsigned int>(codepoint1) << 10u)
    6753              :                                                         // low surrogate occupies the least significant 15 bits
    6754            0 :                                                         + static_cast<unsigned int>(codepoint2)
    6755              :                                                         // there is still the 0xD800, 0xDC00 and 0x10000 noise
    6756              :                                                         // in the result, so we have to subtract with:
    6757              :                                                         // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
    6758            0 :                                                         - 0x35FDC00u);
    6759              :                                     }
    6760              :                                     else
    6761              :                                     {
    6762            0 :                                         error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
    6763            0 :                                         return token_type::parse_error;
    6764              :                                     }
    6765              :                                 }
    6766              :                                 else
    6767              :                                 {
    6768            0 :                                     error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
    6769            0 :                                     return token_type::parse_error;
    6770              :                                 }
    6771              :                             }
    6772              :                             else
    6773              :                             {
    6774            0 :                                 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
    6775              :                                 {
    6776            0 :                                     error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
    6777            0 :                                     return token_type::parse_error;
    6778              :                                 }
    6779              :                             }
    6780              : 
    6781              :                             // result of the above calculation yields a proper codepoint
    6782              :                             JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
    6783              : 
    6784              :                             // translate codepoint into bytes
    6785            0 :                             if (codepoint < 0x80)
    6786              :                             {
    6787              :                                 // 1-byte characters: 0xxxxxxx (ASCII)
    6788              :                                 add(static_cast<char_int_type>(codepoint));
    6789              :                             }
    6790            0 :                             else if (codepoint <= 0x7FF)
    6791              :                             {
    6792              :                                 // 2-byte characters: 110xxxxx 10xxxxxx
    6793            0 :                                 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
    6794              :                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
    6795              :                             }
    6796            0 :                             else if (codepoint <= 0xFFFF)
    6797              :                             {
    6798              :                                 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
    6799            0 :                                 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
    6800            0 :                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
    6801              :                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
    6802              :                             }
    6803              :                             else
    6804              :                             {
    6805              :                                 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    6806            0 :                                 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
    6807            0 :                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
    6808            0 :                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
    6809              :                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
    6810              :                             }
    6811              : 
    6812              :                             break;
    6813              :                         }
    6814              : 
    6815              :                         // other characters after escape
    6816            0 :                         default:
    6817            0 :                             error_message = "invalid string: forbidden character after backslash";
    6818            0 :                             return token_type::parse_error;
    6819              :                     }
    6820              : 
    6821              :                     break;
    6822              :                 }
    6823              : 
    6824              :                 // invalid control characters
    6825            0 :                 case 0x00:
    6826              :                 {
    6827            0 :                     error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
    6828            0 :                     return token_type::parse_error;
    6829              :                 }
    6830              : 
    6831            0 :                 case 0x01:
    6832              :                 {
    6833            0 :                     error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
    6834            0 :                     return token_type::parse_error;
    6835              :                 }
    6836              : 
    6837            0 :                 case 0x02:
    6838              :                 {
    6839            0 :                     error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
    6840            0 :                     return token_type::parse_error;
    6841              :                 }
    6842              : 
    6843            0 :                 case 0x03:
    6844              :                 {
    6845            0 :                     error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
    6846            0 :                     return token_type::parse_error;
    6847              :                 }
    6848              : 
    6849            0 :                 case 0x04:
    6850              :                 {
    6851            0 :                     error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
    6852            0 :                     return token_type::parse_error;
    6853              :                 }
    6854              : 
    6855            0 :                 case 0x05:
    6856              :                 {
    6857            0 :                     error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
    6858            0 :                     return token_type::parse_error;
    6859              :                 }
    6860              : 
    6861            0 :                 case 0x06:
    6862              :                 {
    6863            0 :                     error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
    6864            0 :                     return token_type::parse_error;
    6865              :                 }
    6866              : 
    6867            0 :                 case 0x07:
    6868              :                 {
    6869            0 :                     error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
    6870            0 :                     return token_type::parse_error;
    6871              :                 }
    6872              : 
    6873            0 :                 case 0x08:
    6874              :                 {
    6875            0 :                     error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
    6876            0 :                     return token_type::parse_error;
    6877              :                 }
    6878              : 
    6879            0 :                 case 0x09:
    6880              :                 {
    6881            0 :                     error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
    6882            0 :                     return token_type::parse_error;
    6883              :                 }
    6884              : 
    6885            0 :                 case 0x0A:
    6886              :                 {
    6887            0 :                     error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
    6888            0 :                     return token_type::parse_error;
    6889              :                 }
    6890              : 
    6891            0 :                 case 0x0B:
    6892              :                 {
    6893            0 :                     error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
    6894            0 :                     return token_type::parse_error;
    6895              :                 }
    6896              : 
    6897            0 :                 case 0x0C:
    6898              :                 {
    6899            0 :                     error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
    6900            0 :                     return token_type::parse_error;
    6901              :                 }
    6902              : 
    6903            0 :                 case 0x0D:
    6904              :                 {
    6905            0 :                     error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
    6906            0 :                     return token_type::parse_error;
    6907              :                 }
    6908              : 
    6909            0 :                 case 0x0E:
    6910              :                 {
    6911            0 :                     error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
    6912            0 :                     return token_type::parse_error;
    6913              :                 }
    6914              : 
    6915            0 :                 case 0x0F:
    6916              :                 {
    6917            0 :                     error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
    6918            0 :                     return token_type::parse_error;
    6919              :                 }
    6920              : 
    6921            0 :                 case 0x10:
    6922              :                 {
    6923            0 :                     error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
    6924            0 :                     return token_type::parse_error;
    6925              :                 }
    6926              : 
    6927            0 :                 case 0x11:
    6928              :                 {
    6929            0 :                     error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
    6930            0 :                     return token_type::parse_error;
    6931              :                 }
    6932              : 
    6933            0 :                 case 0x12:
    6934              :                 {
    6935            0 :                     error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
    6936            0 :                     return token_type::parse_error;
    6937              :                 }
    6938              : 
    6939            0 :                 case 0x13:
    6940              :                 {
    6941            0 :                     error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
    6942            0 :                     return token_type::parse_error;
    6943              :                 }
    6944              : 
    6945            0 :                 case 0x14:
    6946              :                 {
    6947            0 :                     error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
    6948            0 :                     return token_type::parse_error;
    6949              :                 }
    6950              : 
    6951            0 :                 case 0x15:
    6952              :                 {
    6953            0 :                     error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
    6954            0 :                     return token_type::parse_error;
    6955              :                 }
    6956              : 
    6957            0 :                 case 0x16:
    6958              :                 {
    6959            0 :                     error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
    6960            0 :                     return token_type::parse_error;
    6961              :                 }
    6962              : 
    6963            0 :                 case 0x17:
    6964              :                 {
    6965            0 :                     error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
    6966            0 :                     return token_type::parse_error;
    6967              :                 }
    6968              : 
    6969            0 :                 case 0x18:
    6970              :                 {
    6971            0 :                     error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
    6972            0 :                     return token_type::parse_error;
    6973              :                 }
    6974              : 
    6975            0 :                 case 0x19:
    6976              :                 {
    6977            0 :                     error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
    6978            0 :                     return token_type::parse_error;
    6979              :                 }
    6980              : 
    6981            0 :                 case 0x1A:
    6982              :                 {
    6983            0 :                     error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
    6984            0 :                     return token_type::parse_error;
    6985              :                 }
    6986              : 
    6987            0 :                 case 0x1B:
    6988              :                 {
    6989            0 :                     error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
    6990            0 :                     return token_type::parse_error;
    6991              :                 }
    6992              : 
    6993            0 :                 case 0x1C:
    6994              :                 {
    6995            0 :                     error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
    6996            0 :                     return token_type::parse_error;
    6997              :                 }
    6998              : 
    6999            0 :                 case 0x1D:
    7000              :                 {
    7001            0 :                     error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
    7002            0 :                     return token_type::parse_error;
    7003              :                 }
    7004              : 
    7005            0 :                 case 0x1E:
    7006              :                 {
    7007            0 :                     error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
    7008            0 :                     return token_type::parse_error;
    7009              :                 }
    7010              : 
    7011            0 :                 case 0x1F:
    7012              :                 {
    7013            0 :                     error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
    7014            0 :                     return token_type::parse_error;
    7015              :                 }
    7016              : 
    7017              :                 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
    7018        14412 :                 case 0x20:
    7019              :                 case 0x21:
    7020              :                 case 0x23:
    7021              :                 case 0x24:
    7022              :                 case 0x25:
    7023              :                 case 0x26:
    7024              :                 case 0x27:
    7025              :                 case 0x28:
    7026              :                 case 0x29:
    7027              :                 case 0x2A:
    7028              :                 case 0x2B:
    7029              :                 case 0x2C:
    7030              :                 case 0x2D:
    7031              :                 case 0x2E:
    7032              :                 case 0x2F:
    7033              :                 case 0x30:
    7034              :                 case 0x31:
    7035              :                 case 0x32:
    7036              :                 case 0x33:
    7037              :                 case 0x34:
    7038              :                 case 0x35:
    7039              :                 case 0x36:
    7040              :                 case 0x37:
    7041              :                 case 0x38:
    7042              :                 case 0x39:
    7043              :                 case 0x3A:
    7044              :                 case 0x3B:
    7045              :                 case 0x3C:
    7046              :                 case 0x3D:
    7047              :                 case 0x3E:
    7048              :                 case 0x3F:
    7049              :                 case 0x40:
    7050              :                 case 0x41:
    7051              :                 case 0x42:
    7052              :                 case 0x43:
    7053              :                 case 0x44:
    7054              :                 case 0x45:
    7055              :                 case 0x46:
    7056              :                 case 0x47:
    7057              :                 case 0x48:
    7058              :                 case 0x49:
    7059              :                 case 0x4A:
    7060              :                 case 0x4B:
    7061              :                 case 0x4C:
    7062              :                 case 0x4D:
    7063              :                 case 0x4E:
    7064              :                 case 0x4F:
    7065              :                 case 0x50:
    7066              :                 case 0x51:
    7067              :                 case 0x52:
    7068              :                 case 0x53:
    7069              :                 case 0x54:
    7070              :                 case 0x55:
    7071              :                 case 0x56:
    7072              :                 case 0x57:
    7073              :                 case 0x58:
    7074              :                 case 0x59:
    7075              :                 case 0x5A:
    7076              :                 case 0x5B:
    7077              :                 case 0x5D:
    7078              :                 case 0x5E:
    7079              :                 case 0x5F:
    7080              :                 case 0x60:
    7081              :                 case 0x61:
    7082              :                 case 0x62:
    7083              :                 case 0x63:
    7084              :                 case 0x64:
    7085              :                 case 0x65:
    7086              :                 case 0x66:
    7087              :                 case 0x67:
    7088              :                 case 0x68:
    7089              :                 case 0x69:
    7090              :                 case 0x6A:
    7091              :                 case 0x6B:
    7092              :                 case 0x6C:
    7093              :                 case 0x6D:
    7094              :                 case 0x6E:
    7095              :                 case 0x6F:
    7096              :                 case 0x70:
    7097              :                 case 0x71:
    7098              :                 case 0x72:
    7099              :                 case 0x73:
    7100              :                 case 0x74:
    7101              :                 case 0x75:
    7102              :                 case 0x76:
    7103              :                 case 0x77:
    7104              :                 case 0x78:
    7105              :                 case 0x79:
    7106              :                 case 0x7A:
    7107              :                 case 0x7B:
    7108              :                 case 0x7C:
    7109              :                 case 0x7D:
    7110              :                 case 0x7E:
    7111              :                 case 0x7F:
    7112              :                 {
    7113        14412 :                     add(current);
    7114              :                     break;
    7115              :                 }
    7116              : 
    7117              :                 // U+0080..U+07FF: bytes C2..DF 80..BF
    7118            0 :                 case 0xC2:
    7119              :                 case 0xC3:
    7120              :                 case 0xC4:
    7121              :                 case 0xC5:
    7122              :                 case 0xC6:
    7123              :                 case 0xC7:
    7124              :                 case 0xC8:
    7125              :                 case 0xC9:
    7126              :                 case 0xCA:
    7127              :                 case 0xCB:
    7128              :                 case 0xCC:
    7129              :                 case 0xCD:
    7130              :                 case 0xCE:
    7131              :                 case 0xCF:
    7132              :                 case 0xD0:
    7133              :                 case 0xD1:
    7134              :                 case 0xD2:
    7135              :                 case 0xD3:
    7136              :                 case 0xD4:
    7137              :                 case 0xD5:
    7138              :                 case 0xD6:
    7139              :                 case 0xD7:
    7140              :                 case 0xD8:
    7141              :                 case 0xD9:
    7142              :                 case 0xDA:
    7143              :                 case 0xDB:
    7144              :                 case 0xDC:
    7145              :                 case 0xDD:
    7146              :                 case 0xDE:
    7147              :                 case 0xDF:
    7148              :                 {
    7149            0 :                     if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
    7150              :                     {
    7151              :                         return token_type::parse_error;
    7152              :                     }
    7153              :                     break;
    7154              :                 }
    7155              : 
    7156              :                 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
    7157            0 :                 case 0xE0:
    7158              :                 {
    7159            0 :                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
    7160              :                     {
    7161              :                         return token_type::parse_error;
    7162              :                     }
    7163              :                     break;
    7164              :                 }
    7165              : 
    7166              :                 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
    7167              :                 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
    7168            0 :                 case 0xE1:
    7169              :                 case 0xE2:
    7170              :                 case 0xE3:
    7171              :                 case 0xE4:
    7172              :                 case 0xE5:
    7173              :                 case 0xE6:
    7174              :                 case 0xE7:
    7175              :                 case 0xE8:
    7176              :                 case 0xE9:
    7177              :                 case 0xEA:
    7178              :                 case 0xEB:
    7179              :                 case 0xEC:
    7180              :                 case 0xEE:
    7181              :                 case 0xEF:
    7182              :                 {
    7183            0 :                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
    7184              :                     {
    7185              :                         return token_type::parse_error;
    7186              :                     }
    7187              :                     break;
    7188              :                 }
    7189              : 
    7190              :                 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
    7191            0 :                 case 0xED:
    7192              :                 {
    7193            0 :                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
    7194              :                     {
    7195              :                         return token_type::parse_error;
    7196              :                     }
    7197              :                     break;
    7198              :                 }
    7199              : 
    7200              :                 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
    7201            0 :                 case 0xF0:
    7202              :                 {
    7203            0 :                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
    7204              :                     {
    7205              :                         return token_type::parse_error;
    7206              :                     }
    7207              :                     break;
    7208              :                 }
    7209              : 
    7210              :                 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
    7211            0 :                 case 0xF1:
    7212              :                 case 0xF2:
    7213              :                 case 0xF3:
    7214              :                 {
    7215            0 :                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
    7216              :                     {
    7217              :                         return token_type::parse_error;
    7218              :                     }
    7219              :                     break;
    7220              :                 }
    7221              : 
    7222              :                 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
    7223            0 :                 case 0xF4:
    7224              :                 {
    7225            0 :                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
    7226              :                     {
    7227              :                         return token_type::parse_error;
    7228              :                     }
    7229              :                     break;
    7230              :                 }
    7231              : 
    7232              :                 // remaining bytes (80..C1 and F5..FF) are ill-formed
    7233            0 :                 default:
    7234              :                 {
    7235            0 :                     error_message = "invalid string: ill-formed UTF-8 byte";
    7236            0 :                     return token_type::parse_error;
    7237              :                 }
    7238              :             }
    7239              :         }
    7240              :     }
    7241              : 
    7242              :     /*!
    7243              :      * @brief scan a comment
    7244              :      * @return whether comment could be scanned successfully
    7245              :      */
    7246            0 :     bool scan_comment()
    7247              :     {
    7248            0 :         switch (get())
    7249              :         {
    7250              :             // single-line comments skip input until a newline or EOF is read
    7251            0 :             case '/':
    7252              :             {
    7253              :                 while (true)
    7254              :                 {
    7255            0 :                     switch (get())
    7256              :                     {
    7257              :                         case '\n':
    7258              :                         case '\r':
    7259              :                         case std::char_traits<char_type>::eof():
    7260              :                         case '\0':
    7261              :                             return true;
    7262              : 
    7263              :                         default:
    7264              :                             break;
    7265              :                     }
    7266              :                 }
    7267              :             }
    7268              : 
    7269              :             // multi-line comments skip input until */ is read
    7270              :             case '*':
    7271              :             {
    7272              :                 while (true)
    7273              :                 {
    7274            0 :                     switch (get())
    7275              :                     {
    7276            0 :                         case std::char_traits<char_type>::eof():
    7277              :                         case '\0':
    7278              :                         {
    7279            0 :                             error_message = "invalid comment; missing closing '*/'";
    7280            0 :                             return false;
    7281              :                         }
    7282              : 
    7283            0 :                         case '*':
    7284              :                         {
    7285            0 :                             switch (get())
    7286              :                             {
    7287              :                                 case '/':
    7288              :                                     return true;
    7289              : 
    7290              :                                 default:
    7291              :                                 {
    7292              :                                     unget();
    7293            0 :                                     continue;
    7294              :                                 }
    7295              :                             }
    7296              :                         }
    7297              : 
    7298            0 :                         default:
    7299            0 :                             continue;
    7300              :                     }
    7301              :                 }
    7302              :             }
    7303              : 
    7304              :             // unexpected character after reading '/'
    7305            0 :             default:
    7306              :             {
    7307            0 :                 error_message = "invalid comment; expecting '/' or '*' after '/'";
    7308            0 :                 return false;
    7309              :             }
    7310              :         }
    7311              :     }
    7312              : 
    7313              :     JSON_HEDLEY_NON_NULL(2)
    7314              :     static void strtof(float& f, const char* str, char** endptr) noexcept
    7315              :     {
    7316              :         f = std::strtof(str, endptr);
    7317              :     }
    7318              : 
    7319              :     JSON_HEDLEY_NON_NULL(2)
    7320              :     static void strtof(double& f, const char* str, char** endptr) noexcept
    7321              :     {
    7322         4248 :         f = std::strtod(str, endptr);
    7323              :     }
    7324              : 
    7325              :     JSON_HEDLEY_NON_NULL(2)
    7326              :     static void strtof(long double& f, const char* str, char** endptr) noexcept
    7327              :     {
    7328              :         f = std::strtold(str, endptr);
    7329              :     }
    7330              : 
    7331              :     /*!
    7332              :     @brief scan a number literal
    7333              : 
    7334              :     This function scans a string according to Sect. 6 of RFC 8259.
    7335              : 
    7336              :     The function is realized with a deterministic finite state machine derived
    7337              :     from the grammar described in RFC 8259. Starting in state "init", the
    7338              :     input is read and used to determined the next state. Only state "done"
    7339              :     accepts the number. State "error" is a trap state to model errors. In the
    7340              :     table below, "anything" means any character but the ones listed before.
    7341              : 
    7342              :     state    | 0        | 1-9      | e E      | +       | -       | .        | anything
    7343              :     ---------|----------|----------|----------|---------|---------|----------|-----------
    7344              :     init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
    7345              :     minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
    7346              :     zero     | done     | done     | exponent | done    | done    | decimal1 | done
    7347              :     any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
    7348              :     decimal1 | decimal2 | decimal2 | [error]  | [error] | [error] | [error]  | [error]
    7349              :     decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
    7350              :     exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
    7351              :     sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
    7352              :     any2     | any2     | any2     | done     | done    | done    | done     | done
    7353              : 
    7354              :     The state machine is realized with one label per state (prefixed with
    7355              :     "scan_number_") and `goto` statements between them. The state machine
    7356              :     contains cycles, but any cycle can be left when EOF is read. Therefore,
    7357              :     the function is guaranteed to terminate.
    7358              : 
    7359              :     During scanning, the read bytes are stored in token_buffer. This string is
    7360              :     then converted to a signed integer, an unsigned integer, or a
    7361              :     floating-point number.
    7362              : 
    7363              :     @return token_type::value_unsigned, token_type::value_integer, or
    7364              :             token_type::value_float if number could be successfully scanned,
    7365              :             token_type::parse_error otherwise
    7366              : 
    7367              :     @note The scanner is independent of the current locale. Internally, the
    7368              :           locale's decimal point is used instead of `.` to work with the
    7369              :           locale-dependent converters.
    7370              :     */
    7371         4456 :     token_type scan_number()  // lgtm [cpp/use-of-goto]
    7372              :     {
    7373              :         // reset token_buffer to store the number's bytes
    7374         4456 :         reset();
    7375              : 
    7376              :         // the type of the parsed number; initially set to unsigned; will be
    7377              :         // changed if minus sign, decimal point or exponent is read
    7378              :         token_type number_type = token_type::value_unsigned;
    7379              : 
    7380              :         // state (init): we just found out we need to scan a number
    7381         4456 :         switch (current)
    7382              :         {
    7383          919 :             case '-':
    7384              :             {
    7385              :                 add(current);
    7386          919 :                 goto scan_number_minus;
    7387              :             }
    7388              : 
    7389          977 :             case '0':
    7390              :             {
    7391              :                 add(current);
    7392          977 :                 goto scan_number_zero;
    7393              :             }
    7394              : 
    7395         2560 :             case '1':
    7396              :             case '2':
    7397              :             case '3':
    7398              :             case '4':
    7399              :             case '5':
    7400              :             case '6':
    7401              :             case '7':
    7402              :             case '8':
    7403              :             case '9':
    7404              :             {
    7405              :                 add(current);
    7406         2560 :                 goto scan_number_any1;
    7407              :             }
    7408              : 
    7409              :             // all other characters are rejected outside scan_number()
    7410              :             default:            // LCOV_EXCL_LINE
    7411              :                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
    7412              :         }
    7413              : 
    7414          919 : scan_number_minus:
    7415              :         // state: we just parsed a leading minus sign
    7416              :         number_type = token_type::value_integer;
    7417          919 :         switch (get())
    7418              :         {
    7419          625 :             case '0':
    7420              :             {
    7421          625 :                 add(current);
    7422          625 :                 goto scan_number_zero;
    7423              :             }
    7424              : 
    7425          294 :             case '1':
    7426              :             case '2':
    7427              :             case '3':
    7428              :             case '4':
    7429              :             case '5':
    7430              :             case '6':
    7431              :             case '7':
    7432              :             case '8':
    7433              :             case '9':
    7434              :             {
    7435          294 :                 add(current);
    7436          294 :                 goto scan_number_any1;
    7437              :             }
    7438              : 
    7439            0 :             default:
    7440              :             {
    7441            0 :                 error_message = "invalid number; expected digit after '-'";
    7442            0 :                 return token_type::parse_error;
    7443              :             }
    7444              :         }
    7445              : 
    7446         1602 : scan_number_zero:
    7447              :         // state: we just parse a zero (maybe with a leading minus sign)
    7448         1602 :         switch (get())
    7449              :         {
    7450         1550 :             case '.':
    7451              :             {
    7452         1550 :                 add(decimal_point_char);
    7453         1550 :                 goto scan_number_decimal1;
    7454              :             }
    7455              : 
    7456            0 :             case 'e':
    7457              :             case 'E':
    7458              :             {
    7459            0 :                 add(current);
    7460            0 :                 goto scan_number_exponent;
    7461              :             }
    7462              : 
    7463           52 :             default:
    7464           52 :                 goto scan_number_done;
    7465              :         }
    7466              : 
    7467         2854 : scan_number_any1:
    7468              :         // state: we just parsed a number 0-9 (maybe with a leading minus sign)
    7469         6543 :         switch (get())
    7470              :         {
    7471         3689 :             case '0':
    7472              :             case '1':
    7473              :             case '2':
    7474              :             case '3':
    7475              :             case '4':
    7476              :             case '5':
    7477              :             case '6':
    7478              :             case '7':
    7479              :             case '8':
    7480              :             case '9':
    7481              :             {
    7482         3689 :                 add(current);
    7483         3689 :                 goto scan_number_any1;
    7484              :             }
    7485              : 
    7486         2698 :             case '.':
    7487              :             {
    7488         2698 :                 add(decimal_point_char);
    7489         2698 :                 goto scan_number_decimal1;
    7490              :             }
    7491              : 
    7492            0 :             case 'e':
    7493              :             case 'E':
    7494              :             {
    7495            0 :                 add(current);
    7496            0 :                 goto scan_number_exponent;
    7497              :             }
    7498              : 
    7499          156 :             default:
    7500          156 :                 goto scan_number_done;
    7501              :         }
    7502              : 
    7503         4248 : scan_number_decimal1:
    7504              :         // state: we just parsed a decimal point
    7505              :         number_type = token_type::value_float;
    7506         4248 :         switch (get())
    7507              :         {
    7508         4248 :             case '0':
    7509              :             case '1':
    7510              :             case '2':
    7511              :             case '3':
    7512              :             case '4':
    7513              :             case '5':
    7514              :             case '6':
    7515              :             case '7':
    7516              :             case '8':
    7517              :             case '9':
    7518              :             {
    7519         4248 :                 add(current);
    7520         4248 :                 goto scan_number_decimal2;
    7521              :             }
    7522              : 
    7523            0 :             default:
    7524              :             {
    7525            0 :                 error_message = "invalid number; expected digit after '.'";
    7526            0 :                 return token_type::parse_error;
    7527              :             }
    7528              :         }
    7529              : 
    7530        20706 : scan_number_decimal2:
    7531              :         // we just parsed at least one number after a decimal point
    7532        20706 :         switch (get())
    7533              :         {
    7534        16458 :             case '0':
    7535              :             case '1':
    7536              :             case '2':
    7537              :             case '3':
    7538              :             case '4':
    7539              :             case '5':
    7540              :             case '6':
    7541              :             case '7':
    7542              :             case '8':
    7543              :             case '9':
    7544              :             {
    7545        16458 :                 add(current);
    7546        16458 :                 goto scan_number_decimal2;
    7547              :             }
    7548              : 
    7549           27 :             case 'e':
    7550              :             case 'E':
    7551              :             {
    7552           27 :                 add(current);
    7553           27 :                 goto scan_number_exponent;
    7554              :             }
    7555              : 
    7556         4221 :             default:
    7557         4221 :                 goto scan_number_done;
    7558              :         }
    7559              : 
    7560           27 : scan_number_exponent:
    7561              :         // we just parsed an exponent
    7562              :         number_type = token_type::value_float;
    7563           27 :         switch (get())
    7564              :         {
    7565           27 :             case '+':
    7566              :             case '-':
    7567              :             {
    7568           27 :                 add(current);
    7569           27 :                 goto scan_number_sign;
    7570              :             }
    7571              : 
    7572            0 :             case '0':
    7573              :             case '1':
    7574              :             case '2':
    7575              :             case '3':
    7576              :             case '4':
    7577              :             case '5':
    7578              :             case '6':
    7579              :             case '7':
    7580              :             case '8':
    7581              :             case '9':
    7582              :             {
    7583            0 :                 add(current);
    7584            0 :                 goto scan_number_any2;
    7585              :             }
    7586              : 
    7587            0 :             default:
    7588              :             {
    7589            0 :                 error_message =
    7590              :                     "invalid number; expected '+', '-', or digit after exponent";
    7591            0 :                 return token_type::parse_error;
    7592              :             }
    7593              :         }
    7594              : 
    7595              : scan_number_sign:
    7596              :         // we just parsed an exponent sign
    7597           27 :         switch (get())
    7598              :         {
    7599           27 :             case '0':
    7600              :             case '1':
    7601              :             case '2':
    7602              :             case '3':
    7603              :             case '4':
    7604              :             case '5':
    7605              :             case '6':
    7606              :             case '7':
    7607              :             case '8':
    7608              :             case '9':
    7609              :             {
    7610           27 :                 add(current);
    7611           27 :                 goto scan_number_any2;
    7612              :             }
    7613              : 
    7614            0 :             default:
    7615              :             {
    7616            0 :                 error_message = "invalid number; expected digit after exponent sign";
    7617            0 :                 return token_type::parse_error;
    7618              :             }
    7619              :         }
    7620              : 
    7621              : scan_number_any2:
    7622              :         // we just parsed a number after the exponent or exponent sign
    7623           54 :         switch (get())
    7624              :         {
    7625           27 :             case '0':
    7626              :             case '1':
    7627              :             case '2':
    7628              :             case '3':
    7629              :             case '4':
    7630              :             case '5':
    7631              :             case '6':
    7632              :             case '7':
    7633              :             case '8':
    7634              :             case '9':
    7635              :             {
    7636           27 :                 add(current);
    7637           27 :                 goto scan_number_any2;
    7638              :             }
    7639              : 
    7640           27 :             default:
    7641           27 :                 goto scan_number_done;
    7642              :         }
    7643              : 
    7644         4456 : scan_number_done:
    7645              :         // unget the character after the number (we only read it to know that
    7646              :         // we are done scanning a number)
    7647              :         unget();
    7648              : 
    7649         4456 :         char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
    7650         4456 :         errno = 0;
    7651              : 
    7652              :         // try to parse integers first and fall back to floats
    7653         4456 :         if (number_type == token_type::value_unsigned)
    7654              :         {
    7655          200 :             const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
    7656              : 
    7657              :             // we checked the number format before
    7658              :             JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
    7659              : 
    7660          200 :             if (errno == 0)
    7661              :             {
    7662          200 :                 value_unsigned = static_cast<number_unsigned_t>(x);
    7663              :                 if (value_unsigned == x)
    7664              :                 {
    7665          200 :                     return token_type::value_unsigned;
    7666              :                 }
    7667              :             }
    7668              :         }
    7669         4256 :         else if (number_type == token_type::value_integer)
    7670              :         {
    7671            8 :             const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
    7672              : 
    7673              :             // we checked the number format before
    7674              :             JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
    7675              : 
    7676            8 :             if (errno == 0)
    7677              :             {
    7678            8 :                 value_integer = static_cast<number_integer_t>(x);
    7679              :                 if (value_integer == x)
    7680              :                 {
    7681            8 :                     return token_type::value_integer;
    7682              :                 }
    7683              :             }
    7684              :         }
    7685              : 
    7686              :         // this code is reached if we parse a floating-point number or if an
    7687              :         // integer conversion above failed
    7688              :         strtof(value_float, token_buffer.data(), &endptr);
    7689              : 
    7690              :         // we checked the number format before
    7691              :         JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
    7692              : 
    7693         4248 :         return token_type::value_float;
    7694              :     }
    7695              : 
    7696              :     /*!
    7697              :     @param[in] literal_text  the literal text to expect
    7698              :     @param[in] length        the length of the passed literal text
    7699              :     @param[in] return_type   the token type to return on success
    7700              :     */
    7701              :     JSON_HEDLEY_NON_NULL(2)
    7702              :     token_type scan_literal(const char_type* literal_text, const std::size_t length,
    7703              :                             token_type return_type)
    7704              :     {
    7705              :         JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
    7706            0 :         for (std::size_t i = 1; i < length; ++i)
    7707              :         {
    7708            0 :             if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
    7709              :             {
    7710            0 :                 error_message = "invalid literal";
    7711            0 :                 return token_type::parse_error;
    7712              :             }
    7713              :         }
    7714              :         return return_type;
    7715              :     }
    7716              : 
    7717              :     /////////////////////
    7718              :     // input management
    7719              :     /////////////////////
    7720              : 
    7721              :     /// reset token_buffer; current character is beginning of token
    7722         6559 :     void reset() noexcept
    7723              :     {
    7724              :         token_buffer.clear();
    7725              :         token_string.clear();
    7726         6559 :         token_string.push_back(std::char_traits<char_type>::to_char_type(current));
    7727         6559 :     }
    7728              : 
    7729              :     /*
    7730              :     @brief get next character from the input
    7731              : 
    7732              :     This function provides the interface to the used input adapter. It does
    7733              :     not throw in case the input reached EOF, but returns a
    7734              :     `std::char_traits<char>::eof()` in that case.  Stores the scanned characters
    7735              :     for use in error messages.
    7736              : 
    7737              :     @return character read from the input
    7738              :     */
    7739       106097 :     char_int_type get()
    7740              :     {
    7741       106097 :         ++position.chars_read_total;
    7742       106097 :         ++position.chars_read_current_line;
    7743              : 
    7744       106097 :         if (next_unget)
    7745              :         {
    7746              :             // just reset the next_unget variable and work with current
    7747         4462 :             next_unget = false;
    7748              :         }
    7749              :         else
    7750              :         {
    7751       101635 :             current = ia.get_character();
    7752              :         }
    7753              : 
    7754       106097 :         if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
    7755              :         {
    7756       106097 :             token_string.push_back(std::char_traits<char_type>::to_char_type(current));
    7757              :         }
    7758              : 
    7759       106097 :         if (current == '\n')
    7760              :         {
    7761         4680 :             ++position.lines_read;
    7762         4680 :             position.chars_read_current_line = 0;
    7763              :         }
    7764              : 
    7765       106097 :         return current;
    7766              :     }
    7767              : 
    7768              :     /*!
    7769              :     @brief unget current character (read it again on next get)
    7770              : 
    7771              :     We implement unget by setting variable next_unget to true. The input is not
    7772              :     changed - we just simulate ungetting by modifying chars_read_total,
    7773              :     chars_read_current_line, and token_string. The next call to get() will
    7774              :     behave as if the unget character is read again.
    7775              :     */
    7776              :     void unget()
    7777              :     {
    7778         4462 :         next_unget = true;
    7779              : 
    7780         4462 :         --position.chars_read_total;
    7781              : 
    7782              :         // in case we "unget" a newline, we have to also decrement the lines_read
    7783         4462 :         if (position.chars_read_current_line == 0)
    7784              :         {
    7785          270 :             if (position.lines_read > 0)
    7786              :             {
    7787          270 :                 --position.lines_read;
    7788              :             }
    7789              :         }
    7790              :         else
    7791              :         {
    7792         4192 :             --position.chars_read_current_line;
    7793              :         }
    7794              : 
    7795         4462 :         if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
    7796              :         {
    7797              :             JSON_ASSERT(!token_string.empty());
    7798              :             token_string.pop_back();
    7799              :         }
    7800              :     }
    7801              : 
    7802              :     /// add a character to token_buffer
    7803              :     void add(char_int_type c)
    7804              :     {
    7805        48538 :         token_buffer.push_back(static_cast<typename string_t::value_type>(c));
    7806        14412 :     }
    7807              : 
    7808              :   public:
    7809              :     /////////////////////
    7810              :     // value getters
    7811              :     /////////////////////
    7812              : 
    7813              :     /// return integer value
    7814              :     constexpr number_integer_t get_number_integer() const noexcept
    7815              :     {
    7816            8 :         return value_integer;
    7817              :     }
    7818              : 
    7819              :     /// return unsigned integer value
    7820              :     constexpr number_unsigned_t get_number_unsigned() const noexcept
    7821              :     {
    7822          200 :         return value_unsigned;
    7823              :     }
    7824              : 
    7825              :     /// return floating-point value
    7826              :     constexpr number_float_t get_number_float() const noexcept
    7827              :     {
    7828         4248 :         return value_float;
    7829              :     }
    7830              : 
    7831              :     /// return current string value (implicitly resets the token; useful only once)
    7832              :     string_t& get_string()
    7833              :     {
    7834         1956 :         return token_buffer;
    7835              :     }
    7836              : 
    7837              :     /////////////////////
    7838              :     // diagnostics
    7839              :     /////////////////////
    7840              : 
    7841              :     /// return position of last read token
    7842              :     constexpr position_t get_position() const noexcept
    7843              :     {
    7844            0 :         return position;
    7845              :     }
    7846              : 
    7847              :     /// return the last read token (for errors only).  Will never contain EOF
    7848              :     /// (an arbitrary value that is not a valid char value, often -1), because
    7849              :     /// 255 may legitimately occur.  May contain NUL, which should be escaped.
    7850            0 :     std::string get_token_string() const
    7851              :     {
    7852              :         // escape control characters
    7853              :         std::string result;
    7854            0 :         for (const auto c : token_string)
    7855              :         {
    7856            0 :             if (static_cast<unsigned char>(c) <= '\x1F')
    7857              :             {
    7858              :                 // escape control characters
    7859            0 :                 std::array<char, 9> cs{{}};
    7860            0 :                 static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
    7861              :                 result += cs.data();
    7862              :             }
    7863              :             else
    7864              :             {
    7865              :                 // add character as is
    7866            0 :                 result.push_back(static_cast<std::string::value_type>(c));
    7867              :             }
    7868              :         }
    7869              : 
    7870            0 :         return result;
    7871              :     }
    7872              : 
    7873              :     /// return syntax error message
    7874              :     JSON_HEDLEY_RETURNS_NON_NULL
    7875              :     constexpr const char* get_error_message() const noexcept
    7876              :     {
    7877            0 :         return error_message;
    7878              :     }
    7879              : 
    7880              :     /////////////////////
    7881              :     // actual scanner
    7882              :     /////////////////////
    7883              : 
    7884              :     /*!
    7885              :     @brief skip the UTF-8 byte order mark
    7886              :     @return true iff there is no BOM or the correct BOM has been skipped
    7887              :     */
    7888           33 :     bool skip_bom()
    7889              :     {
    7890           33 :         if (get() == 0xEF)
    7891              :         {
    7892              :             // check if we completely parse the BOM
    7893           27 :             return get() == 0xBB && get() == 0xBF;
    7894              :         }
    7895              : 
    7896              :         // the first character is not the beginning of the BOM; unget it to
    7897              :         // process is later
    7898              :         unget();
    7899              :         return true;
    7900              :     }
    7901              : 
    7902        15485 :     void skip_whitespace()
    7903              :     {
    7904              :         do
    7905              :         {
    7906        55369 :             get();
    7907              :         }
    7908        55369 :         while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
    7909        15485 :     }
    7910              : 
    7911        15485 :     token_type scan()
    7912              :     {
    7913              :         // initially, skip the BOM
    7914        15485 :         if (position.chars_read_total == 0 && !skip_bom())
    7915              :         {
    7916            0 :             error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
    7917            0 :             return token_type::parse_error;
    7918              :         }
    7919              : 
    7920              :         // read next character and ignore whitespace
    7921        15485 :         skip_whitespace();
    7922              : 
    7923              :         // ignore comments
    7924        15485 :         while (ignore_comments && current == '/')
    7925              :         {
    7926            0 :             if (!scan_comment())
    7927              :             {
    7928              :                 return token_type::parse_error;
    7929              :             }
    7930              : 
    7931              :             // skip following whitespace
    7932            0 :             skip_whitespace();
    7933              :         }
    7934              : 
    7935        15485 :         switch (current)
    7936              :         {
    7937              :             // structural characters
    7938              :             case '[':
    7939              :                 return token_type::begin_array;
    7940          615 :             case ']':
    7941          615 :                 return token_type::end_array;
    7942          585 :             case '{':
    7943          585 :                 return token_type::begin_object;
    7944          585 :             case '}':
    7945          585 :                 return token_type::end_object;
    7946         1956 :             case ':':
    7947         1956 :                 return token_type::name_separator;
    7948         4570 :             case ',':
    7949         4570 :                 return token_type::value_separator;
    7950              : 
    7951              :             // literals
    7952            0 :             case 't':
    7953              :             {
    7954            0 :                 std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
    7955              :                 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
    7956              :             }
    7957            0 :             case 'f':
    7958              :             {
    7959            0 :                 std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
    7960              :                 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
    7961              :             }
    7962            0 :             case 'n':
    7963              :             {
    7964            0 :                 std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
    7965              :                 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
    7966              :             }
    7967              : 
    7968              :             // string
    7969         2103 :             case '\"':
    7970         2103 :                 return scan_string();
    7971              : 
    7972              :             // number
    7973         4456 :             case '-':
    7974              :             case '0':
    7975              :             case '1':
    7976              :             case '2':
    7977              :             case '3':
    7978              :             case '4':
    7979              :             case '5':
    7980              :             case '6':
    7981              :             case '7':
    7982              :             case '8':
    7983              :             case '9':
    7984         4456 :                 return scan_number();
    7985              : 
    7986              :             // end of input (the null byte is needed when parsing from
    7987              :             // string literals)
    7988            0 :             case '\0':
    7989              :             case std::char_traits<char_type>::eof():
    7990            0 :                 return token_type::end_of_input;
    7991              : 
    7992              :             // error
    7993            0 :             default:
    7994            0 :                 error_message = "invalid literal";
    7995            0 :                 return token_type::parse_error;
    7996              :         }
    7997              :     }
    7998              : 
    7999              :   private:
    8000              :     /// input adapter
    8001              :     InputAdapterType ia;
    8002              : 
    8003              :     /// whether comments should be ignored (true) or signaled as errors (false)
    8004              :     const bool ignore_comments = false;
    8005              : 
    8006              :     /// the current character
    8007              :     char_int_type current = std::char_traits<char_type>::eof();
    8008              : 
    8009              :     /// whether the next get() call should just return current
    8010              :     bool next_unget = false;
    8011              : 
    8012              :     /// the start position of the current token
    8013              :     position_t position {};
    8014              : 
    8015              :     /// raw input token string (for error messages)
    8016              :     std::vector<char_type> token_string {};
    8017              : 
    8018              :     /// buffer for variable-length tokens (numbers, strings)
    8019              :     string_t token_buffer {};
    8020              : 
    8021              :     /// a description of occurred lexer errors
    8022              :     const char* error_message = "";
    8023              : 
    8024              :     // number values
    8025              :     number_integer_t value_integer = 0;
    8026              :     number_unsigned_t value_unsigned = 0;
    8027              :     number_float_t value_float = 0;
    8028              : 
    8029              :     /// the decimal point
    8030              :     const char_int_type decimal_point_char = '.';
    8031              : };
    8032              : }  // namespace detail
    8033              : }  // namespace nlohmann
    8034              : 
    8035              : // #include <nlohmann/detail/macro_scope.hpp>
    8036              : 
    8037              : // #include <nlohmann/detail/meta/is_sax.hpp>
    8038              : 
    8039              : 
    8040              : #include <cstdint> // size_t
    8041              : #include <utility> // declval
    8042              : #include <string> // string
    8043              : 
    8044              : // #include <nlohmann/detail/meta/detected.hpp>
    8045              : 
    8046              : // #include <nlohmann/detail/meta/type_traits.hpp>
    8047              : 
    8048              : 
    8049              : namespace nlohmann
    8050              : {
    8051              : namespace detail
    8052              : {
    8053              : template<typename T>
    8054              : using null_function_t = decltype(std::declval<T&>().null());
    8055              : 
    8056              : template<typename T>
    8057              : using boolean_function_t =
    8058              :     decltype(std::declval<T&>().boolean(std::declval<bool>()));
    8059              : 
    8060              : template<typename T, typename Integer>
    8061              : using number_integer_function_t =
    8062              :     decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
    8063              : 
    8064              : template<typename T, typename Unsigned>
    8065              : using number_unsigned_function_t =
    8066              :     decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
    8067              : 
    8068              : template<typename T, typename Float, typename String>
    8069              : using number_float_function_t = decltype(std::declval<T&>().number_float(
    8070              :                                     std::declval<Float>(), std::declval<const String&>()));
    8071              : 
    8072              : template<typename T, typename String>
    8073              : using string_function_t =
    8074              :     decltype(std::declval<T&>().string(std::declval<String&>()));
    8075              : 
    8076              : template<typename T, typename Binary>
    8077              : using binary_function_t =
    8078              :     decltype(std::declval<T&>().binary(std::declval<Binary&>()));
    8079              : 
    8080              : template<typename T>
    8081              : using start_object_function_t =
    8082              :     decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
    8083              : 
    8084              : template<typename T, typename String>
    8085              : using key_function_t =
    8086              :     decltype(std::declval<T&>().key(std::declval<String&>()));
    8087              : 
    8088              : template<typename T>
    8089              : using end_object_function_t = decltype(std::declval<T&>().end_object());
    8090              : 
    8091              : template<typename T>
    8092              : using start_array_function_t =
    8093              :     decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
    8094              : 
    8095              : template<typename T>
    8096              : using end_array_function_t = decltype(std::declval<T&>().end_array());
    8097              : 
    8098              : template<typename T, typename Exception>
    8099              : using parse_error_function_t = decltype(std::declval<T&>().parse_error(
    8100              :         std::declval<std::size_t>(), std::declval<const std::string&>(),
    8101              :         std::declval<const Exception&>()));
    8102              : 
    8103              : template<typename SAX, typename BasicJsonType>
    8104              : struct is_sax
    8105              : {
    8106              :   private:
    8107              :     static_assert(is_basic_json<BasicJsonType>::value,
    8108              :                   "BasicJsonType must be of type basic_json<...>");
    8109              : 
    8110              :     using number_integer_t = typename BasicJsonType::number_integer_t;
    8111              :     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
    8112              :     using number_float_t = typename BasicJsonType::number_float_t;
    8113              :     using string_t = typename BasicJsonType::string_t;
    8114              :     using binary_t = typename BasicJsonType::binary_t;
    8115              :     using exception_t = typename BasicJsonType::exception;
    8116              : 
    8117              :   public:
    8118              :     static constexpr bool value =
    8119              :         is_detected_exact<bool, null_function_t, SAX>::value &&
    8120              :         is_detected_exact<bool, boolean_function_t, SAX>::value &&
    8121              :         is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
    8122              :         is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
    8123              :         is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
    8124              :         is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
    8125              :         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
    8126              :         is_detected_exact<bool, start_object_function_t, SAX>::value &&
    8127              :         is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
    8128              :         is_detected_exact<bool, end_object_function_t, SAX>::value &&
    8129              :         is_detected_exact<bool, start_array_function_t, SAX>::value &&
    8130              :         is_detected_exact<bool, end_array_function_t, SAX>::value &&
    8131              :         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
    8132              : };
    8133              : 
    8134              : template<typename SAX, typename BasicJsonType>
    8135              : struct is_sax_static_asserts
    8136              : {
    8137              :   private:
    8138              :     static_assert(is_basic_json<BasicJsonType>::value,
    8139              :                   "BasicJsonType must be of type basic_json<...>");
    8140              : 
    8141              :     using number_integer_t = typename BasicJsonType::number_integer_t;
    8142              :     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
    8143              :     using number_float_t = typename BasicJsonType::number_float_t;
    8144              :     using string_t = typename BasicJsonType::string_t;
    8145              :     using binary_t = typename BasicJsonType::binary_t;
    8146              :     using exception_t = typename BasicJsonType::exception;
    8147              : 
    8148              :   public:
    8149              :     static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
    8150              :                   "Missing/invalid function: bool null()");
    8151              :     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
    8152              :                   "Missing/invalid function: bool boolean(bool)");
    8153              :     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
    8154              :                   "Missing/invalid function: bool boolean(bool)");
    8155              :     static_assert(
    8156              :         is_detected_exact<bool, number_integer_function_t, SAX,
    8157              :         number_integer_t>::value,
    8158              :         "Missing/invalid function: bool number_integer(number_integer_t)");
    8159              :     static_assert(
    8160              :         is_detected_exact<bool, number_unsigned_function_t, SAX,
    8161              :         number_unsigned_t>::value,
    8162              :         "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
    8163              :     static_assert(is_detected_exact<bool, number_float_function_t, SAX,
    8164              :                   number_float_t, string_t>::value,
    8165              :                   "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
    8166              :     static_assert(
    8167              :         is_detected_exact<bool, string_function_t, SAX, string_t>::value,
    8168              :         "Missing/invalid function: bool string(string_t&)");
    8169              :     static_assert(
    8170              :         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
    8171              :         "Missing/invalid function: bool binary(binary_t&)");
    8172              :     static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
    8173              :                   "Missing/invalid function: bool start_object(std::size_t)");
    8174              :     static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
    8175              :                   "Missing/invalid function: bool key(string_t&)");
    8176              :     static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
    8177              :                   "Missing/invalid function: bool end_object()");
    8178              :     static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
    8179              :                   "Missing/invalid function: bool start_array(std::size_t)");
    8180              :     static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
    8181              :                   "Missing/invalid function: bool end_array()");
    8182              :     static_assert(
    8183              :         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
    8184              :         "Missing/invalid function: bool parse_error(std::size_t, const "
    8185              :         "std::string&, const exception&)");
    8186              : };
    8187              : }  // namespace detail
    8188              : }  // namespace nlohmann
    8189              : 
    8190              : // #include <nlohmann/detail/meta/type_traits.hpp>
    8191              : 
    8192              : // #include <nlohmann/detail/value_t.hpp>
    8193              : 
    8194              : 
    8195              : namespace nlohmann
    8196              : {
    8197              : namespace detail
    8198              : {
    8199              : 
    8200              : /// how to treat CBOR tags
    8201              : enum class cbor_tag_handler_t
    8202              : {
    8203              :     error,   ///< throw a parse_error exception in case of a tag
    8204              :     ignore,  ///< ignore tags
    8205              :     store    ///< store tags as binary type
    8206              : };
    8207              : 
    8208              : /*!
    8209              : @brief determine system byte order
    8210              : 
    8211              : @return true if and only if system's byte order is little endian
    8212              : 
    8213              : @note from https://stackoverflow.com/a/1001328/266378
    8214              : */
    8215              : static inline bool little_endianness(int num = 1) noexcept
    8216              : {
    8217              :     return *reinterpret_cast<char*>(&num) == 1;
    8218              : }
    8219              : 
    8220              : 
    8221              : ///////////////////
    8222              : // binary reader //
    8223              : ///////////////////
    8224              : 
    8225              : /*!
    8226              : @brief deserialization of CBOR, MessagePack, and UBJSON values
    8227              : */
    8228              : template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
    8229              : class binary_reader
    8230              : {
    8231              :     using number_integer_t = typename BasicJsonType::number_integer_t;
    8232              :     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
    8233              :     using number_float_t = typename BasicJsonType::number_float_t;
    8234              :     using string_t = typename BasicJsonType::string_t;
    8235              :     using binary_t = typename BasicJsonType::binary_t;
    8236              :     using json_sax_t = SAX;
    8237              :     using char_type = typename InputAdapterType::char_type;
    8238              :     using char_int_type = typename std::char_traits<char_type>::int_type;
    8239              : 
    8240              :   public:
    8241              :     /*!
    8242              :     @brief create a binary reader
    8243              : 
    8244              :     @param[in] adapter  input adapter to read from
    8245              :     */
    8246              :     explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
    8247              :     {
    8248              :         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
    8249              :     }
    8250              : 
    8251              :     // make class move-only
    8252              :     binary_reader(const binary_reader&) = delete;
    8253              :     binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
    8254              :     binary_reader& operator=(const binary_reader&) = delete;
    8255              :     binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
    8256              :     ~binary_reader() = default;
    8257              : 
    8258              :     /*!
    8259              :     @param[in] format  the binary format to parse
    8260              :     @param[in] sax_    a SAX event processor
    8261              :     @param[in] strict  whether to expect the input to be consumed completed
    8262              :     @param[in] tag_handler  how to treat CBOR tags
    8263              : 
    8264              :     @return whether parsing was successful
    8265              :     */
    8266              :     JSON_HEDLEY_NON_NULL(3)
    8267              :     bool sax_parse(const input_format_t format,
    8268              :                    json_sax_t* sax_,
    8269              :                    const bool strict = true,
    8270              :                    const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
    8271              :     {
    8272              :         sax = sax_;
    8273              :         bool result = false;
    8274              : 
    8275              :         switch (format)
    8276              :         {
    8277              :             case input_format_t::bson:
    8278              :                 result = parse_bson_internal();
    8279              :                 break;
    8280              : 
    8281              :             case input_format_t::cbor:
    8282              :                 result = parse_cbor_internal(true, tag_handler);
    8283              :                 break;
    8284              : 
    8285              :             case input_format_t::msgpack:
    8286              :                 result = parse_msgpack_internal();
    8287              :                 break;
    8288              : 
    8289              :             case input_format_t::ubjson:
    8290              :                 result = parse_ubjson_internal();
    8291              :                 break;
    8292              : 
    8293              :             case input_format_t::json: // LCOV_EXCL_LINE
    8294              :             default:            // LCOV_EXCL_LINE
    8295              :                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
    8296              :         }
    8297              : 
    8298              :         // strict mode: next byte must be EOF
    8299              :         if (result && strict)
    8300              :         {
    8301              :             if (format == input_format_t::ubjson)
    8302              :             {
    8303              :                 get_ignore_noop();
    8304              :             }
    8305              :             else
    8306              :             {
    8307              :                 get();
    8308              :             }
    8309              : 
    8310              :             if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
    8311              :             {
    8312              :                 return sax->parse_error(chars_read, get_token_string(),
    8313              :                                         parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
    8314              :             }
    8315              :         }
    8316              : 
    8317              :         return result;
    8318              :     }
    8319              : 
    8320              :   private:
    8321              :     //////////
    8322              :     // BSON //
    8323              :     //////////
    8324              : 
    8325              :     /*!
    8326              :     @brief Reads in a BSON-object and passes it to the SAX-parser.
    8327              :     @return whether a valid BSON-value was passed to the SAX parser
    8328              :     */
    8329              :     bool parse_bson_internal()
    8330              :     {
    8331              :         std::int32_t document_size{};
    8332              :         get_number<std::int32_t, true>(input_format_t::bson, document_size);
    8333              : 
    8334              :         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
    8335              :         {
    8336              :             return false;
    8337              :         }
    8338              : 
    8339              :         if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
    8340              :         {
    8341              :             return false;
    8342              :         }
    8343              : 
    8344              :         return sax->end_object();
    8345              :     }
    8346              : 
    8347              :     /*!
    8348              :     @brief Parses a C-style string from the BSON input.
    8349              :     @param[in,out] result  A reference to the string variable where the read
    8350              :                             string is to be stored.
    8351              :     @return `true` if the \x00-byte indicating the end of the string was
    8352              :              encountered before the EOF; false` indicates an unexpected EOF.
    8353              :     */
    8354              :     bool get_bson_cstr(string_t& result)
    8355              :     {
    8356              :         auto out = std::back_inserter(result);
    8357              :         while (true)
    8358              :         {
    8359              :             get();
    8360              :             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
    8361              :             {
    8362              :                 return false;
    8363              :             }
    8364              :             if (current == 0x00)
    8365              :             {
    8366              :                 return true;
    8367              :             }
    8368              :             *out++ = static_cast<typename string_t::value_type>(current);
    8369              :         }
    8370              :     }
    8371              : 
    8372              :     /*!
    8373              :     @brief Parses a zero-terminated string of length @a len from the BSON
    8374              :            input.
    8375              :     @param[in] len  The length (including the zero-byte at the end) of the
    8376              :                     string to be read.
    8377              :     @param[in,out] result  A reference to the string variable where the read
    8378              :                             string is to be stored.
    8379              :     @tparam NumberType The type of the length @a len
    8380              :     @pre len >= 1
    8381              :     @return `true` if the string was successfully parsed
    8382              :     */
    8383              :     template<typename NumberType>
    8384              :     bool get_bson_string(const NumberType len, string_t& result)
    8385              :     {
    8386              :         if (JSON_HEDLEY_UNLIKELY(len < 1))
    8387              :         {
    8388              :             auto last_token = get_token_string();
    8389              :             return 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"), BasicJsonType()));
    8390              :         }
    8391              : 
    8392              :         return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
    8393              :     }
    8394              : 
    8395              :     /*!
    8396              :     @brief Parses a byte array input of length @a len from the BSON input.
    8397              :     @param[in] len  The length of the byte array to be read.
    8398              :     @param[in,out] result  A reference to the binary variable where the read
    8399              :                             array is to be stored.
    8400              :     @tparam NumberType The type of the length @a len
    8401              :     @pre len >= 0
    8402              :     @return `true` if the byte array was successfully parsed
    8403              :     */
    8404              :     template<typename NumberType>
    8405              :     bool get_bson_binary(const NumberType len, binary_t& result)
    8406              :     {
    8407              :         if (JSON_HEDLEY_UNLIKELY(len < 0))
    8408              :         {
    8409              :             auto last_token = get_token_string();
    8410              :             return 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"), BasicJsonType()));
    8411              :         }
    8412              : 
    8413              :         // All BSON binary values have a subtype
    8414              :         std::uint8_t subtype{};
    8415              :         get_number<std::uint8_t>(input_format_t::bson, subtype);
    8416              :         result.set_subtype(subtype);
    8417              : 
    8418              :         return get_binary(input_format_t::bson, len, result);
    8419              :     }
    8420              : 
    8421              :     /*!
    8422              :     @brief Read a BSON document element of the given @a element_type.
    8423              :     @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
    8424              :     @param[in] element_type_parse_position The position in the input stream,
    8425              :                where the `element_type` was read.
    8426              :     @warning Not all BSON element types are supported yet. An unsupported
    8427              :              @a element_type will give rise to a parse_error.114:
    8428              :              Unsupported BSON record type 0x...
    8429              :     @return whether a valid BSON-object/array was passed to the SAX parser
    8430              :     */
    8431              :     bool parse_bson_element_internal(const char_int_type element_type,
    8432              :                                      const std::size_t element_type_parse_position)
    8433              :     {
    8434              :         switch (element_type)
    8435              :         {
    8436              :             case 0x01: // double
    8437              :             {
    8438              :                 double number{};
    8439              :                 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
    8440              :             }
    8441              : 
    8442              :             case 0x02: // string
    8443              :             {
    8444              :                 std::int32_t len{};
    8445              :                 string_t value;
    8446              :                 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
    8447              :             }
    8448              : 
    8449              :             case 0x03: // object
    8450              :             {
    8451              :                 return parse_bson_internal();
    8452              :             }
    8453              : 
    8454              :             case 0x04: // array
    8455              :             {
    8456              :                 return parse_bson_array();
    8457              :             }
    8458              : 
    8459              :             case 0x05: // binary
    8460              :             {
    8461              :                 std::int32_t len{};
    8462              :                 binary_t value;
    8463              :                 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
    8464              :             }
    8465              : 
    8466              :             case 0x08: // boolean
    8467              :             {
    8468              :                 return sax->boolean(get() != 0);
    8469              :             }
    8470              : 
    8471              :             case 0x0A: // null
    8472              :             {
    8473              :                 return sax->null();
    8474              :             }
    8475              : 
    8476              :             case 0x10: // int32
    8477              :             {
    8478              :                 std::int32_t value{};
    8479              :                 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
    8480              :             }
    8481              : 
    8482              :             case 0x12: // int64
    8483              :             {
    8484              :                 std::int64_t value{};
    8485              :                 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
    8486              :             }
    8487              : 
    8488              :             default: // anything else not supported (yet)
    8489              :             {
    8490              :                 std::array<char, 3> cr{{}};
    8491              :                 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
    8492              :                 return 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()), BasicJsonType()));
    8493              :             }
    8494              :         }
    8495              :     }
    8496              : 
    8497              :     /*!
    8498              :     @brief Read a BSON element list (as specified in the BSON-spec)
    8499              : 
    8500              :     The same binary layout is used for objects and arrays, hence it must be
    8501              :     indicated with the argument @a is_array which one is expected
    8502              :     (true --> array, false --> object).
    8503              : 
    8504              :     @param[in] is_array Determines if the element list being read is to be
    8505              :                         treated as an object (@a is_array == false), or as an
    8506              :                         array (@a is_array == true).
    8507              :     @return whether a valid BSON-object/array was passed to the SAX parser
    8508              :     */
    8509              :     bool parse_bson_element_list(const bool is_array)
    8510              :     {
    8511              :         string_t key;
    8512              : 
    8513              :         while (auto element_type = get())
    8514              :         {
    8515              :             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
    8516              :             {
    8517              :                 return false;
    8518              :             }
    8519              : 
    8520              :             const std::size_t element_type_parse_position = chars_read;
    8521              :             if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
    8522              :             {
    8523              :                 return false;
    8524              :             }
    8525              : 
    8526              :             if (!is_array && !sax->key(key))
    8527              :             {
    8528              :                 return false;
    8529              :             }
    8530              : 
    8531              :             if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
    8532              :             {
    8533              :                 return false;
    8534              :             }
    8535              : 
    8536              :             // get_bson_cstr only appends
    8537              :             key.clear();
    8538              :         }
    8539              : 
    8540              :         return true;
    8541              :     }
    8542              : 
    8543              :     /*!
    8544              :     @brief Reads an array from the BSON input and passes it to the SAX-parser.
    8545              :     @return whether a valid BSON-array was passed to the SAX parser
    8546              :     */
    8547              :     bool parse_bson_array()
    8548              :     {
    8549              :         std::int32_t document_size{};
    8550              :         get_number<std::int32_t, true>(input_format_t::bson, document_size);
    8551              : 
    8552              :         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
    8553              :         {
    8554              :             return false;
    8555              :         }
    8556              : 
    8557              :         if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
    8558              :         {
    8559              :             return false;
    8560              :         }
    8561              : 
    8562              :         return sax->end_array();
    8563              :     }
    8564              : 
    8565              :     //////////
    8566              :     // CBOR //
    8567              :     //////////
    8568              : 
    8569              :     /*!
    8570              :     @param[in] get_char  whether a new character should be retrieved from the
    8571              :                          input (true) or whether the last read character should
    8572              :                          be considered instead (false)
    8573              :     @param[in] tag_handler how CBOR tags should be treated
    8574              : 
    8575              :     @return whether a valid CBOR value was passed to the SAX parser
    8576              :     */
    8577              :     bool parse_cbor_internal(const bool get_char,
    8578              :                              const cbor_tag_handler_t tag_handler)
    8579              :     {
    8580              :         switch (get_char ? get() : current)
    8581              :         {
    8582              :             // EOF
    8583              :             case std::char_traits<char_type>::eof():
    8584              :                 return unexpect_eof(input_format_t::cbor, "value");
    8585              : 
    8586              :             // Integer 0x00..0x17 (0..23)
    8587              :             case 0x00:
    8588              :             case 0x01:
    8589              :             case 0x02:
    8590              :             case 0x03:
    8591              :             case 0x04:
    8592              :             case 0x05:
    8593              :             case 0x06:
    8594              :             case 0x07:
    8595              :             case 0x08:
    8596              :             case 0x09:
    8597              :             case 0x0A:
    8598              :             case 0x0B:
    8599              :             case 0x0C:
    8600              :             case 0x0D:
    8601              :             case 0x0E:
    8602              :             case 0x0F:
    8603              :             case 0x10:
    8604              :             case 0x11:
    8605              :             case 0x12:
    8606              :             case 0x13:
    8607              :             case 0x14:
    8608              :             case 0x15:
    8609              :             case 0x16:
    8610              :             case 0x17:
    8611              :                 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
    8612              : 
    8613              :             case 0x18: // Unsigned integer (one-byte uint8_t follows)
    8614              :             {
    8615              :                 std::uint8_t number{};
    8616              :                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
    8617              :             }
    8618              : 
    8619              :             case 0x19: // Unsigned integer (two-byte uint16_t follows)
    8620              :             {
    8621              :                 std::uint16_t number{};
    8622              :                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
    8623              :             }
    8624              : 
    8625              :             case 0x1A: // Unsigned integer (four-byte uint32_t follows)
    8626              :             {
    8627              :                 std::uint32_t number{};
    8628              :                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
    8629              :             }
    8630              : 
    8631              :             case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
    8632              :             {
    8633              :                 std::uint64_t number{};
    8634              :                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
    8635              :             }
    8636              : 
    8637              :             // Negative integer -1-0x00..-1-0x17 (-1..-24)
    8638              :             case 0x20:
    8639              :             case 0x21:
    8640              :             case 0x22:
    8641              :             case 0x23:
    8642              :             case 0x24:
    8643              :             case 0x25:
    8644              :             case 0x26:
    8645              :             case 0x27:
    8646              :             case 0x28:
    8647              :             case 0x29:
    8648              :             case 0x2A:
    8649              :             case 0x2B:
    8650              :             case 0x2C:
    8651              :             case 0x2D:
    8652              :             case 0x2E:
    8653              :             case 0x2F:
    8654              :             case 0x30:
    8655              :             case 0x31:
    8656              :             case 0x32:
    8657              :             case 0x33:
    8658              :             case 0x34:
    8659              :             case 0x35:
    8660              :             case 0x36:
    8661              :             case 0x37:
    8662              :                 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
    8663              : 
    8664              :             case 0x38: // Negative integer (one-byte uint8_t follows)
    8665              :             {
    8666              :                 std::uint8_t number{};
    8667              :                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
    8668              :             }
    8669              : 
    8670              :             case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
    8671              :             {
    8672              :                 std::uint16_t number{};
    8673              :                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
    8674              :             }
    8675              : 
    8676              :             case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
    8677              :             {
    8678              :                 std::uint32_t number{};
    8679              :                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
    8680              :             }
    8681              : 
    8682              :             case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
    8683              :             {
    8684              :                 std::uint64_t number{};
    8685              :                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
    8686              :                         - static_cast<number_integer_t>(number));
    8687              :             }
    8688              : 
    8689              :             // Binary data (0x00..0x17 bytes follow)
    8690              :             case 0x40:
    8691              :             case 0x41:
    8692              :             case 0x42:
    8693              :             case 0x43:
    8694              :             case 0x44:
    8695              :             case 0x45:
    8696              :             case 0x46:
    8697              :             case 0x47:
    8698              :             case 0x48:
    8699              :             case 0x49:
    8700              :             case 0x4A:
    8701              :             case 0x4B:
    8702              :             case 0x4C:
    8703              :             case 0x4D:
    8704              :             case 0x4E:
    8705              :             case 0x4F:
    8706              :             case 0x50:
    8707              :             case 0x51:
    8708              :             case 0x52:
    8709              :             case 0x53:
    8710              :             case 0x54:
    8711              :             case 0x55:
    8712              :             case 0x56:
    8713              :             case 0x57:
    8714              :             case 0x58: // Binary data (one-byte uint8_t for n follows)
    8715              :             case 0x59: // Binary data (two-byte uint16_t for n follow)
    8716              :             case 0x5A: // Binary data (four-byte uint32_t for n follow)
    8717              :             case 0x5B: // Binary data (eight-byte uint64_t for n follow)
    8718              :             case 0x5F: // Binary data (indefinite length)
    8719              :             {
    8720              :                 binary_t b;
    8721              :                 return get_cbor_binary(b) && sax->binary(b);
    8722              :             }
    8723              : 
    8724              :             // UTF-8 string (0x00..0x17 bytes follow)
    8725              :             case 0x60:
    8726              :             case 0x61:
    8727              :             case 0x62:
    8728              :             case 0x63:
    8729              :             case 0x64:
    8730              :             case 0x65:
    8731              :             case 0x66:
    8732              :             case 0x67:
    8733              :             case 0x68:
    8734              :             case 0x69:
    8735              :             case 0x6A:
    8736              :             case 0x6B:
    8737              :             case 0x6C:
    8738              :             case 0x6D:
    8739              :             case 0x6E:
    8740              :             case 0x6F:
    8741              :             case 0x70:
    8742              :             case 0x71:
    8743              :             case 0x72:
    8744              :             case 0x73:
    8745              :             case 0x74:
    8746              :             case 0x75:
    8747              :             case 0x76:
    8748              :             case 0x77:
    8749              :             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
    8750              :             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
    8751              :             case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
    8752              :             case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
    8753              :             case 0x7F: // UTF-8 string (indefinite length)
    8754              :             {
    8755              :                 string_t s;
    8756              :                 return get_cbor_string(s) && sax->string(s);
    8757              :             }
    8758              : 
    8759              :             // array (0x00..0x17 data items follow)
    8760              :             case 0x80:
    8761              :             case 0x81:
    8762              :             case 0x82:
    8763              :             case 0x83:
    8764              :             case 0x84:
    8765              :             case 0x85:
    8766              :             case 0x86:
    8767              :             case 0x87:
    8768              :             case 0x88:
    8769              :             case 0x89:
    8770              :             case 0x8A:
    8771              :             case 0x8B:
    8772              :             case 0x8C:
    8773              :             case 0x8D:
    8774              :             case 0x8E:
    8775              :             case 0x8F:
    8776              :             case 0x90:
    8777              :             case 0x91:
    8778              :             case 0x92:
    8779              :             case 0x93:
    8780              :             case 0x94:
    8781              :             case 0x95:
    8782              :             case 0x96:
    8783              :             case 0x97:
    8784              :                 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
    8785              : 
    8786              :             case 0x98: // array (one-byte uint8_t for n follows)
    8787              :             {
    8788              :                 std::uint8_t len{};
    8789              :                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
    8790              :             }
    8791              : 
    8792              :             case 0x99: // array (two-byte uint16_t for n follow)
    8793              :             {
    8794              :                 std::uint16_t len{};
    8795              :                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
    8796              :             }
    8797              : 
    8798              :             case 0x9A: // array (four-byte uint32_t for n follow)
    8799              :             {
    8800              :                 std::uint32_t len{};
    8801              :                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
    8802              :             }
    8803              : 
    8804              :             case 0x9B: // array (eight-byte uint64_t for n follow)
    8805              :             {
    8806              :                 std::uint64_t len{};
    8807              :                 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
    8808              :             }
    8809              : 
    8810              :             case 0x9F: // array (indefinite length)
    8811              :                 return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
    8812              : 
    8813              :             // map (0x00..0x17 pairs of data items follow)
    8814              :             case 0xA0:
    8815              :             case 0xA1:
    8816              :             case 0xA2:
    8817              :             case 0xA3:
    8818              :             case 0xA4:
    8819              :             case 0xA5:
    8820              :             case 0xA6:
    8821              :             case 0xA7:
    8822              :             case 0xA8:
    8823              :             case 0xA9:
    8824              :             case 0xAA:
    8825              :             case 0xAB:
    8826              :             case 0xAC:
    8827              :             case 0xAD:
    8828              :             case 0xAE:
    8829              :             case 0xAF:
    8830              :             case 0xB0:
    8831              :             case 0xB1:
    8832              :             case 0xB2:
    8833              :             case 0xB3:
    8834              :             case 0xB4:
    8835              :             case 0xB5:
    8836              :             case 0xB6:
    8837              :             case 0xB7:
    8838              :                 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
    8839              : 
    8840              :             case 0xB8: // map (one-byte uint8_t for n follows)
    8841              :             {
    8842              :                 std::uint8_t len{};
    8843              :                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
    8844              :             }
    8845              : 
    8846              :             case 0xB9: // map (two-byte uint16_t for n follow)
    8847              :             {
    8848              :                 std::uint16_t len{};
    8849              :                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
    8850              :             }
    8851              : 
    8852              :             case 0xBA: // map (four-byte uint32_t for n follow)
    8853              :             {
    8854              :                 std::uint32_t len{};
    8855              :                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
    8856              :             }
    8857              : 
    8858              :             case 0xBB: // map (eight-byte uint64_t for n follow)
    8859              :             {
    8860              :                 std::uint64_t len{};
    8861              :                 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
    8862              :             }
    8863              : 
    8864              :             case 0xBF: // map (indefinite length)
    8865              :                 return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
    8866              : 
    8867              :             case 0xC6: // tagged item
    8868              :             case 0xC7:
    8869              :             case 0xC8:
    8870              :             case 0xC9:
    8871              :             case 0xCA:
    8872              :             case 0xCB:
    8873              :             case 0xCC:
    8874              :             case 0xCD:
    8875              :             case 0xCE:
    8876              :             case 0xCF:
    8877              :             case 0xD0:
    8878              :             case 0xD1:
    8879              :             case 0xD2:
    8880              :             case 0xD3:
    8881              :             case 0xD4:
    8882              :             case 0xD8: // tagged item (1 bytes follow)
    8883              :             case 0xD9: // tagged item (2 bytes follow)
    8884              :             case 0xDA: // tagged item (4 bytes follow)
    8885              :             case 0xDB: // tagged item (8 bytes follow)
    8886              :             {
    8887              :                 switch (tag_handler)
    8888              :                 {
    8889              :                     case cbor_tag_handler_t::error:
    8890              :                     {
    8891              :                         auto last_token = get_token_string();
    8892              :                         return 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"), BasicJsonType()));
    8893              :                     }
    8894              : 
    8895              :                     case cbor_tag_handler_t::ignore:
    8896              :                     {
    8897              :                         // ignore binary subtype
    8898              :                         switch (current)
    8899              :                         {
    8900              :                             case 0xD8:
    8901              :                             {
    8902              :                                 std::uint8_t subtype_to_ignore{};
    8903              :                                 get_number(input_format_t::cbor, subtype_to_ignore);
    8904              :                                 break;
    8905              :                             }
    8906              :                             case 0xD9:
    8907              :                             {
    8908              :                                 std::uint16_t subtype_to_ignore{};
    8909              :                                 get_number(input_format_t::cbor, subtype_to_ignore);
    8910              :                                 break;
    8911              :                             }
    8912              :                             case 0xDA:
    8913              :                             {
    8914              :                                 std::uint32_t subtype_to_ignore{};
    8915              :                                 get_number(input_format_t::cbor, subtype_to_ignore);
    8916              :                                 break;
    8917              :                             }
    8918              :                             case 0xDB:
    8919              :                             {
    8920              :                                 std::uint64_t subtype_to_ignore{};
    8921              :                                 get_number(input_format_t::cbor, subtype_to_ignore);
    8922              :                                 break;
    8923              :                             }
    8924              :                             default:
    8925              :                                 break;
    8926              :                         }
    8927              :                         return parse_cbor_internal(true, tag_handler);
    8928              :                     }
    8929              : 
    8930              :                     case cbor_tag_handler_t::store:
    8931              :                     {
    8932              :                         binary_t b;
    8933              :                         // use binary subtype and store in binary container
    8934              :                         switch (current)
    8935              :                         {
    8936              :                             case 0xD8:
    8937              :                             {
    8938              :                                 std::uint8_t subtype{};
    8939              :                                 get_number(input_format_t::cbor, subtype);
    8940              :                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
    8941              :                                 break;
    8942              :                             }
    8943              :                             case 0xD9:
    8944              :                             {
    8945              :                                 std::uint16_t subtype{};
    8946              :                                 get_number(input_format_t::cbor, subtype);
    8947              :                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
    8948              :                                 break;
    8949              :                             }
    8950              :                             case 0xDA:
    8951              :                             {
    8952              :                                 std::uint32_t subtype{};
    8953              :                                 get_number(input_format_t::cbor, subtype);
    8954              :                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
    8955              :                                 break;
    8956              :                             }
    8957              :                             case 0xDB:
    8958              :                             {
    8959              :                                 std::uint64_t subtype{};
    8960              :                                 get_number(input_format_t::cbor, subtype);
    8961              :                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
    8962              :                                 break;
    8963              :                             }
    8964              :                             default:
    8965              :                                 return parse_cbor_internal(true, tag_handler);
    8966              :                         }
    8967              :                         get();
    8968              :                         return get_cbor_binary(b) && sax->binary(b);
    8969              :                     }
    8970              : 
    8971              :                     default:                 // LCOV_EXCL_LINE
    8972              :                         JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
    8973              :                         return false;        // LCOV_EXCL_LINE
    8974              :                 }
    8975              :             }
    8976              : 
    8977              :             case 0xF4: // false
    8978              :                 return sax->boolean(false);
    8979              : 
    8980              :             case 0xF5: // true
    8981              :                 return sax->boolean(true);
    8982              : 
    8983              :             case 0xF6: // null
    8984              :                 return sax->null();
    8985              : 
    8986              :             case 0xF9: // Half-Precision Float (two-byte IEEE 754)
    8987              :             {
    8988              :                 const auto byte1_raw = get();
    8989              :                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
    8990              :                 {
    8991              :                     return false;
    8992              :                 }
    8993              :                 const auto byte2_raw = get();
    8994              :                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
    8995              :                 {
    8996              :                     return false;
    8997              :                 }
    8998              : 
    8999              :                 const auto byte1 = static_cast<unsigned char>(byte1_raw);
    9000              :                 const auto byte2 = static_cast<unsigned char>(byte2_raw);
    9001              : 
    9002              :                 // code from RFC 7049, Appendix D, Figure 3:
    9003              :                 // As half-precision floating-point numbers were only added
    9004              :                 // to IEEE 754 in 2008, today's programming platforms often
    9005              :                 // still only have limited support for them. It is very
    9006              :                 // easy to include at least decoding support for them even
    9007              :                 // without such support. An example of a small decoder for
    9008              :                 // half-precision floating-point numbers in the C language
    9009              :                 // is shown in Fig. 3.
    9010              :                 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
    9011              :                 const double val = [&half]
    9012              :                 {
    9013              :                     const int exp = (half >> 10u) & 0x1Fu;
    9014              :                     const unsigned int mant = half & 0x3FFu;
    9015              :                     JSON_ASSERT(0 <= exp&& exp <= 32);
    9016              :                     JSON_ASSERT(mant <= 1024);
    9017              :                     switch (exp)
    9018              :                     {
    9019              :                         case 0:
    9020              :                             return std::ldexp(mant, -24);
    9021              :                         case 31:
    9022              :                             return (mant == 0)
    9023              :                             ? std::numeric_limits<double>::infinity()
    9024              :                             : std::numeric_limits<double>::quiet_NaN();
    9025              :                         default:
    9026              :                             return std::ldexp(mant + 1024, exp - 25);
    9027              :                     }
    9028              :                 }();
    9029              :                 return sax->number_float((half & 0x8000u) != 0
    9030              :                                          ? static_cast<number_float_t>(-val)
    9031              :                                          : static_cast<number_float_t>(val), "");
    9032              :             }
    9033              : 
    9034              :             case 0xFA: // Single-Precision Float (four-byte IEEE 754)
    9035              :             {
    9036              :                 float number{};
    9037              :                 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
    9038              :             }
    9039              : 
    9040              :             case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
    9041              :             {
    9042              :                 double number{};
    9043              :                 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
    9044              :             }
    9045              : 
    9046              :             default: // anything else (0xFF is handled inside the other types)
    9047              :             {
    9048              :                 auto last_token = get_token_string();
    9049              :                 return 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"), BasicJsonType()));
    9050              :             }
    9051              :         }
    9052              :     }
    9053              : 
    9054              :     /*!
    9055              :     @brief reads a CBOR string
    9056              : 
    9057              :     This function first reads starting bytes to determine the expected
    9058              :     string length and then copies this number of bytes into a string.
    9059              :     Additionally, CBOR's strings with indefinite lengths are supported.
    9060              : 
    9061              :     @param[out] result  created string
    9062              : 
    9063              :     @return whether string creation completed
    9064              :     */
    9065              :     bool get_cbor_string(string_t& result)
    9066              :     {
    9067              :         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
    9068              :         {
    9069              :             return false;
    9070              :         }
    9071              : 
    9072              :         switch (current)
    9073              :         {
    9074              :             // UTF-8 string (0x00..0x17 bytes follow)
    9075              :             case 0x60:
    9076              :             case 0x61:
    9077              :             case 0x62:
    9078              :             case 0x63:
    9079              :             case 0x64:
    9080              :             case 0x65:
    9081              :             case 0x66:
    9082              :             case 0x67:
    9083              :             case 0x68:
    9084              :             case 0x69:
    9085              :             case 0x6A:
    9086              :             case 0x6B:
    9087              :             case 0x6C:
    9088              :             case 0x6D:
    9089              :             case 0x6E:
    9090              :             case 0x6F:
    9091              :             case 0x70:
    9092              :             case 0x71:
    9093              :             case 0x72:
    9094              :             case 0x73:
    9095              :             case 0x74:
    9096              :             case 0x75:
    9097              :             case 0x76:
    9098              :             case 0x77:
    9099              :             {
    9100              :                 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
    9101              :             }
    9102              : 
    9103              :             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
    9104              :             {
    9105              :                 std::uint8_t len{};
    9106              :                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
    9107              :             }
    9108              : 
    9109              :             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
    9110              :             {
    9111              :                 std::uint16_t len{};
    9112              :                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
    9113              :             }
    9114              : 
    9115              :             case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
    9116              :             {
    9117              :                 std::uint32_t len{};
    9118              :                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
    9119              :             }
    9120              : 
    9121              :             case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
    9122              :             {
    9123              :                 std::uint64_t len{};
    9124              :                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
    9125              :             }
    9126              : 
    9127              :             case 0x7F: // UTF-8 string (indefinite length)
    9128              :             {
    9129              :                 while (get() != 0xFF)
    9130              :                 {
    9131              :                     string_t chunk;
    9132              :                     if (!get_cbor_string(chunk))
    9133              :                     {
    9134              :                         return false;
    9135              :                     }
    9136              :                     result.append(chunk);
    9137              :                 }
    9138              :                 return true;
    9139              :             }
    9140              : 
    9141              :             default:
    9142              :             {
    9143              :                 auto last_token = get_token_string();
    9144              :                 return 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"), BasicJsonType()));
    9145              :             }
    9146              :         }
    9147              :     }
    9148              : 
    9149              :     /*!
    9150              :     @brief reads a CBOR byte array
    9151              : 
    9152              :     This function first reads starting bytes to determine the expected
    9153              :     byte array length and then copies this number of bytes into the byte array.
    9154              :     Additionally, CBOR's byte arrays with indefinite lengths are supported.
    9155              : 
    9156              :     @param[out] result  created byte array
    9157              : 
    9158              :     @return whether byte array creation completed
    9159              :     */
    9160              :     bool get_cbor_binary(binary_t& result)
    9161              :     {
    9162              :         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
    9163              :         {
    9164              :             return false;
    9165              :         }
    9166              : 
    9167              :         switch (current)
    9168              :         {
    9169              :             // Binary data (0x00..0x17 bytes follow)
    9170              :             case 0x40:
    9171              :             case 0x41:
    9172              :             case 0x42:
    9173              :             case 0x43:
    9174              :             case 0x44:
    9175              :             case 0x45:
    9176              :             case 0x46:
    9177              :             case 0x47:
    9178              :             case 0x48:
    9179              :             case 0x49:
    9180              :             case 0x4A:
    9181              :             case 0x4B:
    9182              :             case 0x4C:
    9183              :             case 0x4D:
    9184              :             case 0x4E:
    9185              :             case 0x4F:
    9186              :             case 0x50:
    9187              :             case 0x51:
    9188              :             case 0x52:
    9189              :             case 0x53:
    9190              :             case 0x54:
    9191              :             case 0x55:
    9192              :             case 0x56:
    9193              :             case 0x57:
    9194              :             {
    9195              :                 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
    9196              :             }
    9197              : 
    9198              :             case 0x58: // Binary data (one-byte uint8_t for n follows)
    9199              :             {
    9200              :                 std::uint8_t len{};
    9201              :                 return get_number(input_format_t::cbor, len) &&
    9202              :                        get_binary(input_format_t::cbor, len, result);
    9203              :             }
    9204              : 
    9205              :             case 0x59: // Binary data (two-byte uint16_t for n follow)
    9206              :             {
    9207              :                 std::uint16_t len{};
    9208              :                 return get_number(input_format_t::cbor, len) &&
    9209              :                        get_binary(input_format_t::cbor, len, result);
    9210              :             }
    9211              : 
    9212              :             case 0x5A: // Binary data (four-byte uint32_t for n follow)
    9213              :             {
    9214              :                 std::uint32_t len{};
    9215              :                 return get_number(input_format_t::cbor, len) &&
    9216              :                        get_binary(input_format_t::cbor, len, result);
    9217              :             }
    9218              : 
    9219              :             case 0x5B: // Binary data (eight-byte uint64_t for n follow)
    9220              :             {
    9221              :                 std::uint64_t len{};
    9222              :                 return get_number(input_format_t::cbor, len) &&
    9223              :                        get_binary(input_format_t::cbor, len, result);
    9224              :             }
    9225              : 
    9226              :             case 0x5F: // Binary data (indefinite length)
    9227              :             {
    9228              :                 while (get() != 0xFF)
    9229              :                 {
    9230              :                     binary_t chunk;
    9231              :                     if (!get_cbor_binary(chunk))
    9232              :                     {
    9233              :                         return false;
    9234              :                     }
    9235              :                     result.insert(result.end(), chunk.begin(), chunk.end());
    9236              :                 }
    9237              :                 return true;
    9238              :             }
    9239              : 
    9240              :             default:
    9241              :             {
    9242              :                 auto last_token = get_token_string();
    9243              :                 return 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"), BasicJsonType()));
    9244              :             }
    9245              :         }
    9246              :     }
    9247              : 
    9248              :     /*!
    9249              :     @param[in] len  the length of the array or static_cast<std::size_t>(-1) for an
    9250              :                     array of indefinite size
    9251              :     @param[in] tag_handler how CBOR tags should be treated
    9252              :     @return whether array creation completed
    9253              :     */
    9254              :     bool get_cbor_array(const std::size_t len,
    9255              :                         const cbor_tag_handler_t tag_handler)
    9256              :     {
    9257              :         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
    9258              :         {
    9259              :             return false;
    9260              :         }
    9261              : 
    9262              :         if (len != static_cast<std::size_t>(-1))
    9263              :         {
    9264              :             for (std::size_t i = 0; i < len; ++i)
    9265              :             {
    9266              :                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
    9267              :                 {
    9268              :                     return false;
    9269              :                 }
    9270              :             }
    9271              :         }
    9272              :         else
    9273              :         {
    9274              :             while (get() != 0xFF)
    9275              :             {
    9276              :                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
    9277              :                 {
    9278              :                     return false;
    9279              :                 }
    9280              :             }
    9281              :         }
    9282              : 
    9283              :         return sax->end_array();
    9284              :     }
    9285              : 
    9286              :     /*!
    9287              :     @param[in] len  the length of the object or static_cast<std::size_t>(-1) for an
    9288              :                     object of indefinite size
    9289              :     @param[in] tag_handler how CBOR tags should be treated
    9290              :     @return whether object creation completed
    9291              :     */
    9292              :     bool get_cbor_object(const std::size_t len,
    9293              :                          const cbor_tag_handler_t tag_handler)
    9294              :     {
    9295              :         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
    9296              :         {
    9297              :             return false;
    9298              :         }
    9299              : 
    9300              :         if (len != 0)
    9301              :         {
    9302              :             string_t key;
    9303              :             if (len != static_cast<std::size_t>(-1))
    9304              :             {
    9305              :                 for (std::size_t i = 0; i < len; ++i)
    9306              :                 {
    9307              :                     get();
    9308              :                     if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
    9309              :                     {
    9310              :                         return false;
    9311              :                     }
    9312              : 
    9313              :                     if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
    9314              :                     {
    9315              :                         return false;
    9316              :                     }
    9317              :                     key.clear();
    9318              :                 }
    9319              :             }
    9320              :             else
    9321              :             {
    9322              :                 while (get() != 0xFF)
    9323              :                 {
    9324              :                     if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
    9325              :                     {
    9326              :                         return false;
    9327              :                     }
    9328              : 
    9329              :                     if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
    9330              :                     {
    9331              :                         return false;
    9332              :                     }
    9333              :                     key.clear();
    9334              :                 }
    9335              :             }
    9336              :         }
    9337              : 
    9338              :         return sax->end_object();
    9339              :     }
    9340              : 
    9341              :     /////////////
    9342              :     // MsgPack //
    9343              :     /////////////
    9344              : 
    9345              :     /*!
    9346              :     @return whether a valid MessagePack value was passed to the SAX parser
    9347              :     */
    9348              :     bool parse_msgpack_internal()
    9349              :     {
    9350              :         switch (get())
    9351              :         {
    9352              :             // EOF
    9353              :             case std::char_traits<char_type>::eof():
    9354              :                 return unexpect_eof(input_format_t::msgpack, "value");
    9355              : 
    9356              :             // positive fixint
    9357              :             case 0x00:
    9358              :             case 0x01:
    9359              :             case 0x02:
    9360              :             case 0x03:
    9361              :             case 0x04:
    9362              :             case 0x05:
    9363              :             case 0x06:
    9364              :             case 0x07:
    9365              :             case 0x08:
    9366              :             case 0x09:
    9367              :             case 0x0A:
    9368              :             case 0x0B:
    9369              :             case 0x0C:
    9370              :             case 0x0D:
    9371              :             case 0x0E:
    9372              :             case 0x0F:
    9373              :             case 0x10:
    9374              :             case 0x11:
    9375              :             case 0x12:
    9376              :             case 0x13:
    9377              :             case 0x14:
    9378              :             case 0x15:
    9379              :             case 0x16:
    9380              :             case 0x17:
    9381              :             case 0x18:
    9382              :             case 0x19:
    9383              :             case 0x1A:
    9384              :             case 0x1B:
    9385              :             case 0x1C:
    9386              :             case 0x1D:
    9387              :             case 0x1E:
    9388              :             case 0x1F:
    9389              :             case 0x20:
    9390              :             case 0x21:
    9391              :             case 0x22:
    9392              :             case 0x23:
    9393              :             case 0x24:
    9394              :             case 0x25:
    9395              :             case 0x26:
    9396              :             case 0x27:
    9397              :             case 0x28:
    9398              :             case 0x29:
    9399              :             case 0x2A:
    9400              :             case 0x2B:
    9401              :             case 0x2C:
    9402              :             case 0x2D:
    9403              :             case 0x2E:
    9404              :             case 0x2F:
    9405              :             case 0x30:
    9406              :             case 0x31:
    9407              :             case 0x32:
    9408              :             case 0x33:
    9409              :             case 0x34:
    9410              :             case 0x35:
    9411              :             case 0x36:
    9412              :             case 0x37:
    9413              :             case 0x38:
    9414              :             case 0x39:
    9415              :             case 0x3A:
    9416              :             case 0x3B:
    9417              :             case 0x3C:
    9418              :             case 0x3D:
    9419              :             case 0x3E:
    9420              :             case 0x3F:
    9421              :             case 0x40:
    9422              :             case 0x41:
    9423              :             case 0x42:
    9424              :             case 0x43:
    9425              :             case 0x44:
    9426              :             case 0x45:
    9427              :             case 0x46:
    9428              :             case 0x47:
    9429              :             case 0x48:
    9430              :             case 0x49:
    9431              :             case 0x4A:
    9432              :             case 0x4B:
    9433              :             case 0x4C:
    9434              :             case 0x4D:
    9435              :             case 0x4E:
    9436              :             case 0x4F:
    9437              :             case 0x50:
    9438              :             case 0x51:
    9439              :             case 0x52:
    9440              :             case 0x53:
    9441              :             case 0x54:
    9442              :             case 0x55:
    9443              :             case 0x56:
    9444              :             case 0x57:
    9445              :             case 0x58:
    9446              :             case 0x59:
    9447              :             case 0x5A:
    9448              :             case 0x5B:
    9449              :             case 0x5C:
    9450              :             case 0x5D:
    9451              :             case 0x5E:
    9452              :             case 0x5F:
    9453              :             case 0x60:
    9454              :             case 0x61:
    9455              :             case 0x62:
    9456              :             case 0x63:
    9457              :             case 0x64:
    9458              :             case 0x65:
    9459              :             case 0x66:
    9460              :             case 0x67:
    9461              :             case 0x68:
    9462              :             case 0x69:
    9463              :             case 0x6A:
    9464              :             case 0x6B:
    9465              :             case 0x6C:
    9466              :             case 0x6D:
    9467              :             case 0x6E:
    9468              :             case 0x6F:
    9469              :             case 0x70:
    9470              :             case 0x71:
    9471              :             case 0x72:
    9472              :             case 0x73:
    9473              :             case 0x74:
    9474              :             case 0x75:
    9475              :             case 0x76:
    9476              :             case 0x77:
    9477              :             case 0x78:
    9478              :             case 0x79:
    9479              :             case 0x7A:
    9480              :             case 0x7B:
    9481              :             case 0x7C:
    9482              :             case 0x7D:
    9483              :             case 0x7E:
    9484              :             case 0x7F:
    9485              :                 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
    9486              : 
    9487              :             // fixmap
    9488              :             case 0x80:
    9489              :             case 0x81:
    9490              :             case 0x82:
    9491              :             case 0x83:
    9492              :             case 0x84:
    9493              :             case 0x85:
    9494              :             case 0x86:
    9495              :             case 0x87:
    9496              :             case 0x88:
    9497              :             case 0x89:
    9498              :             case 0x8A:
    9499              :             case 0x8B:
    9500              :             case 0x8C:
    9501              :             case 0x8D:
    9502              :             case 0x8E:
    9503              :             case 0x8F:
    9504              :                 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
    9505              : 
    9506              :             // fixarray
    9507              :             case 0x90:
    9508              :             case 0x91:
    9509              :             case 0x92:
    9510              :             case 0x93:
    9511              :             case 0x94:
    9512              :             case 0x95:
    9513              :             case 0x96:
    9514              :             case 0x97:
    9515              :             case 0x98:
    9516              :             case 0x99:
    9517              :             case 0x9A:
    9518              :             case 0x9B:
    9519              :             case 0x9C:
    9520              :             case 0x9D:
    9521              :             case 0x9E:
    9522              :             case 0x9F:
    9523              :                 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
    9524              : 
    9525              :             // fixstr
    9526              :             case 0xA0:
    9527              :             case 0xA1:
    9528              :             case 0xA2:
    9529              :             case 0xA3:
    9530              :             case 0xA4:
    9531              :             case 0xA5:
    9532              :             case 0xA6:
    9533              :             case 0xA7:
    9534              :             case 0xA8:
    9535              :             case 0xA9:
    9536              :             case 0xAA:
    9537              :             case 0xAB:
    9538              :             case 0xAC:
    9539              :             case 0xAD:
    9540              :             case 0xAE:
    9541              :             case 0xAF:
    9542              :             case 0xB0:
    9543              :             case 0xB1:
    9544              :             case 0xB2:
    9545              :             case 0xB3:
    9546              :             case 0xB4:
    9547              :             case 0xB5:
    9548              :             case 0xB6:
    9549              :             case 0xB7:
    9550              :             case 0xB8:
    9551              :             case 0xB9:
    9552              :             case 0xBA:
    9553              :             case 0xBB:
    9554              :             case 0xBC:
    9555              :             case 0xBD:
    9556              :             case 0xBE:
    9557              :             case 0xBF:
    9558              :             case 0xD9: // str 8
    9559              :             case 0xDA: // str 16
    9560              :             case 0xDB: // str 32
    9561              :             {
    9562              :                 string_t s;
    9563              :                 return get_msgpack_string(s) && sax->string(s);
    9564              :             }
    9565              : 
    9566              :             case 0xC0: // nil
    9567              :                 return sax->null();
    9568              : 
    9569              :             case 0xC2: // false
    9570              :                 return sax->boolean(false);
    9571              : 
    9572              :             case 0xC3: // true
    9573              :                 return sax->boolean(true);
    9574              : 
    9575              :             case 0xC4: // bin 8
    9576              :             case 0xC5: // bin 16
    9577              :             case 0xC6: // bin 32
    9578              :             case 0xC7: // ext 8
    9579              :             case 0xC8: // ext 16
    9580              :             case 0xC9: // ext 32
    9581              :             case 0xD4: // fixext 1
    9582              :             case 0xD5: // fixext 2
    9583              :             case 0xD6: // fixext 4
    9584              :             case 0xD7: // fixext 8
    9585              :             case 0xD8: // fixext 16
    9586              :             {
    9587              :                 binary_t b;
    9588              :                 return get_msgpack_binary(b) && sax->binary(b);
    9589              :             }
    9590              : 
    9591              :             case 0xCA: // float 32
    9592              :             {
    9593              :                 float number{};
    9594              :                 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
    9595              :             }
    9596              : 
    9597              :             case 0xCB: // float 64
    9598              :             {
    9599              :                 double number{};
    9600              :                 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
    9601              :             }
    9602              : 
    9603              :             case 0xCC: // uint 8
    9604              :             {
    9605              :                 std::uint8_t number{};
    9606              :                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
    9607              :             }
    9608              : 
    9609              :             case 0xCD: // uint 16
    9610              :             {
    9611              :                 std::uint16_t number{};
    9612              :                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
    9613              :             }
    9614              : 
    9615              :             case 0xCE: // uint 32
    9616              :             {
    9617              :                 std::uint32_t number{};
    9618              :                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
    9619              :             }
    9620              : 
    9621              :             case 0xCF: // uint 64
    9622              :             {
    9623              :                 std::uint64_t number{};
    9624              :                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
    9625              :             }
    9626              : 
    9627              :             case 0xD0: // int 8
    9628              :             {
    9629              :                 std::int8_t number{};
    9630              :                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
    9631              :             }
    9632              : 
    9633              :             case 0xD1: // int 16
    9634              :             {
    9635              :                 std::int16_t number{};
    9636              :                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
    9637              :             }
    9638              : 
    9639              :             case 0xD2: // int 32
    9640              :             {
    9641              :                 std::int32_t number{};
    9642              :                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
    9643              :             }
    9644              : 
    9645              :             case 0xD3: // int 64
    9646              :             {
    9647              :                 std::int64_t number{};
    9648              :                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
    9649              :             }
    9650              : 
    9651              :             case 0xDC: // array 16
    9652              :             {
    9653              :                 std::uint16_t len{};
    9654              :                 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
    9655              :             }
    9656              : 
    9657              :             case 0xDD: // array 32
    9658              :             {
    9659              :                 std::uint32_t len{};
    9660              :                 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
    9661              :             }
    9662              : 
    9663              :             case 0xDE: // map 16
    9664              :             {
    9665              :                 std::uint16_t len{};
    9666              :                 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
    9667              :             }
    9668              : 
    9669              :             case 0xDF: // map 32
    9670              :             {
    9671              :                 std::uint32_t len{};
    9672              :                 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
    9673              :             }
    9674              : 
    9675              :             // negative fixint
    9676              :             case 0xE0:
    9677              :             case 0xE1:
    9678              :             case 0xE2:
    9679              :             case 0xE3:
    9680              :             case 0xE4:
    9681              :             case 0xE5:
    9682              :             case 0xE6:
    9683              :             case 0xE7:
    9684              :             case 0xE8:
    9685              :             case 0xE9:
    9686              :             case 0xEA:
    9687              :             case 0xEB:
    9688              :             case 0xEC:
    9689              :             case 0xED:
    9690              :             case 0xEE:
    9691              :             case 0xEF:
    9692              :             case 0xF0:
    9693              :             case 0xF1:
    9694              :             case 0xF2:
    9695              :             case 0xF3:
    9696              :             case 0xF4:
    9697              :             case 0xF5:
    9698              :             case 0xF6:
    9699              :             case 0xF7:
    9700              :             case 0xF8:
    9701              :             case 0xF9:
    9702              :             case 0xFA:
    9703              :             case 0xFB:
    9704              :             case 0xFC:
    9705              :             case 0xFD:
    9706              :             case 0xFE:
    9707              :             case 0xFF:
    9708              :                 return sax->number_integer(static_cast<std::int8_t>(current));
    9709              : 
    9710              :             default: // anything else
    9711              :             {
    9712              :                 auto last_token = get_token_string();
    9713              :                 return 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"), BasicJsonType()));
    9714              :             }
    9715              :         }
    9716              :     }
    9717              : 
    9718              :     /*!
    9719              :     @brief reads a MessagePack string
    9720              : 
    9721              :     This function first reads starting bytes to determine the expected
    9722              :     string length and then copies this number of bytes into a string.
    9723              : 
    9724              :     @param[out] result  created string
    9725              : 
    9726              :     @return whether string creation completed
    9727              :     */
    9728              :     bool get_msgpack_string(string_t& result)
    9729              :     {
    9730              :         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
    9731              :         {
    9732              :             return false;
    9733              :         }
    9734              : 
    9735              :         switch (current)
    9736              :         {
    9737              :             // fixstr
    9738              :             case 0xA0:
    9739              :             case 0xA1:
    9740              :             case 0xA2:
    9741              :             case 0xA3:
    9742              :             case 0xA4:
    9743              :             case 0xA5:
    9744              :             case 0xA6:
    9745              :             case 0xA7:
    9746              :             case 0xA8:
    9747              :             case 0xA9:
    9748              :             case 0xAA:
    9749              :             case 0xAB:
    9750              :             case 0xAC:
    9751              :             case 0xAD:
    9752              :             case 0xAE:
    9753              :             case 0xAF:
    9754              :             case 0xB0:
    9755              :             case 0xB1:
    9756              :             case 0xB2:
    9757              :             case 0xB3:
    9758              :             case 0xB4:
    9759              :             case 0xB5:
    9760              :             case 0xB6:
    9761              :             case 0xB7:
    9762              :             case 0xB8:
    9763              :             case 0xB9:
    9764              :             case 0xBA:
    9765              :             case 0xBB:
    9766              :             case 0xBC:
    9767              :             case 0xBD:
    9768              :             case 0xBE:
    9769              :             case 0xBF:
    9770              :             {
    9771              :                 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
    9772              :             }
    9773              : 
    9774              :             case 0xD9: // str 8
    9775              :             {
    9776              :                 std::uint8_t len{};
    9777              :                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
    9778              :             }
    9779              : 
    9780              :             case 0xDA: // str 16
    9781              :             {
    9782              :                 std::uint16_t len{};
    9783              :                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
    9784              :             }
    9785              : 
    9786              :             case 0xDB: // str 32
    9787              :             {
    9788              :                 std::uint32_t len{};
    9789              :                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
    9790              :             }
    9791              : 
    9792              :             default:
    9793              :             {
    9794              :                 auto last_token = get_token_string();
    9795              :                 return 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"), BasicJsonType()));
    9796              :             }
    9797              :         }
    9798              :     }
    9799              : 
    9800              :     /*!
    9801              :     @brief reads a MessagePack byte array
    9802              : 
    9803              :     This function first reads starting bytes to determine the expected
    9804              :     byte array length and then copies this number of bytes into a byte array.
    9805              : 
    9806              :     @param[out] result  created byte array
    9807              : 
    9808              :     @return whether byte array creation completed
    9809              :     */
    9810              :     bool get_msgpack_binary(binary_t& result)
    9811              :     {
    9812              :         // helper function to set the subtype
    9813              :         auto assign_and_return_true = [&result](std::int8_t subtype)
    9814              :         {
    9815              :             result.set_subtype(static_cast<std::uint8_t>(subtype));
    9816              :             return true;
    9817              :         };
    9818              : 
    9819              :         switch (current)
    9820              :         {
    9821              :             case 0xC4: // bin 8
    9822              :             {
    9823              :                 std::uint8_t len{};
    9824              :                 return get_number(input_format_t::msgpack, len) &&
    9825              :                        get_binary(input_format_t::msgpack, len, result);
    9826              :             }
    9827              : 
    9828              :             case 0xC5: // bin 16
    9829              :             {
    9830              :                 std::uint16_t len{};
    9831              :                 return get_number(input_format_t::msgpack, len) &&
    9832              :                        get_binary(input_format_t::msgpack, len, result);
    9833              :             }
    9834              : 
    9835              :             case 0xC6: // bin 32
    9836              :             {
    9837              :                 std::uint32_t len{};
    9838              :                 return get_number(input_format_t::msgpack, len) &&
    9839              :                        get_binary(input_format_t::msgpack, len, result);
    9840              :             }
    9841              : 
    9842              :             case 0xC7: // ext 8
    9843              :             {
    9844              :                 std::uint8_t len{};
    9845              :                 std::int8_t subtype{};
    9846              :                 return get_number(input_format_t::msgpack, len) &&
    9847              :                        get_number(input_format_t::msgpack, subtype) &&
    9848              :                        get_binary(input_format_t::msgpack, len, result) &&
    9849              :                        assign_and_return_true(subtype);
    9850              :             }
    9851              : 
    9852              :             case 0xC8: // ext 16
    9853              :             {
    9854              :                 std::uint16_t len{};
    9855              :                 std::int8_t subtype{};
    9856              :                 return get_number(input_format_t::msgpack, len) &&
    9857              :                        get_number(input_format_t::msgpack, subtype) &&
    9858              :                        get_binary(input_format_t::msgpack, len, result) &&
    9859              :                        assign_and_return_true(subtype);
    9860              :             }
    9861              : 
    9862              :             case 0xC9: // ext 32
    9863              :             {
    9864              :                 std::uint32_t len{};
    9865              :                 std::int8_t subtype{};
    9866              :                 return get_number(input_format_t::msgpack, len) &&
    9867              :                        get_number(input_format_t::msgpack, subtype) &&
    9868              :                        get_binary(input_format_t::msgpack, len, result) &&
    9869              :                        assign_and_return_true(subtype);
    9870              :             }
    9871              : 
    9872              :             case 0xD4: // fixext 1
    9873              :             {
    9874              :                 std::int8_t subtype{};
    9875              :                 return get_number(input_format_t::msgpack, subtype) &&
    9876              :                        get_binary(input_format_t::msgpack, 1, result) &&
    9877              :                        assign_and_return_true(subtype);
    9878              :             }
    9879              : 
    9880              :             case 0xD5: // fixext 2
    9881              :             {
    9882              :                 std::int8_t subtype{};
    9883              :                 return get_number(input_format_t::msgpack, subtype) &&
    9884              :                        get_binary(input_format_t::msgpack, 2, result) &&
    9885              :                        assign_and_return_true(subtype);
    9886              :             }
    9887              : 
    9888              :             case 0xD6: // fixext 4
    9889              :             {
    9890              :                 std::int8_t subtype{};
    9891              :                 return get_number(input_format_t::msgpack, subtype) &&
    9892              :                        get_binary(input_format_t::msgpack, 4, result) &&
    9893              :                        assign_and_return_true(subtype);
    9894              :             }
    9895              : 
    9896              :             case 0xD7: // fixext 8
    9897              :             {
    9898              :                 std::int8_t subtype{};
    9899              :                 return get_number(input_format_t::msgpack, subtype) &&
    9900              :                        get_binary(input_format_t::msgpack, 8, result) &&
    9901              :                        assign_and_return_true(subtype);
    9902              :             }
    9903              : 
    9904              :             case 0xD8: // fixext 16
    9905              :             {
    9906              :                 std::int8_t subtype{};
    9907              :                 return get_number(input_format_t::msgpack, subtype) &&
    9908              :                        get_binary(input_format_t::msgpack, 16, result) &&
    9909              :                        assign_and_return_true(subtype);
    9910              :             }
    9911              : 
    9912              :             default:           // LCOV_EXCL_LINE
    9913              :                 return false;  // LCOV_EXCL_LINE
    9914              :         }
    9915              :     }
    9916              : 
    9917              :     /*!
    9918              :     @param[in] len  the length of the array
    9919              :     @return whether array creation completed
    9920              :     */
    9921              :     bool get_msgpack_array(const std::size_t len)
    9922              :     {
    9923              :         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
    9924              :         {
    9925              :             return false;
    9926              :         }
    9927              : 
    9928              :         for (std::size_t i = 0; i < len; ++i)
    9929              :         {
    9930              :             if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
    9931              :             {
    9932              :                 return false;
    9933              :             }
    9934              :         }
    9935              : 
    9936              :         return sax->end_array();
    9937              :     }
    9938              : 
    9939              :     /*!
    9940              :     @param[in] len  the length of the object
    9941              :     @return whether object creation completed
    9942              :     */
    9943              :     bool get_msgpack_object(const std::size_t len)
    9944              :     {
    9945              :         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
    9946              :         {
    9947              :             return false;
    9948              :         }
    9949              : 
    9950              :         string_t key;
    9951              :         for (std::size_t i = 0; i < len; ++i)
    9952              :         {
    9953              :             get();
    9954              :             if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
    9955              :             {
    9956              :                 return false;
    9957              :             }
    9958              : 
    9959              :             if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
    9960              :             {
    9961              :                 return false;
    9962              :             }
    9963              :             key.clear();
    9964              :         }
    9965              : 
    9966              :         return sax->end_object();
    9967              :     }
    9968              : 
    9969              :     ////////////
    9970              :     // UBJSON //
    9971              :     ////////////
    9972              : 
    9973              :     /*!
    9974              :     @param[in] get_char  whether a new character should be retrieved from the
    9975              :                          input (true, default) or whether the last read
    9976              :                          character should be considered instead
    9977              : 
    9978              :     @return whether a valid UBJSON value was passed to the SAX parser
    9979              :     */
    9980              :     bool parse_ubjson_internal(const bool get_char = true)
    9981              :     {
    9982              :         return get_ubjson_value(get_char ? get_ignore_noop() : current);
    9983              :     }
    9984              : 
    9985              :     /*!
    9986              :     @brief reads a UBJSON string
    9987              : 
    9988              :     This function is either called after reading the 'S' byte explicitly
    9989              :     indicating a string, or in case of an object key where the 'S' byte can be
    9990              :     left out.
    9991              : 
    9992              :     @param[out] result   created string
    9993              :     @param[in] get_char  whether a new character should be retrieved from the
    9994              :                          input (true, default) or whether the last read
    9995              :                          character should be considered instead
    9996              : 
    9997              :     @return whether string creation completed
    9998              :     */
    9999              :     bool get_ubjson_string(string_t& result, const bool get_char = true)
   10000              :     {
   10001              :         if (get_char)
   10002              :         {
   10003              :             get();  // TODO(niels): may we ignore N here?
   10004              :         }
   10005              : 
   10006              :         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
   10007              :         {
   10008              :             return false;
   10009              :         }
   10010              : 
   10011              :         switch (current)
   10012              :         {
   10013              :             case 'U':
   10014              :             {
   10015              :                 std::uint8_t len{};
   10016              :                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
   10017              :             }
   10018              : 
   10019              :             case 'i':
   10020              :             {
   10021              :                 std::int8_t len{};
   10022              :                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
   10023              :             }
   10024              : 
   10025              :             case 'I':
   10026              :             {
   10027              :                 std::int16_t len{};
   10028              :                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
   10029              :             }
   10030              : 
   10031              :             case 'l':
   10032              :             {
   10033              :                 std::int32_t len{};
   10034              :                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
   10035              :             }
   10036              : 
   10037              :             case 'L':
   10038              :             {
   10039              :                 std::int64_t len{};
   10040              :                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
   10041              :             }
   10042              : 
   10043              :             default:
   10044              :                 auto last_token = get_token_string();
   10045              :                 return 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"), BasicJsonType()));
   10046              :         }
   10047              :     }
   10048              : 
   10049              :     /*!
   10050              :     @param[out] result  determined size
   10051              :     @return whether size determination completed
   10052              :     */
   10053              :     bool get_ubjson_size_value(std::size_t& result)
   10054              :     {
   10055              :         switch (get_ignore_noop())
   10056              :         {
   10057              :             case 'U':
   10058              :             {
   10059              :                 std::uint8_t number{};
   10060              :                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
   10061              :                 {
   10062              :                     return false;
   10063              :                 }
   10064              :                 result = static_cast<std::size_t>(number);
   10065              :                 return true;
   10066              :             }
   10067              : 
   10068              :             case 'i':
   10069              :             {
   10070              :                 std::int8_t number{};
   10071              :                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
   10072              :                 {
   10073              :                     return false;
   10074              :                 }
   10075              :                 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
   10076              :                 return true;
   10077              :             }
   10078              : 
   10079              :             case 'I':
   10080              :             {
   10081              :                 std::int16_t number{};
   10082              :                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
   10083              :                 {
   10084              :                     return false;
   10085              :                 }
   10086              :                 result = static_cast<std::size_t>(number);
   10087              :                 return true;
   10088              :             }
   10089              : 
   10090              :             case 'l':
   10091              :             {
   10092              :                 std::int32_t number{};
   10093              :                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
   10094              :                 {
   10095              :                     return false;
   10096              :                 }
   10097              :                 result = static_cast<std::size_t>(number);
   10098              :                 return true;
   10099              :             }
   10100              : 
   10101              :             case 'L':
   10102              :             {
   10103              :                 std::int64_t number{};
   10104              :                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
   10105              :                 {
   10106              :                     return false;
   10107              :                 }
   10108              :                 result = static_cast<std::size_t>(number);
   10109              :                 return true;
   10110              :             }
   10111              : 
   10112              :             default:
   10113              :             {
   10114              :                 auto last_token = get_token_string();
   10115              :                 return 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"), BasicJsonType()));
   10116              :             }
   10117              :         }
   10118              :     }
   10119              : 
   10120              :     /*!
   10121              :     @brief determine the type and size for a container
   10122              : 
   10123              :     In the optimized UBJSON format, a type and a size can be provided to allow
   10124              :     for a more compact representation.
   10125              : 
   10126              :     @param[out] result  pair of the size and the type
   10127              : 
   10128              :     @return whether pair creation completed
   10129              :     */
   10130              :     bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
   10131              :     {
   10132              :         result.first = string_t::npos; // size
   10133              :         result.second = 0; // type
   10134              : 
   10135              :         get_ignore_noop();
   10136              : 
   10137              :         if (current == '$')
   10138              :         {
   10139              :             result.second = get();  // must not ignore 'N', because 'N' maybe the type
   10140              :             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
   10141              :             {
   10142              :                 return false;
   10143              :             }
   10144              : 
   10145              :             get_ignore_noop();
   10146              :             if (JSON_HEDLEY_UNLIKELY(current != '#'))
   10147              :             {
   10148              :                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
   10149              :                 {
   10150              :                     return false;
   10151              :                 }
   10152              :                 auto last_token = get_token_string();
   10153              :                 return 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"), BasicJsonType()));
   10154              :             }
   10155              : 
   10156              :             return get_ubjson_size_value(result.first);
   10157              :         }
   10158              : 
   10159              :         if (current == '#')
   10160              :         {
   10161              :             return get_ubjson_size_value(result.first);
   10162              :         }
   10163              : 
   10164              :         return true;
   10165              :     }
   10166              : 
   10167              :     /*!
   10168              :     @param prefix  the previously read or set type prefix
   10169              :     @return whether value creation completed
   10170              :     */
   10171              :     bool get_ubjson_value(const char_int_type prefix)
   10172              :     {
   10173              :         switch (prefix)
   10174              :         {
   10175              :             case std::char_traits<char_type>::eof():  // EOF
   10176              :                 return unexpect_eof(input_format_t::ubjson, "value");
   10177              : 
   10178              :             case 'T':  // true
   10179              :                 return sax->boolean(true);
   10180              :             case 'F':  // false
   10181              :                 return sax->boolean(false);
   10182              : 
   10183              :             case 'Z':  // null
   10184              :                 return sax->null();
   10185              : 
   10186              :             case 'U':
   10187              :             {
   10188              :                 std::uint8_t number{};
   10189              :                 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
   10190              :             }
   10191              : 
   10192              :             case 'i':
   10193              :             {
   10194              :                 std::int8_t number{};
   10195              :                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
   10196              :             }
   10197              : 
   10198              :             case 'I':
   10199              :             {
   10200              :                 std::int16_t number{};
   10201              :                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
   10202              :             }
   10203              : 
   10204              :             case 'l':
   10205              :             {
   10206              :                 std::int32_t number{};
   10207              :                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
   10208              :             }
   10209              : 
   10210              :             case 'L':
   10211              :             {
   10212              :                 std::int64_t number{};
   10213              :                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
   10214              :             }
   10215              : 
   10216              :             case 'd':
   10217              :             {
   10218              :                 float number{};
   10219              :                 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
   10220              :             }
   10221              : 
   10222              :             case 'D':
   10223              :             {
   10224              :                 double number{};
   10225              :                 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
   10226              :             }
   10227              : 
   10228              :             case 'H':
   10229              :             {
   10230              :                 return get_ubjson_high_precision_number();
   10231              :             }
   10232              : 
   10233              :             case 'C':  // char
   10234              :             {
   10235              :                 get();
   10236              :                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
   10237              :                 {
   10238              :                     return false;
   10239              :                 }
   10240              :                 if (JSON_HEDLEY_UNLIKELY(current > 127))
   10241              :                 {
   10242              :                     auto last_token = get_token_string();
   10243              :                     return 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"), BasicJsonType()));
   10244              :                 }
   10245              :                 string_t s(1, static_cast<typename string_t::value_type>(current));
   10246              :                 return sax->string(s);
   10247              :             }
   10248              : 
   10249              :             case 'S':  // string
   10250              :             {
   10251              :                 string_t s;
   10252              :                 return get_ubjson_string(s) && sax->string(s);
   10253              :             }
   10254              : 
   10255              :             case '[':  // array
   10256              :                 return get_ubjson_array();
   10257              : 
   10258              :             case '{':  // object
   10259              :                 return get_ubjson_object();
   10260              : 
   10261              :             default: // anything else
   10262              :             {
   10263              :                 auto last_token = get_token_string();
   10264              :                 return 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"), BasicJsonType()));
   10265              :             }
   10266              :         }
   10267              :     }
   10268              : 
   10269              :     /*!
   10270              :     @return whether array creation completed
   10271              :     */
   10272              :     bool get_ubjson_array()
   10273              :     {
   10274              :         std::pair<std::size_t, char_int_type> size_and_type;
   10275              :         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
   10276              :         {
   10277              :             return false;
   10278              :         }
   10279              : 
   10280              :         if (size_and_type.first != string_t::npos)
   10281              :         {
   10282              :             if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
   10283              :             {
   10284              :                 return false;
   10285              :             }
   10286              : 
   10287              :             if (size_and_type.second != 0)
   10288              :             {
   10289              :                 if (size_and_type.second != 'N')
   10290              :                 {
   10291              :                     for (std::size_t i = 0; i < size_and_type.first; ++i)
   10292              :                     {
   10293              :                         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
   10294              :                         {
   10295              :                             return false;
   10296              :                         }
   10297              :                     }
   10298              :                 }
   10299              :             }
   10300              :             else
   10301              :             {
   10302              :                 for (std::size_t i = 0; i < size_and_type.first; ++i)
   10303              :                 {
   10304              :                     if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
   10305              :                     {
   10306              :                         return false;
   10307              :                     }
   10308              :                 }
   10309              :             }
   10310              :         }
   10311              :         else
   10312              :         {
   10313              :             if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
   10314              :             {
   10315              :                 return false;
   10316              :             }
   10317              : 
   10318              :             while (current != ']')
   10319              :             {
   10320              :                 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
   10321              :                 {
   10322              :                     return false;
   10323              :                 }
   10324              :                 get_ignore_noop();
   10325              :             }
   10326              :         }
   10327              : 
   10328              :         return sax->end_array();
   10329              :     }
   10330              : 
   10331              :     /*!
   10332              :     @return whether object creation completed
   10333              :     */
   10334              :     bool get_ubjson_object()
   10335              :     {
   10336              :         std::pair<std::size_t, char_int_type> size_and_type;
   10337              :         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
   10338              :         {
   10339              :             return false;
   10340              :         }
   10341              : 
   10342              :         string_t key;
   10343              :         if (size_and_type.first != string_t::npos)
   10344              :         {
   10345              :             if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
   10346              :             {
   10347              :                 return false;
   10348              :             }
   10349              : 
   10350              :             if (size_and_type.second != 0)
   10351              :             {
   10352              :                 for (std::size_t i = 0; i < size_and_type.first; ++i)
   10353              :                 {
   10354              :                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
   10355              :                     {
   10356              :                         return false;
   10357              :                     }
   10358              :                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
   10359              :                     {
   10360              :                         return false;
   10361              :                     }
   10362              :                     key.clear();
   10363              :                 }
   10364              :             }
   10365              :             else
   10366              :             {
   10367              :                 for (std::size_t i = 0; i < size_and_type.first; ++i)
   10368              :                 {
   10369              :                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
   10370              :                     {
   10371              :                         return false;
   10372              :                     }
   10373              :                     if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
   10374              :                     {
   10375              :                         return false;
   10376              :                     }
   10377              :                     key.clear();
   10378              :                 }
   10379              :             }
   10380              :         }
   10381              :         else
   10382              :         {
   10383              :             if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
   10384              :             {
   10385              :                 return false;
   10386              :             }
   10387              : 
   10388              :             while (current != '}')
   10389              :             {
   10390              :                 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
   10391              :                 {
   10392              :                     return false;
   10393              :                 }
   10394              :                 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
   10395              :                 {
   10396              :                     return false;
   10397              :                 }
   10398              :                 get_ignore_noop();
   10399              :                 key.clear();
   10400              :             }
   10401              :         }
   10402              : 
   10403              :         return sax->end_object();
   10404              :     }
   10405              : 
   10406              :     // Note, no reader for UBJSON binary types is implemented because they do
   10407              :     // not exist
   10408              : 
   10409              :     bool get_ubjson_high_precision_number()
   10410              :     {
   10411              :         // get size of following number string
   10412              :         std::size_t size{};
   10413              :         auto res = get_ubjson_size_value(size);
   10414              :         if (JSON_HEDLEY_UNLIKELY(!res))
   10415              :         {
   10416              :             return res;
   10417              :         }
   10418              : 
   10419              :         // get number string
   10420              :         std::vector<char> number_vector;
   10421              :         for (std::size_t i = 0; i < size; ++i)
   10422              :         {
   10423              :             get();
   10424              :             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
   10425              :             {
   10426              :                 return false;
   10427              :             }
   10428              :             number_vector.push_back(static_cast<char>(current));
   10429              :         }
   10430              : 
   10431              :         // parse number string
   10432              :         using ia_type = decltype(detail::input_adapter(number_vector));
   10433              :         auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
   10434              :         const auto result_number = number_lexer.scan();
   10435              :         const auto number_string = number_lexer.get_token_string();
   10436              :         const auto result_remainder = number_lexer.scan();
   10437              : 
   10438              :         using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
   10439              : 
   10440              :         if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
   10441              :         {
   10442              :             return 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"), BasicJsonType()));
   10443              :         }
   10444              : 
   10445              :         switch (result_number)
   10446              :         {
   10447              :             case token_type::value_integer:
   10448              :                 return sax->number_integer(number_lexer.get_number_integer());
   10449              :             case token_type::value_unsigned:
   10450              :                 return sax->number_unsigned(number_lexer.get_number_unsigned());
   10451              :             case token_type::value_float:
   10452              :                 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
   10453              :             case token_type::uninitialized:
   10454              :             case token_type::literal_true:
   10455              :             case token_type::literal_false:
   10456              :             case token_type::literal_null:
   10457              :             case token_type::value_string:
   10458              :             case token_type::begin_array:
   10459              :             case token_type::begin_object:
   10460              :             case token_type::end_array:
   10461              :             case token_type::end_object:
   10462              :             case token_type::name_separator:
   10463              :             case token_type::value_separator:
   10464              :             case token_type::parse_error:
   10465              :             case token_type::end_of_input:
   10466              :             case token_type::literal_or_value:
   10467              :             default:
   10468              :                 return 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"), BasicJsonType()));
   10469              :         }
   10470              :     }
   10471              : 
   10472              :     ///////////////////////
   10473              :     // Utility functions //
   10474              :     ///////////////////////
   10475              : 
   10476              :     /*!
   10477              :     @brief get next character from the input
   10478              : 
   10479              :     This function provides the interface to the used input adapter. It does
   10480              :     not throw in case the input reached EOF, but returns a -'ve valued
   10481              :     `std::char_traits<char_type>::eof()` in that case.
   10482              : 
   10483              :     @return character read from the input
   10484              :     */
   10485              :     char_int_type get()
   10486              :     {
   10487              :         ++chars_read;
   10488              :         return current = ia.get_character();
   10489              :     }
   10490              : 
   10491              :     /*!
   10492              :     @return character read from the input after ignoring all 'N' entries
   10493              :     */
   10494              :     char_int_type get_ignore_noop()
   10495              :     {
   10496              :         do
   10497              :         {
   10498              :             get();
   10499              :         }
   10500              :         while (current == 'N');
   10501              : 
   10502              :         return current;
   10503              :     }
   10504              : 
   10505              :     /*
   10506              :     @brief read a number from the input
   10507              : 
   10508              :     @tparam NumberType the type of the number
   10509              :     @param[in] format   the current format (for diagnostics)
   10510              :     @param[out] result  number of type @a NumberType
   10511              : 
   10512              :     @return whether conversion completed
   10513              : 
   10514              :     @note This function needs to respect the system's endianness, because
   10515              :           bytes in CBOR, MessagePack, and UBJSON are stored in network order
   10516              :           (big endian) and therefore need reordering on little endian systems.
   10517              :     */
   10518              :     template<typename NumberType, bool InputIsLittleEndian = false>
   10519              :     bool get_number(const input_format_t format, NumberType& result)
   10520              :     {
   10521              :         // step 1: read input into array with system's byte order
   10522              :         std::array<std::uint8_t, sizeof(NumberType)> vec{};
   10523              :         for (std::size_t i = 0; i < sizeof(NumberType); ++i)
   10524              :         {
   10525              :             get();
   10526              :             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
   10527              :             {
   10528              :                 return false;
   10529              :             }
   10530              : 
   10531              :             // reverse byte order prior to conversion if necessary
   10532              :             if (is_little_endian != InputIsLittleEndian)
   10533              :             {
   10534              :                 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
   10535              :             }
   10536              :             else
   10537              :             {
   10538              :                 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
   10539              :             }
   10540              :         }
   10541              : 
   10542              :         // step 2: convert array into number of type T and return
   10543              :         std::memcpy(&result, vec.data(), sizeof(NumberType));
   10544              :         return true;
   10545              :     }
   10546              : 
   10547              :     /*!
   10548              :     @brief create a string by reading characters from the input
   10549              : 
   10550              :     @tparam NumberType the type of the number
   10551              :     @param[in] format the current format (for diagnostics)
   10552              :     @param[in] len number of characters to read
   10553              :     @param[out] result string created by reading @a len bytes
   10554              : 
   10555              :     @return whether string creation completed
   10556              : 
   10557              :     @note We can not reserve @a len bytes for the result, because @a len
   10558              :           may be too large. Usually, @ref unexpect_eof() detects the end of
   10559              :           the input before we run out of string memory.
   10560              :     */
   10561              :     template<typename NumberType>
   10562              :     bool get_string(const input_format_t format,
   10563              :                     const NumberType len,
   10564              :                     string_t& result)
   10565              :     {
   10566              :         bool success = true;
   10567              :         for (NumberType i = 0; i < len; i++)
   10568              :         {
   10569              :             get();
   10570              :             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
   10571              :             {
   10572              :                 success = false;
   10573              :                 break;
   10574              :             }
   10575              :             result.push_back(static_cast<typename string_t::value_type>(current));
   10576              :         }
   10577              :         return success;
   10578              :     }
   10579              : 
   10580              :     /*!
   10581              :     @brief create a byte array by reading bytes from the input
   10582              : 
   10583              :     @tparam NumberType the type of the number
   10584              :     @param[in] format the current format (for diagnostics)
   10585              :     @param[in] len number of bytes to read
   10586              :     @param[out] result byte array created by reading @a len bytes
   10587              : 
   10588              :     @return whether byte array creation completed
   10589              : 
   10590              :     @note We can not reserve @a len bytes for the result, because @a len
   10591              :           may be too large. Usually, @ref unexpect_eof() detects the end of
   10592              :           the input before we run out of memory.
   10593              :     */
   10594              :     template<typename NumberType>
   10595              :     bool get_binary(const input_format_t format,
   10596              :                     const NumberType len,
   10597              :                     binary_t& result)
   10598              :     {
   10599              :         bool success = true;
   10600              :         for (NumberType i = 0; i < len; i++)
   10601              :         {
   10602              :             get();
   10603              :             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
   10604              :             {
   10605              :                 success = false;
   10606              :                 break;
   10607              :             }
   10608              :             result.push_back(static_cast<std::uint8_t>(current));
   10609              :         }
   10610              :         return success;
   10611              :     }
   10612              : 
   10613              :     /*!
   10614              :     @param[in] format   the current format (for diagnostics)
   10615              :     @param[in] context  further context information (for diagnostics)
   10616              :     @return whether the last read character is not EOF
   10617              :     */
   10618              :     JSON_HEDLEY_NON_NULL(3)
   10619              :     bool unexpect_eof(const input_format_t format, const char* context) const
   10620              :     {
   10621              :         if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
   10622              :         {
   10623              :             return sax->parse_error(chars_read, "<end of file>",
   10624              :                                     parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
   10625              :         }
   10626              :         return true;
   10627              :     }
   10628              : 
   10629              :     /*!
   10630              :     @return a string representation of the last read byte
   10631              :     */
   10632              :     std::string get_token_string() const
   10633              :     {
   10634              :         std::array<char, 3> cr{{}};
   10635              :         static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
   10636              :         return std::string{cr.data()};
   10637              :     }
   10638              : 
   10639              :     /*!
   10640              :     @param[in] format   the current format
   10641              :     @param[in] detail   a detailed error message
   10642              :     @param[in] context  further context information
   10643              :     @return a message string to use in the parse_error exceptions
   10644              :     */
   10645              :     std::string exception_message(const input_format_t format,
   10646              :                                   const std::string& detail,
   10647              :                                   const std::string& context) const
   10648              :     {
   10649              :         std::string error_msg = "syntax error while parsing ";
   10650              : 
   10651              :         switch (format)
   10652              :         {
   10653              :             case input_format_t::cbor:
   10654              :                 error_msg += "CBOR";
   10655              :                 break;
   10656              : 
   10657              :             case input_format_t::msgpack:
   10658              :                 error_msg += "MessagePack";
   10659              :                 break;
   10660              : 
   10661              :             case input_format_t::ubjson:
   10662              :                 error_msg += "UBJSON";
   10663              :                 break;
   10664              : 
   10665              :             case input_format_t::bson:
   10666              :                 error_msg += "BSON";
   10667              :                 break;
   10668              : 
   10669              :             case input_format_t::json: // LCOV_EXCL_LINE
   10670              :             default:            // LCOV_EXCL_LINE
   10671              :                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
   10672              :         }
   10673              : 
   10674              :         return error_msg + " " + context + ": " + detail;
   10675              :     }
   10676              : 
   10677              :   private:
   10678              :     /// input adapter
   10679              :     InputAdapterType ia;
   10680              : 
   10681              :     /// the current character
   10682              :     char_int_type current = std::char_traits<char_type>::eof();
   10683              : 
   10684              :     /// the number of characters read
   10685              :     std::size_t chars_read = 0;
   10686              : 
   10687              :     /// whether we can assume little endianness
   10688              :     const bool is_little_endian = little_endianness();
   10689              : 
   10690              :     /// the SAX parser
   10691              :     json_sax_t* sax = nullptr;
   10692              : };
   10693              : }  // namespace detail
   10694              : }  // namespace nlohmann
   10695              : 
   10696              : // #include <nlohmann/detail/input/input_adapters.hpp>
   10697              : 
   10698              : // #include <nlohmann/detail/input/lexer.hpp>
   10699              : 
   10700              : // #include <nlohmann/detail/input/parser.hpp>
   10701              : 
   10702              : 
   10703              : #include <cmath> // isfinite
   10704              : #include <cstdint> // uint8_t
   10705              : #include <functional> // function
   10706              : #include <string> // string
   10707              : #include <utility> // move
   10708              : #include <vector> // vector
   10709              : 
   10710              : // #include <nlohmann/detail/exceptions.hpp>
   10711              : 
   10712              : // #include <nlohmann/detail/input/input_adapters.hpp>
   10713              : 
   10714              : // #include <nlohmann/detail/input/json_sax.hpp>
   10715              : 
   10716              : // #include <nlohmann/detail/input/lexer.hpp>
   10717              : 
   10718              : // #include <nlohmann/detail/macro_scope.hpp>
   10719              : 
   10720              : // #include <nlohmann/detail/meta/is_sax.hpp>
   10721              : 
   10722              : // #include <nlohmann/detail/value_t.hpp>
   10723              : 
   10724              : 
   10725              : namespace nlohmann
   10726              : {
   10727              : namespace detail
   10728              : {
   10729              : ////////////
   10730              : // parser //
   10731              : ////////////
   10732              : 
   10733              : enum class parse_event_t : std::uint8_t
   10734              : {
   10735              :     /// the parser read `{` and started to process a JSON object
   10736              :     object_start,
   10737              :     /// the parser read `}` and finished processing a JSON object
   10738              :     object_end,
   10739              :     /// the parser read `[` and started to process a JSON array
   10740              :     array_start,
   10741              :     /// the parser read `]` and finished processing a JSON array
   10742              :     array_end,
   10743              :     /// the parser read a key of a value in an object
   10744              :     key,
   10745              :     /// the parser finished reading a JSON value
   10746              :     value
   10747              : };
   10748              : 
   10749              : template<typename BasicJsonType>
   10750              : using parser_callback_t =
   10751              :     std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
   10752              : 
   10753              : /*!
   10754              : @brief syntax analysis
   10755              : 
   10756              : This class implements a recursive descent parser.
   10757              : */
   10758              : template<typename BasicJsonType, typename InputAdapterType>
   10759              : class parser
   10760              : {
   10761              :     using number_integer_t = typename BasicJsonType::number_integer_t;
   10762              :     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
   10763              :     using number_float_t = typename BasicJsonType::number_float_t;
   10764              :     using string_t = typename BasicJsonType::string_t;
   10765              :     using lexer_t = lexer<BasicJsonType, InputAdapterType>;
   10766              :     using token_type = typename lexer_t::token_type;
   10767              : 
   10768              :   public:
   10769              :     /// a parser reading from an input adapter
   10770           33 :     explicit parser(InputAdapterType&& adapter,
   10771              :                     const parser_callback_t<BasicJsonType> cb = nullptr,
   10772              :                     const bool allow_exceptions_ = true,
   10773              :                     const bool skip_comments = false)
   10774           33 :         : callback(cb)
   10775           33 :         , m_lexer(std::move(adapter), skip_comments)
   10776           33 :         , allow_exceptions(allow_exceptions_)
   10777              :     {
   10778              :         // read first token
   10779              :         get_token();
   10780            0 :     }
   10781              : 
   10782              :     /*!
   10783              :     @brief public parser interface
   10784              : 
   10785              :     @param[in] strict      whether to expect the last token to be EOF
   10786              :     @param[in,out] result  parsed JSON value
   10787              : 
   10788              :     @throw parse_error.101 in case of an unexpected token
   10789              :     @throw parse_error.102 if to_unicode fails or surrogate error
   10790              :     @throw parse_error.103 if to_unicode fails
   10791              :     */
   10792           33 :     void parse(const bool strict, BasicJsonType& result)
   10793              :     {
   10794           33 :         if (callback)
   10795              :         {
   10796            0 :             json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
   10797            0 :             sax_parse_internal(&sdp);
   10798              : 
   10799              :             // in strict mode, input must be completely read
   10800            0 :             if (strict && (get_token() != token_type::end_of_input))
   10801              :             {
   10802            0 :                 sdp.parse_error(m_lexer.get_position(),
   10803              :                                 m_lexer.get_token_string(),
   10804            0 :                                 parse_error::create(101, m_lexer.get_position(),
   10805            0 :                                                     exception_message(token_type::end_of_input, "value"), BasicJsonType()));
   10806              :             }
   10807              : 
   10808              :             // in case of an error, return discarded value
   10809            0 :             if (sdp.is_errored())
   10810              :             {
   10811            0 :                 result = value_t::discarded;
   10812              :                 return;
   10813              :             }
   10814              : 
   10815              :             // set top-level value to null if it was discarded by the callback
   10816              :             // function
   10817            0 :             if (result.is_discarded())
   10818              :             {
   10819            0 :                 result = nullptr;
   10820              :             }
   10821            0 :         }
   10822              :         else
   10823              :         {
   10824           33 :             json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
   10825           33 :             sax_parse_internal(&sdp);
   10826              : 
   10827              :             // in strict mode, input must be completely read
   10828           33 :             if (strict && (get_token() != token_type::end_of_input))
   10829              :             {
   10830            0 :                 sdp.parse_error(m_lexer.get_position(),
   10831              :                                 m_lexer.get_token_string(),
   10832            0 :                                 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
   10833              :             }
   10834              : 
   10835              :             // in case of an error, return discarded value
   10836           33 :             if (sdp.is_errored())
   10837              :             {
   10838            0 :                 result = value_t::discarded;
   10839              :                 return;
   10840              :             }
   10841              :         }
   10842              : 
   10843              :         result.assert_invariant();
   10844              :     }
   10845              : 
   10846              :     /*!
   10847              :     @brief public accept interface
   10848              : 
   10849              :     @param[in] strict  whether to expect the last token to be EOF
   10850              :     @return whether the input is a proper JSON text
   10851              :     */
   10852              :     bool accept(const bool strict = true)
   10853              :     {
   10854              :         json_sax_acceptor<BasicJsonType> sax_acceptor;
   10855              :         return sax_parse(&sax_acceptor, strict);
   10856              :     }
   10857              : 
   10858              :     template<typename SAX>
   10859              :     JSON_HEDLEY_NON_NULL(2)
   10860              :     bool sax_parse(SAX* sax, const bool strict = true)
   10861              :     {
   10862              :         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
   10863              :         const bool result = sax_parse_internal(sax);
   10864              : 
   10865              :         // strict mode: next byte must be EOF
   10866              :         if (result && strict && (get_token() != token_type::end_of_input))
   10867              :         {
   10868              :             return sax->parse_error(m_lexer.get_position(),
   10869              :                                     m_lexer.get_token_string(),
   10870              :                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
   10871              :         }
   10872              : 
   10873              :         return result;
   10874              :     }
   10875              : 
   10876              :   private:
   10877              :     template<typename SAX>
   10878              :     JSON_HEDLEY_NON_NULL(2)
   10879           33 :     bool sax_parse_internal(SAX* sax)
   10880              :     {
   10881              :         // stack to remember the hierarchy of structured values we are parsing
   10882              :         // true = array; false = object
   10883              :         std::vector<bool> states;
   10884              :         // value to avoid a goto (see comment where set to true)
   10885              :         bool skip_to_state_evaluation = false;
   10886              : 
   10887              :         while (true)
   10888              :         {
   10889         7003 :             if (!skip_to_state_evaluation)
   10890              :             {
   10891              :                 // invariant: get_token() was called before each iteration
   10892         5803 :                 switch (last_token)
   10893              :                 {
   10894          585 :                     case token_type::begin_object:
   10895              :                     {
   10896          585 :                         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
   10897              :                         {
   10898              :                             return false;
   10899              :                         }
   10900              : 
   10901              :                         // closing } -> we are done
   10902          585 :                         if (get_token() == token_type::end_object)
   10903              :                         {
   10904            0 :                             if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
   10905              :                             {
   10906              :                                 return false;
   10907              :                             }
   10908              :                             break;
   10909              :                         }
   10910              : 
   10911              :                         // parse key
   10912          585 :                         if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
   10913              :                         {
   10914            0 :                             return sax->parse_error(m_lexer.get_position(),
   10915              :                                                     m_lexer.get_token_string(),
   10916            0 :                                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
   10917              :                         }
   10918            0 :                         if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
   10919              :                         {
   10920              :                             return false;
   10921              :                         }
   10922              : 
   10923              :                         // parse separator (:)
   10924          585 :                         if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
   10925              :                         {
   10926            0 :                             return sax->parse_error(m_lexer.get_position(),
   10927              :                                                     m_lexer.get_token_string(),
   10928            0 :                                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
   10929              :                         }
   10930              : 
   10931              :                         // remember we are now inside an object
   10932          585 :                         states.push_back(false);
   10933              : 
   10934              :                         // parse values
   10935              :                         get_token();
   10936          585 :                         continue;
   10937              :                     }
   10938              : 
   10939          615 :                     case token_type::begin_array:
   10940              :                     {
   10941          615 :                         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
   10942              :                         {
   10943              :                             return false;
   10944              :                         }
   10945              : 
   10946              :                         // closing ] -> we are done
   10947          615 :                         if (get_token() == token_type::end_array)
   10948              :                         {
   10949            0 :                             if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
   10950              :                             {
   10951              :                                 return false;
   10952              :                             }
   10953              :                             break;
   10954              :                         }
   10955              : 
   10956              :                         // remember we are now inside an array
   10957          615 :                         states.push_back(true);
   10958              : 
   10959              :                         // parse values (no need to call get_token)
   10960          615 :                         continue;
   10961              :                     }
   10962              : 
   10963         4248 :                     case token_type::value_float:
   10964              :                     {
   10965              :                         const auto res = m_lexer.get_number_float();
   10966              : 
   10967         4248 :                         if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
   10968              :                         {
   10969            0 :                             return sax->parse_error(m_lexer.get_position(),
   10970              :                                                     m_lexer.get_token_string(),
   10971            0 :                                                     out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
   10972              :                         }
   10973              : 
   10974         4248 :                         if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
   10975              :                         {
   10976              :                             return false;
   10977              :                         }
   10978              : 
   10979              :                         break;
   10980              :                     }
   10981              : 
   10982            0 :                     case token_type::literal_false:
   10983              :                     {
   10984            0 :                         if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
   10985              :                         {
   10986              :                             return false;
   10987              :                         }
   10988              :                         break;
   10989              :                     }
   10990              : 
   10991              :                     case token_type::literal_null:
   10992              :                     {
   10993              :                         if (JSON_HEDLEY_UNLIKELY(!sax->null()))
   10994              :                         {
   10995              :                             return false;
   10996              :                         }
   10997              :                         break;
   10998              :                     }
   10999              : 
   11000            0 :                     case token_type::literal_true:
   11001              :                     {
   11002            0 :                         if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
   11003              :                         {
   11004              :                             return false;
   11005              :                         }
   11006              :                         break;
   11007              :                     }
   11008              : 
   11009            8 :                     case token_type::value_integer:
   11010              :                     {
   11011            8 :                         if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
   11012              :                         {
   11013              :                             return false;
   11014              :                         }
   11015              :                         break;
   11016              :                     }
   11017              : 
   11018          147 :                     case token_type::value_string:
   11019              :                     {
   11020              :                         if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
   11021              :                         {
   11022              :                             return false;
   11023              :                         }
   11024              :                         break;
   11025              :                     }
   11026              : 
   11027          200 :                     case token_type::value_unsigned:
   11028              :                     {
   11029          200 :                         if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
   11030              :                         {
   11031              :                             return false;
   11032              :                         }
   11033              :                         break;
   11034              :                     }
   11035              : 
   11036            0 :                     case token_type::parse_error:
   11037              :                     {
   11038              :                         // using "uninitialized" to avoid "expected" message
   11039            0 :                         return sax->parse_error(m_lexer.get_position(),
   11040              :                                                 m_lexer.get_token_string(),
   11041            0 :                                                 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
   11042              :                     }
   11043              : 
   11044            0 :                     case token_type::uninitialized:
   11045              :                     case token_type::end_array:
   11046              :                     case token_type::end_object:
   11047              :                     case token_type::name_separator:
   11048              :                     case token_type::value_separator:
   11049              :                     case token_type::end_of_input:
   11050              :                     case token_type::literal_or_value:
   11051              :                     default: // the last token was unexpected
   11052              :                     {
   11053            0 :                         return sax->parse_error(m_lexer.get_position(),
   11054              :                                                 m_lexer.get_token_string(),
   11055            0 :                                                 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
   11056              :                     }
   11057          615 :                 }
   11058              :             }
   11059              :             else
   11060              :             {
   11061              :                 skip_to_state_evaluation = false;
   11062              :             }
   11063              : 
   11064              :             // we reached this line after we successfully parsed a value
   11065              :             if (states.empty())
   11066              :             {
   11067              :                 // empty stack: we reached the end of the hierarchy: done
   11068              :                 return true;
   11069              :             }
   11070              : 
   11071         5770 :             if (states.back())  // array
   11072              :             {
   11073              :                 // comma -> next value
   11074         7013 :                 if (get_token() == token_type::value_separator)
   11075              :                 {
   11076              :                     // parse a new value
   11077              :                     get_token();
   11078         3199 :                     continue;
   11079              :                 }
   11080              : 
   11081              :                 // closing ]
   11082          615 :                 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
   11083              :                 {
   11084            0 :                     if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
   11085              :                     {
   11086              :                         return false;
   11087              :                     }
   11088              : 
   11089              :                     // We are done with this array. Before we can parse a
   11090              :                     // new value, we need to evaluate the new state first.
   11091              :                     // By setting skip_to_state_evaluation to false, we
   11092              :                     // are effectively jumping to the beginning of this if.
   11093              :                     JSON_ASSERT(!states.empty());
   11094              :                     states.pop_back();
   11095              :                     skip_to_state_evaluation = true;
   11096          615 :                     continue;
   11097              :                 }
   11098              : 
   11099            0 :                 return sax->parse_error(m_lexer.get_position(),
   11100              :                                         m_lexer.get_token_string(),
   11101            0 :                                         parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
   11102              :             }
   11103              : 
   11104              :             // states.back() is false -> object
   11105              : 
   11106              :             // comma -> next value
   11107         3327 :             if (get_token() == token_type::value_separator)
   11108              :             {
   11109              :                 // parse key
   11110         1371 :                 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
   11111              :                 {
   11112            0 :                     return sax->parse_error(m_lexer.get_position(),
   11113              :                                             m_lexer.get_token_string(),
   11114            0 :                                             parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
   11115              :                 }
   11116              : 
   11117            0 :                 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
   11118              :                 {
   11119              :                     return false;
   11120              :                 }
   11121              : 
   11122              :                 // parse separator (:)
   11123         1371 :                 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
   11124              :                 {
   11125            0 :                     return sax->parse_error(m_lexer.get_position(),
   11126              :                                             m_lexer.get_token_string(),
   11127            0 :                                             parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
   11128              :                 }
   11129              : 
   11130              :                 // parse values
   11131              :                 get_token();
   11132         1371 :                 continue;
   11133              :             }
   11134              : 
   11135              :             // closing }
   11136          585 :             if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
   11137              :             {
   11138            0 :                 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
   11139              :                 {
   11140              :                     return false;
   11141              :                 }
   11142              : 
   11143              :                 // We are done with this object. Before we can parse a
   11144              :                 // new value, we need to evaluate the new state first.
   11145              :                 // By setting skip_to_state_evaluation to false, we
   11146              :                 // are effectively jumping to the beginning of this if.
   11147              :                 JSON_ASSERT(!states.empty());
   11148              :                 states.pop_back();
   11149              :                 skip_to_state_evaluation = true;
   11150          585 :                 continue;
   11151              :             }
   11152              : 
   11153            0 :             return sax->parse_error(m_lexer.get_position(),
   11154              :                                     m_lexer.get_token_string(),
   11155            0 :                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
   11156              :         }
   11157              :     }
   11158              : 
   11159              :     /// get next token from lexer
   11160              :     token_type get_token()
   11161              :     {
   11162         9544 :         return last_token = m_lexer.scan();
   11163              :     }
   11164              : 
   11165            0 :     std::string exception_message(const token_type expected, const std::string& context)
   11166              :     {
   11167            0 :         std::string error_msg = "syntax error ";
   11168              : 
   11169            0 :         if (!context.empty())
   11170              :         {
   11171            0 :             error_msg += "while parsing " + context + " ";
   11172              :         }
   11173              : 
   11174              :         error_msg += "- ";
   11175              : 
   11176            0 :         if (last_token == token_type::parse_error)
   11177              :         {
   11178            0 :             error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
   11179              :                          m_lexer.get_token_string() + "'";
   11180              :         }
   11181              :         else
   11182              :         {
   11183            0 :             error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
   11184              :         }
   11185              : 
   11186            0 :         if (expected != token_type::uninitialized)
   11187              :         {
   11188            0 :             error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
   11189              :         }
   11190              : 
   11191            0 :         return error_msg;
   11192              :     }
   11193              : 
   11194              :   private:
   11195              :     /// callback function
   11196              :     const parser_callback_t<BasicJsonType> callback = nullptr;
   11197              :     /// the type of the last read token
   11198              :     token_type last_token = token_type::uninitialized;
   11199              :     /// the lexer
   11200              :     lexer_t m_lexer;
   11201              :     /// whether to throw exceptions in case of errors
   11202              :     const bool allow_exceptions = true;
   11203              : };
   11204              : 
   11205              : }  // namespace detail
   11206              : }  // namespace nlohmann
   11207              : 
   11208              : // #include <nlohmann/detail/iterators/internal_iterator.hpp>
   11209              : 
   11210              : 
   11211              : // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
   11212              : 
   11213              : 
   11214              : #include <cstddef> // ptrdiff_t
   11215              : #include <limits>  // numeric_limits
   11216              : 
   11217              : // #include <nlohmann/detail/macro_scope.hpp>
   11218              : 
   11219              : 
   11220              : namespace nlohmann
   11221              : {
   11222              : namespace detail
   11223              : {
   11224              : /*
   11225              : @brief an iterator for primitive JSON types
   11226              : 
   11227              : This class models an iterator for primitive JSON types (boolean, number,
   11228              : string). It's only purpose is to allow the iterator/const_iterator classes
   11229              : to "iterate" over primitive values. Internally, the iterator is modeled by
   11230              : a `difference_type` variable. Value begin_value (`0`) models the begin,
   11231              : end_value (`1`) models past the end.
   11232              : */
   11233          730 : class primitive_iterator_t
   11234              : {
   11235              :   private:
   11236              :     using difference_type = std::ptrdiff_t;
   11237              :     static constexpr difference_type begin_value = 0;
   11238              :     static constexpr difference_type end_value = begin_value + 1;
   11239              : 
   11240              :   JSON_PRIVATE_UNLESS_TESTED:
   11241              :     /// iterator as signed integer type
   11242              :     difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
   11243              : 
   11244              :   public:
   11245              :     constexpr difference_type get_value() const noexcept
   11246              :     {
   11247              :         return m_it;
   11248              :     }
   11249              : 
   11250              :     /// set iterator to a defined beginning
   11251              :     void set_begin() noexcept
   11252              :     {
   11253            0 :         m_it = begin_value;
   11254            0 :     }
   11255              : 
   11256              :     /// set iterator to a defined past the end
   11257              :     void set_end() noexcept
   11258              :     {
   11259            0 :         m_it = end_value;
   11260            0 :     }
   11261              : 
   11262              :     /// return whether the iterator can be dereferenced
   11263              :     constexpr bool is_begin() const noexcept
   11264              :     {
   11265            0 :         return m_it == begin_value;
   11266              :     }
   11267              : 
   11268              :     /// return whether the iterator is at end
   11269              :     constexpr bool is_end() const noexcept
   11270              :     {
   11271              :         return m_it == end_value;
   11272              :     }
   11273              : 
   11274              :     friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
   11275              :     {
   11276            0 :         return lhs.m_it == rhs.m_it;
   11277              :     }
   11278              : 
   11279              :     friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
   11280              :     {
   11281              :         return lhs.m_it < rhs.m_it;
   11282              :     }
   11283              : 
   11284              :     primitive_iterator_t operator+(difference_type n) noexcept
   11285              :     {
   11286              :         auto result = *this;
   11287              :         result += n;
   11288              :         return result;
   11289              :     }
   11290              : 
   11291              :     friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
   11292              :     {
   11293              :         return lhs.m_it - rhs.m_it;
   11294              :     }
   11295              : 
   11296              :     primitive_iterator_t& operator++() noexcept
   11297              :     {
   11298            0 :         ++m_it;
   11299            0 :         return *this;
   11300              :     }
   11301              : 
   11302              :     primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
   11303              :     {
   11304              :         auto result = *this;
   11305              :         ++m_it;
   11306              :         return result;
   11307              :     }
   11308              : 
   11309              :     primitive_iterator_t& operator--() noexcept
   11310              :     {
   11311              :         --m_it;
   11312              :         return *this;
   11313              :     }
   11314              : 
   11315              :     primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
   11316              :     {
   11317              :         auto result = *this;
   11318              :         --m_it;
   11319              :         return result;
   11320              :     }
   11321              : 
   11322              :     primitive_iterator_t& operator+=(difference_type n) noexcept
   11323              :     {
   11324              :         m_it += n;
   11325              :         return *this;
   11326              :     }
   11327              : 
   11328              :     primitive_iterator_t& operator-=(difference_type n) noexcept
   11329              :     {
   11330              :         m_it -= n;
   11331              :         return *this;
   11332              :     }
   11333              : };
   11334              : }  // namespace detail
   11335              : }  // namespace nlohmann
   11336              : 
   11337              : 
   11338              : namespace nlohmann
   11339              : {
   11340              : namespace detail
   11341              : {
   11342              : /*!
   11343              : @brief an iterator value
   11344              : 
   11345              : @note This structure could easily be a union, but MSVC currently does not allow
   11346              : unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
   11347              : */
   11348              : template<typename BasicJsonType> struct internal_iterator
   11349              : {
   11350              :     /// iterator for JSON objects
   11351              :     typename BasicJsonType::object_t::iterator object_iterator {};
   11352              :     /// iterator for JSON arrays
   11353              :     typename BasicJsonType::array_t::iterator array_iterator {};
   11354              :     /// generic iterator for all other types
   11355              :     primitive_iterator_t primitive_iterator {};
   11356              : };
   11357              : }  // namespace detail
   11358              : }  // namespace nlohmann
   11359              : 
   11360              : // #include <nlohmann/detail/iterators/iter_impl.hpp>
   11361              : 
   11362              : 
   11363              : #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
   11364              : #include <type_traits> // conditional, is_const, remove_const
   11365              : 
   11366              : // #include <nlohmann/detail/exceptions.hpp>
   11367              : 
   11368              : // #include <nlohmann/detail/iterators/internal_iterator.hpp>
   11369              : 
   11370              : // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
   11371              : 
   11372              : // #include <nlohmann/detail/macro_scope.hpp>
   11373              : 
   11374              : // #include <nlohmann/detail/meta/cpp_future.hpp>
   11375              : 
   11376              : // #include <nlohmann/detail/meta/type_traits.hpp>
   11377              : 
   11378              : // #include <nlohmann/detail/value_t.hpp>
   11379              : 
   11380              : 
   11381              : namespace nlohmann
   11382              : {
   11383              : namespace detail
   11384              : {
   11385              : // forward declare, to be able to friend it later on
   11386              : template<typename IteratorType> class iteration_proxy;
   11387              : template<typename IteratorType> class iteration_proxy_value;
   11388              : 
   11389              : /*!
   11390              : @brief a template for a bidirectional iterator for the @ref basic_json class
   11391              : This class implements a both iterators (iterator and const_iterator) for the
   11392              : @ref basic_json class.
   11393              : @note An iterator is called *initialized* when a pointer to a JSON value has
   11394              :       been set (e.g., by a constructor or a copy assignment). If the iterator is
   11395              :       default-constructed, it is *uninitialized* and most methods are undefined.
   11396              :       **The library uses assertions to detect calls on uninitialized iterators.**
   11397              : @requirement The class satisfies the following concept requirements:
   11398              : -
   11399              : [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
   11400              :   The iterator that can be moved can be moved in both directions (i.e.
   11401              :   incremented and decremented).
   11402              : @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
   11403              :        iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
   11404              : */
   11405              : template<typename BasicJsonType>
   11406              : class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
   11407              : {
   11408              :     /// the iterator with BasicJsonType of different const-ness
   11409              :     using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
   11410              :     /// allow basic_json to access private members
   11411              :     friend other_iter_impl;
   11412              :     friend BasicJsonType;
   11413              :     friend iteration_proxy<iter_impl>;
   11414              :     friend iteration_proxy_value<iter_impl>;
   11415              : 
   11416              :     using object_t = typename BasicJsonType::object_t;
   11417              :     using array_t = typename BasicJsonType::array_t;
   11418              :     // make sure BasicJsonType is basic_json or const basic_json
   11419              :     static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
   11420              :                   "iter_impl only accepts (const) basic_json");
   11421              : 
   11422              :   public:
   11423              : 
   11424              :     /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
   11425              :     /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
   11426              :     /// A user-defined iterator should provide publicly accessible typedefs named
   11427              :     /// iterator_category, value_type, difference_type, pointer, and reference.
   11428              :     /// Note that value_type is required to be non-const, even for constant iterators.
   11429              :     using iterator_category = std::bidirectional_iterator_tag;
   11430              : 
   11431              :     /// the type of the values when the iterator is dereferenced
   11432              :     using value_type = typename BasicJsonType::value_type;
   11433              :     /// a type to represent differences between iterators
   11434              :     using difference_type = typename BasicJsonType::difference_type;
   11435              :     /// defines a pointer to the type iterated over (value_type)
   11436              :     using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
   11437              :           typename BasicJsonType::const_pointer,
   11438              :           typename BasicJsonType::pointer>::type;
   11439              :     /// defines a reference to the type iterated over (value_type)
   11440              :     using reference =
   11441              :         typename std::conditional<std::is_const<BasicJsonType>::value,
   11442              :         typename BasicJsonType::const_reference,
   11443              :         typename BasicJsonType::reference>::type;
   11444              : 
   11445              :     iter_impl() = default;
   11446              :     ~iter_impl() = default;
   11447              :     iter_impl(iter_impl&&) noexcept = default;
   11448              :     iter_impl& operator=(iter_impl&&) noexcept = default;
   11449              : 
   11450              :     /*!
   11451              :     @brief constructor for a given JSON instance
   11452              :     @param[in] object  pointer to a JSON object for this iterator
   11453              :     @pre object != nullptr
   11454              :     @post The iterator is initialized; i.e. `m_object != nullptr`.
   11455              :     */
   11456          730 :     explicit iter_impl(pointer object) noexcept : m_object(object)
   11457              :     {
   11458              :         JSON_ASSERT(m_object != nullptr);
   11459              : 
   11460          730 :         switch (m_object->m_type)
   11461              :         {
   11462              :             case value_t::object:
   11463              :             {
   11464          436 :                 m_it.object_iterator = typename object_t::iterator();
   11465          436 :                 break;
   11466              :             }
   11467              : 
   11468              :             case value_t::array:
   11469              :             {
   11470          294 :                 m_it.array_iterator = typename array_t::iterator();
   11471          294 :                 break;
   11472              :             }
   11473              : 
   11474            0 :             case value_t::null:
   11475              :             case value_t::string:
   11476              :             case value_t::boolean:
   11477              :             case value_t::number_integer:
   11478              :             case value_t::number_unsigned:
   11479              :             case value_t::number_float:
   11480              :             case value_t::binary:
   11481              :             case value_t::discarded:
   11482              :             default:
   11483              :             {
   11484            0 :                 m_it.primitive_iterator = primitive_iterator_t();
   11485            0 :                 break;
   11486              :             }
   11487              :         }
   11488              :     }
   11489              : 
   11490              :     /*!
   11491              :     @note The conventional copy constructor and copy assignment are implicitly
   11492              :           defined. Combined with the following converting constructor and
   11493              :           assignment, they support: (1) copy from iterator to iterator, (2)
   11494              :           copy from const iterator to const iterator, and (3) conversion from
   11495              :           iterator to const iterator. However conversion from const iterator
   11496              :           to iterator is not defined.
   11497              :     */
   11498              : 
   11499              :     /*!
   11500              :     @brief const copy constructor
   11501              :     @param[in] other const iterator to copy from
   11502              :     @note This copy constructor had to be defined explicitly to circumvent a bug
   11503              :           occurring on msvc v19.0 compiler (VS 2015) debug build. For more
   11504              :           information refer to: https://github.com/nlohmann/json/issues/1608
   11505              :     */
   11506              :     iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
   11507              :         : m_object(other.m_object), m_it(other.m_it)
   11508              :     {}
   11509              : 
   11510              :     /*!
   11511              :     @brief converting assignment
   11512              :     @param[in] other const iterator to copy from
   11513              :     @return const/non-const iterator
   11514              :     @note It is not checked whether @a other is initialized.
   11515              :     */
   11516              :     iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
   11517              :     {
   11518              :         if (&other != this)
   11519              :         {
   11520              :             m_object = other.m_object;
   11521              :             m_it = other.m_it;
   11522              :         }
   11523              :         return *this;
   11524              :     }
   11525              : 
   11526              :     /*!
   11527              :     @brief converting constructor
   11528              :     @param[in] other  non-const iterator to copy from
   11529              :     @note It is not checked whether @a other is initialized.
   11530              :     */
   11531            0 :     iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
   11532            0 :         : m_object(other.m_object), m_it(other.m_it)
   11533              :     {}
   11534              : 
   11535              :     /*!
   11536              :     @brief converting assignment
   11537              :     @param[in] other  non-const iterator to copy from
   11538              :     @return const/non-const iterator
   11539              :     @note It is not checked whether @a other is initialized.
   11540              :     */
   11541              :     iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
   11542              :     {
   11543              :         m_object = other.m_object;
   11544              :         m_it = other.m_it;
   11545              :         return *this;
   11546              :     }
   11547              : 
   11548              :   JSON_PRIVATE_UNLESS_TESTED:
   11549              :     /*!
   11550              :     @brief set the iterator to the first value
   11551              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11552              :     */
   11553              :     void set_begin() noexcept
   11554              :     {
   11555              :         JSON_ASSERT(m_object != nullptr);
   11556              : 
   11557          149 :         switch (m_object->m_type)
   11558              :         {
   11559            2 :             case value_t::object:
   11560              :             {
   11561            2 :                 m_it.object_iterator = m_object->m_value.object->begin();
   11562            2 :                 break;
   11563              :             }
   11564              : 
   11565          147 :             case value_t::array:
   11566              :             {
   11567          147 :                 m_it.array_iterator = m_object->m_value.array->begin();
   11568          147 :                 break;
   11569              :             }
   11570              : 
   11571            0 :             case value_t::null:
   11572              :             {
   11573              :                 // set to end so begin()==end() is true: null is empty
   11574              :                 m_it.primitive_iterator.set_end();
   11575              :                 break;
   11576              :             }
   11577              : 
   11578            0 :             case value_t::string:
   11579              :             case value_t::boolean:
   11580              :             case value_t::number_integer:
   11581              :             case value_t::number_unsigned:
   11582              :             case value_t::number_float:
   11583              :             case value_t::binary:
   11584              :             case value_t::discarded:
   11585              :             default:
   11586              :             {
   11587              :                 m_it.primitive_iterator.set_begin();
   11588              :                 break;
   11589              :             }
   11590              :         }
   11591              :     }
   11592              : 
   11593              :     /*!
   11594              :     @brief set the iterator past the last value
   11595              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11596              :     */
   11597              :     void set_end() noexcept
   11598              :     {
   11599              :         JSON_ASSERT(m_object != nullptr);
   11600              : 
   11601          581 :         switch (m_object->m_type)
   11602              :         {
   11603          434 :             case value_t::object:
   11604              :             {
   11605          434 :                 m_it.object_iterator = m_object->m_value.object->end();
   11606          434 :                 break;
   11607              :             }
   11608              : 
   11609          147 :             case value_t::array:
   11610              :             {
   11611          147 :                 m_it.array_iterator = m_object->m_value.array->end();
   11612          147 :                 break;
   11613              :             }
   11614              : 
   11615            0 :             case value_t::null:
   11616              :             case value_t::string:
   11617              :             case value_t::boolean:
   11618              :             case value_t::number_integer:
   11619              :             case value_t::number_unsigned:
   11620              :             case value_t::number_float:
   11621              :             case value_t::binary:
   11622              :             case value_t::discarded:
   11623              :             default:
   11624              :             {
   11625              :                 m_it.primitive_iterator.set_end();
   11626              :                 break;
   11627              :             }
   11628              :         }
   11629              :     }
   11630              : 
   11631              :   public:
   11632              :     /*!
   11633              :     @brief return a reference to the value pointed to by the iterator
   11634              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11635              :     */
   11636         1974 :     reference operator*() const
   11637              :     {
   11638              :         JSON_ASSERT(m_object != nullptr);
   11639              : 
   11640         1974 :         switch (m_object->m_type)
   11641              :         {
   11642          180 :             case value_t::object:
   11643              :             {
   11644              :                 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
   11645          180 :                 return m_it.object_iterator->second;
   11646              :             }
   11647              : 
   11648         1794 :             case value_t::array:
   11649              :             {
   11650              :                 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
   11651         1794 :                 return *m_it.array_iterator;
   11652              :             }
   11653              : 
   11654            0 :             case value_t::null:
   11655            0 :                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
   11656              : 
   11657            0 :             case value_t::string:
   11658              :             case value_t::boolean:
   11659              :             case value_t::number_integer:
   11660              :             case value_t::number_unsigned:
   11661              :             case value_t::number_float:
   11662              :             case value_t::binary:
   11663              :             case value_t::discarded:
   11664              :             default:
   11665              :             {
   11666            0 :                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
   11667              :                 {
   11668              :                     return *m_object;
   11669              :                 }
   11670              : 
   11671            0 :                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
   11672              :             }
   11673              :         }
   11674              :     }
   11675              : 
   11676              :     /*!
   11677              :     @brief dereference the iterator
   11678              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11679              :     */
   11680          405 :     pointer operator->() const
   11681              :     {
   11682              :         JSON_ASSERT(m_object != nullptr);
   11683              : 
   11684          405 :         switch (m_object->m_type)
   11685              :         {
   11686          405 :             case value_t::object:
   11687              :             {
   11688              :                 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
   11689          405 :                 return &(m_it.object_iterator->second);
   11690              :             }
   11691              : 
   11692            0 :             case value_t::array:
   11693              :             {
   11694              :                 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
   11695            0 :                 return &*m_it.array_iterator;
   11696              :             }
   11697              : 
   11698            0 :             case value_t::null:
   11699              :             case value_t::string:
   11700              :             case value_t::boolean:
   11701              :             case value_t::number_integer:
   11702              :             case value_t::number_unsigned:
   11703              :             case value_t::number_float:
   11704              :             case value_t::binary:
   11705              :             case value_t::discarded:
   11706              :             default:
   11707              :             {
   11708            0 :                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
   11709              :                 {
   11710              :                     return m_object;
   11711              :                 }
   11712              : 
   11713            0 :                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
   11714              :             }
   11715              :         }
   11716              :     }
   11717              : 
   11718              :     /*!
   11719              :     @brief post-increment (it++)
   11720              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11721              :     */
   11722              :     iter_impl const operator++(int) // NOLINT(readability-const-return-type)
   11723              :     {
   11724              :         auto result = *this;
   11725              :         ++(*this);
   11726              :         return result;
   11727              :     }
   11728              : 
   11729              :     /*!
   11730              :     @brief pre-increment (++it)
   11731              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11732              :     */
   11733         1800 :     iter_impl& operator++()
   11734              :     {
   11735              :         JSON_ASSERT(m_object != nullptr);
   11736              : 
   11737         1800 :         switch (m_object->m_type)
   11738              :         {
   11739            6 :             case value_t::object:
   11740              :             {
   11741            6 :                 std::advance(m_it.object_iterator, 1);
   11742              :                 break;
   11743              :             }
   11744              : 
   11745         1794 :             case value_t::array:
   11746              :             {
   11747            0 :                 std::advance(m_it.array_iterator, 1);
   11748              :                 break;
   11749              :             }
   11750              : 
   11751            0 :             case value_t::null:
   11752              :             case value_t::string:
   11753              :             case value_t::boolean:
   11754              :             case value_t::number_integer:
   11755              :             case value_t::number_unsigned:
   11756              :             case value_t::number_float:
   11757              :             case value_t::binary:
   11758              :             case value_t::discarded:
   11759              :             default:
   11760              :             {
   11761              :                 ++m_it.primitive_iterator;
   11762              :                 break;
   11763              :             }
   11764              :         }
   11765              : 
   11766         1800 :         return *this;
   11767              :     }
   11768              : 
   11769              :     /*!
   11770              :     @brief post-decrement (it--)
   11771              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11772              :     */
   11773              :     iter_impl const operator--(int) // NOLINT(readability-const-return-type)
   11774              :     {
   11775              :         auto result = *this;
   11776              :         --(*this);
   11777              :         return result;
   11778              :     }
   11779              : 
   11780              :     /*!
   11781              :     @brief pre-decrement (--it)
   11782              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11783              :     */
   11784              :     iter_impl& operator--()
   11785              :     {
   11786              :         JSON_ASSERT(m_object != nullptr);
   11787              : 
   11788              :         switch (m_object->m_type)
   11789              :         {
   11790              :             case value_t::object:
   11791              :             {
   11792              :                 std::advance(m_it.object_iterator, -1);
   11793              :                 break;
   11794              :             }
   11795              : 
   11796              :             case value_t::array:
   11797              :             {
   11798              :                 std::advance(m_it.array_iterator, -1);
   11799              :                 break;
   11800              :             }
   11801              : 
   11802              :             case value_t::null:
   11803              :             case value_t::string:
   11804              :             case value_t::boolean:
   11805              :             case value_t::number_integer:
   11806              :             case value_t::number_unsigned:
   11807              :             case value_t::number_float:
   11808              :             case value_t::binary:
   11809              :             case value_t::discarded:
   11810              :             default:
   11811              :             {
   11812              :                 --m_it.primitive_iterator;
   11813              :                 break;
   11814              :             }
   11815              :         }
   11816              : 
   11817              :         return *this;
   11818              :     }
   11819              : 
   11820              :     /*!
   11821              :     @brief comparison: equal
   11822              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11823              :     */
   11824              :     template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
   11825         2165 :     bool operator==(const IterImpl& other) const
   11826              :     {
   11827              :         // if objects are not the same, the comparison is undefined
   11828         2165 :         if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
   11829              :         {
   11830            0 :             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
   11831              :         }
   11832              : 
   11833              :         JSON_ASSERT(m_object != nullptr);
   11834              : 
   11835         2165 :         switch (m_object->m_type)
   11836              :         {
   11837          224 :             case value_t::object:
   11838          224 :                 return (m_it.object_iterator == other.m_it.object_iterator);
   11839              : 
   11840         1941 :             case value_t::array:
   11841         1941 :                 return (m_it.array_iterator == other.m_it.array_iterator);
   11842              : 
   11843            0 :             case value_t::null:
   11844              :             case value_t::string:
   11845              :             case value_t::boolean:
   11846              :             case value_t::number_integer:
   11847              :             case value_t::number_unsigned:
   11848              :             case value_t::number_float:
   11849              :             case value_t::binary:
   11850              :             case value_t::discarded:
   11851              :             default:
   11852            0 :                 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
   11853              :         }
   11854              :     }
   11855              : 
   11856              :     /*!
   11857              :     @brief comparison: not equal
   11858              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11859              :     */
   11860              :     template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
   11861              :     bool operator!=(const IterImpl& other) const
   11862              :     {
   11863         1949 :         return !operator==(other);
   11864              :     }
   11865              : 
   11866              :     /*!
   11867              :     @brief comparison: smaller
   11868              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11869              :     */
   11870              :     bool operator<(const iter_impl& other) const
   11871              :     {
   11872              :         // if objects are not the same, the comparison is undefined
   11873              :         if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
   11874              :         {
   11875              :             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
   11876              :         }
   11877              : 
   11878              :         JSON_ASSERT(m_object != nullptr);
   11879              : 
   11880              :         switch (m_object->m_type)
   11881              :         {
   11882              :             case value_t::object:
   11883              :                 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
   11884              : 
   11885              :             case value_t::array:
   11886              :                 return (m_it.array_iterator < other.m_it.array_iterator);
   11887              : 
   11888              :             case value_t::null:
   11889              :             case value_t::string:
   11890              :             case value_t::boolean:
   11891              :             case value_t::number_integer:
   11892              :             case value_t::number_unsigned:
   11893              :             case value_t::number_float:
   11894              :             case value_t::binary:
   11895              :             case value_t::discarded:
   11896              :             default:
   11897              :                 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
   11898              :         }
   11899              :     }
   11900              : 
   11901              :     /*!
   11902              :     @brief comparison: less than or equal
   11903              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11904              :     */
   11905              :     bool operator<=(const iter_impl& other) const
   11906              :     {
   11907              :         return !other.operator < (*this);
   11908              :     }
   11909              : 
   11910              :     /*!
   11911              :     @brief comparison: greater than
   11912              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11913              :     */
   11914              :     bool operator>(const iter_impl& other) const
   11915              :     {
   11916              :         return !operator<=(other);
   11917              :     }
   11918              : 
   11919              :     /*!
   11920              :     @brief comparison: greater than or equal
   11921              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11922              :     */
   11923              :     bool operator>=(const iter_impl& other) const
   11924              :     {
   11925              :         return !operator<(other);
   11926              :     }
   11927              : 
   11928              :     /*!
   11929              :     @brief add to iterator
   11930              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11931              :     */
   11932              :     iter_impl& operator+=(difference_type i)
   11933              :     {
   11934              :         JSON_ASSERT(m_object != nullptr);
   11935              : 
   11936              :         switch (m_object->m_type)
   11937              :         {
   11938              :             case value_t::object:
   11939              :                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
   11940              : 
   11941              :             case value_t::array:
   11942              :             {
   11943              :                 std::advance(m_it.array_iterator, i);
   11944              :                 break;
   11945              :             }
   11946              : 
   11947              :             case value_t::null:
   11948              :             case value_t::string:
   11949              :             case value_t::boolean:
   11950              :             case value_t::number_integer:
   11951              :             case value_t::number_unsigned:
   11952              :             case value_t::number_float:
   11953              :             case value_t::binary:
   11954              :             case value_t::discarded:
   11955              :             default:
   11956              :             {
   11957              :                 m_it.primitive_iterator += i;
   11958              :                 break;
   11959              :             }
   11960              :         }
   11961              : 
   11962              :         return *this;
   11963              :     }
   11964              : 
   11965              :     /*!
   11966              :     @brief subtract from iterator
   11967              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11968              :     */
   11969              :     iter_impl& operator-=(difference_type i)
   11970              :     {
   11971              :         return operator+=(-i);
   11972              :     }
   11973              : 
   11974              :     /*!
   11975              :     @brief add to iterator
   11976              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11977              :     */
   11978              :     iter_impl operator+(difference_type i) const
   11979              :     {
   11980              :         auto result = *this;
   11981              :         result += i;
   11982              :         return result;
   11983              :     }
   11984              : 
   11985              :     /*!
   11986              :     @brief addition of distance and iterator
   11987              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11988              :     */
   11989              :     friend iter_impl operator+(difference_type i, const iter_impl& it)
   11990              :     {
   11991              :         auto result = it;
   11992              :         result += i;
   11993              :         return result;
   11994              :     }
   11995              : 
   11996              :     /*!
   11997              :     @brief subtract from iterator
   11998              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   11999              :     */
   12000              :     iter_impl operator-(difference_type i) const
   12001              :     {
   12002              :         auto result = *this;
   12003              :         result -= i;
   12004              :         return result;
   12005              :     }
   12006              : 
   12007              :     /*!
   12008              :     @brief return difference
   12009              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   12010              :     */
   12011              :     difference_type operator-(const iter_impl& other) const
   12012              :     {
   12013              :         JSON_ASSERT(m_object != nullptr);
   12014              : 
   12015              :         switch (m_object->m_type)
   12016              :         {
   12017              :             case value_t::object:
   12018              :                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
   12019              : 
   12020              :             case value_t::array:
   12021              :                 return m_it.array_iterator - other.m_it.array_iterator;
   12022              : 
   12023              :             case value_t::null:
   12024              :             case value_t::string:
   12025              :             case value_t::boolean:
   12026              :             case value_t::number_integer:
   12027              :             case value_t::number_unsigned:
   12028              :             case value_t::number_float:
   12029              :             case value_t::binary:
   12030              :             case value_t::discarded:
   12031              :             default:
   12032              :                 return m_it.primitive_iterator - other.m_it.primitive_iterator;
   12033              :         }
   12034              :     }
   12035              : 
   12036              :     /*!
   12037              :     @brief access to successor
   12038              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   12039              :     */
   12040              :     reference operator[](difference_type n) const
   12041              :     {
   12042              :         JSON_ASSERT(m_object != nullptr);
   12043              : 
   12044              :         switch (m_object->m_type)
   12045              :         {
   12046              :             case value_t::object:
   12047              :                 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
   12048              : 
   12049              :             case value_t::array:
   12050              :                 return *std::next(m_it.array_iterator, n);
   12051              : 
   12052              :             case value_t::null:
   12053              :                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
   12054              : 
   12055              :             case value_t::string:
   12056              :             case value_t::boolean:
   12057              :             case value_t::number_integer:
   12058              :             case value_t::number_unsigned:
   12059              :             case value_t::number_float:
   12060              :             case value_t::binary:
   12061              :             case value_t::discarded:
   12062              :             default:
   12063              :             {
   12064              :                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
   12065              :                 {
   12066              :                     return *m_object;
   12067              :                 }
   12068              : 
   12069              :                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
   12070              :             }
   12071              :         }
   12072              :     }
   12073              : 
   12074              :     /*!
   12075              :     @brief return the key of an object iterator
   12076              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   12077              :     */
   12078            6 :     const typename object_t::key_type& key() const
   12079              :     {
   12080              :         JSON_ASSERT(m_object != nullptr);
   12081              : 
   12082            6 :         if (JSON_HEDLEY_LIKELY(m_object->is_object()))
   12083              :         {
   12084            6 :             return m_it.object_iterator->first;
   12085              :         }
   12086              : 
   12087            0 :         JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
   12088              :     }
   12089              : 
   12090              :     /*!
   12091              :     @brief return the value of an iterator
   12092              :     @pre The iterator is initialized; i.e. `m_object != nullptr`.
   12093              :     */
   12094              :     reference value() const
   12095              :     {
   12096           18 :         return operator*();
   12097              :     }
   12098              : 
   12099              :   JSON_PRIVATE_UNLESS_TESTED:
   12100              :     /// associated JSON instance
   12101              :     pointer m_object = nullptr;
   12102              :     /// the actual iterator of the associated instance
   12103              :     internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
   12104              : };
   12105              : } // namespace detail
   12106              : } // namespace nlohmann
   12107              : 
   12108              : // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
   12109              : 
   12110              : // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
   12111              : 
   12112              : 
   12113              : #include <cstddef> // ptrdiff_t
   12114              : #include <iterator> // reverse_iterator
   12115              : #include <utility> // declval
   12116              : 
   12117              : namespace nlohmann
   12118              : {
   12119              : namespace detail
   12120              : {
   12121              : //////////////////////
   12122              : // reverse_iterator //
   12123              : //////////////////////
   12124              : 
   12125              : /*!
   12126              : @brief a template for a reverse iterator class
   12127              : 
   12128              : @tparam Base the base iterator type to reverse. Valid types are @ref
   12129              : iterator (to create @ref reverse_iterator) and @ref const_iterator (to
   12130              : create @ref const_reverse_iterator).
   12131              : 
   12132              : @requirement The class satisfies the following concept requirements:
   12133              : -
   12134              : [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
   12135              :   The iterator that can be moved can be moved in both directions (i.e.
   12136              :   incremented and decremented).
   12137              : - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
   12138              :   It is possible to write to the pointed-to element (only if @a Base is
   12139              :   @ref iterator).
   12140              : 
   12141              : @since version 1.0.0
   12142              : */
   12143              : template<typename Base>
   12144              : class json_reverse_iterator : public std::reverse_iterator<Base>
   12145              : {
   12146              :   public:
   12147              :     using difference_type = std::ptrdiff_t;
   12148              :     /// shortcut to the reverse iterator adapter
   12149              :     using base_iterator = std::reverse_iterator<Base>;
   12150              :     /// the reference type for the pointed-to element
   12151              :     using reference = typename Base::reference;
   12152              : 
   12153              :     /// create reverse iterator from iterator
   12154              :     explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
   12155              :         : base_iterator(it) {}
   12156              : 
   12157              :     /// create reverse iterator from base class
   12158              :     explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
   12159              : 
   12160              :     /// post-increment (it++)
   12161              :     json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
   12162              :     {
   12163              :         return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
   12164              :     }
   12165              : 
   12166              :     /// pre-increment (++it)
   12167              :     json_reverse_iterator& operator++()
   12168              :     {
   12169              :         return static_cast<json_reverse_iterator&>(base_iterator::operator++());
   12170              :     }
   12171              : 
   12172              :     /// post-decrement (it--)
   12173              :     json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
   12174              :     {
   12175              :         return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
   12176              :     }
   12177              : 
   12178              :     /// pre-decrement (--it)
   12179              :     json_reverse_iterator& operator--()
   12180              :     {
   12181              :         return static_cast<json_reverse_iterator&>(base_iterator::operator--());
   12182              :     }
   12183              : 
   12184              :     /// add to iterator
   12185              :     json_reverse_iterator& operator+=(difference_type i)
   12186              :     {
   12187              :         return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
   12188              :     }
   12189              : 
   12190              :     /// add to iterator
   12191              :     json_reverse_iterator operator+(difference_type i) const
   12192              :     {
   12193              :         return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
   12194              :     }
   12195              : 
   12196              :     /// subtract from iterator
   12197              :     json_reverse_iterator operator-(difference_type i) const
   12198              :     {
   12199              :         return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
   12200              :     }
   12201              : 
   12202              :     /// return difference
   12203              :     difference_type operator-(const json_reverse_iterator& other) const
   12204              :     {
   12205              :         return base_iterator(*this) - base_iterator(other);
   12206              :     }
   12207              : 
   12208              :     /// access to successor
   12209              :     reference operator[](difference_type n) const
   12210              :     {
   12211              :         return *(this->operator+(n));
   12212              :     }
   12213              : 
   12214              :     /// return the key of an object iterator
   12215              :     auto key() const -> decltype(std::declval<Base>().key())
   12216              :     {
   12217              :         auto it = --this->base();
   12218              :         return it.key();
   12219              :     }
   12220              : 
   12221              :     /// return the value of an iterator
   12222              :     reference value() const
   12223              :     {
   12224              :         auto it = --this->base();
   12225              :         return it.operator * ();
   12226              :     }
   12227              : };
   12228              : }  // namespace detail
   12229              : }  // namespace nlohmann
   12230              : 
   12231              : // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
   12232              : 
   12233              : // #include <nlohmann/detail/json_pointer.hpp>
   12234              : 
   12235              : 
   12236              : #include <algorithm> // all_of
   12237              : #include <cctype> // isdigit
   12238              : #include <limits> // max
   12239              : #include <numeric> // accumulate
   12240              : #include <string> // string
   12241              : #include <utility> // move
   12242              : #include <vector> // vector
   12243              : 
   12244              : // #include <nlohmann/detail/exceptions.hpp>
   12245              : 
   12246              : // #include <nlohmann/detail/macro_scope.hpp>
   12247              : 
   12248              : // #include <nlohmann/detail/string_escape.hpp>
   12249              : 
   12250              : // #include <nlohmann/detail/value_t.hpp>
   12251              : 
   12252              : 
   12253              : namespace nlohmann
   12254              : {
   12255              : 
   12256              : /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
   12257              : /// @sa https://json.nlohmann.me/api/json_pointer/
   12258              : template<typename BasicJsonType>
   12259              : class json_pointer
   12260              : {
   12261              :     // allow basic_json to access private members
   12262              :     NLOHMANN_BASIC_JSON_TPL_DECLARATION
   12263              :     friend class basic_json;
   12264              : 
   12265              :   public:
   12266              :     /// @brief create JSON pointer
   12267              :     /// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/
   12268              :     explicit json_pointer(const std::string& s = "")
   12269              :         : reference_tokens(split(s))
   12270              :     {}
   12271              : 
   12272              :     /// @brief return a string representation of the JSON pointer
   12273              :     /// @sa https://json.nlohmann.me/api/json_pointer/to_string/
   12274              :     std::string to_string() const
   12275              :     {
   12276              :         return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
   12277              :                                std::string{},
   12278              :                                [](const std::string & a, const std::string & b)
   12279              :         {
   12280              :             return a + "/" + detail::escape(b);
   12281              :         });
   12282              :     }
   12283              : 
   12284              :     /// @brief return a string representation of the JSON pointer
   12285              :     /// @sa https://json.nlohmann.me/api/json_pointer/operator_string/
   12286              :     operator std::string() const
   12287              :     {
   12288              :         return to_string();
   12289              :     }
   12290              : 
   12291              :     /// @brief append another JSON pointer at the end of this JSON pointer
   12292              :     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
   12293              :     json_pointer& operator/=(const json_pointer& ptr)
   12294              :     {
   12295              :         reference_tokens.insert(reference_tokens.end(),
   12296              :                                 ptr.reference_tokens.begin(),
   12297              :                                 ptr.reference_tokens.end());
   12298              :         return *this;
   12299              :     }
   12300              : 
   12301              :     /// @brief append an unescaped reference token at the end of this JSON pointer
   12302              :     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
   12303              :     json_pointer& operator/=(std::string token)
   12304              :     {
   12305              :         push_back(std::move(token));
   12306              :         return *this;
   12307              :     }
   12308              : 
   12309              :     /// @brief append an array index at the end of this JSON pointer
   12310              :     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
   12311              :     json_pointer& operator/=(std::size_t array_idx)
   12312              :     {
   12313              :         return *this /= std::to_string(array_idx);
   12314              :     }
   12315              : 
   12316              :     /// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
   12317              :     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
   12318              :     friend json_pointer operator/(const json_pointer& lhs,
   12319              :                                   const json_pointer& rhs)
   12320              :     {
   12321              :         return json_pointer(lhs) /= rhs;
   12322              :     }
   12323              : 
   12324              :     /// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
   12325              :     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
   12326              :     friend json_pointer operator/(const json_pointer& lhs, std::string token) // NOLINT(performance-unnecessary-value-param)
   12327              :     {
   12328              :         return json_pointer(lhs) /= std::move(token);
   12329              :     }
   12330              : 
   12331              :     /// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
   12332              :     /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
   12333              :     friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
   12334              :     {
   12335              :         return json_pointer(lhs) /= array_idx;
   12336              :     }
   12337              : 
   12338              :     /// @brief returns the parent of this JSON pointer
   12339              :     /// @sa https://json.nlohmann.me/api/json_pointer/parent_pointer/
   12340              :     json_pointer parent_pointer() const
   12341              :     {
   12342              :         if (empty())
   12343              :         {
   12344              :             return *this;
   12345              :         }
   12346              : 
   12347              :         json_pointer res = *this;
   12348              :         res.pop_back();
   12349              :         return res;
   12350              :     }
   12351              : 
   12352              :     /// @brief remove last reference token
   12353              :     /// @sa https://json.nlohmann.me/api/json_pointer/pop_back/
   12354              :     void pop_back()
   12355              :     {
   12356              :         if (JSON_HEDLEY_UNLIKELY(empty()))
   12357              :         {
   12358              :             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
   12359              :         }
   12360              : 
   12361              :         reference_tokens.pop_back();
   12362              :     }
   12363              : 
   12364              :     /// @brief return last reference token
   12365              :     /// @sa https://json.nlohmann.me/api/json_pointer/back/
   12366              :     const std::string& back() const
   12367              :     {
   12368              :         if (JSON_HEDLEY_UNLIKELY(empty()))
   12369              :         {
   12370              :             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
   12371              :         }
   12372              : 
   12373              :         return reference_tokens.back();
   12374              :     }
   12375              : 
   12376              :     /// @brief append an unescaped token at the end of the reference pointer
   12377              :     /// @sa https://json.nlohmann.me/api/json_pointer/push_back/
   12378              :     void push_back(const std::string& token)
   12379              :     {
   12380              :         reference_tokens.push_back(token);
   12381              :     }
   12382              : 
   12383              :     /// @brief append an unescaped token at the end of the reference pointer
   12384              :     /// @sa https://json.nlohmann.me/api/json_pointer/push_back/
   12385              :     void push_back(std::string&& token)
   12386              :     {
   12387              :         reference_tokens.push_back(std::move(token));
   12388              :     }
   12389              : 
   12390              :     /// @brief return whether pointer points to the root document
   12391              :     /// @sa https://json.nlohmann.me/api/json_pointer/empty/
   12392              :     bool empty() const noexcept
   12393              :     {
   12394              :         return reference_tokens.empty();
   12395              :     }
   12396              : 
   12397              :   private:
   12398              :     /*!
   12399              :     @param[in] s  reference token to be converted into an array index
   12400              : 
   12401              :     @return integer representation of @a s
   12402              : 
   12403              :     @throw parse_error.106  if an array index begins with '0'
   12404              :     @throw parse_error.109  if an array index begins not with a digit
   12405              :     @throw out_of_range.404 if string @a s could not be converted to an integer
   12406              :     @throw out_of_range.410 if an array index exceeds size_type
   12407              :     */
   12408              :     static typename BasicJsonType::size_type array_index(const std::string& s)
   12409              :     {
   12410              :         using size_type = typename BasicJsonType::size_type;
   12411              : 
   12412              :         // error condition (cf. RFC 6901, Sect. 4)
   12413              :         if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
   12414              :         {
   12415              :             JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
   12416              :         }
   12417              : 
   12418              :         // error condition (cf. RFC 6901, Sect. 4)
   12419              :         if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
   12420              :         {
   12421              :             JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
   12422              :         }
   12423              : 
   12424              :         std::size_t processed_chars = 0;
   12425              :         unsigned long long res = 0;  // NOLINT(runtime/int)
   12426              :         JSON_TRY
   12427              :         {
   12428              :             res = std::stoull(s, &processed_chars);
   12429              :         }
   12430              :         JSON_CATCH(std::out_of_range&)
   12431              :         {
   12432              :             JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
   12433              :         }
   12434              : 
   12435              :         // check if the string was completely read
   12436              :         if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
   12437              :         {
   12438              :             JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
   12439              :         }
   12440              : 
   12441              :         // only triggered on special platforms (like 32bit), see also
   12442              :         // https://github.com/nlohmann/json/pull/2203
   12443              :         if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))  // NOLINT(runtime/int)
   12444              :         {
   12445              :             JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
   12446              :         }
   12447              : 
   12448              :         return static_cast<size_type>(res);
   12449              :     }
   12450              : 
   12451              :   JSON_PRIVATE_UNLESS_TESTED:
   12452              :     json_pointer top() const
   12453              :     {
   12454              :         if (JSON_HEDLEY_UNLIKELY(empty()))
   12455              :         {
   12456              :             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
   12457              :         }
   12458              : 
   12459              :         json_pointer result = *this;
   12460              :         result.reference_tokens = {reference_tokens[0]};
   12461              :         return result;
   12462              :     }
   12463              : 
   12464              :   private:
   12465              :     /*!
   12466              :     @brief create and return a reference to the pointed to value
   12467              : 
   12468              :     @complexity Linear in the number of reference tokens.
   12469              : 
   12470              :     @throw parse_error.109 if array index is not a number
   12471              :     @throw type_error.313 if value cannot be unflattened
   12472              :     */
   12473              :     BasicJsonType& get_and_create(BasicJsonType& j) const
   12474              :     {
   12475              :         auto* result = &j;
   12476              : 
   12477              :         // in case no reference tokens exist, return a reference to the JSON value
   12478              :         // j which will be overwritten by a primitive value
   12479              :         for (const auto& reference_token : reference_tokens)
   12480              :         {
   12481              :             switch (result->type())
   12482              :             {
   12483              :                 case detail::value_t::null:
   12484              :                 {
   12485              :                     if (reference_token == "0")
   12486              :                     {
   12487              :                         // start a new array if reference token is 0
   12488              :                         result = &result->operator[](0);
   12489              :                     }
   12490              :                     else
   12491              :                     {
   12492              :                         // start a new object otherwise
   12493              :                         result = &result->operator[](reference_token);
   12494              :                     }
   12495              :                     break;
   12496              :                 }
   12497              : 
   12498              :                 case detail::value_t::object:
   12499              :                 {
   12500              :                     // create an entry in the object
   12501              :                     result = &result->operator[](reference_token);
   12502              :                     break;
   12503              :                 }
   12504              : 
   12505              :                 case detail::value_t::array:
   12506              :                 {
   12507              :                     // create an entry in the array
   12508              :                     result = &result->operator[](array_index(reference_token));
   12509              :                     break;
   12510              :                 }
   12511              : 
   12512              :                 /*
   12513              :                 The following code is only reached if there exists a reference
   12514              :                 token _and_ the current value is primitive. In this case, we have
   12515              :                 an error situation, because primitive values may only occur as
   12516              :                 single value; that is, with an empty list of reference tokens.
   12517              :                 */
   12518              :                 case detail::value_t::string:
   12519              :                 case detail::value_t::boolean:
   12520              :                 case detail::value_t::number_integer:
   12521              :                 case detail::value_t::number_unsigned:
   12522              :                 case detail::value_t::number_float:
   12523              :                 case detail::value_t::binary:
   12524              :                 case detail::value_t::discarded:
   12525              :                 default:
   12526              :                     JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
   12527              :             }
   12528              :         }
   12529              : 
   12530              :         return *result;
   12531              :     }
   12532              : 
   12533              :     /*!
   12534              :     @brief return a reference to the pointed to value
   12535              : 
   12536              :     @note This version does not throw if a value is not present, but tries to
   12537              :           create nested values instead. For instance, calling this function
   12538              :           with pointer `"/this/that"` on a null value is equivalent to calling
   12539              :           `operator[]("this").operator[]("that")` on that value, effectively
   12540              :           changing the null value to an object.
   12541              : 
   12542              :     @param[in] ptr  a JSON value
   12543              : 
   12544              :     @return reference to the JSON value pointed to by the JSON pointer
   12545              : 
   12546              :     @complexity Linear in the length of the JSON pointer.
   12547              : 
   12548              :     @throw parse_error.106   if an array index begins with '0'
   12549              :     @throw parse_error.109   if an array index was not a number
   12550              :     @throw out_of_range.404  if the JSON pointer can not be resolved
   12551              :     */
   12552              :     BasicJsonType& get_unchecked(BasicJsonType* ptr) const
   12553              :     {
   12554              :         for (const auto& reference_token : reference_tokens)
   12555              :         {
   12556              :             // convert null values to arrays or objects before continuing
   12557              :             if (ptr->is_null())
   12558              :             {
   12559              :                 // check if reference token is a number
   12560              :                 const bool nums =
   12561              :                     std::all_of(reference_token.begin(), reference_token.end(),
   12562              :                                 [](const unsigned char x)
   12563              :                 {
   12564              :                     return std::isdigit(x);
   12565              :                 });
   12566              : 
   12567              :                 // change value to array for numbers or "-" or to object otherwise
   12568              :                 *ptr = (nums || reference_token == "-")
   12569              :                        ? detail::value_t::array
   12570              :                        : detail::value_t::object;
   12571              :             }
   12572              : 
   12573              :             switch (ptr->type())
   12574              :             {
   12575              :                 case detail::value_t::object:
   12576              :                 {
   12577              :                     // use unchecked object access
   12578              :                     ptr = &ptr->operator[](reference_token);
   12579              :                     break;
   12580              :                 }
   12581              : 
   12582              :                 case detail::value_t::array:
   12583              :                 {
   12584              :                     if (reference_token == "-")
   12585              :                     {
   12586              :                         // explicitly treat "-" as index beyond the end
   12587              :                         ptr = &ptr->operator[](ptr->m_value.array->size());
   12588              :                     }
   12589              :                     else
   12590              :                     {
   12591              :                         // convert array index to number; unchecked access
   12592              :                         ptr = &ptr->operator[](array_index(reference_token));
   12593              :                     }
   12594              :                     break;
   12595              :                 }
   12596              : 
   12597              :                 case detail::value_t::null:
   12598              :                 case detail::value_t::string:
   12599              :                 case detail::value_t::boolean:
   12600              :                 case detail::value_t::number_integer:
   12601              :                 case detail::value_t::number_unsigned:
   12602              :                 case detail::value_t::number_float:
   12603              :                 case detail::value_t::binary:
   12604              :                 case detail::value_t::discarded:
   12605              :                 default:
   12606              :                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
   12607              :             }
   12608              :         }
   12609              : 
   12610              :         return *ptr;
   12611              :     }
   12612              : 
   12613              :     /*!
   12614              :     @throw parse_error.106   if an array index begins with '0'
   12615              :     @throw parse_error.109   if an array index was not a number
   12616              :     @throw out_of_range.402  if the array index '-' is used
   12617              :     @throw out_of_range.404  if the JSON pointer can not be resolved
   12618              :     */
   12619              :     BasicJsonType& get_checked(BasicJsonType* ptr) const
   12620              :     {
   12621              :         for (const auto& reference_token : reference_tokens)
   12622              :         {
   12623              :             switch (ptr->type())
   12624              :             {
   12625              :                 case detail::value_t::object:
   12626              :                 {
   12627              :                     // note: at performs range check
   12628              :                     ptr = &ptr->at(reference_token);
   12629              :                     break;
   12630              :                 }
   12631              : 
   12632              :                 case detail::value_t::array:
   12633              :                 {
   12634              :                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
   12635              :                     {
   12636              :                         // "-" always fails the range check
   12637              :                         JSON_THROW(detail::out_of_range::create(402,
   12638              :                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
   12639              :                                                                 ") is out of range", *ptr));
   12640              :                     }
   12641              : 
   12642              :                     // note: at performs range check
   12643              :                     ptr = &ptr->at(array_index(reference_token));
   12644              :                     break;
   12645              :                 }
   12646              : 
   12647              :                 case detail::value_t::null:
   12648              :                 case detail::value_t::string:
   12649              :                 case detail::value_t::boolean:
   12650              :                 case detail::value_t::number_integer:
   12651              :                 case detail::value_t::number_unsigned:
   12652              :                 case detail::value_t::number_float:
   12653              :                 case detail::value_t::binary:
   12654              :                 case detail::value_t::discarded:
   12655              :                 default:
   12656              :                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
   12657              :             }
   12658              :         }
   12659              : 
   12660              :         return *ptr;
   12661              :     }
   12662              : 
   12663              :     /*!
   12664              :     @brief return a const reference to the pointed to value
   12665              : 
   12666              :     @param[in] ptr  a JSON value
   12667              : 
   12668              :     @return const reference to the JSON value pointed to by the JSON
   12669              :     pointer
   12670              : 
   12671              :     @throw parse_error.106   if an array index begins with '0'
   12672              :     @throw parse_error.109   if an array index was not a number
   12673              :     @throw out_of_range.402  if the array index '-' is used
   12674              :     @throw out_of_range.404  if the JSON pointer can not be resolved
   12675              :     */
   12676              :     const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
   12677              :     {
   12678              :         for (const auto& reference_token : reference_tokens)
   12679              :         {
   12680              :             switch (ptr->type())
   12681              :             {
   12682              :                 case detail::value_t::object:
   12683              :                 {
   12684              :                     // use unchecked object access
   12685              :                     ptr = &ptr->operator[](reference_token);
   12686              :                     break;
   12687              :                 }
   12688              : 
   12689              :                 case detail::value_t::array:
   12690              :                 {
   12691              :                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
   12692              :                     {
   12693              :                         // "-" cannot be used for const access
   12694              :                         JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
   12695              :                     }
   12696              : 
   12697              :                     // use unchecked array access
   12698              :                     ptr = &ptr->operator[](array_index(reference_token));
   12699              :                     break;
   12700              :                 }
   12701              : 
   12702              :                 case detail::value_t::null:
   12703              :                 case detail::value_t::string:
   12704              :                 case detail::value_t::boolean:
   12705              :                 case detail::value_t::number_integer:
   12706              :                 case detail::value_t::number_unsigned:
   12707              :                 case detail::value_t::number_float:
   12708              :                 case detail::value_t::binary:
   12709              :                 case detail::value_t::discarded:
   12710              :                 default:
   12711              :                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
   12712              :             }
   12713              :         }
   12714              : 
   12715              :         return *ptr;
   12716              :     }
   12717              : 
   12718              :     /*!
   12719              :     @throw parse_error.106   if an array index begins with '0'
   12720              :     @throw parse_error.109   if an array index was not a number
   12721              :     @throw out_of_range.402  if the array index '-' is used
   12722              :     @throw out_of_range.404  if the JSON pointer can not be resolved
   12723              :     */
   12724              :     const BasicJsonType& get_checked(const BasicJsonType* ptr) const
   12725              :     {
   12726              :         for (const auto& reference_token : reference_tokens)
   12727              :         {
   12728              :             switch (ptr->type())
   12729              :             {
   12730              :                 case detail::value_t::object:
   12731              :                 {
   12732              :                     // note: at performs range check
   12733              :                     ptr = &ptr->at(reference_token);
   12734              :                     break;
   12735              :                 }
   12736              : 
   12737              :                 case detail::value_t::array:
   12738              :                 {
   12739              :                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
   12740              :                     {
   12741              :                         // "-" always fails the range check
   12742              :                         JSON_THROW(detail::out_of_range::create(402,
   12743              :                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
   12744              :                                                                 ") is out of range", *ptr));
   12745              :                     }
   12746              : 
   12747              :                     // note: at performs range check
   12748              :                     ptr = &ptr->at(array_index(reference_token));
   12749              :                     break;
   12750              :                 }
   12751              : 
   12752              :                 case detail::value_t::null:
   12753              :                 case detail::value_t::string:
   12754              :                 case detail::value_t::boolean:
   12755              :                 case detail::value_t::number_integer:
   12756              :                 case detail::value_t::number_unsigned:
   12757              :                 case detail::value_t::number_float:
   12758              :                 case detail::value_t::binary:
   12759              :                 case detail::value_t::discarded:
   12760              :                 default:
   12761              :                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
   12762              :             }
   12763              :         }
   12764              : 
   12765              :         return *ptr;
   12766              :     }
   12767              : 
   12768              :     /*!
   12769              :     @throw parse_error.106   if an array index begins with '0'
   12770              :     @throw parse_error.109   if an array index was not a number
   12771              :     */
   12772              :     bool contains(const BasicJsonType* ptr) const
   12773              :     {
   12774              :         for (const auto& reference_token : reference_tokens)
   12775              :         {
   12776              :             switch (ptr->type())
   12777              :             {
   12778              :                 case detail::value_t::object:
   12779              :                 {
   12780              :                     if (!ptr->contains(reference_token))
   12781              :                     {
   12782              :                         // we did not find the key in the object
   12783              :                         return false;
   12784              :                     }
   12785              : 
   12786              :                     ptr = &ptr->operator[](reference_token);
   12787              :                     break;
   12788              :                 }
   12789              : 
   12790              :                 case detail::value_t::array:
   12791              :                 {
   12792              :                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
   12793              :                     {
   12794              :                         // "-" always fails the range check
   12795              :                         return false;
   12796              :                     }
   12797              :                     if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
   12798              :                     {
   12799              :                         // invalid char
   12800              :                         return false;
   12801              :                     }
   12802              :                     if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
   12803              :                     {
   12804              :                         if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
   12805              :                         {
   12806              :                             // first char should be between '1' and '9'
   12807              :                             return false;
   12808              :                         }
   12809              :                         for (std::size_t i = 1; i < reference_token.size(); i++)
   12810              :                         {
   12811              :                             if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
   12812              :                             {
   12813              :                                 // other char should be between '0' and '9'
   12814              :                                 return false;
   12815              :                             }
   12816              :                         }
   12817              :                     }
   12818              : 
   12819              :                     const auto idx = array_index(reference_token);
   12820              :                     if (idx >= ptr->size())
   12821              :                     {
   12822              :                         // index out of range
   12823              :                         return false;
   12824              :                     }
   12825              : 
   12826              :                     ptr = &ptr->operator[](idx);
   12827              :                     break;
   12828              :                 }
   12829              : 
   12830              :                 case detail::value_t::null:
   12831              :                 case detail::value_t::string:
   12832              :                 case detail::value_t::boolean:
   12833              :                 case detail::value_t::number_integer:
   12834              :                 case detail::value_t::number_unsigned:
   12835              :                 case detail::value_t::number_float:
   12836              :                 case detail::value_t::binary:
   12837              :                 case detail::value_t::discarded:
   12838              :                 default:
   12839              :                 {
   12840              :                     // we do not expect primitive values if there is still a
   12841              :                     // reference token to process
   12842              :                     return false;
   12843              :                 }
   12844              :             }
   12845              :         }
   12846              : 
   12847              :         // no reference token left means we found a primitive value
   12848              :         return true;
   12849              :     }
   12850              : 
   12851              :     /*!
   12852              :     @brief split the string input to reference tokens
   12853              : 
   12854              :     @note This function is only called by the json_pointer constructor.
   12855              :           All exceptions below are documented there.
   12856              : 
   12857              :     @throw parse_error.107  if the pointer is not empty or begins with '/'
   12858              :     @throw parse_error.108  if character '~' is not followed by '0' or '1'
   12859              :     */
   12860              :     static std::vector<std::string> split(const std::string& reference_string)
   12861              :     {
   12862              :         std::vector<std::string> result;
   12863              : 
   12864              :         // special case: empty reference string -> no reference tokens
   12865              :         if (reference_string.empty())
   12866              :         {
   12867              :             return result;
   12868              :         }
   12869              : 
   12870              :         // check if nonempty reference string begins with slash
   12871              :         if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
   12872              :         {
   12873              :             JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
   12874              :         }
   12875              : 
   12876              :         // extract the reference tokens:
   12877              :         // - slash: position of the last read slash (or end of string)
   12878              :         // - start: position after the previous slash
   12879              :         for (
   12880              :             // search for the first slash after the first character
   12881              :             std::size_t slash = reference_string.find_first_of('/', 1),
   12882              :             // set the beginning of the first reference token
   12883              :             start = 1;
   12884              :             // we can stop if start == 0 (if slash == std::string::npos)
   12885              :             start != 0;
   12886              :             // set the beginning of the next reference token
   12887              :             // (will eventually be 0 if slash == std::string::npos)
   12888              :             start = (slash == std::string::npos) ? 0 : slash + 1,
   12889              :             // find next slash
   12890              :             slash = reference_string.find_first_of('/', start))
   12891              :         {
   12892              :             // use the text between the beginning of the reference token
   12893              :             // (start) and the last slash (slash).
   12894              :             auto reference_token = reference_string.substr(start, slash - start);
   12895              : 
   12896              :             // check reference tokens are properly escaped
   12897              :             for (std::size_t pos = reference_token.find_first_of('~');
   12898              :                     pos != std::string::npos;
   12899              :                     pos = reference_token.find_first_of('~', pos + 1))
   12900              :             {
   12901              :                 JSON_ASSERT(reference_token[pos] == '~');
   12902              : 
   12903              :                 // ~ must be followed by 0 or 1
   12904              :                 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
   12905              :                                          (reference_token[pos + 1] != '0' &&
   12906              :                                           reference_token[pos + 1] != '1')))
   12907              :                 {
   12908              :                     JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
   12909              :                 }
   12910              :             }
   12911              : 
   12912              :             // finally, store the reference token
   12913              :             detail::unescape(reference_token);
   12914              :             result.push_back(reference_token);
   12915              :         }
   12916              : 
   12917              :         return result;
   12918              :     }
   12919              : 
   12920              :   private:
   12921              :     /*!
   12922              :     @param[in] reference_string  the reference string to the current value
   12923              :     @param[in] value             the value to consider
   12924              :     @param[in,out] result        the result object to insert values to
   12925              : 
   12926              :     @note Empty objects or arrays are flattened to `null`.
   12927              :     */
   12928              :     static void flatten(const std::string& reference_string,
   12929              :                         const BasicJsonType& value,
   12930              :                         BasicJsonType& result)
   12931              :     {
   12932              :         switch (value.type())
   12933              :         {
   12934              :             case detail::value_t::array:
   12935              :             {
   12936              :                 if (value.m_value.array->empty())
   12937              :                 {
   12938              :                     // flatten empty array as null
   12939              :                     result[reference_string] = nullptr;
   12940              :                 }
   12941              :                 else
   12942              :                 {
   12943              :                     // iterate array and use index as reference string
   12944              :                     for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
   12945              :                     {
   12946              :                         flatten(reference_string + "/" + std::to_string(i),
   12947              :                                 value.m_value.array->operator[](i), result);
   12948              :                     }
   12949              :                 }
   12950              :                 break;
   12951              :             }
   12952              : 
   12953              :             case detail::value_t::object:
   12954              :             {
   12955              :                 if (value.m_value.object->empty())
   12956              :                 {
   12957              :                     // flatten empty object as null
   12958              :                     result[reference_string] = nullptr;
   12959              :                 }
   12960              :                 else
   12961              :                 {
   12962              :                     // iterate object and use keys as reference string
   12963              :                     for (const auto& element : *value.m_value.object)
   12964              :                     {
   12965              :                         flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
   12966              :                     }
   12967              :                 }
   12968              :                 break;
   12969              :             }
   12970              : 
   12971              :             case detail::value_t::null:
   12972              :             case detail::value_t::string:
   12973              :             case detail::value_t::boolean:
   12974              :             case detail::value_t::number_integer:
   12975              :             case detail::value_t::number_unsigned:
   12976              :             case detail::value_t::number_float:
   12977              :             case detail::value_t::binary:
   12978              :             case detail::value_t::discarded:
   12979              :             default:
   12980              :             {
   12981              :                 // add primitive value with its reference string
   12982              :                 result[reference_string] = value;
   12983              :                 break;
   12984              :             }
   12985              :         }
   12986              :     }
   12987              : 
   12988              :     /*!
   12989              :     @param[in] value  flattened JSON
   12990              : 
   12991              :     @return unflattened JSON
   12992              : 
   12993              :     @throw parse_error.109 if array index is not a number
   12994              :     @throw type_error.314  if value is not an object
   12995              :     @throw type_error.315  if object values are not primitive
   12996              :     @throw type_error.313  if value cannot be unflattened
   12997              :     */
   12998              :     static BasicJsonType
   12999              :     unflatten(const BasicJsonType& value)
   13000              :     {
   13001              :         if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
   13002              :         {
   13003              :             JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
   13004              :         }
   13005              : 
   13006              :         BasicJsonType result;
   13007              : 
   13008              :         // iterate the JSON object values
   13009              :         for (const auto& element : *value.m_value.object)
   13010              :         {
   13011              :             if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
   13012              :             {
   13013              :                 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
   13014              :             }
   13015              : 
   13016              :             // assign value to reference pointed to by JSON pointer; Note that if
   13017              :             // the JSON pointer is "" (i.e., points to the whole value), function
   13018              :             // get_and_create returns a reference to result itself. An assignment
   13019              :             // will then create a primitive value.
   13020              :             json_pointer(element.first).get_and_create(result) = element.second;
   13021              :         }
   13022              : 
   13023              :         return result;
   13024              :     }
   13025              : 
   13026              :     /*!
   13027              :     @brief compares two JSON pointers for equality
   13028              : 
   13029              :     @param[in] lhs  JSON pointer to compare
   13030              :     @param[in] rhs  JSON pointer to compare
   13031              :     @return whether @a lhs is equal to @a rhs
   13032              : 
   13033              :     @complexity Linear in the length of the JSON pointer
   13034              : 
   13035              :     @exceptionsafety No-throw guarantee: this function never throws exceptions.
   13036              :     */
   13037              :     friend bool operator==(json_pointer const& lhs,
   13038              :                            json_pointer const& rhs) noexcept
   13039              :     {
   13040              :         return lhs.reference_tokens == rhs.reference_tokens;
   13041              :     }
   13042              : 
   13043              :     /*!
   13044              :     @brief compares two JSON pointers for inequality
   13045              : 
   13046              :     @param[in] lhs  JSON pointer to compare
   13047              :     @param[in] rhs  JSON pointer to compare
   13048              :     @return whether @a lhs is not equal @a rhs
   13049              : 
   13050              :     @complexity Linear in the length of the JSON pointer
   13051              : 
   13052              :     @exceptionsafety No-throw guarantee: this function never throws exceptions.
   13053              :     */
   13054              :     friend bool operator!=(json_pointer const& lhs,
   13055              :                            json_pointer const& rhs) noexcept
   13056              :     {
   13057              :         return !(lhs == rhs);
   13058              :     }
   13059              : 
   13060              :     /// the reference tokens
   13061              :     std::vector<std::string> reference_tokens;
   13062              : };
   13063              : }  // namespace nlohmann
   13064              : 
   13065              : // #include <nlohmann/detail/json_ref.hpp>
   13066              : 
   13067              : 
   13068              : #include <initializer_list>
   13069              : #include <utility>
   13070              : 
   13071              : // #include <nlohmann/detail/meta/type_traits.hpp>
   13072              : 
   13073              : 
   13074              : namespace nlohmann
   13075              : {
   13076              : namespace detail
   13077              : {
   13078              : template<typename BasicJsonType>
   13079              : class json_ref
   13080              : {
   13081              :   public:
   13082              :     using value_type = BasicJsonType;
   13083              : 
   13084              :     json_ref(value_type&& value)
   13085              :         : owned_value(std::move(value))
   13086              :     {}
   13087              : 
   13088              :     json_ref(const value_type& value)
   13089              :         : value_ref(&value)
   13090              :     {}
   13091              : 
   13092              :     json_ref(std::initializer_list<json_ref> init)
   13093              :         : owned_value(init)
   13094              :     {}
   13095              : 
   13096              :     template <
   13097              :         class... Args,
   13098              :         enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
   13099              :     json_ref(Args && ... args)
   13100              :         : owned_value(std::forward<Args>(args)...)
   13101              :     {}
   13102              : 
   13103              :     // class should be movable only
   13104              :     json_ref(json_ref&&) noexcept = default;
   13105              :     json_ref(const json_ref&) = delete;
   13106              :     json_ref& operator=(const json_ref&) = delete;
   13107              :     json_ref& operator=(json_ref&&) = delete;
   13108              :     ~json_ref() = default;
   13109              : 
   13110              :     value_type moved_or_copied() const
   13111              :     {
   13112              :         if (value_ref == nullptr)
   13113              :         {
   13114              :             return std::move(owned_value);
   13115              :         }
   13116              :         return *value_ref;
   13117              :     }
   13118              : 
   13119              :     value_type const& operator*() const
   13120              :     {
   13121              :         return value_ref ? *value_ref : owned_value;
   13122              :     }
   13123              : 
   13124              :     value_type const* operator->() const
   13125              :     {
   13126              :         return &** this;
   13127              :     }
   13128              : 
   13129              :   private:
   13130              :     mutable value_type owned_value = nullptr;
   13131              :     value_type const* value_ref = nullptr;
   13132              : };
   13133              : }  // namespace detail
   13134              : }  // namespace nlohmann
   13135              : 
   13136              : // #include <nlohmann/detail/macro_scope.hpp>
   13137              : 
   13138              : // #include <nlohmann/detail/string_escape.hpp>
   13139              : 
   13140              : // #include <nlohmann/detail/meta/cpp_future.hpp>
   13141              : 
   13142              : // #include <nlohmann/detail/meta/type_traits.hpp>
   13143              : 
   13144              : // #include <nlohmann/detail/output/binary_writer.hpp>
   13145              : 
   13146              : 
   13147              : #include <algorithm> // reverse
   13148              : #include <array> // array
   13149              : #include <cmath> // isnan, isinf
   13150              : #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
   13151              : #include <cstring> // memcpy
   13152              : #include <limits> // numeric_limits
   13153              : #include <string> // string
   13154              : #include <utility> // move
   13155              : 
   13156              : // #include <nlohmann/detail/input/binary_reader.hpp>
   13157              : 
   13158              : // #include <nlohmann/detail/macro_scope.hpp>
   13159              : 
   13160              : // #include <nlohmann/detail/output/output_adapters.hpp>
   13161              : 
   13162              : 
   13163              : #include <algorithm> // copy
   13164              : #include <cstddef> // size_t
   13165              : #include <iterator> // back_inserter
   13166              : #include <memory> // shared_ptr, make_shared
   13167              : #include <string> // basic_string
   13168              : #include <vector> // vector
   13169              : 
   13170              : #ifndef JSON_NO_IO
   13171              :     #include <ios>      // streamsize
   13172              :     #include <ostream>  // basic_ostream
   13173              : #endif  // JSON_NO_IO
   13174              : 
   13175              : // #include <nlohmann/detail/macro_scope.hpp>
   13176              : 
   13177              : 
   13178              : namespace nlohmann
   13179              : {
   13180              : namespace detail
   13181              : {
   13182              : /// abstract output adapter interface
   13183              : template<typename CharType> struct output_adapter_protocol
   13184              : {
   13185              :     virtual void write_character(CharType c) = 0;
   13186              :     virtual void write_characters(const CharType* s, std::size_t length) = 0;
   13187              :     virtual ~output_adapter_protocol() = default;
   13188              : 
   13189              :     output_adapter_protocol() = default;
   13190              :     output_adapter_protocol(const output_adapter_protocol&) = default;
   13191              :     output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
   13192              :     output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
   13193              :     output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
   13194              : };
   13195              : 
   13196              : /// a type to simplify interfaces
   13197              : template<typename CharType>
   13198              : using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
   13199              : 
   13200              : /// output adapter for byte vectors
   13201              : template<typename CharType, typename AllocatorType = std::allocator<CharType>>
   13202              : class output_vector_adapter : public output_adapter_protocol<CharType>
   13203              : {
   13204              :   public:
   13205              :     explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
   13206              :         : v(vec)
   13207              :     {}
   13208              : 
   13209              :     void write_character(CharType c) override
   13210              :     {
   13211              :         v.push_back(c);
   13212              :     }
   13213              : 
   13214              :     JSON_HEDLEY_NON_NULL(2)
   13215              :     void write_characters(const CharType* s, std::size_t length) override
   13216              :     {
   13217              :         std::copy(s, s + length, std::back_inserter(v));
   13218              :     }
   13219              : 
   13220              :   private:
   13221              :     std::vector<CharType, AllocatorType>& v;
   13222              : };
   13223              : 
   13224              : #ifndef JSON_NO_IO
   13225              : /// output adapter for output streams
   13226              : template<typename CharType>
   13227              : class output_stream_adapter : public output_adapter_protocol<CharType>
   13228              : {
   13229              :   public:
   13230              :     explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
   13231              :         : stream(s)
   13232              :     {}
   13233              : 
   13234              :     void write_character(CharType c) override
   13235              :     {
   13236              :         stream.put(c);
   13237              :     }
   13238              : 
   13239              :     JSON_HEDLEY_NON_NULL(2)
   13240              :     void write_characters(const CharType* s, std::size_t length) override
   13241              :     {
   13242              :         stream.write(s, static_cast<std::streamsize>(length));
   13243              :     }
   13244              : 
   13245              :   private:
   13246              :     std::basic_ostream<CharType>& stream;
   13247              : };
   13248              : #endif  // JSON_NO_IO
   13249              : 
   13250              : /// output adapter for basic_string
   13251              : template<typename CharType, typename StringType = std::basic_string<CharType>>
   13252              : class output_string_adapter : public output_adapter_protocol<CharType>
   13253              : {
   13254              :   public:
   13255              :     explicit output_string_adapter(StringType& s) noexcept
   13256              :         : str(s)
   13257              :     {}
   13258              : 
   13259              :     void write_character(CharType c) override
   13260              :     {
   13261              :         str.push_back(c);
   13262              :     }
   13263              : 
   13264              :     JSON_HEDLEY_NON_NULL(2)
   13265              :     void write_characters(const CharType* s, std::size_t length) override
   13266              :     {
   13267              :         str.append(s, length);
   13268              :     }
   13269              : 
   13270              :   private:
   13271              :     StringType& str;
   13272              : };
   13273              : 
   13274              : template<typename CharType, typename StringType = std::basic_string<CharType>>
   13275              : class output_adapter
   13276              : {
   13277              :   public:
   13278              :     template<typename AllocatorType = std::allocator<CharType>>
   13279              :     output_adapter(std::vector<CharType, AllocatorType>& vec)
   13280              :         : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
   13281              : 
   13282              : #ifndef JSON_NO_IO
   13283              :     output_adapter(std::basic_ostream<CharType>& s)
   13284              :         : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
   13285              : #endif  // JSON_NO_IO
   13286              : 
   13287              :     output_adapter(StringType& s)
   13288              :         : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
   13289              : 
   13290              :     operator output_adapter_t<CharType>()
   13291              :     {
   13292              :         return oa;
   13293              :     }
   13294              : 
   13295              :   private:
   13296              :     output_adapter_t<CharType> oa = nullptr;
   13297              : };
   13298              : }  // namespace detail
   13299              : }  // namespace nlohmann
   13300              : 
   13301              : 
   13302              : namespace nlohmann
   13303              : {
   13304              : namespace detail
   13305              : {
   13306              : ///////////////////
   13307              : // binary writer //
   13308              : ///////////////////
   13309              : 
   13310              : /*!
   13311              : @brief serialization to CBOR and MessagePack values
   13312              : */
   13313              : template<typename BasicJsonType, typename CharType>
   13314              : class binary_writer
   13315              : {
   13316              :     using string_t = typename BasicJsonType::string_t;
   13317              :     using binary_t = typename BasicJsonType::binary_t;
   13318              :     using number_float_t = typename BasicJsonType::number_float_t;
   13319              : 
   13320              :   public:
   13321              :     /*!
   13322              :     @brief create a binary writer
   13323              : 
   13324              :     @param[in] adapter  output adapter to write to
   13325              :     */
   13326              :     explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
   13327              :     {
   13328              :         JSON_ASSERT(oa);
   13329              :     }
   13330              : 
   13331              :     /*!
   13332              :     @param[in] j  JSON value to serialize
   13333              :     @pre       j.type() == value_t::object
   13334              :     */
   13335              :     void write_bson(const BasicJsonType& j)
   13336              :     {
   13337              :         switch (j.type())
   13338              :         {
   13339              :             case value_t::object:
   13340              :             {
   13341              :                 write_bson_object(*j.m_value.object);
   13342              :                 break;
   13343              :             }
   13344              : 
   13345              :             case value_t::null:
   13346              :             case value_t::array:
   13347              :             case value_t::string:
   13348              :             case value_t::boolean:
   13349              :             case value_t::number_integer:
   13350              :             case value_t::number_unsigned:
   13351              :             case value_t::number_float:
   13352              :             case value_t::binary:
   13353              :             case value_t::discarded:
   13354              :             default:
   13355              :             {
   13356              :                 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
   13357              :             }
   13358              :         }
   13359              :     }
   13360              : 
   13361              :     /*!
   13362              :     @param[in] j  JSON value to serialize
   13363              :     */
   13364              :     void write_cbor(const BasicJsonType& j)
   13365              :     {
   13366              :         switch (j.type())
   13367              :         {
   13368              :             case value_t::null:
   13369              :             {
   13370              :                 oa->write_character(to_char_type(0xF6));
   13371              :                 break;
   13372              :             }
   13373              : 
   13374              :             case value_t::boolean:
   13375              :             {
   13376              :                 oa->write_character(j.m_value.boolean
   13377              :                                     ? to_char_type(0xF5)
   13378              :                                     : to_char_type(0xF4));
   13379              :                 break;
   13380              :             }
   13381              : 
   13382              :             case value_t::number_integer:
   13383              :             {
   13384              :                 if (j.m_value.number_integer >= 0)
   13385              :                 {
   13386              :                     // CBOR does not differentiate between positive signed
   13387              :                     // integers and unsigned integers. Therefore, we used the
   13388              :                     // code from the value_t::number_unsigned case here.
   13389              :                     if (j.m_value.number_integer <= 0x17)
   13390              :                     {
   13391              :                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
   13392              :                     }
   13393              :                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
   13394              :                     {
   13395              :                         oa->write_character(to_char_type(0x18));
   13396              :                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
   13397              :                     }
   13398              :                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
   13399              :                     {
   13400              :                         oa->write_character(to_char_type(0x19));
   13401              :                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
   13402              :                     }
   13403              :                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
   13404              :                     {
   13405              :                         oa->write_character(to_char_type(0x1A));
   13406              :                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
   13407              :                     }
   13408              :                     else
   13409              :                     {
   13410              :                         oa->write_character(to_char_type(0x1B));
   13411              :                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
   13412              :                     }
   13413              :                 }
   13414              :                 else
   13415              :                 {
   13416              :                     // The conversions below encode the sign in the first
   13417              :                     // byte, and the value is converted to a positive number.
   13418              :                     const auto positive_number = -1 - j.m_value.number_integer;
   13419              :                     if (j.m_value.number_integer >= -24)
   13420              :                     {
   13421              :                         write_number(static_cast<std::uint8_t>(0x20 + positive_number));
   13422              :                     }
   13423              :                     else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
   13424              :                     {
   13425              :                         oa->write_character(to_char_type(0x38));
   13426              :                         write_number(static_cast<std::uint8_t>(positive_number));
   13427              :                     }
   13428              :                     else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
   13429              :                     {
   13430              :                         oa->write_character(to_char_type(0x39));
   13431              :                         write_number(static_cast<std::uint16_t>(positive_number));
   13432              :                     }
   13433              :                     else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
   13434              :                     {
   13435              :                         oa->write_character(to_char_type(0x3A));
   13436              :                         write_number(static_cast<std::uint32_t>(positive_number));
   13437              :                     }
   13438              :                     else
   13439              :                     {
   13440              :                         oa->write_character(to_char_type(0x3B));
   13441              :                         write_number(static_cast<std::uint64_t>(positive_number));
   13442              :                     }
   13443              :                 }
   13444              :                 break;
   13445              :             }
   13446              : 
   13447              :             case value_t::number_unsigned:
   13448              :             {
   13449              :                 if (j.m_value.number_unsigned <= 0x17)
   13450              :                 {
   13451              :                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
   13452              :                 }
   13453              :                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
   13454              :                 {
   13455              :                     oa->write_character(to_char_type(0x18));
   13456              :                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
   13457              :                 }
   13458              :                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
   13459              :                 {
   13460              :                     oa->write_character(to_char_type(0x19));
   13461              :                     write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
   13462              :                 }
   13463              :                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
   13464              :                 {
   13465              :                     oa->write_character(to_char_type(0x1A));
   13466              :                     write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
   13467              :                 }
   13468              :                 else
   13469              :                 {
   13470              :                     oa->write_character(to_char_type(0x1B));
   13471              :                     write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
   13472              :                 }
   13473              :                 break;
   13474              :             }
   13475              : 
   13476              :             case value_t::number_float:
   13477              :             {
   13478              :                 if (std::isnan(j.m_value.number_float))
   13479              :                 {
   13480              :                     // NaN is 0xf97e00 in CBOR
   13481              :                     oa->write_character(to_char_type(0xF9));
   13482              :                     oa->write_character(to_char_type(0x7E));
   13483              :                     oa->write_character(to_char_type(0x00));
   13484              :                 }
   13485              :                 else if (std::isinf(j.m_value.number_float))
   13486              :                 {
   13487              :                     // Infinity is 0xf97c00, -Infinity is 0xf9fc00
   13488              :                     oa->write_character(to_char_type(0xf9));
   13489              :                     oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
   13490              :                     oa->write_character(to_char_type(0x00));
   13491              :                 }
   13492              :                 else
   13493              :                 {
   13494              :                     write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
   13495              :                 }
   13496              :                 break;
   13497              :             }
   13498              : 
   13499              :             case value_t::string:
   13500              :             {
   13501              :                 // step 1: write control byte and the string length
   13502              :                 const auto N = j.m_value.string->size();
   13503              :                 if (N <= 0x17)
   13504              :                 {
   13505              :                     write_number(static_cast<std::uint8_t>(0x60 + N));
   13506              :                 }
   13507              :                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
   13508              :                 {
   13509              :                     oa->write_character(to_char_type(0x78));
   13510              :                     write_number(static_cast<std::uint8_t>(N));
   13511              :                 }
   13512              :                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
   13513              :                 {
   13514              :                     oa->write_character(to_char_type(0x79));
   13515              :                     write_number(static_cast<std::uint16_t>(N));
   13516              :                 }
   13517              :                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
   13518              :                 {
   13519              :                     oa->write_character(to_char_type(0x7A));
   13520              :                     write_number(static_cast<std::uint32_t>(N));
   13521              :                 }
   13522              :                 // LCOV_EXCL_START
   13523              :                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
   13524              :                 {
   13525              :                     oa->write_character(to_char_type(0x7B));
   13526              :                     write_number(static_cast<std::uint64_t>(N));
   13527              :                 }
   13528              :                 // LCOV_EXCL_STOP
   13529              : 
   13530              :                 // step 2: write the string
   13531              :                 oa->write_characters(
   13532              :                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
   13533              :                     j.m_value.string->size());
   13534              :                 break;
   13535              :             }
   13536              : 
   13537              :             case value_t::array:
   13538              :             {
   13539              :                 // step 1: write control byte and the array size
   13540              :                 const auto N = j.m_value.array->size();
   13541              :                 if (N <= 0x17)
   13542              :                 {
   13543              :                     write_number(static_cast<std::uint8_t>(0x80 + N));
   13544              :                 }
   13545              :                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
   13546              :                 {
   13547              :                     oa->write_character(to_char_type(0x98));
   13548              :                     write_number(static_cast<std::uint8_t>(N));
   13549              :                 }
   13550              :                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
   13551              :                 {
   13552              :                     oa->write_character(to_char_type(0x99));
   13553              :                     write_number(static_cast<std::uint16_t>(N));
   13554              :                 }
   13555              :                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
   13556              :                 {
   13557              :                     oa->write_character(to_char_type(0x9A));
   13558              :                     write_number(static_cast<std::uint32_t>(N));
   13559              :                 }
   13560              :                 // LCOV_EXCL_START
   13561              :                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
   13562              :                 {
   13563              :                     oa->write_character(to_char_type(0x9B));
   13564              :                     write_number(static_cast<std::uint64_t>(N));
   13565              :                 }
   13566              :                 // LCOV_EXCL_STOP
   13567              : 
   13568              :                 // step 2: write each element
   13569              :                 for (const auto& el : *j.m_value.array)
   13570              :                 {
   13571              :                     write_cbor(el);
   13572              :                 }
   13573              :                 break;
   13574              :             }
   13575              : 
   13576              :             case value_t::binary:
   13577              :             {
   13578              :                 if (j.m_value.binary->has_subtype())
   13579              :                 {
   13580              :                     if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
   13581              :                     {
   13582              :                         write_number(static_cast<std::uint8_t>(0xd8));
   13583              :                         write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
   13584              :                     }
   13585              :                     else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
   13586              :                     {
   13587              :                         write_number(static_cast<std::uint8_t>(0xd9));
   13588              :                         write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
   13589              :                     }
   13590              :                     else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
   13591              :                     {
   13592              :                         write_number(static_cast<std::uint8_t>(0xda));
   13593              :                         write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
   13594              :                     }
   13595              :                     else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
   13596              :                     {
   13597              :                         write_number(static_cast<std::uint8_t>(0xdb));
   13598              :                         write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
   13599              :                     }
   13600              :                 }
   13601              : 
   13602              :                 // step 1: write control byte and the binary array size
   13603              :                 const auto N = j.m_value.binary->size();
   13604              :                 if (N <= 0x17)
   13605              :                 {
   13606              :                     write_number(static_cast<std::uint8_t>(0x40 + N));
   13607              :                 }
   13608              :                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
   13609              :                 {
   13610              :                     oa->write_character(to_char_type(0x58));
   13611              :                     write_number(static_cast<std::uint8_t>(N));
   13612              :                 }
   13613              :                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
   13614              :                 {
   13615              :                     oa->write_character(to_char_type(0x59));
   13616              :                     write_number(static_cast<std::uint16_t>(N));
   13617              :                 }
   13618              :                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
   13619              :                 {
   13620              :                     oa->write_character(to_char_type(0x5A));
   13621              :                     write_number(static_cast<std::uint32_t>(N));
   13622              :                 }
   13623              :                 // LCOV_EXCL_START
   13624              :                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
   13625              :                 {
   13626              :                     oa->write_character(to_char_type(0x5B));
   13627              :                     write_number(static_cast<std::uint64_t>(N));
   13628              :                 }
   13629              :                 // LCOV_EXCL_STOP
   13630              : 
   13631              :                 // step 2: write each element
   13632              :                 oa->write_characters(
   13633              :                     reinterpret_cast<const CharType*>(j.m_value.binary->data()),
   13634              :                     N);
   13635              : 
   13636              :                 break;
   13637              :             }
   13638              : 
   13639              :             case value_t::object:
   13640              :             {
   13641              :                 // step 1: write control byte and the object size
   13642              :                 const auto N = j.m_value.object->size();
   13643              :                 if (N <= 0x17)
   13644              :                 {
   13645              :                     write_number(static_cast<std::uint8_t>(0xA0 + N));
   13646              :                 }
   13647              :                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
   13648              :                 {
   13649              :                     oa->write_character(to_char_type(0xB8));
   13650              :                     write_number(static_cast<std::uint8_t>(N));
   13651              :                 }
   13652              :                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
   13653              :                 {
   13654              :                     oa->write_character(to_char_type(0xB9));
   13655              :                     write_number(static_cast<std::uint16_t>(N));
   13656              :                 }
   13657              :                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
   13658              :                 {
   13659              :                     oa->write_character(to_char_type(0xBA));
   13660              :                     write_number(static_cast<std::uint32_t>(N));
   13661              :                 }
   13662              :                 // LCOV_EXCL_START
   13663              :                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
   13664              :                 {
   13665              :                     oa->write_character(to_char_type(0xBB));
   13666              :                     write_number(static_cast<std::uint64_t>(N));
   13667              :                 }
   13668              :                 // LCOV_EXCL_STOP
   13669              : 
   13670              :                 // step 2: write each element
   13671              :                 for (const auto& el : *j.m_value.object)
   13672              :                 {
   13673              :                     write_cbor(el.first);
   13674              :                     write_cbor(el.second);
   13675              :                 }
   13676              :                 break;
   13677              :             }
   13678              : 
   13679              :             case value_t::discarded:
   13680              :             default:
   13681              :                 break;
   13682              :         }
   13683              :     }
   13684              : 
   13685              :     /*!
   13686              :     @param[in] j  JSON value to serialize
   13687              :     */
   13688              :     void write_msgpack(const BasicJsonType& j)
   13689              :     {
   13690              :         switch (j.type())
   13691              :         {
   13692              :             case value_t::null: // nil
   13693              :             {
   13694              :                 oa->write_character(to_char_type(0xC0));
   13695              :                 break;
   13696              :             }
   13697              : 
   13698              :             case value_t::boolean: // true and false
   13699              :             {
   13700              :                 oa->write_character(j.m_value.boolean
   13701              :                                     ? to_char_type(0xC3)
   13702              :                                     : to_char_type(0xC2));
   13703              :                 break;
   13704              :             }
   13705              : 
   13706              :             case value_t::number_integer:
   13707              :             {
   13708              :                 if (j.m_value.number_integer >= 0)
   13709              :                 {
   13710              :                     // MessagePack does not differentiate between positive
   13711              :                     // signed integers and unsigned integers. Therefore, we used
   13712              :                     // the code from the value_t::number_unsigned case here.
   13713              :                     if (j.m_value.number_unsigned < 128)
   13714              :                     {
   13715              :                         // positive fixnum
   13716              :                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
   13717              :                     }
   13718              :                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
   13719              :                     {
   13720              :                         // uint 8
   13721              :                         oa->write_character(to_char_type(0xCC));
   13722              :                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
   13723              :                     }
   13724              :                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
   13725              :                     {
   13726              :                         // uint 16
   13727              :                         oa->write_character(to_char_type(0xCD));
   13728              :                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
   13729              :                     }
   13730              :                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
   13731              :                     {
   13732              :                         // uint 32
   13733              :                         oa->write_character(to_char_type(0xCE));
   13734              :                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
   13735              :                     }
   13736              :                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
   13737              :                     {
   13738              :                         // uint 64
   13739              :                         oa->write_character(to_char_type(0xCF));
   13740              :                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
   13741              :                     }
   13742              :                 }
   13743              :                 else
   13744              :                 {
   13745              :                     if (j.m_value.number_integer >= -32)
   13746              :                     {
   13747              :                         // negative fixnum
   13748              :                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
   13749              :                     }
   13750              :                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
   13751              :                              j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
   13752              :                     {
   13753              :                         // int 8
   13754              :                         oa->write_character(to_char_type(0xD0));
   13755              :                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
   13756              :                     }
   13757              :                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
   13758              :                              j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
   13759              :                     {
   13760              :                         // int 16
   13761              :                         oa->write_character(to_char_type(0xD1));
   13762              :                         write_number(static_cast<std::int16_t>(j.m_value.number_integer));
   13763              :                     }
   13764              :                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
   13765              :                              j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
   13766              :                     {
   13767              :                         // int 32
   13768              :                         oa->write_character(to_char_type(0xD2));
   13769              :                         write_number(static_cast<std::int32_t>(j.m_value.number_integer));
   13770              :                     }
   13771              :                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
   13772              :                              j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
   13773              :                     {
   13774              :                         // int 64
   13775              :                         oa->write_character(to_char_type(0xD3));
   13776              :                         write_number(static_cast<std::int64_t>(j.m_value.number_integer));
   13777              :                     }
   13778              :                 }
   13779              :                 break;
   13780              :             }
   13781              : 
   13782              :             case value_t::number_unsigned:
   13783              :             {
   13784              :                 if (j.m_value.number_unsigned < 128)
   13785              :                 {
   13786              :                     // positive fixnum
   13787              :                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
   13788              :                 }
   13789              :                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
   13790              :                 {
   13791              :                     // uint 8
   13792              :                     oa->write_character(to_char_type(0xCC));
   13793              :                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
   13794              :                 }
   13795              :                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
   13796              :                 {
   13797              :                     // uint 16
   13798              :                     oa->write_character(to_char_type(0xCD));
   13799              :                     write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
   13800              :                 }
   13801              :                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
   13802              :                 {
   13803              :                     // uint 32
   13804              :                     oa->write_character(to_char_type(0xCE));
   13805              :                     write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
   13806              :                 }
   13807              :                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
   13808              :                 {
   13809              :                     // uint 64
   13810              :                     oa->write_character(to_char_type(0xCF));
   13811              :                     write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
   13812              :                 }
   13813              :                 break;
   13814              :             }
   13815              : 
   13816              :             case value_t::number_float:
   13817              :             {
   13818              :                 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
   13819              :                 break;
   13820              :             }
   13821              : 
   13822              :             case value_t::string:
   13823              :             {
   13824              :                 // step 1: write control byte and the string length
   13825              :                 const auto N = j.m_value.string->size();
   13826              :                 if (N <= 31)
   13827              :                 {
   13828              :                     // fixstr
   13829              :                     write_number(static_cast<std::uint8_t>(0xA0 | N));
   13830              :                 }
   13831              :                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
   13832              :                 {
   13833              :                     // str 8
   13834              :                     oa->write_character(to_char_type(0xD9));
   13835              :                     write_number(static_cast<std::uint8_t>(N));
   13836              :                 }
   13837              :                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
   13838              :                 {
   13839              :                     // str 16
   13840              :                     oa->write_character(to_char_type(0xDA));
   13841              :                     write_number(static_cast<std::uint16_t>(N));
   13842              :                 }
   13843              :                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
   13844              :                 {
   13845              :                     // str 32
   13846              :                     oa->write_character(to_char_type(0xDB));
   13847              :                     write_number(static_cast<std::uint32_t>(N));
   13848              :                 }
   13849              : 
   13850              :                 // step 2: write the string
   13851              :                 oa->write_characters(
   13852              :                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
   13853              :                     j.m_value.string->size());
   13854              :                 break;
   13855              :             }
   13856              : 
   13857              :             case value_t::array:
   13858              :             {
   13859              :                 // step 1: write control byte and the array size
   13860              :                 const auto N = j.m_value.array->size();
   13861              :                 if (N <= 15)
   13862              :                 {
   13863              :                     // fixarray
   13864              :                     write_number(static_cast<std::uint8_t>(0x90 | N));
   13865              :                 }
   13866              :                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
   13867              :                 {
   13868              :                     // array 16
   13869              :                     oa->write_character(to_char_type(0xDC));
   13870              :                     write_number(static_cast<std::uint16_t>(N));
   13871              :                 }
   13872              :                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
   13873              :                 {
   13874              :                     // array 32
   13875              :                     oa->write_character(to_char_type(0xDD));
   13876              :                     write_number(static_cast<std::uint32_t>(N));
   13877              :                 }
   13878              : 
   13879              :                 // step 2: write each element
   13880              :                 for (const auto& el : *j.m_value.array)
   13881              :                 {
   13882              :                     write_msgpack(el);
   13883              :                 }
   13884              :                 break;
   13885              :             }
   13886              : 
   13887              :             case value_t::binary:
   13888              :             {
   13889              :                 // step 0: determine if the binary type has a set subtype to
   13890              :                 // determine whether or not to use the ext or fixext types
   13891              :                 const bool use_ext = j.m_value.binary->has_subtype();
   13892              : 
   13893              :                 // step 1: write control byte and the byte string length
   13894              :                 const auto N = j.m_value.binary->size();
   13895              :                 if (N <= (std::numeric_limits<std::uint8_t>::max)())
   13896              :                 {
   13897              :                     std::uint8_t output_type{};
   13898              :                     bool fixed = true;
   13899              :                     if (use_ext)
   13900              :                     {
   13901              :                         switch (N)
   13902              :                         {
   13903              :                             case 1:
   13904              :                                 output_type = 0xD4; // fixext 1
   13905              :                                 break;
   13906              :                             case 2:
   13907              :                                 output_type = 0xD5; // fixext 2
   13908              :                                 break;
   13909              :                             case 4:
   13910              :                                 output_type = 0xD6; // fixext 4
   13911              :                                 break;
   13912              :                             case 8:
   13913              :                                 output_type = 0xD7; // fixext 8
   13914              :                                 break;
   13915              :                             case 16:
   13916              :                                 output_type = 0xD8; // fixext 16
   13917              :                                 break;
   13918              :                             default:
   13919              :                                 output_type = 0xC7; // ext 8
   13920              :                                 fixed = false;
   13921              :                                 break;
   13922              :                         }
   13923              : 
   13924              :                     }
   13925              :                     else
   13926              :                     {
   13927              :                         output_type = 0xC4; // bin 8
   13928              :                         fixed = false;
   13929              :                     }
   13930              : 
   13931              :                     oa->write_character(to_char_type(output_type));
   13932              :                     if (!fixed)
   13933              :                     {
   13934              :                         write_number(static_cast<std::uint8_t>(N));
   13935              :                     }
   13936              :                 }
   13937              :                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
   13938              :                 {
   13939              :                     std::uint8_t output_type = use_ext
   13940              :                                                ? 0xC8 // ext 16
   13941              :                                                : 0xC5; // bin 16
   13942              : 
   13943              :                     oa->write_character(to_char_type(output_type));
   13944              :                     write_number(static_cast<std::uint16_t>(N));
   13945              :                 }
   13946              :                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
   13947              :                 {
   13948              :                     std::uint8_t output_type = use_ext
   13949              :                                                ? 0xC9 // ext 32
   13950              :                                                : 0xC6; // bin 32
   13951              : 
   13952              :                     oa->write_character(to_char_type(output_type));
   13953              :                     write_number(static_cast<std::uint32_t>(N));
   13954              :                 }
   13955              : 
   13956              :                 // step 1.5: if this is an ext type, write the subtype
   13957              :                 if (use_ext)
   13958              :                 {
   13959              :                     write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
   13960              :                 }
   13961              : 
   13962              :                 // step 2: write the byte string
   13963              :                 oa->write_characters(
   13964              :                     reinterpret_cast<const CharType*>(j.m_value.binary->data()),
   13965              :                     N);
   13966              : 
   13967              :                 break;
   13968              :             }
   13969              : 
   13970              :             case value_t::object:
   13971              :             {
   13972              :                 // step 1: write control byte and the object size
   13973              :                 const auto N = j.m_value.object->size();
   13974              :                 if (N <= 15)
   13975              :                 {
   13976              :                     // fixmap
   13977              :                     write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
   13978              :                 }
   13979              :                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
   13980              :                 {
   13981              :                     // map 16
   13982              :                     oa->write_character(to_char_type(0xDE));
   13983              :                     write_number(static_cast<std::uint16_t>(N));
   13984              :                 }
   13985              :                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
   13986              :                 {
   13987              :                     // map 32
   13988              :                     oa->write_character(to_char_type(0xDF));
   13989              :                     write_number(static_cast<std::uint32_t>(N));
   13990              :                 }
   13991              : 
   13992              :                 // step 2: write each element
   13993              :                 for (const auto& el : *j.m_value.object)
   13994              :                 {
   13995              :                     write_msgpack(el.first);
   13996              :                     write_msgpack(el.second);
   13997              :                 }
   13998              :                 break;
   13999              :             }
   14000              : 
   14001              :             case value_t::discarded:
   14002              :             default:
   14003              :                 break;
   14004              :         }
   14005              :     }
   14006              : 
   14007              :     /*!
   14008              :     @param[in] j  JSON value to serialize
   14009              :     @param[in] use_count   whether to use '#' prefixes (optimized format)
   14010              :     @param[in] use_type    whether to use '$' prefixes (optimized format)
   14011              :     @param[in] add_prefix  whether prefixes need to be used for this value
   14012              :     */
   14013              :     void write_ubjson(const BasicJsonType& j, const bool use_count,
   14014              :                       const bool use_type, const bool add_prefix = true)
   14015              :     {
   14016              :         switch (j.type())
   14017              :         {
   14018              :             case value_t::null:
   14019              :             {
   14020              :                 if (add_prefix)
   14021              :                 {
   14022              :                     oa->write_character(to_char_type('Z'));
   14023              :                 }
   14024              :                 break;
   14025              :             }
   14026              : 
   14027              :             case value_t::boolean:
   14028              :             {
   14029              :                 if (add_prefix)
   14030              :                 {
   14031              :                     oa->write_character(j.m_value.boolean
   14032              :                                         ? to_char_type('T')
   14033              :                                         : to_char_type('F'));
   14034              :                 }
   14035              :                 break;
   14036              :             }
   14037              : 
   14038              :             case value_t::number_integer:
   14039              :             {
   14040              :                 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
   14041              :                 break;
   14042              :             }
   14043              : 
   14044              :             case value_t::number_unsigned:
   14045              :             {
   14046              :                 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
   14047              :                 break;
   14048              :             }
   14049              : 
   14050              :             case value_t::number_float:
   14051              :             {
   14052              :                 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
   14053              :                 break;
   14054              :             }
   14055              : 
   14056              :             case value_t::string:
   14057              :             {
   14058              :                 if (add_prefix)
   14059              :                 {
   14060              :                     oa->write_character(to_char_type('S'));
   14061              :                 }
   14062              :                 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
   14063              :                 oa->write_characters(
   14064              :                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
   14065              :                     j.m_value.string->size());
   14066              :                 break;
   14067              :             }
   14068              : 
   14069              :             case value_t::array:
   14070              :             {
   14071              :                 if (add_prefix)
   14072              :                 {
   14073              :                     oa->write_character(to_char_type('['));
   14074              :                 }
   14075              : 
   14076              :                 bool prefix_required = true;
   14077              :                 if (use_type && !j.m_value.array->empty())
   14078              :                 {
   14079              :                     JSON_ASSERT(use_count);
   14080              :                     const CharType first_prefix = ubjson_prefix(j.front());
   14081              :                     const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
   14082              :                                                          [this, first_prefix](const BasicJsonType & v)
   14083              :                     {
   14084              :                         return ubjson_prefix(v) == first_prefix;
   14085              :                     });
   14086              : 
   14087              :                     if (same_prefix)
   14088              :                     {
   14089              :                         prefix_required = false;
   14090              :                         oa->write_character(to_char_type('$'));
   14091              :                         oa->write_character(first_prefix);
   14092              :                     }
   14093              :                 }
   14094              : 
   14095              :                 if (use_count)
   14096              :                 {
   14097              :                     oa->write_character(to_char_type('#'));
   14098              :                     write_number_with_ubjson_prefix(j.m_value.array->size(), true);
   14099              :                 }
   14100              : 
   14101              :                 for (const auto& el : *j.m_value.array)
   14102              :                 {
   14103              :                     write_ubjson(el, use_count, use_type, prefix_required);
   14104              :                 }
   14105              : 
   14106              :                 if (!use_count)
   14107              :                 {
   14108              :                     oa->write_character(to_char_type(']'));
   14109              :                 }
   14110              : 
   14111              :                 break;
   14112              :             }
   14113              : 
   14114              :             case value_t::binary:
   14115              :             {
   14116              :                 if (add_prefix)
   14117              :                 {
   14118              :                     oa->write_character(to_char_type('['));
   14119              :                 }
   14120              : 
   14121              :                 if (use_type && !j.m_value.binary->empty())
   14122              :                 {
   14123              :                     JSON_ASSERT(use_count);
   14124              :                     oa->write_character(to_char_type('$'));
   14125              :                     oa->write_character('U');
   14126              :                 }
   14127              : 
   14128              :                 if (use_count)
   14129              :                 {
   14130              :                     oa->write_character(to_char_type('#'));
   14131              :                     write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
   14132              :                 }
   14133              : 
   14134              :                 if (use_type)
   14135              :                 {
   14136              :                     oa->write_characters(
   14137              :                         reinterpret_cast<const CharType*>(j.m_value.binary->data()),
   14138              :                         j.m_value.binary->size());
   14139              :                 }
   14140              :                 else
   14141              :                 {
   14142              :                     for (size_t i = 0; i < j.m_value.binary->size(); ++i)
   14143              :                     {
   14144              :                         oa->write_character(to_char_type('U'));
   14145              :                         oa->write_character(j.m_value.binary->data()[i]);
   14146              :                     }
   14147              :                 }
   14148              : 
   14149              :                 if (!use_count)
   14150              :                 {
   14151              :                     oa->write_character(to_char_type(']'));
   14152              :                 }
   14153              : 
   14154              :                 break;
   14155              :             }
   14156              : 
   14157              :             case value_t::object:
   14158              :             {
   14159              :                 if (add_prefix)
   14160              :                 {
   14161              :                     oa->write_character(to_char_type('{'));
   14162              :                 }
   14163              : 
   14164              :                 bool prefix_required = true;
   14165              :                 if (use_type && !j.m_value.object->empty())
   14166              :                 {
   14167              :                     JSON_ASSERT(use_count);
   14168              :                     const CharType first_prefix = ubjson_prefix(j.front());
   14169              :                     const bool same_prefix = std::all_of(j.begin(), j.end(),
   14170              :                                                          [this, first_prefix](const BasicJsonType & v)
   14171              :                     {
   14172              :                         return ubjson_prefix(v) == first_prefix;
   14173              :                     });
   14174              : 
   14175              :                     if (same_prefix)
   14176              :                     {
   14177              :                         prefix_required = false;
   14178              :                         oa->write_character(to_char_type('$'));
   14179              :                         oa->write_character(first_prefix);
   14180              :                     }
   14181              :                 }
   14182              : 
   14183              :                 if (use_count)
   14184              :                 {
   14185              :                     oa->write_character(to_char_type('#'));
   14186              :                     write_number_with_ubjson_prefix(j.m_value.object->size(), true);
   14187              :                 }
   14188              : 
   14189              :                 for (const auto& el : *j.m_value.object)
   14190              :                 {
   14191              :                     write_number_with_ubjson_prefix(el.first.size(), true);
   14192              :                     oa->write_characters(
   14193              :                         reinterpret_cast<const CharType*>(el.first.c_str()),
   14194              :                         el.first.size());
   14195              :                     write_ubjson(el.second, use_count, use_type, prefix_required);
   14196              :                 }
   14197              : 
   14198              :                 if (!use_count)
   14199              :                 {
   14200              :                     oa->write_character(to_char_type('}'));
   14201              :                 }
   14202              : 
   14203              :                 break;
   14204              :             }
   14205              : 
   14206              :             case value_t::discarded:
   14207              :             default:
   14208              :                 break;
   14209              :         }
   14210              :     }
   14211              : 
   14212              :   private:
   14213              :     //////////
   14214              :     // BSON //
   14215              :     //////////
   14216              : 
   14217              :     /*!
   14218              :     @return The size of a BSON document entry header, including the id marker
   14219              :             and the entry name size (and its null-terminator).
   14220              :     */
   14221              :     static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
   14222              :     {
   14223              :         const auto it = name.find(static_cast<typename string_t::value_type>(0));
   14224              :         if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
   14225              :         {
   14226              :             JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
   14227              :             static_cast<void>(j);
   14228              :         }
   14229              : 
   14230              :         return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
   14231              :     }
   14232              : 
   14233              :     /*!
   14234              :     @brief Writes the given @a element_type and @a name to the output adapter
   14235              :     */
   14236              :     void write_bson_entry_header(const string_t& name,
   14237              :                                  const std::uint8_t element_type)
   14238              :     {
   14239              :         oa->write_character(to_char_type(element_type)); // boolean
   14240              :         oa->write_characters(
   14241              :             reinterpret_cast<const CharType*>(name.c_str()),
   14242              :             name.size() + 1u);
   14243              :     }
   14244              : 
   14245              :     /*!
   14246              :     @brief Writes a BSON element with key @a name and boolean value @a value
   14247              :     */
   14248              :     void write_bson_boolean(const string_t& name,
   14249              :                             const bool value)
   14250              :     {
   14251              :         write_bson_entry_header(name, 0x08);
   14252              :         oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
   14253              :     }
   14254              : 
   14255              :     /*!
   14256              :     @brief Writes a BSON element with key @a name and double value @a value
   14257              :     */
   14258              :     void write_bson_double(const string_t& name,
   14259              :                            const double value)
   14260              :     {
   14261              :         write_bson_entry_header(name, 0x01);
   14262              :         write_number<double, true>(value);
   14263              :     }
   14264              : 
   14265              :     /*!
   14266              :     @return The size of the BSON-encoded string in @a value
   14267              :     */
   14268              :     static std::size_t calc_bson_string_size(const string_t& value)
   14269              :     {
   14270              :         return sizeof(std::int32_t) + value.size() + 1ul;
   14271              :     }
   14272              : 
   14273              :     /*!
   14274              :     @brief Writes a BSON element with key @a name and string value @a value
   14275              :     */
   14276              :     void write_bson_string(const string_t& name,
   14277              :                            const string_t& value)
   14278              :     {
   14279              :         write_bson_entry_header(name, 0x02);
   14280              : 
   14281              :         write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
   14282              :         oa->write_characters(
   14283              :             reinterpret_cast<const CharType*>(value.c_str()),
   14284              :             value.size() + 1);
   14285              :     }
   14286              : 
   14287              :     /*!
   14288              :     @brief Writes a BSON element with key @a name and null value
   14289              :     */
   14290              :     void write_bson_null(const string_t& name)
   14291              :     {
   14292              :         write_bson_entry_header(name, 0x0A);
   14293              :     }
   14294              : 
   14295              :     /*!
   14296              :     @return The size of the BSON-encoded integer @a value
   14297              :     */
   14298              :     static std::size_t calc_bson_integer_size(const std::int64_t value)
   14299              :     {
   14300              :         return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
   14301              :                ? sizeof(std::int32_t)
   14302              :                : sizeof(std::int64_t);
   14303              :     }
   14304              : 
   14305              :     /*!
   14306              :     @brief Writes a BSON element with key @a name and integer @a value
   14307              :     */
   14308              :     void write_bson_integer(const string_t& name,
   14309              :                             const std::int64_t value)
   14310              :     {
   14311              :         if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
   14312              :         {
   14313              :             write_bson_entry_header(name, 0x10); // int32
   14314              :             write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
   14315              :         }
   14316              :         else
   14317              :         {
   14318              :             write_bson_entry_header(name, 0x12); // int64
   14319              :             write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
   14320              :         }
   14321              :     }
   14322              : 
   14323              :     /*!
   14324              :     @return The size of the BSON-encoded unsigned integer in @a j
   14325              :     */
   14326              :     static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
   14327              :     {
   14328              :         return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
   14329              :                ? sizeof(std::int32_t)
   14330              :                : sizeof(std::int64_t);
   14331              :     }
   14332              : 
   14333              :     /*!
   14334              :     @brief Writes a BSON element with key @a name and unsigned @a value
   14335              :     */
   14336              :     void write_bson_unsigned(const string_t& name,
   14337              :                              const BasicJsonType& j)
   14338              :     {
   14339              :         if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
   14340              :         {
   14341              :             write_bson_entry_header(name, 0x10 /* int32 */);
   14342              :             write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
   14343              :         }
   14344              :         else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
   14345              :         {
   14346              :             write_bson_entry_header(name, 0x12 /* int64 */);
   14347              :             write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
   14348              :         }
   14349              :         else
   14350              :         {
   14351              :             JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", j));
   14352              :         }
   14353              :     }
   14354              : 
   14355              :     /*!
   14356              :     @brief Writes a BSON element with key @a name and object @a value
   14357              :     */
   14358              :     void write_bson_object_entry(const string_t& name,
   14359              :                                  const typename BasicJsonType::object_t& value)
   14360              :     {
   14361              :         write_bson_entry_header(name, 0x03); // object
   14362              :         write_bson_object(value);
   14363              :     }
   14364              : 
   14365              :     /*!
   14366              :     @return The size of the BSON-encoded array @a value
   14367              :     */
   14368              :     static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
   14369              :     {
   14370              :         std::size_t array_index = 0ul;
   14371              : 
   14372              :         const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
   14373              :         {
   14374              :             return result + calc_bson_element_size(std::to_string(array_index++), el);
   14375              :         });
   14376              : 
   14377              :         return sizeof(std::int32_t) + embedded_document_size + 1ul;
   14378              :     }
   14379              : 
   14380              :     /*!
   14381              :     @return The size of the BSON-encoded binary array @a value
   14382              :     */
   14383              :     static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
   14384              :     {
   14385              :         return sizeof(std::int32_t) + value.size() + 1ul;
   14386              :     }
   14387              : 
   14388              :     /*!
   14389              :     @brief Writes a BSON element with key @a name and array @a value
   14390              :     */
   14391              :     void write_bson_array(const string_t& name,
   14392              :                           const typename BasicJsonType::array_t& value)
   14393              :     {
   14394              :         write_bson_entry_header(name, 0x04); // array
   14395              :         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
   14396              : 
   14397              :         std::size_t array_index = 0ul;
   14398              : 
   14399              :         for (const auto& el : value)
   14400              :         {
   14401              :             write_bson_element(std::to_string(array_index++), el);
   14402              :         }
   14403              : 
   14404              :         oa->write_character(to_char_type(0x00));
   14405              :     }
   14406              : 
   14407              :     /*!
   14408              :     @brief Writes a BSON element with key @a name and binary value @a value
   14409              :     */
   14410              :     void write_bson_binary(const string_t& name,
   14411              :                            const binary_t& value)
   14412              :     {
   14413              :         write_bson_entry_header(name, 0x05);
   14414              : 
   14415              :         write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
   14416              :         write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
   14417              : 
   14418              :         oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
   14419              :     }
   14420              : 
   14421              :     /*!
   14422              :     @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
   14423              :     @return The calculated size for the BSON document entry for @a j with the given @a name.
   14424              :     */
   14425              :     static std::size_t calc_bson_element_size(const string_t& name,
   14426              :             const BasicJsonType& j)
   14427              :     {
   14428              :         const auto header_size = calc_bson_entry_header_size(name, j);
   14429              :         switch (j.type())
   14430              :         {
   14431              :             case value_t::object:
   14432              :                 return header_size + calc_bson_object_size(*j.m_value.object);
   14433              : 
   14434              :             case value_t::array:
   14435              :                 return header_size + calc_bson_array_size(*j.m_value.array);
   14436              : 
   14437              :             case value_t::binary:
   14438              :                 return header_size + calc_bson_binary_size(*j.m_value.binary);
   14439              : 
   14440              :             case value_t::boolean:
   14441              :                 return header_size + 1ul;
   14442              : 
   14443              :             case value_t::number_float:
   14444              :                 return header_size + 8ul;
   14445              : 
   14446              :             case value_t::number_integer:
   14447              :                 return header_size + calc_bson_integer_size(j.m_value.number_integer);
   14448              : 
   14449              :             case value_t::number_unsigned:
   14450              :                 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
   14451              : 
   14452              :             case value_t::string:
   14453              :                 return header_size + calc_bson_string_size(*j.m_value.string);
   14454              : 
   14455              :             case value_t::null:
   14456              :                 return header_size + 0ul;
   14457              : 
   14458              :             // LCOV_EXCL_START
   14459              :             case value_t::discarded:
   14460              :             default:
   14461              :                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
   14462              :                 return 0ul;
   14463              :                 // LCOV_EXCL_STOP
   14464              :         }
   14465              :     }
   14466              : 
   14467              :     /*!
   14468              :     @brief Serializes the JSON value @a j to BSON and associates it with the
   14469              :            key @a name.
   14470              :     @param name The name to associate with the JSON entity @a j within the
   14471              :                 current BSON document
   14472              :     */
   14473              :     void write_bson_element(const string_t& name,
   14474              :                             const BasicJsonType& j)
   14475              :     {
   14476              :         switch (j.type())
   14477              :         {
   14478              :             case value_t::object:
   14479              :                 return write_bson_object_entry(name, *j.m_value.object);
   14480              : 
   14481              :             case value_t::array:
   14482              :                 return write_bson_array(name, *j.m_value.array);
   14483              : 
   14484              :             case value_t::binary:
   14485              :                 return write_bson_binary(name, *j.m_value.binary);
   14486              : 
   14487              :             case value_t::boolean:
   14488              :                 return write_bson_boolean(name, j.m_value.boolean);
   14489              : 
   14490              :             case value_t::number_float:
   14491              :                 return write_bson_double(name, j.m_value.number_float);
   14492              : 
   14493              :             case value_t::number_integer:
   14494              :                 return write_bson_integer(name, j.m_value.number_integer);
   14495              : 
   14496              :             case value_t::number_unsigned:
   14497              :                 return write_bson_unsigned(name, j);
   14498              : 
   14499              :             case value_t::string:
   14500              :                 return write_bson_string(name, *j.m_value.string);
   14501              : 
   14502              :             case value_t::null:
   14503              :                 return write_bson_null(name);
   14504              : 
   14505              :             // LCOV_EXCL_START
   14506              :             case value_t::discarded:
   14507              :             default:
   14508              :                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
   14509              :                 return;
   14510              :                 // LCOV_EXCL_STOP
   14511              :         }
   14512              :     }
   14513              : 
   14514              :     /*!
   14515              :     @brief Calculates the size of the BSON serialization of the given
   14516              :            JSON-object @a j.
   14517              :     @param[in] value  JSON value to serialize
   14518              :     @pre       value.type() == value_t::object
   14519              :     */
   14520              :     static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
   14521              :     {
   14522              :         std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
   14523              :                                     [](size_t result, const typename BasicJsonType::object_t::value_type & el)
   14524              :         {
   14525              :             return result += calc_bson_element_size(el.first, el.second);
   14526              :         });
   14527              : 
   14528              :         return sizeof(std::int32_t) + document_size + 1ul;
   14529              :     }
   14530              : 
   14531              :     /*!
   14532              :     @param[in] value  JSON value to serialize
   14533              :     @pre       value.type() == value_t::object
   14534              :     */
   14535              :     void write_bson_object(const typename BasicJsonType::object_t& value)
   14536              :     {
   14537              :         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
   14538              : 
   14539              :         for (const auto& el : value)
   14540              :         {
   14541              :             write_bson_element(el.first, el.second);
   14542              :         }
   14543              : 
   14544              :         oa->write_character(to_char_type(0x00));
   14545              :     }
   14546              : 
   14547              :     //////////
   14548              :     // CBOR //
   14549              :     //////////
   14550              : 
   14551              :     static constexpr CharType get_cbor_float_prefix(float /*unused*/)
   14552              :     {
   14553              :         return to_char_type(0xFA);  // Single-Precision Float
   14554              :     }
   14555              : 
   14556              :     static constexpr CharType get_cbor_float_prefix(double /*unused*/)
   14557              :     {
   14558              :         return to_char_type(0xFB);  // Double-Precision Float
   14559              :     }
   14560              : 
   14561              :     /////////////
   14562              :     // MsgPack //
   14563              :     /////////////
   14564              : 
   14565              :     static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
   14566              :     {
   14567              :         return to_char_type(0xCA);  // float 32
   14568              :     }
   14569              : 
   14570              :     static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
   14571              :     {
   14572              :         return to_char_type(0xCB);  // float 64
   14573              :     }
   14574              : 
   14575              :     ////////////
   14576              :     // UBJSON //
   14577              :     ////////////
   14578              : 
   14579              :     // UBJSON: write number (floating point)
   14580              :     template<typename NumberType, typename std::enable_if<
   14581              :                  std::is_floating_point<NumberType>::value, int>::type = 0>
   14582              :     void write_number_with_ubjson_prefix(const NumberType n,
   14583              :                                          const bool add_prefix)
   14584              :     {
   14585              :         if (add_prefix)
   14586              :         {
   14587              :             oa->write_character(get_ubjson_float_prefix(n));
   14588              :         }
   14589              :         write_number(n);
   14590              :     }
   14591              : 
   14592              :     // UBJSON: write number (unsigned integer)
   14593              :     template<typename NumberType, typename std::enable_if<
   14594              :                  std::is_unsigned<NumberType>::value, int>::type = 0>
   14595              :     void write_number_with_ubjson_prefix(const NumberType n,
   14596              :                                          const bool add_prefix)
   14597              :     {
   14598              :         if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
   14599              :         {
   14600              :             if (add_prefix)
   14601              :             {
   14602              :                 oa->write_character(to_char_type('i'));  // int8
   14603              :             }
   14604              :             write_number(static_cast<std::uint8_t>(n));
   14605              :         }
   14606              :         else if (n <= (std::numeric_limits<std::uint8_t>::max)())
   14607              :         {
   14608              :             if (add_prefix)
   14609              :             {
   14610              :                 oa->write_character(to_char_type('U'));  // uint8
   14611              :             }
   14612              :             write_number(static_cast<std::uint8_t>(n));
   14613              :         }
   14614              :         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
   14615              :         {
   14616              :             if (add_prefix)
   14617              :             {
   14618              :                 oa->write_character(to_char_type('I'));  // int16
   14619              :             }
   14620              :             write_number(static_cast<std::int16_t>(n));
   14621              :         }
   14622              :         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
   14623              :         {
   14624              :             if (add_prefix)
   14625              :             {
   14626              :                 oa->write_character(to_char_type('l'));  // int32
   14627              :             }
   14628              :             write_number(static_cast<std::int32_t>(n));
   14629              :         }
   14630              :         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
   14631              :         {
   14632              :             if (add_prefix)
   14633              :             {
   14634              :                 oa->write_character(to_char_type('L'));  // int64
   14635              :             }
   14636              :             write_number(static_cast<std::int64_t>(n));
   14637              :         }
   14638              :         else
   14639              :         {
   14640              :             if (add_prefix)
   14641              :             {
   14642              :                 oa->write_character(to_char_type('H'));  // high-precision number
   14643              :             }
   14644              : 
   14645              :             const auto number = BasicJsonType(n).dump();
   14646              :             write_number_with_ubjson_prefix(number.size(), true);
   14647              :             for (std::size_t i = 0; i < number.size(); ++i)
   14648              :             {
   14649              :                 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
   14650              :             }
   14651              :         }
   14652              :     }
   14653              : 
   14654              :     // UBJSON: write number (signed integer)
   14655              :     template < typename NumberType, typename std::enable_if <
   14656              :                    std::is_signed<NumberType>::value&&
   14657              :                    !std::is_floating_point<NumberType>::value, int >::type = 0 >
   14658              :     void write_number_with_ubjson_prefix(const NumberType n,
   14659              :                                          const bool add_prefix)
   14660              :     {
   14661              :         if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
   14662              :         {
   14663              :             if (add_prefix)
   14664              :             {
   14665              :                 oa->write_character(to_char_type('i'));  // int8
   14666              :             }
   14667              :             write_number(static_cast<std::int8_t>(n));
   14668              :         }
   14669              :         else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
   14670              :         {
   14671              :             if (add_prefix)
   14672              :             {
   14673              :                 oa->write_character(to_char_type('U'));  // uint8
   14674              :             }
   14675              :             write_number(static_cast<std::uint8_t>(n));
   14676              :         }
   14677              :         else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
   14678              :         {
   14679              :             if (add_prefix)
   14680              :             {
   14681              :                 oa->write_character(to_char_type('I'));  // int16
   14682              :             }
   14683              :             write_number(static_cast<std::int16_t>(n));
   14684              :         }
   14685              :         else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
   14686              :         {
   14687              :             if (add_prefix)
   14688              :             {
   14689              :                 oa->write_character(to_char_type('l'));  // int32
   14690              :             }
   14691              :             write_number(static_cast<std::int32_t>(n));
   14692              :         }
   14693              :         else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
   14694              :         {
   14695              :             if (add_prefix)
   14696              :             {
   14697              :                 oa->write_character(to_char_type('L'));  // int64
   14698              :             }
   14699              :             write_number(static_cast<std::int64_t>(n));
   14700              :         }
   14701              :         // LCOV_EXCL_START
   14702              :         else
   14703              :         {
   14704              :             if (add_prefix)
   14705              :             {
   14706              :                 oa->write_character(to_char_type('H'));  // high-precision number
   14707              :             }
   14708              : 
   14709              :             const auto number = BasicJsonType(n).dump();
   14710              :             write_number_with_ubjson_prefix(number.size(), true);
   14711              :             for (std::size_t i = 0; i < number.size(); ++i)
   14712              :             {
   14713              :                 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
   14714              :             }
   14715              :         }
   14716              :         // LCOV_EXCL_STOP
   14717              :     }
   14718              : 
   14719              :     /*!
   14720              :     @brief determine the type prefix of container values
   14721              :     */
   14722              :     CharType ubjson_prefix(const BasicJsonType& j) const noexcept
   14723              :     {
   14724              :         switch (j.type())
   14725              :         {
   14726              :             case value_t::null:
   14727              :                 return 'Z';
   14728              : 
   14729              :             case value_t::boolean:
   14730              :                 return j.m_value.boolean ? 'T' : 'F';
   14731              : 
   14732              :             case value_t::number_integer:
   14733              :             {
   14734              :                 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
   14735              :                 {
   14736              :                     return 'i';
   14737              :                 }
   14738              :                 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
   14739              :                 {
   14740              :                     return 'U';
   14741              :                 }
   14742              :                 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
   14743              :                 {
   14744              :                     return 'I';
   14745              :                 }
   14746              :                 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
   14747              :                 {
   14748              :                     return 'l';
   14749              :                 }
   14750              :                 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
   14751              :                 {
   14752              :                     return 'L';
   14753              :                 }
   14754              :                 // anything else is treated as high-precision number
   14755              :                 return 'H'; // LCOV_EXCL_LINE
   14756              :             }
   14757              : 
   14758              :             case value_t::number_unsigned:
   14759              :             {
   14760              :                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
   14761              :                 {
   14762              :                     return 'i';
   14763              :                 }
   14764              :                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
   14765              :                 {
   14766              :                     return 'U';
   14767              :                 }
   14768              :                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
   14769              :                 {
   14770              :                     return 'I';
   14771              :                 }
   14772              :                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
   14773              :                 {
   14774              :                     return 'l';
   14775              :                 }
   14776              :                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
   14777              :                 {
   14778              :                     return 'L';
   14779              :                 }
   14780              :                 // anything else is treated as high-precision number
   14781              :                 return 'H'; // LCOV_EXCL_LINE
   14782              :             }
   14783              : 
   14784              :             case value_t::number_float:
   14785              :                 return get_ubjson_float_prefix(j.m_value.number_float);
   14786              : 
   14787              :             case value_t::string:
   14788              :                 return 'S';
   14789              : 
   14790              :             case value_t::array: // fallthrough
   14791              :             case value_t::binary:
   14792              :                 return '[';
   14793              : 
   14794              :             case value_t::object:
   14795              :                 return '{';
   14796              : 
   14797              :             case value_t::discarded:
   14798              :             default:  // discarded values
   14799              :                 return 'N';
   14800              :         }
   14801              :     }
   14802              : 
   14803              :     static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
   14804              :     {
   14805              :         return 'd';  // float 32
   14806              :     }
   14807              : 
   14808              :     static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
   14809              :     {
   14810              :         return 'D';  // float 64
   14811              :     }
   14812              : 
   14813              :     ///////////////////////
   14814              :     // Utility functions //
   14815              :     ///////////////////////
   14816              : 
   14817              :     /*
   14818              :     @brief write a number to output input
   14819              :     @param[in] n number of type @a NumberType
   14820              :     @tparam NumberType the type of the number
   14821              :     @tparam OutputIsLittleEndian Set to true if output data is
   14822              :                                  required to be little endian
   14823              : 
   14824              :     @note This function needs to respect the system's endianness, because bytes
   14825              :           in CBOR, MessagePack, and UBJSON are stored in network order (big
   14826              :           endian) and therefore need reordering on little endian systems.
   14827              :     */
   14828              :     template<typename NumberType, bool OutputIsLittleEndian = false>
   14829              :     void write_number(const NumberType n)
   14830              :     {
   14831              :         // step 1: write number to array of length NumberType
   14832              :         std::array<CharType, sizeof(NumberType)> vec{};
   14833              :         std::memcpy(vec.data(), &n, sizeof(NumberType));
   14834              : 
   14835              :         // step 2: write array to output (with possible reordering)
   14836              :         if (is_little_endian != OutputIsLittleEndian)
   14837              :         {
   14838              :             // reverse byte order prior to conversion if necessary
   14839              :             std::reverse(vec.begin(), vec.end());
   14840              :         }
   14841              : 
   14842              :         oa->write_characters(vec.data(), sizeof(NumberType));
   14843              :     }
   14844              : 
   14845              :     void write_compact_float(const number_float_t n, detail::input_format_t format)
   14846              :     {
   14847              : #ifdef __GNUC__
   14848              : #pragma GCC diagnostic push
   14849              : #pragma GCC diagnostic ignored "-Wfloat-equal"
   14850              : #endif
   14851              :         if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
   14852              :                 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
   14853              :                 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
   14854              :         {
   14855              :             oa->write_character(format == detail::input_format_t::cbor
   14856              :                                 ? get_cbor_float_prefix(static_cast<float>(n))
   14857              :                                 : get_msgpack_float_prefix(static_cast<float>(n)));
   14858              :             write_number(static_cast<float>(n));
   14859              :         }
   14860              :         else
   14861              :         {
   14862              :             oa->write_character(format == detail::input_format_t::cbor
   14863              :                                 ? get_cbor_float_prefix(n)
   14864              :                                 : get_msgpack_float_prefix(n));
   14865              :             write_number(n);
   14866              :         }
   14867              : #ifdef __GNUC__
   14868              : #pragma GCC diagnostic pop
   14869              : #endif
   14870              :     }
   14871              : 
   14872              :   public:
   14873              :     // The following to_char_type functions are implement the conversion
   14874              :     // between uint8_t and CharType. In case CharType is not unsigned,
   14875              :     // such a conversion is required to allow values greater than 128.
   14876              :     // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
   14877              :     template < typename C = CharType,
   14878              :                enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
   14879              :     static constexpr CharType to_char_type(std::uint8_t x) noexcept
   14880              :     {
   14881              :         return *reinterpret_cast<char*>(&x);
   14882              :     }
   14883              : 
   14884              :     template < typename C = CharType,
   14885              :                enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
   14886              :     static CharType to_char_type(std::uint8_t x) noexcept
   14887              :     {
   14888              :         static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
   14889              :         static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
   14890              :         CharType result;
   14891              :         std::memcpy(&result, &x, sizeof(x));
   14892              :         return result;
   14893              :     }
   14894              : 
   14895              :     template<typename C = CharType,
   14896              :              enable_if_t<std::is_unsigned<C>::value>* = nullptr>
   14897              :     static constexpr CharType to_char_type(std::uint8_t x) noexcept
   14898              :     {
   14899              :         return x;
   14900              :     }
   14901              : 
   14902              :     template < typename InputCharType, typename C = CharType,
   14903              :                enable_if_t <
   14904              :                    std::is_signed<C>::value &&
   14905              :                    std::is_signed<char>::value &&
   14906              :                    std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
   14907              :                    > * = nullptr >
   14908              :     static constexpr CharType to_char_type(InputCharType x) noexcept
   14909              :     {
   14910              :         return x;
   14911              :     }
   14912              : 
   14913              :   private:
   14914              :     /// whether we can assume little endianness
   14915              :     const bool is_little_endian = little_endianness();
   14916              : 
   14917              :     /// the output
   14918              :     output_adapter_t<CharType> oa = nullptr;
   14919              : };
   14920              : }  // namespace detail
   14921              : }  // namespace nlohmann
   14922              : 
   14923              : // #include <nlohmann/detail/output/output_adapters.hpp>
   14924              : 
   14925              : // #include <nlohmann/detail/output/serializer.hpp>
   14926              : 
   14927              : 
   14928              : #include <algorithm> // reverse, remove, fill, find, none_of
   14929              : #include <array> // array
   14930              : #include <clocale> // localeconv, lconv
   14931              : #include <cmath> // labs, isfinite, isnan, signbit
   14932              : #include <cstddef> // size_t, ptrdiff_t
   14933              : #include <cstdint> // uint8_t
   14934              : #include <cstdio> // snprintf
   14935              : #include <limits> // numeric_limits
   14936              : #include <string> // string, char_traits
   14937              : #include <iomanip> // setfill, setw
   14938              : #include <sstream> // stringstream
   14939              : #include <type_traits> // is_same
   14940              : #include <utility> // move
   14941              : 
   14942              : // #include <nlohmann/detail/conversions/to_chars.hpp>
   14943              : 
   14944              : 
   14945              : #include <array> // array
   14946              : #include <cmath>   // signbit, isfinite
   14947              : #include <cstdint> // intN_t, uintN_t
   14948              : #include <cstring> // memcpy, memmove
   14949              : #include <limits> // numeric_limits
   14950              : #include <type_traits> // conditional
   14951              : 
   14952              : // #include <nlohmann/detail/macro_scope.hpp>
   14953              : 
   14954              : 
   14955              : namespace nlohmann
   14956              : {
   14957              : namespace detail
   14958              : {
   14959              : 
   14960              : /*!
   14961              : @brief implements the Grisu2 algorithm for binary to decimal floating-point
   14962              : conversion.
   14963              : 
   14964              : This implementation is a slightly modified version of the reference
   14965              : implementation which may be obtained from
   14966              : http://florian.loitsch.com/publications (bench.tar.gz).
   14967              : 
   14968              : The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
   14969              : 
   14970              : For a detailed description of the algorithm see:
   14971              : 
   14972              : [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
   14973              :     Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
   14974              :     Language Design and Implementation, PLDI 2010
   14975              : [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
   14976              :     Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
   14977              :     Design and Implementation, PLDI 1996
   14978              : */
   14979              : namespace dtoa_impl
   14980              : {
   14981              : 
   14982              : template<typename Target, typename Source>
   14983              : Target reinterpret_bits(const Source source)
   14984              : {
   14985              :     static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
   14986              : 
   14987              :     Target target;
   14988              :     std::memcpy(&target, &source, sizeof(Source));
   14989              :     return target;
   14990              : }
   14991              : 
   14992              : struct diyfp // f * 2^e
   14993              : {
   14994              :     static constexpr int kPrecision = 64; // = q
   14995              : 
   14996              :     std::uint64_t f = 0;
   14997              :     int e = 0;
   14998              : 
   14999              :     constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
   15000              : 
   15001              :     /*!
   15002              :     @brief returns x - y
   15003              :     @pre x.e == y.e and x.f >= y.f
   15004              :     */
   15005              :     static diyfp sub(const diyfp& x, const diyfp& y) noexcept
   15006              :     {
   15007              :         JSON_ASSERT(x.e == y.e);
   15008              :         JSON_ASSERT(x.f >= y.f);
   15009              : 
   15010              :         return {x.f - y.f, x.e};
   15011              :     }
   15012              : 
   15013              :     /*!
   15014              :     @brief returns x * y
   15015              :     @note The result is rounded. (Only the upper q bits are returned.)
   15016              :     */
   15017              :     static diyfp mul(const diyfp& x, const diyfp& y) noexcept
   15018              :     {
   15019              :         static_assert(kPrecision == 64, "internal error");
   15020              : 
   15021              :         // Computes:
   15022              :         //  f = round((x.f * y.f) / 2^q)
   15023              :         //  e = x.e + y.e + q
   15024              : 
   15025              :         // Emulate the 64-bit * 64-bit multiplication:
   15026              :         //
   15027              :         // p = u * v
   15028              :         //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
   15029              :         //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
   15030              :         //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
   15031              :         //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
   15032              :         //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
   15033              :         //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
   15034              :         //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
   15035              :         //
   15036              :         // (Since Q might be larger than 2^32 - 1)
   15037              :         //
   15038              :         //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
   15039              :         //
   15040              :         // (Q_hi + H does not overflow a 64-bit int)
   15041              :         //
   15042              :         //   = p_lo + 2^64 p_hi
   15043              : 
   15044              :         const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
   15045              :         const std::uint64_t u_hi = x.f >> 32u;
   15046              :         const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
   15047              :         const std::uint64_t v_hi = y.f >> 32u;
   15048              : 
   15049              :         const std::uint64_t p0 = u_lo * v_lo;
   15050              :         const std::uint64_t p1 = u_lo * v_hi;
   15051              :         const std::uint64_t p2 = u_hi * v_lo;
   15052              :         const std::uint64_t p3 = u_hi * v_hi;
   15053              : 
   15054              :         const std::uint64_t p0_hi = p0 >> 32u;
   15055              :         const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
   15056              :         const std::uint64_t p1_hi = p1 >> 32u;
   15057              :         const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
   15058              :         const std::uint64_t p2_hi = p2 >> 32u;
   15059              : 
   15060              :         std::uint64_t Q = p0_hi + p1_lo + p2_lo;
   15061              : 
   15062              :         // The full product might now be computed as
   15063              :         //
   15064              :         // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
   15065              :         // p_lo = p0_lo + (Q << 32)
   15066              :         //
   15067              :         // But in this particular case here, the full p_lo is not required.
   15068              :         // Effectively we only need to add the highest bit in p_lo to p_hi (and
   15069              :         // Q_hi + 1 does not overflow).
   15070              : 
   15071              :         Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
   15072              : 
   15073              :         const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
   15074              : 
   15075              :         return {h, x.e + y.e + 64};
   15076              :     }
   15077              : 
   15078              :     /*!
   15079              :     @brief normalize x such that the significand is >= 2^(q-1)
   15080              :     @pre x.f != 0
   15081              :     */
   15082              :     static diyfp normalize(diyfp x) noexcept
   15083              :     {
   15084              :         JSON_ASSERT(x.f != 0);
   15085              : 
   15086              :         while ((x.f >> 63u) == 0)
   15087              :         {
   15088              :             x.f <<= 1u;
   15089              :             x.e--;
   15090              :         }
   15091              : 
   15092              :         return x;
   15093              :     }
   15094              : 
   15095              :     /*!
   15096              :     @brief normalize x such that the result has the exponent E
   15097              :     @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
   15098              :     */
   15099              :     static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
   15100              :     {
   15101              :         const int delta = x.e - target_exponent;
   15102              : 
   15103              :         JSON_ASSERT(delta >= 0);
   15104              :         JSON_ASSERT(((x.f << delta) >> delta) == x.f);
   15105              : 
   15106              :         return {x.f << delta, target_exponent};
   15107              :     }
   15108              : };
   15109              : 
   15110              : struct boundaries
   15111              : {
   15112              :     diyfp w;
   15113              :     diyfp minus;
   15114              :     diyfp plus;
   15115              : };
   15116              : 
   15117              : /*!
   15118              : Compute the (normalized) diyfp representing the input number 'value' and its
   15119              : boundaries.
   15120              : 
   15121              : @pre value must be finite and positive
   15122              : */
   15123              : template<typename FloatType>
   15124              : boundaries compute_boundaries(FloatType value)
   15125              : {
   15126              :     JSON_ASSERT(std::isfinite(value));
   15127              :     JSON_ASSERT(value > 0);
   15128              : 
   15129              :     // Convert the IEEE representation into a diyfp.
   15130              :     //
   15131              :     // If v is denormal:
   15132              :     //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
   15133              :     // If v is normalized:
   15134              :     //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
   15135              : 
   15136              :     static_assert(std::numeric_limits<FloatType>::is_iec559,
   15137              :                   "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
   15138              : 
   15139              :     constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
   15140              :     constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
   15141              :     constexpr int      kMinExp    = 1 - kBias;
   15142              :     constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
   15143              : 
   15144              :     using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
   15145              : 
   15146              :     const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
   15147              :     const std::uint64_t E = bits >> (kPrecision - 1);
   15148              :     const std::uint64_t F = bits & (kHiddenBit - 1);
   15149              : 
   15150              :     const bool is_denormal = E == 0;
   15151              :     const diyfp v = is_denormal
   15152              :                     ? diyfp(F, kMinExp)
   15153              :                     : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
   15154              : 
   15155              :     // Compute the boundaries m- and m+ of the floating-point value
   15156              :     // v = f * 2^e.
   15157              :     //
   15158              :     // Determine v- and v+, the floating-point predecessor and successor if v,
   15159              :     // respectively.
   15160              :     //
   15161              :     //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
   15162              :     //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
   15163              :     //
   15164              :     //      v+ = v + 2^e
   15165              :     //
   15166              :     // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
   15167              :     // between m- and m+ round to v, regardless of how the input rounding
   15168              :     // algorithm breaks ties.
   15169              :     //
   15170              :     //      ---+-------------+-------------+-------------+-------------+---  (A)
   15171              :     //         v-            m-            v             m+            v+
   15172              :     //
   15173              :     //      -----------------+------+------+-------------+-------------+---  (B)
   15174              :     //                       v-     m-     v             m+            v+
   15175              : 
   15176              :     const bool lower_boundary_is_closer = F == 0 && E > 1;
   15177              :     const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
   15178              :     const diyfp m_minus = lower_boundary_is_closer
   15179              :                           ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
   15180              :                           : diyfp(2 * v.f - 1, v.e - 1); // (A)
   15181              : 
   15182              :     // Determine the normalized w+ = m+.
   15183              :     const diyfp w_plus = diyfp::normalize(m_plus);
   15184              : 
   15185              :     // Determine w- = m- such that e_(w-) = e_(w+).
   15186              :     const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
   15187              : 
   15188              :     return {diyfp::normalize(v), w_minus, w_plus};
   15189              : }
   15190              : 
   15191              : // Given normalized diyfp w, Grisu needs to find a (normalized) cached
   15192              : // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
   15193              : // within a certain range [alpha, gamma] (Definition 3.2 from [1])
   15194              : //
   15195              : //      alpha <= e = e_c + e_w + q <= gamma
   15196              : //
   15197              : // or
   15198              : //
   15199              : //      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
   15200              : //                          <= f_c * f_w * 2^gamma
   15201              : //
   15202              : // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
   15203              : //
   15204              : //      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
   15205              : //
   15206              : // or
   15207              : //
   15208              : //      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
   15209              : //
   15210              : // The choice of (alpha,gamma) determines the size of the table and the form of
   15211              : // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
   15212              : // in practice:
   15213              : //
   15214              : // The idea is to cut the number c * w = f * 2^e into two parts, which can be
   15215              : // processed independently: An integral part p1, and a fractional part p2:
   15216              : //
   15217              : //      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
   15218              : //              = (f div 2^-e) + (f mod 2^-e) * 2^e
   15219              : //              = p1 + p2 * 2^e
   15220              : //
   15221              : // The conversion of p1 into decimal form requires a series of divisions and
   15222              : // modulos by (a power of) 10. These operations are faster for 32-bit than for
   15223              : // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
   15224              : // achieved by choosing
   15225              : //
   15226              : //      -e >= 32   or   e <= -32 := gamma
   15227              : //
   15228              : // In order to convert the fractional part
   15229              : //
   15230              : //      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
   15231              : //
   15232              : // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
   15233              : // d[-i] are extracted in order:
   15234              : //
   15235              : //      (10 * p2) div 2^-e = d[-1]
   15236              : //      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
   15237              : //
   15238              : // The multiplication by 10 must not overflow. It is sufficient to choose
   15239              : //
   15240              : //      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
   15241              : //
   15242              : // Since p2 = f mod 2^-e < 2^-e,
   15243              : //
   15244              : //      -e <= 60   or   e >= -60 := alpha
   15245              : 
   15246              : constexpr int kAlpha = -60;
   15247              : constexpr int kGamma = -32;
   15248              : 
   15249              : struct cached_power // c = f * 2^e ~= 10^k
   15250              : {
   15251              :     std::uint64_t f;
   15252              :     int e;
   15253              :     int k;
   15254              : };
   15255              : 
   15256              : /*!
   15257              : For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
   15258              : power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
   15259              : satisfies (Definition 3.2 from [1])
   15260              : 
   15261              :      alpha <= e_c + e + q <= gamma.
   15262              : */
   15263              : inline cached_power get_cached_power_for_binary_exponent(int e)
   15264              : {
   15265              :     // Now
   15266              :     //
   15267              :     //      alpha <= e_c + e + q <= gamma                                    (1)
   15268              :     //      ==> f_c * 2^alpha <= c * 2^e * 2^q
   15269              :     //
   15270              :     // and since the c's are normalized, 2^(q-1) <= f_c,
   15271              :     //
   15272              :     //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
   15273              :     //      ==> 2^(alpha - e - 1) <= c
   15274              :     //
   15275              :     // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
   15276              :     //
   15277              :     //      k = ceil( log_10( 2^(alpha - e - 1) ) )
   15278              :     //        = ceil( (alpha - e - 1) * log_10(2) )
   15279              :     //
   15280              :     // From the paper:
   15281              :     // "In theory the result of the procedure could be wrong since c is rounded,
   15282              :     //  and the computation itself is approximated [...]. In practice, however,
   15283              :     //  this simple function is sufficient."
   15284              :     //
   15285              :     // For IEEE double precision floating-point numbers converted into
   15286              :     // normalized diyfp's w = f * 2^e, with q = 64,
   15287              :     //
   15288              :     //      e >= -1022      (min IEEE exponent)
   15289              :     //           -52        (p - 1)
   15290              :     //           -52        (p - 1, possibly normalize denormal IEEE numbers)
   15291              :     //           -11        (normalize the diyfp)
   15292              :     //         = -1137
   15293              :     //
   15294              :     // and
   15295              :     //
   15296              :     //      e <= +1023      (max IEEE exponent)
   15297              :     //           -52        (p - 1)
   15298              :     //           -11        (normalize the diyfp)
   15299              :     //         = 960
   15300              :     //
   15301              :     // This binary exponent range [-1137,960] results in a decimal exponent
   15302              :     // range [-307,324]. One does not need to store a cached power for each
   15303              :     // k in this range. For each such k it suffices to find a cached power
   15304              :     // such that the exponent of the product lies in [alpha,gamma].
   15305              :     // This implies that the difference of the decimal exponents of adjacent
   15306              :     // table entries must be less than or equal to
   15307              :     //
   15308              :     //      floor( (gamma - alpha) * log_10(2) ) = 8.
   15309              :     //
   15310              :     // (A smaller distance gamma-alpha would require a larger table.)
   15311              : 
   15312              :     // NB:
   15313              :     // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
   15314              : 
   15315              :     constexpr int kCachedPowersMinDecExp = -300;
   15316              :     constexpr int kCachedPowersDecStep = 8;
   15317              : 
   15318              :     static constexpr std::array<cached_power, 79> kCachedPowers =
   15319              :     {
   15320              :         {
   15321              :             { 0xAB70FE17C79AC6CA, -1060, -300 },
   15322              :             { 0xFF77B1FCBEBCDC4F, -1034, -292 },
   15323              :             { 0xBE5691EF416BD60C, -1007, -284 },
   15324              :             { 0x8DD01FAD907FFC3C,  -980, -276 },
   15325              :             { 0xD3515C2831559A83,  -954, -268 },
   15326              :             { 0x9D71AC8FADA6C9B5,  -927, -260 },
   15327              :             { 0xEA9C227723EE8BCB,  -901, -252 },
   15328              :             { 0xAECC49914078536D,  -874, -244 },
   15329              :             { 0x823C12795DB6CE57,  -847, -236 },
   15330              :             { 0xC21094364DFB5637,  -821, -228 },
   15331              :             { 0x9096EA6F3848984F,  -794, -220 },
   15332              :             { 0xD77485CB25823AC7,  -768, -212 },
   15333              :             { 0xA086CFCD97BF97F4,  -741, -204 },
   15334              :             { 0xEF340A98172AACE5,  -715, -196 },
   15335              :             { 0xB23867FB2A35B28E,  -688, -188 },
   15336              :             { 0x84C8D4DFD2C63F3B,  -661, -180 },
   15337              :             { 0xC5DD44271AD3CDBA,  -635, -172 },
   15338              :             { 0x936B9FCEBB25C996,  -608, -164 },
   15339              :             { 0xDBAC6C247D62A584,  -582, -156 },
   15340              :             { 0xA3AB66580D5FDAF6,  -555, -148 },
   15341              :             { 0xF3E2F893DEC3F126,  -529, -140 },
   15342              :             { 0xB5B5ADA8AAFF80B8,  -502, -132 },
   15343              :             { 0x87625F056C7C4A8B,  -475, -124 },
   15344              :             { 0xC9BCFF6034C13053,  -449, -116 },
   15345              :             { 0x964E858C91BA2655,  -422, -108 },
   15346              :             { 0xDFF9772470297EBD,  -396, -100 },
   15347              :             { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
   15348              :             { 0xF8A95FCF88747D94,  -343,  -84 },
   15349              :             { 0xB94470938FA89BCF,  -316,  -76 },
   15350              :             { 0x8A08F0F8BF0F156B,  -289,  -68 },
   15351              :             { 0xCDB02555653131B6,  -263,  -60 },
   15352              :             { 0x993FE2C6D07B7FAC,  -236,  -52 },
   15353              :             { 0xE45C10C42A2B3B06,  -210,  -44 },
   15354              :             { 0xAA242499697392D3,  -183,  -36 },
   15355              :             { 0xFD87B5F28300CA0E,  -157,  -28 },
   15356              :             { 0xBCE5086492111AEB,  -130,  -20 },
   15357              :             { 0x8CBCCC096F5088CC,  -103,  -12 },
   15358              :             { 0xD1B71758E219652C,   -77,   -4 },
   15359              :             { 0x9C40000000000000,   -50,    4 },
   15360              :             { 0xE8D4A51000000000,   -24,   12 },
   15361              :             { 0xAD78EBC5AC620000,     3,   20 },
   15362              :             { 0x813F3978F8940984,    30,   28 },
   15363              :             { 0xC097CE7BC90715B3,    56,   36 },
   15364              :             { 0x8F7E32CE7BEA5C70,    83,   44 },
   15365              :             { 0xD5D238A4ABE98068,   109,   52 },
   15366              :             { 0x9F4F2726179A2245,   136,   60 },
   15367              :             { 0xED63A231D4C4FB27,   162,   68 },
   15368              :             { 0xB0DE65388CC8ADA8,   189,   76 },
   15369              :             { 0x83C7088E1AAB65DB,   216,   84 },
   15370              :             { 0xC45D1DF942711D9A,   242,   92 },
   15371              :             { 0x924D692CA61BE758,   269,  100 },
   15372              :             { 0xDA01EE641A708DEA,   295,  108 },
   15373              :             { 0xA26DA3999AEF774A,   322,  116 },
   15374              :             { 0xF209787BB47D6B85,   348,  124 },
   15375              :             { 0xB454E4A179DD1877,   375,  132 },
   15376              :             { 0x865B86925B9BC5C2,   402,  140 },
   15377              :             { 0xC83553C5C8965D3D,   428,  148 },
   15378              :             { 0x952AB45CFA97A0B3,   455,  156 },
   15379              :             { 0xDE469FBD99A05FE3,   481,  164 },
   15380              :             { 0xA59BC234DB398C25,   508,  172 },
   15381              :             { 0xF6C69A72A3989F5C,   534,  180 },
   15382              :             { 0xB7DCBF5354E9BECE,   561,  188 },
   15383              :             { 0x88FCF317F22241E2,   588,  196 },
   15384              :             { 0xCC20CE9BD35C78A5,   614,  204 },
   15385              :             { 0x98165AF37B2153DF,   641,  212 },
   15386              :             { 0xE2A0B5DC971F303A,   667,  220 },
   15387              :             { 0xA8D9D1535CE3B396,   694,  228 },
   15388              :             { 0xFB9B7CD9A4A7443C,   720,  236 },
   15389              :             { 0xBB764C4CA7A44410,   747,  244 },
   15390              :             { 0x8BAB8EEFB6409C1A,   774,  252 },
   15391              :             { 0xD01FEF10A657842C,   800,  260 },
   15392              :             { 0x9B10A4E5E9913129,   827,  268 },
   15393              :             { 0xE7109BFBA19C0C9D,   853,  276 },
   15394              :             { 0xAC2820D9623BF429,   880,  284 },
   15395              :             { 0x80444B5E7AA7CF85,   907,  292 },
   15396              :             { 0xBF21E44003ACDD2D,   933,  300 },
   15397              :             { 0x8E679C2F5E44FF8F,   960,  308 },
   15398              :             { 0xD433179D9C8CB841,   986,  316 },
   15399              :             { 0x9E19DB92B4E31BA9,  1013,  324 },
   15400              :         }
   15401              :     };
   15402              : 
   15403              :     // This computation gives exactly the same results for k as
   15404              :     //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
   15405              :     // for |e| <= 1500, but doesn't require floating-point operations.
   15406              :     // NB: log_10(2) ~= 78913 / 2^18
   15407              :     JSON_ASSERT(e >= -1500);
   15408              :     JSON_ASSERT(e <=  1500);
   15409              :     const int f = kAlpha - e - 1;
   15410              :     const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
   15411              : 
   15412              :     const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
   15413              :     JSON_ASSERT(index >= 0);
   15414              :     JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
   15415              : 
   15416              :     const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
   15417              :     JSON_ASSERT(kAlpha <= cached.e + e + 64);
   15418              :     JSON_ASSERT(kGamma >= cached.e + e + 64);
   15419              : 
   15420              :     return cached;
   15421              : }
   15422              : 
   15423              : /*!
   15424              : For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
   15425              : For n == 0, returns 1 and sets pow10 := 1.
   15426              : */
   15427              : inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
   15428              : {
   15429              :     // LCOV_EXCL_START
   15430              :     if (n >= 1000000000)
   15431              :     {
   15432              :         pow10 = 1000000000;
   15433              :         return 10;
   15434              :     }
   15435              :     // LCOV_EXCL_STOP
   15436              :     if (n >= 100000000)
   15437              :     {
   15438              :         pow10 = 100000000;
   15439              :         return  9;
   15440              :     }
   15441              :     if (n >= 10000000)
   15442              :     {
   15443              :         pow10 = 10000000;
   15444              :         return  8;
   15445              :     }
   15446              :     if (n >= 1000000)
   15447              :     {
   15448              :         pow10 = 1000000;
   15449              :         return  7;
   15450              :     }
   15451              :     if (n >= 100000)
   15452              :     {
   15453              :         pow10 = 100000;
   15454              :         return  6;
   15455              :     }
   15456              :     if (n >= 10000)
   15457              :     {
   15458              :         pow10 = 10000;
   15459              :         return  5;
   15460              :     }
   15461              :     if (n >= 1000)
   15462              :     {
   15463              :         pow10 = 1000;
   15464              :         return  4;
   15465              :     }
   15466              :     if (n >= 100)
   15467              :     {
   15468              :         pow10 = 100;
   15469              :         return  3;
   15470              :     }
   15471              :     if (n >= 10)
   15472              :     {
   15473              :         pow10 = 10;
   15474              :         return  2;
   15475              :     }
   15476              : 
   15477              :     pow10 = 1;
   15478              :     return 1;
   15479              : }
   15480              : 
   15481              : inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
   15482              :                          std::uint64_t rest, std::uint64_t ten_k)
   15483              : {
   15484              :     JSON_ASSERT(len >= 1);
   15485              :     JSON_ASSERT(dist <= delta);
   15486              :     JSON_ASSERT(rest <= delta);
   15487              :     JSON_ASSERT(ten_k > 0);
   15488              : 
   15489              :     //               <--------------------------- delta ---->
   15490              :     //                                  <---- dist --------->
   15491              :     // --------------[------------------+-------------------]--------------
   15492              :     //               M-                 w                   M+
   15493              :     //
   15494              :     //                                  ten_k
   15495              :     //                                <------>
   15496              :     //                                       <---- rest ---->
   15497              :     // --------------[------------------+----+--------------]--------------
   15498              :     //                                  w    V
   15499              :     //                                       = buf * 10^k
   15500              :     //
   15501              :     // ten_k represents a unit-in-the-last-place in the decimal representation
   15502              :     // stored in buf.
   15503              :     // Decrement buf by ten_k while this takes buf closer to w.
   15504              : 
   15505              :     // The tests are written in this order to avoid overflow in unsigned
   15506              :     // integer arithmetic.
   15507              : 
   15508              :     while (rest < dist
   15509              :             && delta - rest >= ten_k
   15510              :             && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
   15511              :     {
   15512              :         JSON_ASSERT(buf[len - 1] != '0');
   15513              :         buf[len - 1]--;
   15514              :         rest += ten_k;
   15515              :     }
   15516              : }
   15517              : 
   15518              : /*!
   15519              : Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
   15520              : M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
   15521              : */
   15522              : inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
   15523              :                              diyfp M_minus, diyfp w, diyfp M_plus)
   15524              : {
   15525              :     static_assert(kAlpha >= -60, "internal error");
   15526              :     static_assert(kGamma <= -32, "internal error");
   15527              : 
   15528              :     // Generates the digits (and the exponent) of a decimal floating-point
   15529              :     // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
   15530              :     // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
   15531              :     //
   15532              :     //               <--------------------------- delta ---->
   15533              :     //                                  <---- dist --------->
   15534              :     // --------------[------------------+-------------------]--------------
   15535              :     //               M-                 w                   M+
   15536              :     //
   15537              :     // Grisu2 generates the digits of M+ from left to right and stops as soon as
   15538              :     // V is in [M-,M+].
   15539              : 
   15540              :     JSON_ASSERT(M_plus.e >= kAlpha);
   15541              :     JSON_ASSERT(M_plus.e <= kGamma);
   15542              : 
   15543              :     std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
   15544              :     std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
   15545              : 
   15546              :     // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
   15547              :     //
   15548              :     //      M+ = f * 2^e
   15549              :     //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
   15550              :     //         = ((p1        ) * 2^-e + (p2        )) * 2^e
   15551              :     //         = p1 + p2 * 2^e
   15552              : 
   15553              :     const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
   15554              : 
   15555              :     auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
   15556              :     std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
   15557              : 
   15558              :     // 1)
   15559              :     //
   15560              :     // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
   15561              : 
   15562              :     JSON_ASSERT(p1 > 0);
   15563              : 
   15564              :     std::uint32_t pow10{};
   15565              :     const int k = find_largest_pow10(p1, pow10);
   15566              : 
   15567              :     //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
   15568              :     //
   15569              :     //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
   15570              :     //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
   15571              :     //
   15572              :     //      M+ = p1                                             + p2 * 2^e
   15573              :     //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
   15574              :     //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
   15575              :     //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
   15576              :     //
   15577              :     // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
   15578              :     //
   15579              :     //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
   15580              :     //
   15581              :     // but stop as soon as
   15582              :     //
   15583              :     //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
   15584              : 
   15585              :     int n = k;
   15586              :     while (n > 0)
   15587              :     {
   15588              :         // Invariants:
   15589              :         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
   15590              :         //      pow10 = 10^(n-1) <= p1 < 10^n
   15591              :         //
   15592              :         const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
   15593              :         const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
   15594              :         //
   15595              :         //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
   15596              :         //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
   15597              :         //
   15598              :         JSON_ASSERT(d <= 9);
   15599              :         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
   15600              :         //
   15601              :         //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
   15602              :         //
   15603              :         p1 = r;
   15604              :         n--;
   15605              :         //
   15606              :         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
   15607              :         //      pow10 = 10^n
   15608              :         //
   15609              : 
   15610              :         // Now check if enough digits have been generated.
   15611              :         // Compute
   15612              :         //
   15613              :         //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
   15614              :         //
   15615              :         // Note:
   15616              :         // Since rest and delta share the same exponent e, it suffices to
   15617              :         // compare the significands.
   15618              :         const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
   15619              :         if (rest <= delta)
   15620              :         {
   15621              :             // V = buffer * 10^n, with M- <= V <= M+.
   15622              : 
   15623              :             decimal_exponent += n;
   15624              : 
   15625              :             // We may now just stop. But instead look if the buffer could be
   15626              :             // decremented to bring V closer to w.
   15627              :             //
   15628              :             // pow10 = 10^n is now 1 ulp in the decimal representation V.
   15629              :             // The rounding procedure works with diyfp's with an implicit
   15630              :             // exponent of e.
   15631              :             //
   15632              :             //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
   15633              :             //
   15634              :             const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
   15635              :             grisu2_round(buffer, length, dist, delta, rest, ten_n);
   15636              : 
   15637              :             return;
   15638              :         }
   15639              : 
   15640              :         pow10 /= 10;
   15641              :         //
   15642              :         //      pow10 = 10^(n-1) <= p1 < 10^n
   15643              :         // Invariants restored.
   15644              :     }
   15645              : 
   15646              :     // 2)
   15647              :     //
   15648              :     // The digits of the integral part have been generated:
   15649              :     //
   15650              :     //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
   15651              :     //         = buffer            + p2 * 2^e
   15652              :     //
   15653              :     // Now generate the digits of the fractional part p2 * 2^e.
   15654              :     //
   15655              :     // Note:
   15656              :     // No decimal point is generated: the exponent is adjusted instead.
   15657              :     //
   15658              :     // p2 actually represents the fraction
   15659              :     //
   15660              :     //      p2 * 2^e
   15661              :     //          = p2 / 2^-e
   15662              :     //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
   15663              :     //
   15664              :     // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
   15665              :     //
   15666              :     //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
   15667              :     //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
   15668              :     //
   15669              :     // using
   15670              :     //
   15671              :     //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
   15672              :     //                = (                   d) * 2^-e + (                   r)
   15673              :     //
   15674              :     // or
   15675              :     //      10^m * p2 * 2^e = d + r * 2^e
   15676              :     //
   15677              :     // i.e.
   15678              :     //
   15679              :     //      M+ = buffer + p2 * 2^e
   15680              :     //         = buffer + 10^-m * (d + r * 2^e)
   15681              :     //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
   15682              :     //
   15683              :     // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
   15684              : 
   15685              :     JSON_ASSERT(p2 > delta);
   15686              : 
   15687              :     int m = 0;
   15688              :     for (;;)
   15689              :     {
   15690              :         // Invariant:
   15691              :         //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
   15692              :         //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
   15693              :         //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
   15694              :         //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
   15695              :         //
   15696              :         JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
   15697              :         p2 *= 10;
   15698              :         const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
   15699              :         const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
   15700              :         //
   15701              :         //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
   15702              :         //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
   15703              :         //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
   15704              :         //
   15705              :         JSON_ASSERT(d <= 9);
   15706              :         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
   15707              :         //
   15708              :         //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
   15709              :         //
   15710              :         p2 = r;
   15711              :         m++;
   15712              :         //
   15713              :         //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
   15714              :         // Invariant restored.
   15715              : 
   15716              :         // Check if enough digits have been generated.
   15717              :         //
   15718              :         //      10^-m * p2 * 2^e <= delta * 2^e
   15719              :         //              p2 * 2^e <= 10^m * delta * 2^e
   15720              :         //                    p2 <= 10^m * delta
   15721              :         delta *= 10;
   15722              :         dist  *= 10;
   15723              :         if (p2 <= delta)
   15724              :         {
   15725              :             break;
   15726              :         }
   15727              :     }
   15728              : 
   15729              :     // V = buffer * 10^-m, with M- <= V <= M+.
   15730              : 
   15731              :     decimal_exponent -= m;
   15732              : 
   15733              :     // 1 ulp in the decimal representation is now 10^-m.
   15734              :     // Since delta and dist are now scaled by 10^m, we need to do the
   15735              :     // same with ulp in order to keep the units in sync.
   15736              :     //
   15737              :     //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
   15738              :     //
   15739              :     const std::uint64_t ten_m = one.f;
   15740              :     grisu2_round(buffer, length, dist, delta, p2, ten_m);
   15741              : 
   15742              :     // By construction this algorithm generates the shortest possible decimal
   15743              :     // number (Loitsch, Theorem 6.2) which rounds back to w.
   15744              :     // For an input number of precision p, at least
   15745              :     //
   15746              :     //      N = 1 + ceil(p * log_10(2))
   15747              :     //
   15748              :     // decimal digits are sufficient to identify all binary floating-point
   15749              :     // numbers (Matula, "In-and-Out conversions").
   15750              :     // This implies that the algorithm does not produce more than N decimal
   15751              :     // digits.
   15752              :     //
   15753              :     //      N = 17 for p = 53 (IEEE double precision)
   15754              :     //      N = 9  for p = 24 (IEEE single precision)
   15755              : }
   15756              : 
   15757              : /*!
   15758              : v = buf * 10^decimal_exponent
   15759              : len is the length of the buffer (number of decimal digits)
   15760              : The buffer must be large enough, i.e. >= max_digits10.
   15761              : */
   15762              : JSON_HEDLEY_NON_NULL(1)
   15763              : inline void grisu2(char* buf, int& len, int& decimal_exponent,
   15764              :                    diyfp m_minus, diyfp v, diyfp m_plus)
   15765              : {
   15766              :     JSON_ASSERT(m_plus.e == m_minus.e);
   15767              :     JSON_ASSERT(m_plus.e == v.e);
   15768              : 
   15769              :     //  --------(-----------------------+-----------------------)--------    (A)
   15770              :     //          m-                      v                       m+
   15771              :     //
   15772              :     //  --------------------(-----------+-----------------------)--------    (B)
   15773              :     //                      m-          v                       m+
   15774              :     //
   15775              :     // First scale v (and m- and m+) such that the exponent is in the range
   15776              :     // [alpha, gamma].
   15777              : 
   15778              :     const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
   15779              : 
   15780              :     const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
   15781              : 
   15782              :     // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
   15783              :     const diyfp w       = diyfp::mul(v,       c_minus_k);
   15784              :     const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
   15785              :     const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
   15786              : 
   15787              :     //  ----(---+---)---------------(---+---)---------------(---+---)----
   15788              :     //          w-                      w                       w+
   15789              :     //          = c*m-                  = c*v                   = c*m+
   15790              :     //
   15791              :     // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
   15792              :     // w+ are now off by a small amount.
   15793              :     // In fact:
   15794              :     //
   15795              :     //      w - v * 10^k < 1 ulp
   15796              :     //
   15797              :     // To account for this inaccuracy, add resp. subtract 1 ulp.
   15798              :     //
   15799              :     //  --------+---[---------------(---+---)---------------]---+--------
   15800              :     //          w-  M-                  w                   M+  w+
   15801              :     //
   15802              :     // Now any number in [M-, M+] (bounds included) will round to w when input,
   15803              :     // regardless of how the input rounding algorithm breaks ties.
   15804              :     //
   15805              :     // And digit_gen generates the shortest possible such number in [M-, M+].
   15806              :     // Note that this does not mean that Grisu2 always generates the shortest
   15807              :     // possible number in the interval (m-, m+).
   15808              :     const diyfp M_minus(w_minus.f + 1, w_minus.e);
   15809              :     const diyfp M_plus (w_plus.f  - 1, w_plus.e );
   15810              : 
   15811              :     decimal_exponent = -cached.k; // = -(-k) = k
   15812              : 
   15813              :     grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
   15814              : }
   15815              : 
   15816              : /*!
   15817              : v = buf * 10^decimal_exponent
   15818              : len is the length of the buffer (number of decimal digits)
   15819              : The buffer must be large enough, i.e. >= max_digits10.
   15820              : */
   15821              : template<typename FloatType>
   15822              : JSON_HEDLEY_NON_NULL(1)
   15823              : void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
   15824              : {
   15825              :     static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
   15826              :                   "internal error: not enough precision");
   15827              : 
   15828              :     JSON_ASSERT(std::isfinite(value));
   15829              :     JSON_ASSERT(value > 0);
   15830              : 
   15831              :     // If the neighbors (and boundaries) of 'value' are always computed for double-precision
   15832              :     // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
   15833              :     // decimal representations are not exactly "short".
   15834              :     //
   15835              :     // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
   15836              :     // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
   15837              :     // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
   15838              :     // does.
   15839              :     // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
   15840              :     // representation using the corresponding std::from_chars function recovers value exactly". That
   15841              :     // indicates that single precision floating-point numbers should be recovered using
   15842              :     // 'std::strtof'.
   15843              :     //
   15844              :     // NB: If the neighbors are computed for single-precision numbers, there is a single float
   15845              :     //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
   15846              :     //     value is off by 1 ulp.
   15847              : #if 0
   15848              :     const boundaries w = compute_boundaries(static_cast<double>(value));
   15849              : #else
   15850              :     const boundaries w = compute_boundaries(value);
   15851              : #endif
   15852              : 
   15853              :     grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
   15854              : }
   15855              : 
   15856              : /*!
   15857              : @brief appends a decimal representation of e to buf
   15858              : @return a pointer to the element following the exponent.
   15859              : @pre -1000 < e < 1000
   15860              : */
   15861              : JSON_HEDLEY_NON_NULL(1)
   15862              : JSON_HEDLEY_RETURNS_NON_NULL
   15863              : inline char* append_exponent(char* buf, int e)
   15864              : {
   15865              :     JSON_ASSERT(e > -1000);
   15866              :     JSON_ASSERT(e <  1000);
   15867              : 
   15868              :     if (e < 0)
   15869              :     {
   15870              :         e = -e;
   15871              :         *buf++ = '-';
   15872              :     }
   15873              :     else
   15874              :     {
   15875              :         *buf++ = '+';
   15876              :     }
   15877              : 
   15878              :     auto k = static_cast<std::uint32_t>(e);
   15879              :     if (k < 10)
   15880              :     {
   15881              :         // Always print at least two digits in the exponent.
   15882              :         // This is for compatibility with printf("%g").
   15883              :         *buf++ = '0';
   15884              :         *buf++ = static_cast<char>('0' + k);
   15885              :     }
   15886              :     else if (k < 100)
   15887              :     {
   15888              :         *buf++ = static_cast<char>('0' + k / 10);
   15889              :         k %= 10;
   15890              :         *buf++ = static_cast<char>('0' + k);
   15891              :     }
   15892              :     else
   15893              :     {
   15894              :         *buf++ = static_cast<char>('0' + k / 100);
   15895              :         k %= 100;
   15896              :         *buf++ = static_cast<char>('0' + k / 10);
   15897              :         k %= 10;
   15898              :         *buf++ = static_cast<char>('0' + k);
   15899              :     }
   15900              : 
   15901              :     return buf;
   15902              : }
   15903              : 
   15904              : /*!
   15905              : @brief prettify v = buf * 10^decimal_exponent
   15906              : 
   15907              : If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
   15908              : notation. Otherwise it will be printed in exponential notation.
   15909              : 
   15910              : @pre min_exp < 0
   15911              : @pre max_exp > 0
   15912              : */
   15913              : JSON_HEDLEY_NON_NULL(1)
   15914              : JSON_HEDLEY_RETURNS_NON_NULL
   15915              : inline char* format_buffer(char* buf, int len, int decimal_exponent,
   15916              :                            int min_exp, int max_exp)
   15917              : {
   15918              :     JSON_ASSERT(min_exp < 0);
   15919              :     JSON_ASSERT(max_exp > 0);
   15920              : 
   15921              :     const int k = len;
   15922              :     const int n = len + decimal_exponent;
   15923              : 
   15924              :     // v = buf * 10^(n-k)
   15925              :     // k is the length of the buffer (number of decimal digits)
   15926              :     // n is the position of the decimal point relative to the start of the buffer.
   15927              : 
   15928              :     if (k <= n && n <= max_exp)
   15929              :     {
   15930              :         // digits[000]
   15931              :         // len <= max_exp + 2
   15932              : 
   15933              :         std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
   15934              :         // Make it look like a floating-point number (#362, #378)
   15935              :         buf[n + 0] = '.';
   15936              :         buf[n + 1] = '0';
   15937              :         return buf + (static_cast<size_t>(n) + 2);
   15938              :     }
   15939              : 
   15940              :     if (0 < n && n <= max_exp)
   15941              :     {
   15942              :         // dig.its
   15943              :         // len <= max_digits10 + 1
   15944              : 
   15945              :         JSON_ASSERT(k > n);
   15946              : 
   15947              :         std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
   15948              :         buf[n] = '.';
   15949              :         return buf + (static_cast<size_t>(k) + 1U);
   15950              :     }
   15951              : 
   15952              :     if (min_exp < n && n <= 0)
   15953              :     {
   15954              :         // 0.[000]digits
   15955              :         // len <= 2 + (-min_exp - 1) + max_digits10
   15956              : 
   15957              :         std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
   15958              :         buf[0] = '0';
   15959              :         buf[1] = '.';
   15960              :         std::memset(buf + 2, '0', static_cast<size_t>(-n));
   15961              :         return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
   15962              :     }
   15963              : 
   15964              :     if (k == 1)
   15965              :     {
   15966              :         // dE+123
   15967              :         // len <= 1 + 5
   15968              : 
   15969              :         buf += 1;
   15970              :     }
   15971              :     else
   15972              :     {
   15973              :         // d.igitsE+123
   15974              :         // len <= max_digits10 + 1 + 5
   15975              : 
   15976              :         std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
   15977              :         buf[1] = '.';
   15978              :         buf += 1 + static_cast<size_t>(k);
   15979              :     }
   15980              : 
   15981              :     *buf++ = 'e';
   15982              :     return append_exponent(buf, n - 1);
   15983              : }
   15984              : 
   15985              : } // namespace dtoa_impl
   15986              : 
   15987              : /*!
   15988              : @brief generates a decimal representation of the floating-point number value in [first, last).
   15989              : 
   15990              : The format of the resulting decimal representation is similar to printf's %g
   15991              : format. Returns an iterator pointing past-the-end of the decimal representation.
   15992              : 
   15993              : @note The input number must be finite, i.e. NaN's and Inf's are not supported.
   15994              : @note The buffer must be large enough.
   15995              : @note The result is NOT null-terminated.
   15996              : */
   15997              : template<typename FloatType>
   15998              : JSON_HEDLEY_NON_NULL(1, 2)
   15999              : JSON_HEDLEY_RETURNS_NON_NULL
   16000              : char* to_chars(char* first, const char* last, FloatType value)
   16001              : {
   16002              :     static_cast<void>(last); // maybe unused - fix warning
   16003              :     JSON_ASSERT(std::isfinite(value));
   16004              : 
   16005              :     // Use signbit(value) instead of (value < 0) since signbit works for -0.
   16006              :     if (std::signbit(value))
   16007              :     {
   16008              :         value = -value;
   16009              :         *first++ = '-';
   16010              :     }
   16011              : 
   16012              : #ifdef __GNUC__
   16013              : #pragma GCC diagnostic push
   16014              : #pragma GCC diagnostic ignored "-Wfloat-equal"
   16015              : #endif
   16016              :     if (value == 0) // +-0
   16017              :     {
   16018              :         *first++ = '0';
   16019              :         // Make it look like a floating-point number (#362, #378)
   16020              :         *first++ = '.';
   16021              :         *first++ = '0';
   16022              :         return first;
   16023              :     }
   16024              : #ifdef __GNUC__
   16025              : #pragma GCC diagnostic pop
   16026              : #endif
   16027              : 
   16028              :     JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
   16029              : 
   16030              :     // Compute v = buffer * 10^decimal_exponent.
   16031              :     // The decimal digits are stored in the buffer, which needs to be interpreted
   16032              :     // as an unsigned decimal integer.
   16033              :     // len is the length of the buffer, i.e. the number of decimal digits.
   16034              :     int len = 0;
   16035              :     int decimal_exponent = 0;
   16036              :     dtoa_impl::grisu2(first, len, decimal_exponent, value);
   16037              : 
   16038              :     JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
   16039              : 
   16040              :     // Format the buffer like printf("%.*g", prec, value)
   16041              :     constexpr int kMinExp = -4;
   16042              :     // Use digits10 here to increase compatibility with version 2.
   16043              :     constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
   16044              : 
   16045              :     JSON_ASSERT(last - first >= kMaxExp + 2);
   16046              :     JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
   16047              :     JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
   16048              : 
   16049              :     return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
   16050              : }
   16051              : 
   16052              : } // namespace detail
   16053              : } // namespace nlohmann
   16054              : 
   16055              : // #include <nlohmann/detail/exceptions.hpp>
   16056              : 
   16057              : // #include <nlohmann/detail/macro_scope.hpp>
   16058              : 
   16059              : // #include <nlohmann/detail/meta/cpp_future.hpp>
   16060              : 
   16061              : // #include <nlohmann/detail/output/binary_writer.hpp>
   16062              : 
   16063              : // #include <nlohmann/detail/output/output_adapters.hpp>
   16064              : 
   16065              : // #include <nlohmann/detail/value_t.hpp>
   16066              : 
   16067              : 
   16068              : namespace nlohmann
   16069              : {
   16070              : namespace detail
   16071              : {
   16072              : ///////////////////
   16073              : // serialization //
   16074              : ///////////////////
   16075              : 
   16076              : /// how to treat decoding errors
   16077              : enum class error_handler_t
   16078              : {
   16079              :     strict,  ///< throw a type_error exception in case of invalid UTF-8
   16080              :     replace, ///< replace invalid UTF-8 sequences with U+FFFD
   16081              :     ignore   ///< ignore invalid UTF-8 sequences
   16082              : };
   16083              : 
   16084              : template<typename BasicJsonType>
   16085              : class serializer
   16086              : {
   16087              :     using string_t = typename BasicJsonType::string_t;
   16088              :     using number_float_t = typename BasicJsonType::number_float_t;
   16089              :     using number_integer_t = typename BasicJsonType::number_integer_t;
   16090              :     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
   16091              :     using binary_char_t = typename BasicJsonType::binary_t::value_type;
   16092              :     static constexpr std::uint8_t UTF8_ACCEPT = 0;
   16093              :     static constexpr std::uint8_t UTF8_REJECT = 1;
   16094              : 
   16095              :   public:
   16096              :     /*!
   16097              :     @param[in] s  output stream to serialize to
   16098              :     @param[in] ichar  indentation character to use
   16099              :     @param[in] error_handler_  how to react on decoding errors
   16100              :     */
   16101              :     serializer(output_adapter_t<char> s, const char ichar,
   16102              :                error_handler_t error_handler_ = error_handler_t::strict)
   16103              :         : o(std::move(s))
   16104              :         , loc(std::localeconv())
   16105              :         , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
   16106              :         , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
   16107              :         , indent_char(ichar)
   16108              :         , indent_string(512, indent_char)
   16109              :         , error_handler(error_handler_)
   16110              :     {}
   16111              : 
   16112              :     // delete because of pointer members
   16113              :     serializer(const serializer&) = delete;
   16114              :     serializer& operator=(const serializer&) = delete;
   16115              :     serializer(serializer&&) = delete;
   16116              :     serializer& operator=(serializer&&) = delete;
   16117              :     ~serializer() = default;
   16118              : 
   16119              :     /*!
   16120              :     @brief internal implementation of the serialization function
   16121              : 
   16122              :     This function is called by the public member function dump and organizes
   16123              :     the serialization internally. The indentation level is propagated as
   16124              :     additional parameter. In case of arrays and objects, the function is
   16125              :     called recursively.
   16126              : 
   16127              :     - strings and object keys are escaped using `escape_string()`
   16128              :     - integer numbers are converted implicitly via `operator<<`
   16129              :     - floating-point numbers are converted to a string using `"%g"` format
   16130              :     - binary values are serialized as objects containing the subtype and the
   16131              :       byte array
   16132              : 
   16133              :     @param[in] val               value to serialize
   16134              :     @param[in] pretty_print      whether the output shall be pretty-printed
   16135              :     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
   16136              :     in the output are escaped with `\uXXXX` sequences, and the result consists
   16137              :     of ASCII characters only.
   16138              :     @param[in] indent_step       the indent level
   16139              :     @param[in] current_indent    the current indent level (only used internally)
   16140              :     */
   16141              :     void dump(const BasicJsonType& val,
   16142              :               const bool pretty_print,
   16143              :               const bool ensure_ascii,
   16144              :               const unsigned int indent_step,
   16145              :               const unsigned int current_indent = 0)
   16146              :     {
   16147              :         switch (val.m_type)
   16148              :         {
   16149              :             case value_t::object:
   16150              :             {
   16151              :                 if (val.m_value.object->empty())
   16152              :                 {
   16153              :                     o->write_characters("{}", 2);
   16154              :                     return;
   16155              :                 }
   16156              : 
   16157              :                 if (pretty_print)
   16158              :                 {
   16159              :                     o->write_characters("{\n", 2);
   16160              : 
   16161              :                     // variable to hold indentation for recursive calls
   16162              :                     const auto new_indent = current_indent + indent_step;
   16163              :                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
   16164              :                     {
   16165              :                         indent_string.resize(indent_string.size() * 2, ' ');
   16166              :                     }
   16167              : 
   16168              :                     // first n-1 elements
   16169              :                     auto i = val.m_value.object->cbegin();
   16170              :                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
   16171              :                     {
   16172              :                         o->write_characters(indent_string.c_str(), new_indent);
   16173              :                         o->write_character('\"');
   16174              :                         dump_escaped(i->first, ensure_ascii);
   16175              :                         o->write_characters("\": ", 3);
   16176              :                         dump(i->second, true, ensure_ascii, indent_step, new_indent);
   16177              :                         o->write_characters(",\n", 2);
   16178              :                     }
   16179              : 
   16180              :                     // last element
   16181              :                     JSON_ASSERT(i != val.m_value.object->cend());
   16182              :                     JSON_ASSERT(std::next(i) == val.m_value.object->cend());
   16183              :                     o->write_characters(indent_string.c_str(), new_indent);
   16184              :                     o->write_character('\"');
   16185              :                     dump_escaped(i->first, ensure_ascii);
   16186              :                     o->write_characters("\": ", 3);
   16187              :                     dump(i->second, true, ensure_ascii, indent_step, new_indent);
   16188              : 
   16189              :                     o->write_character('\n');
   16190              :                     o->write_characters(indent_string.c_str(), current_indent);
   16191              :                     o->write_character('}');
   16192              :                 }
   16193              :                 else
   16194              :                 {
   16195              :                     o->write_character('{');
   16196              : 
   16197              :                     // first n-1 elements
   16198              :                     auto i = val.m_value.object->cbegin();
   16199              :                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
   16200              :                     {
   16201              :                         o->write_character('\"');
   16202              :                         dump_escaped(i->first, ensure_ascii);
   16203              :                         o->write_characters("\":", 2);
   16204              :                         dump(i->second, false, ensure_ascii, indent_step, current_indent);
   16205              :                         o->write_character(',');
   16206              :                     }
   16207              : 
   16208              :                     // last element
   16209              :                     JSON_ASSERT(i != val.m_value.object->cend());
   16210              :                     JSON_ASSERT(std::next(i) == val.m_value.object->cend());
   16211              :                     o->write_character('\"');
   16212              :                     dump_escaped(i->first, ensure_ascii);
   16213              :                     o->write_characters("\":", 2);
   16214              :                     dump(i->second, false, ensure_ascii, indent_step, current_indent);
   16215              : 
   16216              :                     o->write_character('}');
   16217              :                 }
   16218              : 
   16219              :                 return;
   16220              :             }
   16221              : 
   16222              :             case value_t::array:
   16223              :             {
   16224              :                 if (val.m_value.array->empty())
   16225              :                 {
   16226              :                     o->write_characters("[]", 2);
   16227              :                     return;
   16228              :                 }
   16229              : 
   16230              :                 if (pretty_print)
   16231              :                 {
   16232              :                     o->write_characters("[\n", 2);
   16233              : 
   16234              :                     // variable to hold indentation for recursive calls
   16235              :                     const auto new_indent = current_indent + indent_step;
   16236              :                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
   16237              :                     {
   16238              :                         indent_string.resize(indent_string.size() * 2, ' ');
   16239              :                     }
   16240              : 
   16241              :                     // first n-1 elements
   16242              :                     for (auto i = val.m_value.array->cbegin();
   16243              :                             i != val.m_value.array->cend() - 1; ++i)
   16244              :                     {
   16245              :                         o->write_characters(indent_string.c_str(), new_indent);
   16246              :                         dump(*i, true, ensure_ascii, indent_step, new_indent);
   16247              :                         o->write_characters(",\n", 2);
   16248              :                     }
   16249              : 
   16250              :                     // last element
   16251              :                     JSON_ASSERT(!val.m_value.array->empty());
   16252              :                     o->write_characters(indent_string.c_str(), new_indent);
   16253              :                     dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
   16254              : 
   16255              :                     o->write_character('\n');
   16256              :                     o->write_characters(indent_string.c_str(), current_indent);
   16257              :                     o->write_character(']');
   16258              :                 }
   16259              :                 else
   16260              :                 {
   16261              :                     o->write_character('[');
   16262              : 
   16263              :                     // first n-1 elements
   16264              :                     for (auto i = val.m_value.array->cbegin();
   16265              :                             i != val.m_value.array->cend() - 1; ++i)
   16266              :                     {
   16267              :                         dump(*i, false, ensure_ascii, indent_step, current_indent);
   16268              :                         o->write_character(',');
   16269              :                     }
   16270              : 
   16271              :                     // last element
   16272              :                     JSON_ASSERT(!val.m_value.array->empty());
   16273              :                     dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
   16274              : 
   16275              :                     o->write_character(']');
   16276              :                 }
   16277              : 
   16278              :                 return;
   16279              :             }
   16280              : 
   16281              :             case value_t::string:
   16282              :             {
   16283              :                 o->write_character('\"');
   16284              :                 dump_escaped(*val.m_value.string, ensure_ascii);
   16285              :                 o->write_character('\"');
   16286              :                 return;
   16287              :             }
   16288              : 
   16289              :             case value_t::binary:
   16290              :             {
   16291              :                 if (pretty_print)
   16292              :                 {
   16293              :                     o->write_characters("{\n", 2);
   16294              : 
   16295              :                     // variable to hold indentation for recursive calls
   16296              :                     const auto new_indent = current_indent + indent_step;
   16297              :                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
   16298              :                     {
   16299              :                         indent_string.resize(indent_string.size() * 2, ' ');
   16300              :                     }
   16301              : 
   16302              :                     o->write_characters(indent_string.c_str(), new_indent);
   16303              : 
   16304              :                     o->write_characters("\"bytes\": [", 10);
   16305              : 
   16306              :                     if (!val.m_value.binary->empty())
   16307              :                     {
   16308              :                         for (auto i = val.m_value.binary->cbegin();
   16309              :                                 i != val.m_value.binary->cend() - 1; ++i)
   16310              :                         {
   16311              :                             dump_integer(*i);
   16312              :                             o->write_characters(", ", 2);
   16313              :                         }
   16314              :                         dump_integer(val.m_value.binary->back());
   16315              :                     }
   16316              : 
   16317              :                     o->write_characters("],\n", 3);
   16318              :                     o->write_characters(indent_string.c_str(), new_indent);
   16319              : 
   16320              :                     o->write_characters("\"subtype\": ", 11);
   16321              :                     if (val.m_value.binary->has_subtype())
   16322              :                     {
   16323              :                         dump_integer(val.m_value.binary->subtype());
   16324              :                     }
   16325              :                     else
   16326              :                     {
   16327              :                         o->write_characters("null", 4);
   16328              :                     }
   16329              :                     o->write_character('\n');
   16330              :                     o->write_characters(indent_string.c_str(), current_indent);
   16331              :                     o->write_character('}');
   16332              :                 }
   16333              :                 else
   16334              :                 {
   16335              :                     o->write_characters("{\"bytes\":[", 10);
   16336              : 
   16337              :                     if (!val.m_value.binary->empty())
   16338              :                     {
   16339              :                         for (auto i = val.m_value.binary->cbegin();
   16340              :                                 i != val.m_value.binary->cend() - 1; ++i)
   16341              :                         {
   16342              :                             dump_integer(*i);
   16343              :                             o->write_character(',');
   16344              :                         }
   16345              :                         dump_integer(val.m_value.binary->back());
   16346              :                     }
   16347              : 
   16348              :                     o->write_characters("],\"subtype\":", 12);
   16349              :                     if (val.m_value.binary->has_subtype())
   16350              :                     {
   16351              :                         dump_integer(val.m_value.binary->subtype());
   16352              :                         o->write_character('}');
   16353              :                     }
   16354              :                     else
   16355              :                     {
   16356              :                         o->write_characters("null}", 5);
   16357              :                     }
   16358              :                 }
   16359              :                 return;
   16360              :             }
   16361              : 
   16362              :             case value_t::boolean:
   16363              :             {
   16364              :                 if (val.m_value.boolean)
   16365              :                 {
   16366              :                     o->write_characters("true", 4);
   16367              :                 }
   16368              :                 else
   16369              :                 {
   16370              :                     o->write_characters("false", 5);
   16371              :                 }
   16372              :                 return;
   16373              :             }
   16374              : 
   16375              :             case value_t::number_integer:
   16376              :             {
   16377              :                 dump_integer(val.m_value.number_integer);
   16378              :                 return;
   16379              :             }
   16380              : 
   16381              :             case value_t::number_unsigned:
   16382              :             {
   16383              :                 dump_integer(val.m_value.number_unsigned);
   16384              :                 return;
   16385              :             }
   16386              : 
   16387              :             case value_t::number_float:
   16388              :             {
   16389              :                 dump_float(val.m_value.number_float);
   16390              :                 return;
   16391              :             }
   16392              : 
   16393              :             case value_t::discarded:
   16394              :             {
   16395              :                 o->write_characters("<discarded>", 11);
   16396              :                 return;
   16397              :             }
   16398              : 
   16399              :             case value_t::null:
   16400              :             {
   16401              :                 o->write_characters("null", 4);
   16402              :                 return;
   16403              :             }
   16404              : 
   16405              :             default:            // LCOV_EXCL_LINE
   16406              :                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
   16407              :         }
   16408              :     }
   16409              : 
   16410              :   JSON_PRIVATE_UNLESS_TESTED:
   16411              :     /*!
   16412              :     @brief dump escaped string
   16413              : 
   16414              :     Escape a string by replacing certain special characters by a sequence of an
   16415              :     escape character (backslash) and another character and other control
   16416              :     characters by a sequence of "\u" followed by a four-digit hex
   16417              :     representation. The escaped string is written to output stream @a o.
   16418              : 
   16419              :     @param[in] s  the string to escape
   16420              :     @param[in] ensure_ascii  whether to escape non-ASCII characters with
   16421              :                              \uXXXX sequences
   16422              : 
   16423              :     @complexity Linear in the length of string @a s.
   16424              :     */
   16425              :     void dump_escaped(const string_t& s, const bool ensure_ascii)
   16426              :     {
   16427              :         std::uint32_t codepoint{};
   16428              :         std::uint8_t state = UTF8_ACCEPT;
   16429              :         std::size_t bytes = 0;  // number of bytes written to string_buffer
   16430              : 
   16431              :         // number of bytes written at the point of the last valid byte
   16432              :         std::size_t bytes_after_last_accept = 0;
   16433              :         std::size_t undumped_chars = 0;
   16434              : 
   16435              :         for (std::size_t i = 0; i < s.size(); ++i)
   16436              :         {
   16437              :             const auto byte = static_cast<std::uint8_t>(s[i]);
   16438              : 
   16439              :             switch (decode(state, codepoint, byte))
   16440              :             {
   16441              :                 case UTF8_ACCEPT:  // decode found a new code point
   16442              :                 {
   16443              :                     switch (codepoint)
   16444              :                     {
   16445              :                         case 0x08: // backspace
   16446              :                         {
   16447              :                             string_buffer[bytes++] = '\\';
   16448              :                             string_buffer[bytes++] = 'b';
   16449              :                             break;
   16450              :                         }
   16451              : 
   16452              :                         case 0x09: // horizontal tab
   16453              :                         {
   16454              :                             string_buffer[bytes++] = '\\';
   16455              :                             string_buffer[bytes++] = 't';
   16456              :                             break;
   16457              :                         }
   16458              : 
   16459              :                         case 0x0A: // newline
   16460              :                         {
   16461              :                             string_buffer[bytes++] = '\\';
   16462              :                             string_buffer[bytes++] = 'n';
   16463              :                             break;
   16464              :                         }
   16465              : 
   16466              :                         case 0x0C: // formfeed
   16467              :                         {
   16468              :                             string_buffer[bytes++] = '\\';
   16469              :                             string_buffer[bytes++] = 'f';
   16470              :                             break;
   16471              :                         }
   16472              : 
   16473              :                         case 0x0D: // carriage return
   16474              :                         {
   16475              :                             string_buffer[bytes++] = '\\';
   16476              :                             string_buffer[bytes++] = 'r';
   16477              :                             break;
   16478              :                         }
   16479              : 
   16480              :                         case 0x22: // quotation mark
   16481              :                         {
   16482              :                             string_buffer[bytes++] = '\\';
   16483              :                             string_buffer[bytes++] = '\"';
   16484              :                             break;
   16485              :                         }
   16486              : 
   16487              :                         case 0x5C: // reverse solidus
   16488              :                         {
   16489              :                             string_buffer[bytes++] = '\\';
   16490              :                             string_buffer[bytes++] = '\\';
   16491              :                             break;
   16492              :                         }
   16493              : 
   16494              :                         default:
   16495              :                         {
   16496              :                             // escape control characters (0x00..0x1F) or, if
   16497              :                             // ensure_ascii parameter is used, non-ASCII characters
   16498              :                             if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
   16499              :                             {
   16500              :                                 if (codepoint <= 0xFFFF)
   16501              :                                 {
   16502              :                                     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
   16503              :                                     static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
   16504              :                                                                       static_cast<std::uint16_t>(codepoint)));
   16505              :                                     bytes += 6;
   16506              :                                 }
   16507              :                                 else
   16508              :                                 {
   16509              :                                     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
   16510              :                                     static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
   16511              :                                                                       static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
   16512              :                                                                       static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
   16513              :                                     bytes += 12;
   16514              :                                 }
   16515              :                             }
   16516              :                             else
   16517              :                             {
   16518              :                                 // copy byte to buffer (all previous bytes
   16519              :                                 // been copied have in default case above)
   16520              :                                 string_buffer[bytes++] = s[i];
   16521              :                             }
   16522              :                             break;
   16523              :                         }
   16524              :                     }
   16525              : 
   16526              :                     // write buffer and reset index; there must be 13 bytes
   16527              :                     // left, as this is the maximal number of bytes to be
   16528              :                     // written ("\uxxxx\uxxxx\0") for one code point
   16529              :                     if (string_buffer.size() - bytes < 13)
   16530              :                     {
   16531              :                         o->write_characters(string_buffer.data(), bytes);
   16532              :                         bytes = 0;
   16533              :                     }
   16534              : 
   16535              :                     // remember the byte position of this accept
   16536              :                     bytes_after_last_accept = bytes;
   16537              :                     undumped_chars = 0;
   16538              :                     break;
   16539              :                 }
   16540              : 
   16541              :                 case UTF8_REJECT:  // decode found invalid UTF-8 byte
   16542              :                 {
   16543              :                     switch (error_handler)
   16544              :                     {
   16545              :                         case error_handler_t::strict:
   16546              :                         {
   16547              :                             std::stringstream ss;
   16548              :                             ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (byte | 0);
   16549              :                             JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + ss.str(), BasicJsonType()));
   16550              :                         }
   16551              : 
   16552              :                         case error_handler_t::ignore:
   16553              :                         case error_handler_t::replace:
   16554              :                         {
   16555              :                             // in case we saw this character the first time, we
   16556              :                             // would like to read it again, because the byte
   16557              :                             // may be OK for itself, but just not OK for the
   16558              :                             // previous sequence
   16559              :                             if (undumped_chars > 0)
   16560              :                             {
   16561              :                                 --i;
   16562              :                             }
   16563              : 
   16564              :                             // reset length buffer to the last accepted index;
   16565              :                             // thus removing/ignoring the invalid characters
   16566              :                             bytes = bytes_after_last_accept;
   16567              : 
   16568              :                             if (error_handler == error_handler_t::replace)
   16569              :                             {
   16570              :                                 // add a replacement character
   16571              :                                 if (ensure_ascii)
   16572              :                                 {
   16573              :                                     string_buffer[bytes++] = '\\';
   16574              :                                     string_buffer[bytes++] = 'u';
   16575              :                                     string_buffer[bytes++] = 'f';
   16576              :                                     string_buffer[bytes++] = 'f';
   16577              :                                     string_buffer[bytes++] = 'f';
   16578              :                                     string_buffer[bytes++] = 'd';
   16579              :                                 }
   16580              :                                 else
   16581              :                                 {
   16582              :                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
   16583              :                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
   16584              :                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
   16585              :                                 }
   16586              : 
   16587              :                                 // write buffer and reset index; there must be 13 bytes
   16588              :                                 // left, as this is the maximal number of bytes to be
   16589              :                                 // written ("\uxxxx\uxxxx\0") for one code point
   16590              :                                 if (string_buffer.size() - bytes < 13)
   16591              :                                 {
   16592              :                                     o->write_characters(string_buffer.data(), bytes);
   16593              :                                     bytes = 0;
   16594              :                                 }
   16595              : 
   16596              :                                 bytes_after_last_accept = bytes;
   16597              :                             }
   16598              : 
   16599              :                             undumped_chars = 0;
   16600              : 
   16601              :                             // continue processing the string
   16602              :                             state = UTF8_ACCEPT;
   16603              :                             break;
   16604              :                         }
   16605              : 
   16606              :                         default:            // LCOV_EXCL_LINE
   16607              :                             JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
   16608              :                     }
   16609              :                     break;
   16610              :                 }
   16611              : 
   16612              :                 default:  // decode found yet incomplete multi-byte code point
   16613              :                 {
   16614              :                     if (!ensure_ascii)
   16615              :                     {
   16616              :                         // code point will not be escaped - copy byte to buffer
   16617              :                         string_buffer[bytes++] = s[i];
   16618              :                     }
   16619              :                     ++undumped_chars;
   16620              :                     break;
   16621              :                 }
   16622              :             }
   16623              :         }
   16624              : 
   16625              :         // we finished processing the string
   16626              :         if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
   16627              :         {
   16628              :             // write buffer
   16629              :             if (bytes > 0)
   16630              :             {
   16631              :                 o->write_characters(string_buffer.data(), bytes);
   16632              :             }
   16633              :         }
   16634              :         else
   16635              :         {
   16636              :             // we finish reading, but do not accept: string was incomplete
   16637              :             switch (error_handler)
   16638              :             {
   16639              :                 case error_handler_t::strict:
   16640              :                 {
   16641              :                     std::stringstream ss;
   16642              :                     ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (static_cast<std::uint8_t>(s.back()) | 0);
   16643              :                     JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + ss.str(), BasicJsonType()));
   16644              :                 }
   16645              : 
   16646              :                 case error_handler_t::ignore:
   16647              :                 {
   16648              :                     // write all accepted bytes
   16649              :                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
   16650              :                     break;
   16651              :                 }
   16652              : 
   16653              :                 case error_handler_t::replace:
   16654              :                 {
   16655              :                     // write all accepted bytes
   16656              :                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
   16657              :                     // add a replacement character
   16658              :                     if (ensure_ascii)
   16659              :                     {
   16660              :                         o->write_characters("\\ufffd", 6);
   16661              :                     }
   16662              :                     else
   16663              :                     {
   16664              :                         o->write_characters("\xEF\xBF\xBD", 3);
   16665              :                     }
   16666              :                     break;
   16667              :                 }
   16668              : 
   16669              :                 default:            // LCOV_EXCL_LINE
   16670              :                     JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
   16671              :             }
   16672              :         }
   16673              :     }
   16674              : 
   16675              :   private:
   16676              :     /*!
   16677              :     @brief count digits
   16678              : 
   16679              :     Count the number of decimal (base 10) digits for an input unsigned integer.
   16680              : 
   16681              :     @param[in] x  unsigned integer number to count its digits
   16682              :     @return    number of decimal digits
   16683              :     */
   16684              :     inline unsigned int count_digits(number_unsigned_t x) noexcept
   16685              :     {
   16686              :         unsigned int n_digits = 1;
   16687              :         for (;;)
   16688              :         {
   16689              :             if (x < 10)
   16690              :             {
   16691              :                 return n_digits;
   16692              :             }
   16693              :             if (x < 100)
   16694              :             {
   16695              :                 return n_digits + 1;
   16696              :             }
   16697              :             if (x < 1000)
   16698              :             {
   16699              :                 return n_digits + 2;
   16700              :             }
   16701              :             if (x < 10000)
   16702              :             {
   16703              :                 return n_digits + 3;
   16704              :             }
   16705              :             x = x / 10000u;
   16706              :             n_digits += 4;
   16707              :         }
   16708              :     }
   16709              : 
   16710              :     // templates to avoid warnings about useless casts
   16711              :     template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
   16712              :     bool is_negative_number(NumberType x)
   16713              :     {
   16714              :         return x < 0;
   16715              :     }
   16716              : 
   16717              :     template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
   16718              :     bool is_negative_number(NumberType /*unused*/)
   16719              :     {
   16720              :         return false;
   16721              :     }
   16722              : 
   16723              :     /*!
   16724              :     @brief dump an integer
   16725              : 
   16726              :     Dump a given integer to output stream @a o. Works internally with
   16727              :     @a number_buffer.
   16728              : 
   16729              :     @param[in] x  integer number (signed or unsigned) to dump
   16730              :     @tparam NumberType either @a number_integer_t or @a number_unsigned_t
   16731              :     */
   16732              :     template < typename NumberType, detail::enable_if_t <
   16733              :                    std::is_integral<NumberType>::value ||
   16734              :                    std::is_same<NumberType, number_unsigned_t>::value ||
   16735              :                    std::is_same<NumberType, number_integer_t>::value ||
   16736              :                    std::is_same<NumberType, binary_char_t>::value,
   16737              :                    int > = 0 >
   16738              :     void dump_integer(NumberType x)
   16739              :     {
   16740              :         static constexpr std::array<std::array<char, 2>, 100> digits_to_99
   16741              :         {
   16742              :             {
   16743              :                 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
   16744              :                 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
   16745              :                 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
   16746              :                 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
   16747              :                 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
   16748              :                 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
   16749              :                 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
   16750              :                 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
   16751              :                 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
   16752              :                 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
   16753              :             }
   16754              :         };
   16755              : 
   16756              :         // special case for "0"
   16757              :         if (x == 0)
   16758              :         {
   16759              :             o->write_character('0');
   16760              :             return;
   16761              :         }
   16762              : 
   16763              :         // use a pointer to fill the buffer
   16764              :         auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
   16765              : 
   16766              :         number_unsigned_t abs_value;
   16767              : 
   16768              :         unsigned int n_chars{};
   16769              : 
   16770              :         if (is_negative_number(x))
   16771              :         {
   16772              :             *buffer_ptr = '-';
   16773              :             abs_value = remove_sign(static_cast<number_integer_t>(x));
   16774              : 
   16775              :             // account one more byte for the minus sign
   16776              :             n_chars = 1 + count_digits(abs_value);
   16777              :         }
   16778              :         else
   16779              :         {
   16780              :             abs_value = static_cast<number_unsigned_t>(x);
   16781              :             n_chars = count_digits(abs_value);
   16782              :         }
   16783              : 
   16784              :         // spare 1 byte for '\0'
   16785              :         JSON_ASSERT(n_chars < number_buffer.size() - 1);
   16786              : 
   16787              :         // jump to the end to generate the string from backward,
   16788              :         // so we later avoid reversing the result
   16789              :         buffer_ptr += n_chars;
   16790              : 
   16791              :         // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
   16792              :         // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
   16793              :         while (abs_value >= 100)
   16794              :         {
   16795              :             const auto digits_index = static_cast<unsigned>((abs_value % 100));
   16796              :             abs_value /= 100;
   16797              :             *(--buffer_ptr) = digits_to_99[digits_index][1];
   16798              :             *(--buffer_ptr) = digits_to_99[digits_index][0];
   16799              :         }
   16800              : 
   16801              :         if (abs_value >= 10)
   16802              :         {
   16803              :             const auto digits_index = static_cast<unsigned>(abs_value);
   16804              :             *(--buffer_ptr) = digits_to_99[digits_index][1];
   16805              :             *(--buffer_ptr) = digits_to_99[digits_index][0];
   16806              :         }
   16807              :         else
   16808              :         {
   16809              :             *(--buffer_ptr) = static_cast<char>('0' + abs_value);
   16810              :         }
   16811              : 
   16812              :         o->write_characters(number_buffer.data(), n_chars);
   16813              :     }
   16814              : 
   16815              :     /*!
   16816              :     @brief dump a floating-point number
   16817              : 
   16818              :     Dump a given floating-point number to output stream @a o. Works internally
   16819              :     with @a number_buffer.
   16820              : 
   16821              :     @param[in] x  floating-point number to dump
   16822              :     */
   16823              :     void dump_float(number_float_t x)
   16824              :     {
   16825              :         // NaN / inf
   16826              :         if (!std::isfinite(x))
   16827              :         {
   16828              :             o->write_characters("null", 4);
   16829              :             return;
   16830              :         }
   16831              : 
   16832              :         // If number_float_t is an IEEE-754 single or double precision number,
   16833              :         // use the Grisu2 algorithm to produce short numbers which are
   16834              :         // guaranteed to round-trip, using strtof and strtod, resp.
   16835              :         //
   16836              :         // NB: The test below works if <long double> == <double>.
   16837              :         static constexpr bool is_ieee_single_or_double
   16838              :             = (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) ||
   16839              :               (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);
   16840              : 
   16841              :         dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
   16842              :     }
   16843              : 
   16844              :     void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
   16845              :     {
   16846              :         auto* begin = number_buffer.data();
   16847              :         auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
   16848              : 
   16849              :         o->write_characters(begin, static_cast<size_t>(end - begin));
   16850              :     }
   16851              : 
   16852              :     void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
   16853              :     {
   16854              :         // get number of digits for a float -> text -> float round-trip
   16855              :         static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
   16856              : 
   16857              :         // the actual conversion
   16858              :         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
   16859              :         std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
   16860              : 
   16861              :         // negative value indicates an error
   16862              :         JSON_ASSERT(len > 0);
   16863              :         // check if buffer was large enough
   16864              :         JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
   16865              : 
   16866              :         // erase thousands separator
   16867              :         if (thousands_sep != '\0')
   16868              :         {
   16869              :             // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
   16870              :             const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
   16871              :             std::fill(end, number_buffer.end(), '\0');
   16872              :             JSON_ASSERT((end - number_buffer.begin()) <= len);
   16873              :             len = (end - number_buffer.begin());
   16874              :         }
   16875              : 
   16876              :         // convert decimal point to '.'
   16877              :         if (decimal_point != '\0' && decimal_point != '.')
   16878              :         {
   16879              :             // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
   16880              :             const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
   16881              :             if (dec_pos != number_buffer.end())
   16882              :             {
   16883              :                 *dec_pos = '.';
   16884              :             }
   16885              :         }
   16886              : 
   16887              :         o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
   16888              : 
   16889              :         // determine if we need to append ".0"
   16890              :         const bool value_is_int_like =
   16891              :             std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
   16892              :                          [](char c)
   16893              :         {
   16894              :             return c == '.' || c == 'e';
   16895              :         });
   16896              : 
   16897              :         if (value_is_int_like)
   16898              :         {
   16899              :             o->write_characters(".0", 2);
   16900              :         }
   16901              :     }
   16902              : 
   16903              :     /*!
   16904              :     @brief check whether a string is UTF-8 encoded
   16905              : 
   16906              :     The function checks each byte of a string whether it is UTF-8 encoded. The
   16907              :     result of the check is stored in the @a state parameter. The function must
   16908              :     be called initially with state 0 (accept). State 1 means the string must
   16909              :     be rejected, because the current byte is not allowed. If the string is
   16910              :     completely processed, but the state is non-zero, the string ended
   16911              :     prematurely; that is, the last byte indicated more bytes should have
   16912              :     followed.
   16913              : 
   16914              :     @param[in,out] state  the state of the decoding
   16915              :     @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)
   16916              :     @param[in] byte       next byte to decode
   16917              :     @return               new state
   16918              : 
   16919              :     @note The function has been edited: a std::array is used.
   16920              : 
   16921              :     @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
   16922              :     @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
   16923              :     */
   16924              :     static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
   16925              :     {
   16926              :         static const std::array<std::uint8_t, 400> utf8d =
   16927              :         {
   16928              :             {
   16929              :                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
   16930              :                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
   16931              :                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
   16932              :                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
   16933              :                 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
   16934              :                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
   16935              :                 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
   16936              :                 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
   16937              :                 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
   16938              :                 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
   16939              :                 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
   16940              :                 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
   16941              :                 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
   16942              :                 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
   16943              :             }
   16944              :         };
   16945              : 
   16946              :         JSON_ASSERT(byte < utf8d.size());
   16947              :         const std::uint8_t type = utf8d[byte];
   16948              : 
   16949              :         codep = (state != UTF8_ACCEPT)
   16950              :                 ? (byte & 0x3fu) | (codep << 6u)
   16951              :                 : (0xFFu >> type) & (byte);
   16952              : 
   16953              :         std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
   16954              :         JSON_ASSERT(index < 400);
   16955              :         state = utf8d[index];
   16956              :         return state;
   16957              :     }
   16958              : 
   16959              :     /*
   16960              :      * Overload to make the compiler happy while it is instantiating
   16961              :      * dump_integer for number_unsigned_t.
   16962              :      * Must never be called.
   16963              :      */
   16964              :     number_unsigned_t remove_sign(number_unsigned_t x)
   16965              :     {
   16966              :         JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
   16967              :         return x; // LCOV_EXCL_LINE
   16968              :     }
   16969              : 
   16970              :     /*
   16971              :      * Helper function for dump_integer
   16972              :      *
   16973              :      * This function takes a negative signed integer and returns its absolute
   16974              :      * value as unsigned integer. The plus/minus shuffling is necessary as we can
   16975              :      * not directly remove the sign of an arbitrary signed integer as the
   16976              :      * absolute values of INT_MIN and INT_MAX are usually not the same. See
   16977              :      * #1708 for details.
   16978              :      */
   16979              :     inline number_unsigned_t remove_sign(number_integer_t x) noexcept
   16980              :     {
   16981              :         JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
   16982              :         return static_cast<number_unsigned_t>(-(x + 1)) + 1;
   16983              :     }
   16984              : 
   16985              :   private:
   16986              :     /// the output of the serializer
   16987              :     output_adapter_t<char> o = nullptr;
   16988              : 
   16989              :     /// a (hopefully) large enough character buffer
   16990              :     std::array<char, 64> number_buffer{{}};
   16991              : 
   16992              :     /// the locale
   16993              :     const std::lconv* loc = nullptr;
   16994              :     /// the locale's thousand separator character
   16995              :     const char thousands_sep = '\0';
   16996              :     /// the locale's decimal point character
   16997              :     const char decimal_point = '\0';
   16998              : 
   16999              :     /// string buffer
   17000              :     std::array<char, 512> string_buffer{{}};
   17001              : 
   17002              :     /// the indentation character
   17003              :     const char indent_char;
   17004              :     /// the indentation string
   17005              :     string_t indent_string;
   17006              : 
   17007              :     /// error_handler how to react on decoding errors
   17008              :     const error_handler_t error_handler;
   17009              : };
   17010              : }  // namespace detail
   17011              : }  // namespace nlohmann
   17012              : 
   17013              : // #include <nlohmann/detail/value_t.hpp>
   17014              : 
   17015              : // #include <nlohmann/json_fwd.hpp>
   17016              : 
   17017              : // #include <nlohmann/ordered_map.hpp>
   17018              : 
   17019              : 
   17020              : #include <functional> // less
   17021              : #include <initializer_list> // initializer_list
   17022              : #include <iterator> // input_iterator_tag, iterator_traits
   17023              : #include <memory> // allocator
   17024              : #include <stdexcept> // for out_of_range
   17025              : #include <type_traits> // enable_if, is_convertible
   17026              : #include <utility> // pair
   17027              : #include <vector> // vector
   17028              : 
   17029              : // #include <nlohmann/detail/macro_scope.hpp>
   17030              : 
   17031              : 
   17032              : namespace nlohmann
   17033              : {
   17034              : 
   17035              : /// ordered_map: a minimal map-like container that preserves insertion order
   17036              : /// for use within nlohmann::basic_json<ordered_map>
   17037              : template <class Key, class T, class IgnoredLess = std::less<Key>,
   17038              :           class Allocator = std::allocator<std::pair<const Key, T>>>
   17039              :                   struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
   17040              : {
   17041              :     using key_type = Key;
   17042              :     using mapped_type = T;
   17043              :     using Container = std::vector<std::pair<const Key, T>, Allocator>;
   17044              :     using iterator = typename Container::iterator;
   17045              :     using const_iterator = typename Container::const_iterator;
   17046              :     using size_type = typename Container::size_type;
   17047              :     using value_type = typename Container::value_type;
   17048              : 
   17049              :     // Explicit constructors instead of `using Container::Container`
   17050              :     // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
   17051              :     ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
   17052              :     template <class It>
   17053              :     ordered_map(It first, It last, const Allocator& alloc = Allocator())
   17054              :         : Container{first, last, alloc} {}
   17055              :     ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
   17056              :         : Container{init, alloc} {}
   17057              : 
   17058              :     std::pair<iterator, bool> emplace(const key_type& key, T&& t)
   17059              :     {
   17060              :         for (auto it = this->begin(); it != this->end(); ++it)
   17061              :         {
   17062              :             if (it->first == key)
   17063              :             {
   17064              :                 return {it, false};
   17065              :             }
   17066              :         }
   17067              :         Container::emplace_back(key, t);
   17068              :         return {--this->end(), true};
   17069              :     }
   17070              : 
   17071              :     T& operator[](const Key& key)
   17072              :     {
   17073              :         return emplace(key, T{}).first->second;
   17074              :     }
   17075              : 
   17076              :     const T& operator[](const Key& key) const
   17077              :     {
   17078              :         return at(key);
   17079              :     }
   17080              : 
   17081              :     T& at(const Key& key)
   17082              :     {
   17083              :         for (auto it = this->begin(); it != this->end(); ++it)
   17084              :         {
   17085              :             if (it->first == key)
   17086              :             {
   17087              :                 return it->second;
   17088              :             }
   17089              :         }
   17090              : 
   17091              :         JSON_THROW(std::out_of_range("key not found"));
   17092              :     }
   17093              : 
   17094              :     const T& at(const Key& key) const
   17095              :     {
   17096              :         for (auto it = this->begin(); it != this->end(); ++it)
   17097              :         {
   17098              :             if (it->first == key)
   17099              :             {
   17100              :                 return it->second;
   17101              :             }
   17102              :         }
   17103              : 
   17104              :         JSON_THROW(std::out_of_range("key not found"));
   17105              :     }
   17106              : 
   17107              :     size_type erase(const Key& key)
   17108              :     {
   17109              :         for (auto it = this->begin(); it != this->end(); ++it)
   17110              :         {
   17111              :             if (it->first == key)
   17112              :             {
   17113              :                 // Since we cannot move const Keys, re-construct them in place
   17114              :                 for (auto next = it; ++next != this->end(); ++it)
   17115              :                 {
   17116              :                     it->~value_type(); // Destroy but keep allocation
   17117              :                     new (&*it) value_type{std::move(*next)};
   17118              :                 }
   17119              :                 Container::pop_back();
   17120              :                 return 1;
   17121              :             }
   17122              :         }
   17123              :         return 0;
   17124              :     }
   17125              : 
   17126              :     iterator erase(iterator pos)
   17127              :     {
   17128              :         return erase(pos, std::next(pos));
   17129              :     }
   17130              : 
   17131              :     iterator erase(iterator first, iterator last)
   17132              :     {
   17133              :         const auto elements_affected = std::distance(first, last);
   17134              :         const auto offset = std::distance(Container::begin(), first);
   17135              : 
   17136              :         // This is the start situation. We need to delete elements_affected
   17137              :         // elements (3 in this example: e, f, g), and need to return an
   17138              :         // iterator past the last deleted element (h in this example).
   17139              :         // Note that offset is the distance from the start of the vector
   17140              :         // to first. We will need this later.
   17141              : 
   17142              :         // [ a, b, c, d, e, f, g, h, i, j ]
   17143              :         //               ^        ^
   17144              :         //             first    last
   17145              : 
   17146              :         // Since we cannot move const Keys, we re-construct them in place.
   17147              :         // We start at first and re-construct (viz. copy) the elements from
   17148              :         // the back of the vector. Example for first iteration:
   17149              : 
   17150              :         //               ,--------.
   17151              :         //               v        |   destroy e and re-construct with h
   17152              :         // [ a, b, c, d, e, f, g, h, i, j ]
   17153              :         //               ^        ^
   17154              :         //               it       it + elements_affected
   17155              : 
   17156              :         for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
   17157              :         {
   17158              :             it->~value_type(); // destroy but keep allocation
   17159              :             new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
   17160              :         }
   17161              : 
   17162              :         // [ a, b, c, d, h, i, j, h, i, j ]
   17163              :         //               ^        ^
   17164              :         //             first    last
   17165              : 
   17166              :         // remove the unneeded elements at the end of the vector
   17167              :         Container::resize(this->size() - static_cast<size_type>(elements_affected));
   17168              : 
   17169              :         // [ a, b, c, d, h, i, j ]
   17170              :         //               ^        ^
   17171              :         //             first    last
   17172              : 
   17173              :         // first is now pointing past the last deleted element, but we cannot
   17174              :         // use this iterator, because it may have been invalidated by the
   17175              :         // resize call. Instead, we can return begin() + offset.
   17176              :         return Container::begin() + offset;
   17177              :     }
   17178              : 
   17179              :     size_type count(const Key& key) const
   17180              :     {
   17181              :         for (auto it = this->begin(); it != this->end(); ++it)
   17182              :         {
   17183              :             if (it->first == key)
   17184              :             {
   17185              :                 return 1;
   17186              :             }
   17187              :         }
   17188              :         return 0;
   17189              :     }
   17190              : 
   17191              :     iterator find(const Key& key)
   17192              :     {
   17193              :         for (auto it = this->begin(); it != this->end(); ++it)
   17194              :         {
   17195              :             if (it->first == key)
   17196              :             {
   17197              :                 return it;
   17198              :             }
   17199              :         }
   17200              :         return Container::end();
   17201              :     }
   17202              : 
   17203              :     const_iterator find(const Key& key) const
   17204              :     {
   17205              :         for (auto it = this->begin(); it != this->end(); ++it)
   17206              :         {
   17207              :             if (it->first == key)
   17208              :             {
   17209              :                 return it;
   17210              :             }
   17211              :         }
   17212              :         return Container::end();
   17213              :     }
   17214              : 
   17215              :     std::pair<iterator, bool> insert( value_type&& value )
   17216              :     {
   17217              :         return emplace(value.first, std::move(value.second));
   17218              :     }
   17219              : 
   17220              :     std::pair<iterator, bool> insert( const value_type& value )
   17221              :     {
   17222              :         for (auto it = this->begin(); it != this->end(); ++it)
   17223              :         {
   17224              :             if (it->first == value.first)
   17225              :             {
   17226              :                 return {it, false};
   17227              :             }
   17228              :         }
   17229              :         Container::push_back(value);
   17230              :         return {--this->end(), true};
   17231              :     }
   17232              : 
   17233              :     template<typename InputIt>
   17234              :     using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
   17235              :             std::input_iterator_tag>::value>::type;
   17236              : 
   17237              :     template<typename InputIt, typename = require_input_iter<InputIt>>
   17238              :     void insert(InputIt first, InputIt last)
   17239              :     {
   17240              :         for (auto it = first; it != last; ++it)
   17241              :         {
   17242              :             insert(*it);
   17243              :         }
   17244              :     }
   17245              : };
   17246              : 
   17247              : }  // namespace nlohmann
   17248              : 
   17249              : 
   17250              : #if defined(JSON_HAS_CPP_17)
   17251              :     #include <string_view>
   17252              : #endif
   17253              : 
   17254              : /*!
   17255              : @brief namespace for Niels Lohmann
   17256              : @see https://github.com/nlohmann
   17257              : @since version 1.0.0
   17258              : */
   17259              : namespace nlohmann
   17260              : {
   17261              : 
   17262              : /*!
   17263              : @brief a class to store JSON values
   17264              : 
   17265              : @internal
   17266              : @invariant The member variables @a m_value and @a m_type have the following
   17267              : relationship:
   17268              : - If `m_type == value_t::object`, then `m_value.object != nullptr`.
   17269              : - If `m_type == value_t::array`, then `m_value.array != nullptr`.
   17270              : - If `m_type == value_t::string`, then `m_value.string != nullptr`.
   17271              : The invariants are checked by member function assert_invariant().
   17272              : 
   17273              : @note ObjectType trick from https://stackoverflow.com/a/9860911
   17274              : @endinternal
   17275              : 
   17276              : @since version 1.0.0
   17277              : 
   17278              : @nosubgrouping
   17279              : */
   17280              : NLOHMANN_BASIC_JSON_TPL_DECLARATION
   17281              : class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
   17282              : {
   17283              :   private:
   17284              :     template<detail::value_t> friend struct detail::external_constructor;
   17285              :     friend ::nlohmann::json_pointer<basic_json>;
   17286              : 
   17287              :     template<typename BasicJsonType, typename InputType>
   17288              :     friend class ::nlohmann::detail::parser;
   17289              :     friend ::nlohmann::detail::serializer<basic_json>;
   17290              :     template<typename BasicJsonType>
   17291              :     friend class ::nlohmann::detail::iter_impl;
   17292              :     template<typename BasicJsonType, typename CharType>
   17293              :     friend class ::nlohmann::detail::binary_writer;
   17294              :     template<typename BasicJsonType, typename InputType, typename SAX>
   17295              :     friend class ::nlohmann::detail::binary_reader;
   17296              :     template<typename BasicJsonType>
   17297              :     friend class ::nlohmann::detail::json_sax_dom_parser;
   17298              :     template<typename BasicJsonType>
   17299              :     friend class ::nlohmann::detail::json_sax_dom_callback_parser;
   17300              :     friend class ::nlohmann::detail::exception;
   17301              : 
   17302              :     /// workaround type for MSVC
   17303              :     using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
   17304              : 
   17305              :   JSON_PRIVATE_UNLESS_TESTED:
   17306              :     // convenience aliases for types residing in namespace detail;
   17307              :     using lexer = ::nlohmann::detail::lexer_base<basic_json>;
   17308              : 
   17309              :     template<typename InputAdapterType>
   17310           33 :     static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
   17311              :         InputAdapterType adapter,
   17312              :         detail::parser_callback_t<basic_json>cb = nullptr,
   17313              :         const bool allow_exceptions = true,
   17314              :         const bool ignore_comments = false
   17315              :                                  )
   17316              :     {
   17317              :         return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
   17318           66 :                 std::move(cb), allow_exceptions, ignore_comments);
   17319              :     }
   17320              : 
   17321              :   private:
   17322              :     using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
   17323              :     template<typename BasicJsonType>
   17324              :     using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
   17325              :     template<typename BasicJsonType>
   17326              :     using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
   17327              :     template<typename Iterator>
   17328              :     using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
   17329              :     template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
   17330              : 
   17331              :     template<typename CharType>
   17332              :     using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
   17333              : 
   17334              :     template<typename InputType>
   17335              :     using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
   17336              :     template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
   17337              : 
   17338              :   JSON_PRIVATE_UNLESS_TESTED:
   17339              :     using serializer = ::nlohmann::detail::serializer<basic_json>;
   17340              : 
   17341              :   public:
   17342              :     using value_t = detail::value_t;
   17343              :     /// JSON Pointer, see @ref nlohmann::json_pointer
   17344              :     using json_pointer = ::nlohmann::json_pointer<basic_json>;
   17345              :     template<typename T, typename SFINAE>
   17346              :     using json_serializer = JSONSerializer<T, SFINAE>;
   17347              :     /// how to treat decoding errors
   17348              :     using error_handler_t = detail::error_handler_t;
   17349              :     /// how to treat CBOR tags
   17350              :     using cbor_tag_handler_t = detail::cbor_tag_handler_t;
   17351              :     /// helper type for initializer lists of basic_json values
   17352              :     using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
   17353              : 
   17354              :     using input_format_t = detail::input_format_t;
   17355              :     /// SAX interface type, see @ref nlohmann::json_sax
   17356              :     using json_sax_t = json_sax<basic_json>;
   17357              : 
   17358              :     ////////////////
   17359              :     // exceptions //
   17360              :     ////////////////
   17361              : 
   17362              :     /// @name exceptions
   17363              :     /// Classes to implement user-defined exceptions.
   17364              :     /// @{
   17365              : 
   17366              :     using exception = detail::exception;
   17367              :     using parse_error = detail::parse_error;
   17368              :     using invalid_iterator = detail::invalid_iterator;
   17369              :     using type_error = detail::type_error;
   17370              :     using out_of_range = detail::out_of_range;
   17371              :     using other_error = detail::other_error;
   17372              : 
   17373              :     /// @}
   17374              : 
   17375              : 
   17376              :     /////////////////////
   17377              :     // container types //
   17378              :     /////////////////////
   17379              : 
   17380              :     /// @name container types
   17381              :     /// The canonic container types to use @ref basic_json like any other STL
   17382              :     /// container.
   17383              :     /// @{
   17384              : 
   17385              :     /// the type of elements in a basic_json container
   17386              :     using value_type = basic_json;
   17387              : 
   17388              :     /// the type of an element reference
   17389              :     using reference = value_type&;
   17390              :     /// the type of an element const reference
   17391              :     using const_reference = const value_type&;
   17392              : 
   17393              :     /// a type to represent differences between iterators
   17394              :     using difference_type = std::ptrdiff_t;
   17395              :     /// a type to represent container sizes
   17396              :     using size_type = std::size_t;
   17397              : 
   17398              :     /// the allocator type
   17399              :     using allocator_type = AllocatorType<basic_json>;
   17400              : 
   17401              :     /// the type of an element pointer
   17402              :     using pointer = typename std::allocator_traits<allocator_type>::pointer;
   17403              :     /// the type of an element const pointer
   17404              :     using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
   17405              : 
   17406              :     /// an iterator for a basic_json container
   17407              :     using iterator = iter_impl<basic_json>;
   17408              :     /// a const iterator for a basic_json container
   17409              :     using const_iterator = iter_impl<const basic_json>;
   17410              :     /// a reverse iterator for a basic_json container
   17411              :     using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
   17412              :     /// a const reverse iterator for a basic_json container
   17413              :     using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
   17414              : 
   17415              :     /// @}
   17416              : 
   17417              : 
   17418              :     /// @brief returns the allocator associated with the container
   17419              :     /// @sa https://json.nlohmann.me/api/basic_json/get_allocator/
   17420              :     static allocator_type get_allocator()
   17421              :     {
   17422              :         return allocator_type();
   17423              :     }
   17424              : 
   17425              :     /// @brief returns version information on the library
   17426              :     /// @sa https://json.nlohmann.me/api/basic_json/meta/
   17427              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   17428              :     static basic_json meta()
   17429              :     {
   17430              :         basic_json result;
   17431              : 
   17432              :         result["copyright"] = "(C) 2013-2022 Niels Lohmann";
   17433              :         result["name"] = "JSON for Modern C++";
   17434              :         result["url"] = "https://github.com/nlohmann/json";
   17435              :         result["version"]["string"] =
   17436              :             std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
   17437              :             std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
   17438              :             std::to_string(NLOHMANN_JSON_VERSION_PATCH);
   17439              :         result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
   17440              :         result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
   17441              :         result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
   17442              : 
   17443              : #ifdef _WIN32
   17444              :         result["platform"] = "win32";
   17445              : #elif defined __linux__
   17446              :         result["platform"] = "linux";
   17447              : #elif defined __APPLE__
   17448              :         result["platform"] = "apple";
   17449              : #elif defined __unix__
   17450              :         result["platform"] = "unix";
   17451              : #else
   17452              :         result["platform"] = "unknown";
   17453              : #endif
   17454              : 
   17455              : #if defined(__ICC) || defined(__INTEL_COMPILER)
   17456              :         result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
   17457              : #elif defined(__clang__)
   17458              :         result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
   17459              : #elif defined(__GNUC__) || defined(__GNUG__)
   17460              :         result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
   17461              : #elif defined(__HP_cc) || defined(__HP_aCC)
   17462              :         result["compiler"] = "hp"
   17463              : #elif defined(__IBMCPP__)
   17464              :         result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
   17465              : #elif defined(_MSC_VER)
   17466              :         result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
   17467              : #elif defined(__PGI)
   17468              :         result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
   17469              : #elif defined(__SUNPRO_CC)
   17470              :         result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
   17471              : #else
   17472              :         result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
   17473              : #endif
   17474              : 
   17475              : #ifdef __cplusplus
   17476              :         result["compiler"]["c++"] = std::to_string(__cplusplus);
   17477              : #else
   17478              :         result["compiler"]["c++"] = "unknown";
   17479              : #endif
   17480              :         return result;
   17481              :     }
   17482              : 
   17483              : 
   17484              :     ///////////////////////////
   17485              :     // JSON value data types //
   17486              :     ///////////////////////////
   17487              : 
   17488              :     /// @name JSON value data types
   17489              :     /// The data types to store a JSON value. These types are derived from
   17490              :     /// the template arguments passed to class @ref basic_json.
   17491              :     /// @{
   17492              : 
   17493              :     /// @brief object key comparator type
   17494              :     /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/
   17495              : #if defined(JSON_HAS_CPP_14)
   17496              :     // Use transparent comparator if possible, combined with perfect forwarding
   17497              :     // on find() and count() calls prevents unnecessary string construction.
   17498              :     using object_comparator_t = std::less<>;
   17499              : #else
   17500              :     using object_comparator_t = std::less<StringType>;
   17501              : #endif
   17502              : 
   17503              :     /// @brief a type for an object
   17504              :     /// @sa https://json.nlohmann.me/api/basic_json/object_t/
   17505              :     using object_t = ObjectType<StringType,
   17506              :           basic_json,
   17507              :           object_comparator_t,
   17508              :           AllocatorType<std::pair<const StringType,
   17509              :           basic_json>>>;
   17510              : 
   17511              :     /// @brief a type for an array
   17512              :     /// @sa https://json.nlohmann.me/api/basic_json/array_t/
   17513              :     using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
   17514              : 
   17515              :     /// @brief a type for a string
   17516              :     /// @sa https://json.nlohmann.me/api/basic_json/string_t/
   17517              :     using string_t = StringType;
   17518              : 
   17519              :     /// @brief a type for a boolean
   17520              :     /// @sa https://json.nlohmann.me/api/basic_json/boolean_t/
   17521              :     using boolean_t = BooleanType;
   17522              : 
   17523              :     /// @brief a type for a number (integer)
   17524              :     /// @sa https://json.nlohmann.me/api/basic_json/number_integer_t/
   17525              :     using number_integer_t = NumberIntegerType;
   17526              : 
   17527              :     /// @brief a type for a number (unsigned)
   17528              :     /// @sa https://json.nlohmann.me/api/basic_json/number_unsigned_t/
   17529              :     using number_unsigned_t = NumberUnsignedType;
   17530              : 
   17531              :     /// @brief a type for a number (floating-point)
   17532              :     /// @sa https://json.nlohmann.me/api/basic_json/number_float_t/
   17533              :     using number_float_t = NumberFloatType;
   17534              : 
   17535              :     /// @brief a type for a packed binary type
   17536              :     /// @sa https://json.nlohmann.me/api/basic_json/binary_t/
   17537              :     using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
   17538              : 
   17539              :     /// @}
   17540              : 
   17541              :   private:
   17542              : 
   17543              :     /// helper for exception-safe object creation
   17544              :     template<typename T, typename... Args>
   17545              :     JSON_HEDLEY_RETURNS_NON_NULL
   17546          147 :     static T* create(Args&& ... args)
   17547              :     {
   17548              :         AllocatorType<T> alloc;
   17549              :         using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
   17550              : 
   17551              :         auto deleter = [&](T * obj)
   17552              :         {
   17553              :             AllocatorTraits::deallocate(alloc, obj, 1);
   17554              :         };
   17555              :         std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
   17556              :         AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
   17557              :         JSON_ASSERT(obj != nullptr);
   17558          147 :         return obj.release();
   17559              :     }
   17560              : 
   17561              :     ////////////////////////
   17562              :     // JSON value storage //
   17563              :     ////////////////////////
   17564              : 
   17565              :   JSON_PRIVATE_UNLESS_TESTED:
   17566              :     /*!
   17567              :     @brief a JSON value
   17568              : 
   17569              :     The actual storage for a JSON value of the @ref basic_json class. This
   17570              :     union combines the different storage types for the JSON value types
   17571              :     defined in @ref value_t.
   17572              : 
   17573              :     JSON type | value_t type    | used type
   17574              :     --------- | --------------- | ------------------------
   17575              :     object    | object          | pointer to @ref object_t
   17576              :     array     | array           | pointer to @ref array_t
   17577              :     string    | string          | pointer to @ref string_t
   17578              :     boolean   | boolean         | @ref boolean_t
   17579              :     number    | number_integer  | @ref number_integer_t
   17580              :     number    | number_unsigned | @ref number_unsigned_t
   17581              :     number    | number_float    | @ref number_float_t
   17582              :     binary    | binary          | pointer to @ref binary_t
   17583              :     null      | null            | *no value is stored*
   17584              : 
   17585              :     @note Variable-length types (objects, arrays, and strings) are stored as
   17586              :     pointers. The size of the union should not exceed 64 bits if the default
   17587              :     value types are used.
   17588              : 
   17589              :     @since version 1.0.0
   17590              :     */
   17591              :     union json_value
   17592              :     {
   17593              :         /// object (stored with pointer to save storage)
   17594              :         object_t* object;
   17595              :         /// array (stored with pointer to save storage)
   17596              :         array_t* array;
   17597              :         /// string (stored with pointer to save storage)
   17598              :         string_t* string;
   17599              :         /// binary (stored with pointer to save storage)
   17600              :         binary_t* binary;
   17601              :         /// boolean
   17602              :         boolean_t boolean;
   17603              :         /// number (integer)
   17604              :         number_integer_t number_integer;
   17605              :         /// number (unsigned integer)
   17606              :         number_unsigned_t number_unsigned;
   17607              :         /// number (floating-point)
   17608              :         number_float_t number_float;
   17609              : 
   17610              :         /// default constructor (for null values)
   17611              :         json_value() = default;
   17612              :         /// constructor for booleans
   17613            0 :         json_value(boolean_t v) noexcept : boolean(v) {}
   17614              :         /// constructor for numbers (integer)
   17615              :         json_value(number_integer_t v) noexcept : number_integer(v) {}
   17616              :         /// constructor for numbers (unsigned)
   17617              :         json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
   17618              :         /// constructor for numbers (floating-point)
   17619              :         json_value(number_float_t v) noexcept : number_float(v) {}
   17620              :         /// constructor for empty values of a given type
   17621         3195 :         json_value(value_t t)
   17622              :         {
   17623         3195 :             switch (t)
   17624              :             {
   17625              :                 case value_t::object:
   17626              :                 {
   17627          585 :                     object = create<object_t>();
   17628          585 :                     break;
   17629              :                 }
   17630              : 
   17631              :                 case value_t::array:
   17632              :                 {
   17633          615 :                     array = create<array_t>();
   17634          615 :                     break;
   17635              :                 }
   17636              : 
   17637            0 :                 case value_t::string:
   17638              :                 {
   17639            0 :                     string = create<string_t>("");
   17640            0 :                     break;
   17641              :                 }
   17642              : 
   17643              :                 case value_t::binary:
   17644              :                 {
   17645            0 :                     binary = create<binary_t>();
   17646            0 :                     break;
   17647              :                 }
   17648              : 
   17649            0 :                 case value_t::boolean:
   17650              :                 {
   17651            0 :                     boolean = static_cast<boolean_t>(false);
   17652            0 :                     break;
   17653              :                 }
   17654              : 
   17655            0 :                 case value_t::number_integer:
   17656              :                 {
   17657            0 :                     number_integer = static_cast<number_integer_t>(0);
   17658            0 :                     break;
   17659              :                 }
   17660              : 
   17661            0 :                 case value_t::number_unsigned:
   17662              :                 {
   17663            0 :                     number_unsigned = static_cast<number_unsigned_t>(0);
   17664            0 :                     break;
   17665              :                 }
   17666              : 
   17667            0 :                 case value_t::number_float:
   17668              :                 {
   17669            0 :                     number_float = static_cast<number_float_t>(0.0);
   17670            0 :                     break;
   17671              :                 }
   17672              : 
   17673         1995 :                 case value_t::null:
   17674              :                 {
   17675         1995 :                     object = nullptr;  // silence warning, see #821
   17676         1995 :                     break;
   17677              :                 }
   17678              : 
   17679            0 :                 case value_t::discarded:
   17680              :                 default:
   17681              :                 {
   17682            0 :                     object = nullptr;  // silence warning, see #821
   17683              :                     if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
   17684              :                     {
   17685              :                         JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.5", basic_json())); // LCOV_EXCL_LINE
   17686              :                     }
   17687              :                     break;
   17688              :                 }
   17689              :             }
   17690         3195 :         }
   17691              : 
   17692              :         /// constructor for strings
   17693          147 :         json_value(const string_t& value) : string(create<string_t>(value)) {}
   17694              : 
   17695              :         /// constructor for rvalue strings
   17696              :         json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
   17697              : 
   17698              :         /// constructor for objects
   17699            0 :         json_value(const object_t& value) : object(create<object_t>(value)) {}
   17700              : 
   17701              :         /// constructor for rvalue objects
   17702              :         json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
   17703              : 
   17704              :         /// constructor for arrays
   17705            0 :         json_value(const array_t& value) : array(create<array_t>(value)) {}
   17706              : 
   17707              :         /// constructor for rvalue arrays
   17708              :         json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
   17709              : 
   17710              :         /// constructor for binary arrays
   17711              :         json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
   17712              : 
   17713              :         /// constructor for rvalue binary arrays
   17714              :         json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
   17715              : 
   17716              :         /// constructor for binary arrays (internal type)
   17717            0 :         json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
   17718              : 
   17719              :         /// constructor for rvalue binary arrays (internal type)
   17720              :         json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
   17721              : 
   17722        20338 :         void destroy(value_t t)
   17723              :         {
   17724        20338 :             if (t == value_t::array || t == value_t::object)
   17725              :             {
   17726              :                 // flatten the current json_value to a heap-allocated stack
   17727              :                 std::vector<basic_json> stack;
   17728              : 
   17729              :                 // move the top-level items to stack
   17730          432 :                 if (t == value_t::array)
   17731              :                 {
   17732          135 :                     stack.reserve(array->size());
   17733          135 :                     std::move(array->begin(), array->end(), std::back_inserter(stack));
   17734              :                 }
   17735              :                 else
   17736              :                 {
   17737          297 :                     stack.reserve(object->size());
   17738          513 :                     for (auto&& it : *object)
   17739              :                     {
   17740          216 :                         stack.push_back(std::move(it.second));
   17741              :                     }
   17742              :                 }
   17743              : 
   17744         6168 :                 while (!stack.empty())
   17745              :                 {
   17746              :                     // move the last item to local variable to be processed
   17747              :                     basic_json current_item(std::move(stack.back()));
   17748              :                     stack.pop_back();
   17749              : 
   17750              :                     // if current_item is array/object, move
   17751              :                     // its children to the stack to be processed later
   17752         2868 :                     if (current_item.is_array())
   17753              :                     {
   17754          135 :                         std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
   17755              : 
   17756          135 :                         current_item.m_value.array->clear();
   17757              :                     }
   17758         2733 :                     else if (current_item.is_object())
   17759              :                     {
   17760         1188 :                         for (auto&& it : *current_item.m_value.object)
   17761              :                         {
   17762          918 :                             stack.push_back(std::move(it.second));
   17763              :                         }
   17764              : 
   17765          270 :                         current_item.m_value.object->clear();
   17766              :                     }
   17767              : 
   17768              :                     // it's now safe that current_item get destructed
   17769              :                     // since it doesn't have any children
   17770              :                 }
   17771          432 :             }
   17772              : 
   17773        20338 :             switch (t)
   17774              :             {
   17775              :                 case value_t::object:
   17776              :                 {
   17777              :                     AllocatorType<object_t> alloc;
   17778          297 :                     std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
   17779          297 :                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
   17780              :                     break;
   17781              :                 }
   17782              : 
   17783              :                 case value_t::array:
   17784              :                 {
   17785              :                     AllocatorType<array_t> alloc;
   17786          135 :                     std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
   17787          135 :                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
   17788              :                     break;
   17789              :                 }
   17790              : 
   17791              :                 case value_t::string:
   17792              :                 {
   17793              :                     AllocatorType<string_t> alloc;
   17794          135 :                     std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
   17795          135 :                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
   17796              :                     break;
   17797              :                 }
   17798              : 
   17799              :                 case value_t::binary:
   17800              :                 {
   17801              :                     AllocatorType<binary_t> alloc;
   17802            0 :                     std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
   17803            0 :                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
   17804              :                     break;
   17805              :                 }
   17806              : 
   17807              :                 case value_t::null:
   17808              :                 case value_t::boolean:
   17809              :                 case value_t::number_integer:
   17810              :                 case value_t::number_unsigned:
   17811              :                 case value_t::number_float:
   17812              :                 case value_t::discarded:
   17813              :                 default:
   17814              :                 {
   17815              :                     break;
   17816              :                 }
   17817              :             }
   17818        20338 :         }
   17819              :     };
   17820              : 
   17821              :   private:
   17822              :     /*!
   17823              :     @brief checks the class invariants
   17824              : 
   17825              :     This function asserts the class invariants. It needs to be called at the
   17826              :     end of every constructor to make sure that created objects respect the
   17827              :     invariant. Furthermore, it has to be called each time the type of a JSON
   17828              :     value is changed, because the invariant expresses a relationship between
   17829              :     @a m_type and @a m_value.
   17830              : 
   17831              :     Furthermore, the parent relation is checked for arrays and objects: If
   17832              :     @a check_parents true and the value is an array or object, then the
   17833              :     container's elements must have the current value as parent.
   17834              : 
   17835              :     @param[in] check_parents  whether the parent relation should be checked.
   17836              :                The value is true by default and should only be set to false
   17837              :                during destruction of objects when the invariant does not
   17838              :                need to hold.
   17839              :     */
   17840              :     void assert_invariant(bool check_parents = true) const noexcept
   17841              :     {
   17842              :         JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
   17843              :         JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
   17844              :         JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
   17845              :         JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
   17846              : 
   17847              : #if JSON_DIAGNOSTICS
   17848              :         JSON_TRY
   17849              :         {
   17850              :             // cppcheck-suppress assertWithSideEffect
   17851              :             JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
   17852              :             {
   17853              :                 return j.m_parent == this;
   17854              :             }));
   17855              :         }
   17856              :         JSON_CATCH(...) {} // LCOV_EXCL_LINE
   17857              : #endif
   17858              :         static_cast<void>(check_parents);
   17859            0 :     }
   17860              : 
   17861              :     void set_parents()
   17862              :     {
   17863              : #if JSON_DIAGNOSTICS
   17864              :         switch (m_type)
   17865              :         {
   17866              :             case value_t::array:
   17867              :             {
   17868              :                 for (auto& element : *m_value.array)
   17869              :                 {
   17870              :                     element.m_parent = this;
   17871              :                 }
   17872              :                 break;
   17873              :             }
   17874              : 
   17875              :             case value_t::object:
   17876              :             {
   17877              :                 for (auto& element : *m_value.object)
   17878              :                 {
   17879              :                     element.second.m_parent = this;
   17880              :                 }
   17881              :                 break;
   17882              :             }
   17883              : 
   17884              :             case value_t::null:
   17885              :             case value_t::string:
   17886              :             case value_t::boolean:
   17887              :             case value_t::number_integer:
   17888              :             case value_t::number_unsigned:
   17889              :             case value_t::number_float:
   17890              :             case value_t::binary:
   17891              :             case value_t::discarded:
   17892              :             default:
   17893              :                 break;
   17894              :         }
   17895              : #endif
   17896              :     }
   17897              : 
   17898              :     iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
   17899              :     {
   17900              : #if JSON_DIAGNOSTICS
   17901              :         for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
   17902              :         {
   17903              :             (it + i)->m_parent = this;
   17904              :         }
   17905              : #else
   17906              :         static_cast<void>(count_set_parents);
   17907              : #endif
   17908              :         return it;
   17909              :     }
   17910              : 
   17911              :     reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
   17912              :     {
   17913              : #if JSON_DIAGNOSTICS
   17914              :         if (old_capacity != static_cast<std::size_t>(-1))
   17915              :         {
   17916              :             // see https://github.com/nlohmann/json/issues/2838
   17917              :             JSON_ASSERT(type() == value_t::array);
   17918              :             if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
   17919              :             {
   17920              :                 // capacity has changed: update all parents
   17921              :                 set_parents();
   17922              :                 return j;
   17923              :             }
   17924              :         }
   17925              : 
   17926              :         // ordered_json uses a vector internally, so pointers could have
   17927              :         // been invalidated; see https://github.com/nlohmann/json/issues/2962
   17928              : #ifdef JSON_HEDLEY_MSVC_VERSION
   17929              : #pragma warning(push )
   17930              : #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
   17931              : #endif
   17932              :         if (detail::is_ordered_map<object_t>::value)
   17933              :         {
   17934              :             set_parents();
   17935              :             return j;
   17936              :         }
   17937              : #ifdef JSON_HEDLEY_MSVC_VERSION
   17938              : #pragma warning( pop )
   17939              : #endif
   17940              : 
   17941              :         j.m_parent = this;
   17942              : #else
   17943              :         static_cast<void>(j);
   17944              :         static_cast<void>(old_capacity);
   17945              : #endif
   17946              :         return j;
   17947              :     }
   17948              : 
   17949              :   public:
   17950              :     //////////////////////////
   17951              :     // JSON parser callback //
   17952              :     //////////////////////////
   17953              : 
   17954              :     /// @brief parser event types
   17955              :     /// @sa https://json.nlohmann.me/api/basic_json/parse_event_t/
   17956              :     using parse_event_t = detail::parse_event_t;
   17957              : 
   17958              :     /// @brief per-element parser callback type
   17959              :     /// @sa https://json.nlohmann.me/api/basic_json/parser_callback_t/
   17960              :     using parser_callback_t = detail::parser_callback_t<basic_json>;
   17961              : 
   17962              :     //////////////////
   17963              :     // constructors //
   17964              :     //////////////////
   17965              : 
   17966              :     /// @name constructors and destructors
   17967              :     /// Constructors of class @ref basic_json, copy/move constructor, copy
   17968              :     /// assignment, static functions creating objects, and the destructor.
   17969              :     /// @{
   17970              : 
   17971              :     /// @brief create an empty value with a given type
   17972              :     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
   17973         3195 :     basic_json(const value_t v)
   17974         3187 :         : m_type(v), m_value(v)
   17975              :     {
   17976              :         assert_invariant();
   17977            0 :     }
   17978              : 
   17979              :     /// @brief create a null object
   17980              :     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
   17981            0 :     basic_json(std::nullptr_t = nullptr) noexcept
   17982              :         : basic_json(value_t::null)
   17983              :     {
   17984              :         assert_invariant();
   17985            0 :     }
   17986              : 
   17987              :     /// @brief create a JSON value from compatible types
   17988              :     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
   17989              :     template < typename CompatibleType,
   17990              :                typename U = detail::uncvref_t<CompatibleType>,
   17991              :                detail::enable_if_t <
   17992              :                    !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
   17993         4604 :     basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
   17994              :                 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
   17995              :                                            std::forward<CompatibleType>(val))))
   17996         4603 :     {
   17997              :         JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
   17998              :         set_parents();
   17999              :         assert_invariant();
   18000         3814 :     }
   18001              : 
   18002              :     /// @brief create a JSON value from an existing one
   18003              :     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
   18004              :     template < typename BasicJsonType,
   18005              :                detail::enable_if_t <
   18006              :                    detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
   18007              :     basic_json(const BasicJsonType& val)
   18008              :     {
   18009              :         using other_boolean_t = typename BasicJsonType::boolean_t;
   18010              :         using other_number_float_t = typename BasicJsonType::number_float_t;
   18011              :         using other_number_integer_t = typename BasicJsonType::number_integer_t;
   18012              :         using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
   18013              :         using other_string_t = typename BasicJsonType::string_t;
   18014              :         using other_object_t = typename BasicJsonType::object_t;
   18015              :         using other_array_t = typename BasicJsonType::array_t;
   18016              :         using other_binary_t = typename BasicJsonType::binary_t;
   18017              : 
   18018              :         switch (val.type())
   18019              :         {
   18020              :             case value_t::boolean:
   18021              :                 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
   18022              :                 break;
   18023              :             case value_t::number_float:
   18024              :                 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
   18025              :                 break;
   18026              :             case value_t::number_integer:
   18027              :                 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
   18028              :                 break;
   18029              :             case value_t::number_unsigned:
   18030              :                 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
   18031              :                 break;
   18032              :             case value_t::string:
   18033              :                 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
   18034              :                 break;
   18035              :             case value_t::object:
   18036              :                 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
   18037              :                 break;
   18038              :             case value_t::array:
   18039              :                 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
   18040              :                 break;
   18041              :             case value_t::binary:
   18042              :                 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
   18043              :                 break;
   18044              :             case value_t::null:
   18045              :                 *this = nullptr;
   18046              :                 break;
   18047              :             case value_t::discarded:
   18048              :                 m_type = value_t::discarded;
   18049              :                 break;
   18050              :             default:            // LCOV_EXCL_LINE
   18051              :                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
   18052              :         }
   18053              :         set_parents();
   18054              :         assert_invariant();
   18055              :     }
   18056              : 
   18057              :     /// @brief create a container (array or object) from an initializer list
   18058              :     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
   18059              :     basic_json(initializer_list_t init,
   18060              :                bool type_deduction = true,
   18061              :                value_t manual_type = value_t::array)
   18062              :     {
   18063              :         // check if each element is an array with two elements whose first
   18064              :         // element is a string
   18065              :         bool is_an_object = std::all_of(init.begin(), init.end(),
   18066              :                                         [](const detail::json_ref<basic_json>& element_ref)
   18067              :         {
   18068              :             return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
   18069              :         });
   18070              : 
   18071              :         // adjust type if type deduction is not wanted
   18072              :         if (!type_deduction)
   18073              :         {
   18074              :             // if array is wanted, do not create an object though possible
   18075              :             if (manual_type == value_t::array)
   18076              :             {
   18077              :                 is_an_object = false;
   18078              :             }
   18079              : 
   18080              :             // if object is wanted but impossible, throw an exception
   18081              :             if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
   18082              :             {
   18083              :                 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
   18084              :             }
   18085              :         }
   18086              : 
   18087              :         if (is_an_object)
   18088              :         {
   18089              :             // the initializer list is a list of pairs -> create object
   18090              :             m_type = value_t::object;
   18091              :             m_value = value_t::object;
   18092              : 
   18093              :             for (auto& element_ref : init)
   18094              :             {
   18095              :                 auto element = element_ref.moved_or_copied();
   18096              :                 m_value.object->emplace(
   18097              :                     std::move(*((*element.m_value.array)[0].m_value.string)),
   18098              :                     std::move((*element.m_value.array)[1]));
   18099              :             }
   18100              :         }
   18101              :         else
   18102              :         {
   18103              :             // the initializer list describes an array -> create array
   18104              :             m_type = value_t::array;
   18105              :             m_value.array = create<array_t>(init.begin(), init.end());
   18106              :         }
   18107              : 
   18108              :         set_parents();
   18109              :         assert_invariant();
   18110              :     }
   18111              : 
   18112              :     /// @brief explicitly create a binary array (without subtype)
   18113              :     /// @sa https://json.nlohmann.me/api/basic_json/binary/
   18114              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   18115              :     static basic_json binary(const typename binary_t::container_type& init)
   18116              :     {
   18117              :         auto res = basic_json();
   18118              :         res.m_type = value_t::binary;
   18119              :         res.m_value = init;
   18120              :         return res;
   18121              :     }
   18122              : 
   18123              :     /// @brief explicitly create a binary array (with subtype)
   18124              :     /// @sa https://json.nlohmann.me/api/basic_json/binary/
   18125              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   18126              :     static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
   18127              :     {
   18128              :         auto res = basic_json();
   18129              :         res.m_type = value_t::binary;
   18130              :         res.m_value = binary_t(init, subtype);
   18131              :         return res;
   18132              :     }
   18133              : 
   18134              :     /// @brief explicitly create a binary array
   18135              :     /// @sa https://json.nlohmann.me/api/basic_json/binary/
   18136              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   18137              :     static basic_json binary(typename binary_t::container_type&& init)
   18138              :     {
   18139              :         auto res = basic_json();
   18140              :         res.m_type = value_t::binary;
   18141              :         res.m_value = std::move(init);
   18142              :         return res;
   18143              :     }
   18144              : 
   18145              :     /// @brief explicitly create a binary array (with subtype)
   18146              :     /// @sa https://json.nlohmann.me/api/basic_json/binary/
   18147              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   18148              :     static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
   18149              :     {
   18150              :         auto res = basic_json();
   18151              :         res.m_type = value_t::binary;
   18152              :         res.m_value = binary_t(std::move(init), subtype);
   18153              :         return res;
   18154              :     }
   18155              : 
   18156              :     /// @brief explicitly create an array from an initializer list
   18157              :     /// @sa https://json.nlohmann.me/api/basic_json/array/
   18158              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   18159              :     static basic_json array(initializer_list_t init = {})
   18160              :     {
   18161              :         return basic_json(init, false, value_t::array);
   18162              :     }
   18163              : 
   18164              :     /// @brief explicitly create an object from an initializer list
   18165              :     /// @sa https://json.nlohmann.me/api/basic_json/object/
   18166              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   18167              :     static basic_json object(initializer_list_t init = {})
   18168              :     {
   18169              :         return basic_json(init, false, value_t::object);
   18170              :     }
   18171              : 
   18172              :     /// @brief construct an array with count copies of given value
   18173              :     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
   18174              :     basic_json(size_type cnt, const basic_json& val)
   18175              :         : m_type(value_t::array)
   18176              :     {
   18177              :         m_value.array = create<array_t>(cnt, val);
   18178              :         set_parents();
   18179              :         assert_invariant();
   18180              :     }
   18181              : 
   18182              :     /// @brief construct a JSON container given an iterator range
   18183              :     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
   18184              :     template < class InputIT, typename std::enable_if <
   18185              :                    std::is_same<InputIT, typename basic_json_t::iterator>::value ||
   18186              :                    std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
   18187              :     basic_json(InputIT first, InputIT last)
   18188              :     {
   18189              :         JSON_ASSERT(first.m_object != nullptr);
   18190              :         JSON_ASSERT(last.m_object != nullptr);
   18191              : 
   18192              :         // make sure iterator fits the current value
   18193              :         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
   18194              :         {
   18195              :             JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
   18196              :         }
   18197              : 
   18198              :         // copy type from first iterator
   18199              :         m_type = first.m_object->m_type;
   18200              : 
   18201              :         // check if iterator range is complete for primitive values
   18202              :         switch (m_type)
   18203              :         {
   18204              :             case value_t::boolean:
   18205              :             case value_t::number_float:
   18206              :             case value_t::number_integer:
   18207              :             case value_t::number_unsigned:
   18208              :             case value_t::string:
   18209              :             {
   18210              :                 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
   18211              :                                          || !last.m_it.primitive_iterator.is_end()))
   18212              :                 {
   18213              :                     JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
   18214              :                 }
   18215              :                 break;
   18216              :             }
   18217              : 
   18218              :             case value_t::null:
   18219              :             case value_t::object:
   18220              :             case value_t::array:
   18221              :             case value_t::binary:
   18222              :             case value_t::discarded:
   18223              :             default:
   18224              :                 break;
   18225              :         }
   18226              : 
   18227              :         switch (m_type)
   18228              :         {
   18229              :             case value_t::number_integer:
   18230              :             {
   18231              :                 m_value.number_integer = first.m_object->m_value.number_integer;
   18232              :                 break;
   18233              :             }
   18234              : 
   18235              :             case value_t::number_unsigned:
   18236              :             {
   18237              :                 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
   18238              :                 break;
   18239              :             }
   18240              : 
   18241              :             case value_t::number_float:
   18242              :             {
   18243              :                 m_value.number_float = first.m_object->m_value.number_float;
   18244              :                 break;
   18245              :             }
   18246              : 
   18247              :             case value_t::boolean:
   18248              :             {
   18249              :                 m_value.boolean = first.m_object->m_value.boolean;
   18250              :                 break;
   18251              :             }
   18252              : 
   18253              :             case value_t::string:
   18254              :             {
   18255              :                 m_value = *first.m_object->m_value.string;
   18256              :                 break;
   18257              :             }
   18258              : 
   18259              :             case value_t::object:
   18260              :             {
   18261              :                 m_value.object = create<object_t>(first.m_it.object_iterator,
   18262              :                                                   last.m_it.object_iterator);
   18263              :                 break;
   18264              :             }
   18265              : 
   18266              :             case value_t::array:
   18267              :             {
   18268              :                 m_value.array = create<array_t>(first.m_it.array_iterator,
   18269              :                                                 last.m_it.array_iterator);
   18270              :                 break;
   18271              :             }
   18272              : 
   18273              :             case value_t::binary:
   18274              :             {
   18275              :                 m_value = *first.m_object->m_value.binary;
   18276              :                 break;
   18277              :             }
   18278              : 
   18279              :             case value_t::null:
   18280              :             case value_t::discarded:
   18281              :             default:
   18282              :                 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
   18283              :         }
   18284              : 
   18285              :         set_parents();
   18286              :         assert_invariant();
   18287              :     }
   18288              : 
   18289              : 
   18290              :     ///////////////////////////////////////
   18291              :     // other constructors and destructor //
   18292              :     ///////////////////////////////////////
   18293              : 
   18294              :     template<typename JsonRef,
   18295              :              detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
   18296              :                                  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
   18297              :     basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
   18298              : 
   18299              :     /// @brief copy constructor
   18300              :     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
   18301            0 :     basic_json(const basic_json& other)
   18302            0 :         : m_type(other.m_type)
   18303              :     {
   18304              :         // check of passed value is valid
   18305              :         other.assert_invariant();
   18306              : 
   18307            0 :         switch (m_type)
   18308              :         {
   18309            0 :             case value_t::object:
   18310              :             {
   18311            0 :                 m_value = *other.m_value.object;
   18312            0 :                 break;
   18313              :             }
   18314              : 
   18315            0 :             case value_t::array:
   18316              :             {
   18317            0 :                 m_value = *other.m_value.array;
   18318            0 :                 break;
   18319              :             }
   18320              : 
   18321            0 :             case value_t::string:
   18322              :             {
   18323            0 :                 m_value = *other.m_value.string;
   18324            0 :                 break;
   18325              :             }
   18326              : 
   18327            0 :             case value_t::boolean:
   18328              :             {
   18329            0 :                 m_value = other.m_value.boolean;
   18330            0 :                 break;
   18331              :             }
   18332              : 
   18333            0 :             case value_t::number_integer:
   18334              :             {
   18335            0 :                 m_value = other.m_value.number_integer;
   18336            0 :                 break;
   18337              :             }
   18338              : 
   18339            0 :             case value_t::number_unsigned:
   18340              :             {
   18341            0 :                 m_value = other.m_value.number_unsigned;
   18342            0 :                 break;
   18343              :             }
   18344              : 
   18345            0 :             case value_t::number_float:
   18346              :             {
   18347            0 :                 m_value = other.m_value.number_float;
   18348            0 :                 break;
   18349              :             }
   18350              : 
   18351            0 :             case value_t::binary:
   18352              :             {
   18353            0 :                 m_value = *other.m_value.binary;
   18354            0 :                 break;
   18355              :             }
   18356              : 
   18357              :             case value_t::null:
   18358              :             case value_t::discarded:
   18359              :             default:
   18360              :                 break;
   18361              :         }
   18362              : 
   18363              :         set_parents();
   18364              :         assert_invariant();
   18365            0 :     }
   18366              : 
   18367              :     /// @brief move constructor
   18368              :     /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
   18369        10849 :     basic_json(basic_json&& other) noexcept
   18370        10849 :         : m_type(std::move(other.m_type)),
   18371        10849 :           m_value(std::move(other.m_value))
   18372              :     {
   18373              :         // check that passed value is valid
   18374              :         other.assert_invariant(false);
   18375              : 
   18376              :         // invalidate payload
   18377        10849 :         other.m_type = value_t::null;
   18378        10849 :         other.m_value = {};
   18379              : 
   18380              :         set_parents();
   18381              :         assert_invariant();
   18382              :     }
   18383              : 
   18384              :     /// @brief copy assignment
   18385              :     /// @sa https://json.nlohmann.me/api/basic_json/operator=/
   18386              :     basic_json& operator=(basic_json other) noexcept (
   18387              :         std::is_nothrow_move_constructible<value_t>::value&&
   18388              :         std::is_nothrow_move_assignable<value_t>::value&&
   18389              :         std::is_nothrow_move_constructible<json_value>::value&&
   18390              :         std::is_nothrow_move_assignable<json_value>::value
   18391              :     )
   18392              :     {
   18393              :         // check that passed value is valid
   18394              :         other.assert_invariant();
   18395              : 
   18396              :         using std::swap;
   18397              :         swap(m_type, other.m_type);
   18398              :         swap(m_value, other.m_value);
   18399              : 
   18400              :         set_parents();
   18401              :         assert_invariant();
   18402              :         return *this;
   18403              :     }
   18404              : 
   18405              :     /// @brief destructor
   18406              :     /// @sa https://json.nlohmann.me/api/basic_json/~basic_json/
   18407        10849 :     ~basic_json() noexcept
   18408              :     {
   18409              :         assert_invariant(false);
   18410        14600 :         m_value.destroy(m_type);
   18411         3750 :     }
   18412              : 
   18413              :     /// @}
   18414              : 
   18415              :   public:
   18416              :     ///////////////////////
   18417              :     // object inspection //
   18418              :     ///////////////////////
   18419              : 
   18420              :     /// @name object inspection
   18421              :     /// Functions to inspect the type of a JSON value.
   18422              :     /// @{
   18423              : 
   18424              :     /// @brief serialization
   18425              :     /// @sa https://json.nlohmann.me/api/basic_json/dump/
   18426              :     string_t dump(const int indent = -1,
   18427              :                   const char indent_char = ' ',
   18428              :                   const bool ensure_ascii = false,
   18429              :                   const error_handler_t error_handler = error_handler_t::strict) const
   18430              :     {
   18431              :         string_t result;
   18432              :         serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
   18433              : 
   18434              :         if (indent >= 0)
   18435              :         {
   18436              :             s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
   18437              :         }
   18438              :         else
   18439              :         {
   18440              :             s.dump(*this, false, ensure_ascii, 0);
   18441              :         }
   18442              : 
   18443              :         return result;
   18444              :     }
   18445              : 
   18446              :     /// @brief return the type of the JSON value (explicit)
   18447              :     /// @sa https://json.nlohmann.me/api/basic_json/type/
   18448              :     constexpr value_t type() const noexcept
   18449              :     {
   18450            6 :         return m_type;
   18451              :     }
   18452              : 
   18453              :     /// @brief return whether type is primitive
   18454              :     /// @sa https://json.nlohmann.me/api/basic_json/is_primitive/
   18455              :     constexpr bool is_primitive() const noexcept
   18456              :     {
   18457              :         return is_null() || is_string() || is_boolean() || is_number() || is_binary();
   18458              :     }
   18459              : 
   18460              :     /// @brief return whether type is structured
   18461              :     /// @sa https://json.nlohmann.me/api/basic_json/is_structured/
   18462              :     constexpr bool is_structured() const noexcept
   18463              :     {
   18464            0 :         return is_array() || is_object();
   18465              :     }
   18466              : 
   18467              :     /// @brief return whether value is null
   18468              :     /// @sa https://json.nlohmann.me/api/basic_json/is_null/
   18469              :     constexpr bool is_null() const noexcept
   18470              :     {
   18471           54 :         return m_type == value_t::null;
   18472              :     }
   18473              : 
   18474              :     /// @brief return whether value is a boolean
   18475              :     /// @sa https://json.nlohmann.me/api/basic_json/is_boolean/
   18476              :     constexpr bool is_boolean() const noexcept
   18477              :     {
   18478              :         return m_type == value_t::boolean;
   18479              :     }
   18480              : 
   18481              :     /// @brief return whether value is a number
   18482              :     /// @sa https://json.nlohmann.me/api/basic_json/is_number/
   18483              :     constexpr bool is_number() const noexcept
   18484              :     {
   18485              :         return is_number_integer() || is_number_float();
   18486              :     }
   18487              : 
   18488              :     /// @brief return whether value is an integer number
   18489              :     /// @sa https://json.nlohmann.me/api/basic_json/is_number_integer/
   18490              :     constexpr bool is_number_integer() const noexcept
   18491              :     {
   18492              :         return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
   18493              :     }
   18494              : 
   18495              :     /// @brief return whether value is an unsigned integer number
   18496              :     /// @sa https://json.nlohmann.me/api/basic_json/is_number_unsigned/
   18497              :     constexpr bool is_number_unsigned() const noexcept
   18498              :     {
   18499              :         return m_type == value_t::number_unsigned;
   18500              :     }
   18501              : 
   18502              :     /// @brief return whether value is a floating-point number
   18503              :     /// @sa https://json.nlohmann.me/api/basic_json/is_number_float/
   18504              :     constexpr bool is_number_float() const noexcept
   18505              :     {
   18506              :         return m_type == value_t::number_float;
   18507              :     }
   18508              : 
   18509              :     /// @brief return whether value is an object
   18510              :     /// @sa https://json.nlohmann.me/api/basic_json/is_object/
   18511              :     constexpr bool is_object() const noexcept
   18512              :     {
   18513           60 :         return m_type == value_t::object;
   18514              :     }
   18515              : 
   18516              :     /// @brief return whether value is an array
   18517              :     /// @sa https://json.nlohmann.me/api/basic_json/is_array/
   18518              :     constexpr bool is_array() const noexcept
   18519              :     {
   18520         8785 :         return m_type == value_t::array;
   18521              :     }
   18522              : 
   18523              :     /// @brief return whether value is a string
   18524              :     /// @sa https://json.nlohmann.me/api/basic_json/is_string/
   18525              :     constexpr bool is_string() const noexcept
   18526              :     {
   18527           81 :         return m_type == value_t::string;
   18528              :     }
   18529              : 
   18530              :     /// @brief return whether value is a binary array
   18531              :     /// @sa https://json.nlohmann.me/api/basic_json/is_binary/
   18532              :     constexpr bool is_binary() const noexcept
   18533              :     {
   18534              :         return m_type == value_t::binary;
   18535              :     }
   18536              : 
   18537              :     /// @brief return whether value is discarded
   18538              :     /// @sa https://json.nlohmann.me/api/basic_json/is_discarded/
   18539              :     constexpr bool is_discarded() const noexcept
   18540              :     {
   18541            0 :         return m_type == value_t::discarded;
   18542              :     }
   18543              : 
   18544              :     /// @brief return the type of the JSON value (implicit)
   18545              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_value_t/
   18546              :     constexpr operator value_t() const noexcept
   18547              :     {
   18548         2391 :         return m_type;
   18549              :     }
   18550              : 
   18551              :     /// @}
   18552              : 
   18553              :   private:
   18554              :     //////////////////
   18555              :     // value access //
   18556              :     //////////////////
   18557              : 
   18558              :     /// get a boolean (explicit)
   18559              :     boolean_t get_impl(boolean_t* /*unused*/) const
   18560              :     {
   18561              :         if (JSON_HEDLEY_LIKELY(is_boolean()))
   18562              :         {
   18563              :             return m_value.boolean;
   18564              :         }
   18565              : 
   18566              :         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
   18567              :     }
   18568              : 
   18569              :     /// get a pointer to the value (object)
   18570              :     object_t* get_impl_ptr(object_t* /*unused*/) noexcept
   18571              :     {
   18572              :         return is_object() ? m_value.object : nullptr;
   18573              :     }
   18574              : 
   18575              :     /// get a pointer to the value (object)
   18576              :     constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
   18577              :     {
   18578           54 :         return is_object() ? m_value.object : nullptr;
   18579              :     }
   18580              : 
   18581              :     /// get a pointer to the value (array)
   18582              :     array_t* get_impl_ptr(array_t* /*unused*/) noexcept
   18583              :     {
   18584              :         return is_array() ? m_value.array : nullptr;
   18585              :     }
   18586              : 
   18587              :     /// get a pointer to the value (array)
   18588              :     constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
   18589              :     {
   18590              :         return is_array() ? m_value.array : nullptr;
   18591              :     }
   18592              : 
   18593              :     /// get a pointer to the value (string)
   18594              :     string_t* get_impl_ptr(string_t* /*unused*/) noexcept
   18595              :     {
   18596              :         return is_string() ? m_value.string : nullptr;
   18597              :     }
   18598              : 
   18599              :     /// get a pointer to the value (string)
   18600              :     constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
   18601              :     {
   18602           81 :         return is_string() ? m_value.string : nullptr;
   18603              :     }
   18604              : 
   18605              :     /// get a pointer to the value (boolean)
   18606              :     boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
   18607              :     {
   18608              :         return is_boolean() ? &m_value.boolean : nullptr;
   18609              :     }
   18610              : 
   18611              :     /// get a pointer to the value (boolean)
   18612              :     constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
   18613              :     {
   18614              :         return is_boolean() ? &m_value.boolean : nullptr;
   18615              :     }
   18616              : 
   18617              :     /// get a pointer to the value (integer number)
   18618              :     number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
   18619              :     {
   18620              :         return is_number_integer() ? &m_value.number_integer : nullptr;
   18621              :     }
   18622              : 
   18623              :     /// get a pointer to the value (integer number)
   18624              :     constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
   18625              :     {
   18626            0 :         return is_number_integer() ? &m_value.number_integer : nullptr;
   18627              :     }
   18628              : 
   18629              :     /// get a pointer to the value (unsigned number)
   18630              :     number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
   18631              :     {
   18632              :         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
   18633              :     }
   18634              : 
   18635              :     /// get a pointer to the value (unsigned number)
   18636              :     constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
   18637              :     {
   18638           31 :         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
   18639              :     }
   18640              : 
   18641              :     /// get a pointer to the value (floating-point number)
   18642              :     number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
   18643              :     {
   18644              :         return is_number_float() ? &m_value.number_float : nullptr;
   18645              :     }
   18646              : 
   18647              :     /// get a pointer to the value (floating-point number)
   18648              :     constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
   18649              :     {
   18650         2360 :         return is_number_float() ? &m_value.number_float : nullptr;
   18651              :     }
   18652              : 
   18653              :     /// get a pointer to the value (binary)
   18654              :     binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
   18655              :     {
   18656              :         return is_binary() ? m_value.binary : nullptr;
   18657              :     }
   18658              : 
   18659              :     /// get a pointer to the value (binary)
   18660              :     constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
   18661              :     {
   18662              :         return is_binary() ? m_value.binary : nullptr;
   18663              :     }
   18664              : 
   18665              :     /*!
   18666              :     @brief helper function to implement get_ref()
   18667              : 
   18668              :     This function helps to implement get_ref() without code duplication for
   18669              :     const and non-const overloads
   18670              : 
   18671              :     @tparam ThisType will be deduced as `basic_json` or `const basic_json`
   18672              : 
   18673              :     @throw type_error.303 if ReferenceType does not match underlying value
   18674              :     type of the current JSON
   18675              :     */
   18676              :     template<typename ReferenceType, typename ThisType>
   18677              :     static ReferenceType get_ref_impl(ThisType& obj)
   18678              :     {
   18679              :         // delegate the call to get_ptr<>()
   18680              :         auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
   18681              : 
   18682              :         if (JSON_HEDLEY_LIKELY(ptr != nullptr))
   18683              :         {
   18684              :             return *ptr;
   18685              :         }
   18686              : 
   18687              :         JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
   18688              :     }
   18689              : 
   18690              :   public:
   18691              :     /// @name value access
   18692              :     /// Direct access to the stored value of a JSON value.
   18693              :     /// @{
   18694              : 
   18695              :     /// @brief get a pointer value (implicit)
   18696              :     /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/
   18697              :     template<typename PointerType, typename std::enable_if<
   18698              :                  std::is_pointer<PointerType>::value, int>::type = 0>
   18699              :     auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
   18700              :     {
   18701              :         // delegate the call to get_impl_ptr<>()
   18702              :         return get_impl_ptr(static_cast<PointerType>(nullptr));
   18703              :     }
   18704              : 
   18705              :     /// @brief get a pointer value (implicit)
   18706              :     /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/
   18707              :     template < typename PointerType, typename std::enable_if <
   18708              :                    std::is_pointer<PointerType>::value&&
   18709              :                    std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
   18710              :     constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
   18711              :     {
   18712              :         // delegate the call to get_impl_ptr<>() const
   18713              :         return get_impl_ptr(static_cast<PointerType>(nullptr));
   18714              :     }
   18715              : 
   18716              :   private:
   18717              :     /*!
   18718              :     @brief get a value (explicit)
   18719              : 
   18720              :     Explicit type conversion between the JSON value and a compatible value
   18721              :     which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
   18722              :     and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
   18723              :     The value is converted by calling the @ref json_serializer<ValueType>
   18724              :     `from_json()` method.
   18725              : 
   18726              :     The function is equivalent to executing
   18727              :     @code {.cpp}
   18728              :     ValueType ret;
   18729              :     JSONSerializer<ValueType>::from_json(*this, ret);
   18730              :     return ret;
   18731              :     @endcode
   18732              : 
   18733              :     This overloads is chosen if:
   18734              :     - @a ValueType is not @ref basic_json,
   18735              :     - @ref json_serializer<ValueType> has a `from_json()` method of the form
   18736              :       `void from_json(const basic_json&, ValueType&)`, and
   18737              :     - @ref json_serializer<ValueType> does not have a `from_json()` method of
   18738              :       the form `ValueType from_json(const basic_json&)`
   18739              : 
   18740              :     @tparam ValueType the returned value type
   18741              : 
   18742              :     @return copy of the JSON value, converted to @a ValueType
   18743              : 
   18744              :     @throw what @ref json_serializer<ValueType> `from_json()` method throws
   18745              : 
   18746              :     @liveexample{The example below shows several conversions from JSON values
   18747              :     to other types. There a few things to note: (1) Floating-point numbers can
   18748              :     be converted to integers\, (2) A JSON array can be converted to a standard
   18749              :     `std::vector<short>`\, (3) A JSON object can be converted to C++
   18750              :     associative containers such as `std::unordered_map<std::string\,
   18751              :     json>`.,get__ValueType_const}
   18752              : 
   18753              :     @since version 2.1.0
   18754              :     */
   18755              :     template < typename ValueType,
   18756              :                detail::enable_if_t <
   18757              :                    detail::is_default_constructible<ValueType>::value&&
   18758              :                    detail::has_from_json<basic_json_t, ValueType>::value,
   18759              :                    int > = 0 >
   18760           54 :     ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
   18761              :                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
   18762              :     {
   18763         2445 :         auto ret = ValueType();
   18764              :         JSONSerializer<ValueType>::from_json(*this, ret);
   18765         2445 :         return ret;
   18766            0 :     }
   18767              : 
   18768              :     /*!
   18769              :     @brief get a value (explicit); special case
   18770              : 
   18771              :     Explicit type conversion between the JSON value and a compatible value
   18772              :     which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
   18773              :     and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
   18774              :     The value is converted by calling the @ref json_serializer<ValueType>
   18775              :     `from_json()` method.
   18776              : 
   18777              :     The function is equivalent to executing
   18778              :     @code {.cpp}
   18779              :     return JSONSerializer<ValueType>::from_json(*this);
   18780              :     @endcode
   18781              : 
   18782              :     This overloads is chosen if:
   18783              :     - @a ValueType is not @ref basic_json and
   18784              :     - @ref json_serializer<ValueType> has a `from_json()` method of the form
   18785              :       `ValueType from_json(const basic_json&)`
   18786              : 
   18787              :     @note If @ref json_serializer<ValueType> has both overloads of
   18788              :     `from_json()`, this one is chosen.
   18789              : 
   18790              :     @tparam ValueType the returned value type
   18791              : 
   18792              :     @return copy of the JSON value, converted to @a ValueType
   18793              : 
   18794              :     @throw what @ref json_serializer<ValueType> `from_json()` method throws
   18795              : 
   18796              :     @since version 2.1.0
   18797              :     */
   18798              :     template < typename ValueType,
   18799              :                detail::enable_if_t <
   18800              :                    detail::has_non_default_from_json<basic_json_t, ValueType>::value,
   18801              :                    int > = 0 >
   18802              :     ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
   18803              :                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
   18804              :     {
   18805              :         return JSONSerializer<ValueType>::from_json(*this);
   18806              :     }
   18807              : 
   18808              :     /*!
   18809              :     @brief get special-case overload
   18810              : 
   18811              :     This overloads converts the current @ref basic_json in a different
   18812              :     @ref basic_json type
   18813              : 
   18814              :     @tparam BasicJsonType == @ref basic_json
   18815              : 
   18816              :     @return a copy of *this, converted into @a BasicJsonType
   18817              : 
   18818              :     @complexity Depending on the implementation of the called `from_json()`
   18819              :                 method.
   18820              : 
   18821              :     @since version 3.2.0
   18822              :     */
   18823              :     template < typename BasicJsonType,
   18824              :                detail::enable_if_t <
   18825              :                    detail::is_basic_json<BasicJsonType>::value,
   18826              :                    int > = 0 >
   18827              :     BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
   18828              :     {
   18829              :         return *this;
   18830              :     }
   18831              : 
   18832              :     /*!
   18833              :     @brief get special-case overload
   18834              : 
   18835              :     This overloads avoids a lot of template boilerplate, it can be seen as the
   18836              :     identity method
   18837              : 
   18838              :     @tparam BasicJsonType == @ref basic_json
   18839              : 
   18840              :     @return a copy of *this
   18841              : 
   18842              :     @complexity Constant.
   18843              : 
   18844              :     @since version 2.1.0
   18845              :     */
   18846              :     template<typename BasicJsonType,
   18847              :              detail::enable_if_t<
   18848              :                  std::is_same<BasicJsonType, basic_json_t>::value,
   18849              :                  int> = 0>
   18850              :     basic_json get_impl(detail::priority_tag<3> /*unused*/) const
   18851              :     {
   18852              :         return *this;
   18853              :     }
   18854              : 
   18855              :     /*!
   18856              :     @brief get a pointer value (explicit)
   18857              :     @copydoc get()
   18858              :     */
   18859              :     template<typename PointerType,
   18860              :              detail::enable_if_t<
   18861              :                  std::is_pointer<PointerType>::value,
   18862              :                  int> = 0>
   18863              :     constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
   18864              :     -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
   18865              :     {
   18866              :         // delegate the call to get_ptr
   18867              :         return get_ptr<PointerType>();
   18868              :     }
   18869              : 
   18870              :   public:
   18871              :     /*!
   18872              :     @brief get a (pointer) value (explicit)
   18873              : 
   18874              :     Performs explicit type conversion between the JSON value and a compatible value if required.
   18875              : 
   18876              :     - If the requested type is a pointer to the internally stored JSON value that pointer is returned.
   18877              :     No copies are made.
   18878              : 
   18879              :     - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
   18880              :     from the current @ref basic_json.
   18881              : 
   18882              :     - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
   18883              :     method.
   18884              : 
   18885              :     @tparam ValueTypeCV the provided value type
   18886              :     @tparam ValueType the returned value type
   18887              : 
   18888              :     @return copy of the JSON value, converted to @tparam ValueType if necessary
   18889              : 
   18890              :     @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
   18891              : 
   18892              :     @since version 2.1.0
   18893              :     */
   18894              :     template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
   18895              : #if defined(JSON_HAS_CPP_14)
   18896              :     constexpr
   18897              : #endif
   18898          228 :     auto get() const noexcept(
   18899              :     noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
   18900              :     -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
   18901              :     {
   18902              :         // we cannot static_assert on ValueTypeCV being non-const, because
   18903              :         // there is support for get<const basic_json_t>(), which is why we
   18904              :         // still need the uncvref
   18905              :         static_assert(!std::is_reference<ValueTypeCV>::value,
   18906              :                       "get() cannot be used with reference types, you might want to use get_ref()");
   18907          282 :         return get_impl<ValueType>(detail::priority_tag<4> {});
   18908              :     }
   18909              : 
   18910              :     /*!
   18911              :     @brief get a pointer value (explicit)
   18912              : 
   18913              :     Explicit pointer access to the internally stored JSON value. No copies are
   18914              :     made.
   18915              : 
   18916              :     @warning The pointer becomes invalid if the underlying JSON object
   18917              :     changes.
   18918              : 
   18919              :     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
   18920              :     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
   18921              :     @ref number_unsigned_t, or @ref number_float_t.
   18922              : 
   18923              :     @return pointer to the internally stored JSON value if the requested
   18924              :     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
   18925              : 
   18926              :     @complexity Constant.
   18927              : 
   18928              :     @liveexample{The example below shows how pointers to internal values of a
   18929              :     JSON value can be requested. Note that no type conversions are made and a
   18930              :     `nullptr` is returned if the value and the requested pointer type does not
   18931              :     match.,get__PointerType}
   18932              : 
   18933              :     @sa see @ref get_ptr() for explicit pointer-member access
   18934              : 
   18935              :     @since version 1.0.0
   18936              :     */
   18937              :     template<typename PointerType, typename std::enable_if<
   18938              :                  std::is_pointer<PointerType>::value, int>::type = 0>
   18939              :     auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
   18940              :     {
   18941              :         // delegate the call to get_ptr
   18942              :         return get_ptr<PointerType>();
   18943              :     }
   18944              : 
   18945              :     /// @brief get a value (explicit)
   18946              :     /// @sa https://json.nlohmann.me/api/basic_json/get_to/
   18947              :     template < typename ValueType,
   18948              :                detail::enable_if_t <
   18949              :                    !detail::is_basic_json<ValueType>::value&&
   18950              :                    detail::has_from_json<basic_json_t, ValueType>::value,
   18951              :                    int > = 0 >
   18952              :     ValueType & get_to(ValueType& v) const noexcept(noexcept(
   18953              :                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
   18954              :     {
   18955              :         JSONSerializer<ValueType>::from_json(*this, v);
   18956              :         return v;
   18957              :     }
   18958              : 
   18959              :     // specialization to allow calling get_to with a basic_json value
   18960              :     // see https://github.com/nlohmann/json/issues/2175
   18961              :     template<typename ValueType,
   18962              :              detail::enable_if_t <
   18963              :                  detail::is_basic_json<ValueType>::value,
   18964              :                  int> = 0>
   18965              :     ValueType & get_to(ValueType& v) const
   18966              :     {
   18967              :         v = *this;
   18968              :         return v;
   18969              :     }
   18970              : 
   18971              :     template <
   18972              :         typename T, std::size_t N,
   18973              :         typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
   18974              :         detail::enable_if_t <
   18975              :             detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
   18976              :     Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
   18977              :     noexcept(noexcept(JSONSerializer<Array>::from_json(
   18978              :                           std::declval<const basic_json_t&>(), v)))
   18979              :     {
   18980              :         JSONSerializer<Array>::from_json(*this, v);
   18981              :         return v;
   18982              :     }
   18983              : 
   18984              :     /// @brief get a reference value (implicit)
   18985              :     /// @sa https://json.nlohmann.me/api/basic_json/get_ref/
   18986              :     template<typename ReferenceType, typename std::enable_if<
   18987              :                  std::is_reference<ReferenceType>::value, int>::type = 0>
   18988              :     ReferenceType get_ref()
   18989              :     {
   18990              :         // delegate call to get_ref_impl
   18991              :         return get_ref_impl<ReferenceType>(*this);
   18992              :     }
   18993              : 
   18994              :     /// @brief get a reference value (implicit)
   18995              :     /// @sa https://json.nlohmann.me/api/basic_json/get_ref/
   18996              :     template < typename ReferenceType, typename std::enable_if <
   18997              :                    std::is_reference<ReferenceType>::value&&
   18998              :                    std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
   18999              :     ReferenceType get_ref() const
   19000              :     {
   19001              :         // delegate call to get_ref_impl
   19002              :         return get_ref_impl<ReferenceType>(*this);
   19003              :     }
   19004              : 
   19005              :     /*!
   19006              :     @brief get a value (implicit)
   19007              : 
   19008              :     Implicit type conversion between the JSON value and a compatible value.
   19009              :     The call is realized by calling @ref get() const.
   19010              : 
   19011              :     @tparam ValueType non-pointer type compatible to the JSON value, for
   19012              :     instance `int` for JSON integer numbers, `bool` for JSON booleans, or
   19013              :     `std::vector` types for JSON arrays. The character type of @ref string_t
   19014              :     as well as an initializer list of this type is excluded to avoid
   19015              :     ambiguities as these types implicitly convert to `std::string`.
   19016              : 
   19017              :     @return copy of the JSON value, converted to type @a ValueType
   19018              : 
   19019              :     @throw type_error.302 in case passed type @a ValueType is incompatible
   19020              :     to the JSON value type (e.g., the JSON value is of type boolean, but a
   19021              :     string is requested); see example below
   19022              : 
   19023              :     @complexity Linear in the size of the JSON value.
   19024              : 
   19025              :     @liveexample{The example below shows several conversions from JSON values
   19026              :     to other types. There a few things to note: (1) Floating-point numbers can
   19027              :     be converted to integers\, (2) A JSON array can be converted to a standard
   19028              :     `std::vector<short>`\, (3) A JSON object can be converted to C++
   19029              :     associative containers such as `std::unordered_map<std::string\,
   19030              :     json>`.,operator__ValueType}
   19031              : 
   19032              :     @since version 1.0.0
   19033              :     */
   19034              :     template < typename ValueType, typename std::enable_if <
   19035              :                    detail::conjunction <
   19036              :                        detail::negation<std::is_pointer<ValueType>>,
   19037              :                        detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
   19038              :                                         detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
   19039              :                                         detail::negation<detail::is_basic_json<ValueType>>,
   19040              :                                         detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
   19041              : 
   19042              : #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
   19043              :                                                 detail::negation<std::is_same<ValueType, std::string_view>>,
   19044              : #endif
   19045              :                                                 detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
   19046              :                                                 >::value, int >::type = 0 >
   19047              :                                         JSON_EXPLICIT operator ValueType() const
   19048              :     {
   19049              :         // delegate the call to get<>() const
   19050           12 :         return get<ValueType>();
   19051              :     }
   19052              : 
   19053              :     /// @brief get a binary value
   19054              :     /// @sa https://json.nlohmann.me/api/basic_json/get_binary/
   19055              :     binary_t& get_binary()
   19056              :     {
   19057              :         if (!is_binary())
   19058              :         {
   19059              :             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
   19060              :         }
   19061              : 
   19062              :         return *get_ptr<binary_t*>();
   19063              :     }
   19064              : 
   19065              :     /// @brief get a binary value
   19066              :     /// @sa https://json.nlohmann.me/api/basic_json/get_binary/
   19067              :     const binary_t& get_binary() const
   19068              :     {
   19069              :         if (!is_binary())
   19070              :         {
   19071              :             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
   19072              :         }
   19073              : 
   19074              :         return *get_ptr<const binary_t*>();
   19075              :     }
   19076              : 
   19077              :     /// @}
   19078              : 
   19079              : 
   19080              :     ////////////////////
   19081              :     // element access //
   19082              :     ////////////////////
   19083              : 
   19084              :     /// @name element access
   19085              :     /// Access to the JSON value.
   19086              :     /// @{
   19087              : 
   19088              :     /// @brief access specified array element with bounds checking
   19089              :     /// @sa https://json.nlohmann.me/api/basic_json/at/
   19090              :     reference at(size_type idx)
   19091              :     {
   19092              :         // at only works for arrays
   19093              :         if (JSON_HEDLEY_LIKELY(is_array()))
   19094              :         {
   19095              :             JSON_TRY
   19096              :             {
   19097              :                 return set_parent(m_value.array->at(idx));
   19098              :             }
   19099              :             JSON_CATCH (std::out_of_range&)
   19100              :             {
   19101              :                 // create better exception explanation
   19102              :                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
   19103              :             }
   19104              :         }
   19105              :         else
   19106              :         {
   19107              :             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
   19108              :         }
   19109              :     }
   19110              : 
   19111              :     /// @brief access specified array element with bounds checking
   19112              :     /// @sa https://json.nlohmann.me/api/basic_json/at/
   19113              :     const_reference at(size_type idx) const
   19114              :     {
   19115              :         // at only works for arrays
   19116              :         if (JSON_HEDLEY_LIKELY(is_array()))
   19117              :         {
   19118              :             JSON_TRY
   19119              :             {
   19120              :                 return m_value.array->at(idx);
   19121              :             }
   19122              :             JSON_CATCH (std::out_of_range&)
   19123              :             {
   19124              :                 // create better exception explanation
   19125              :                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
   19126              :             }
   19127              :         }
   19128              :         else
   19129              :         {
   19130              :             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
   19131              :         }
   19132              :     }
   19133              : 
   19134              :     /// @brief access specified object element with bounds checking
   19135              :     /// @sa https://json.nlohmann.me/api/basic_json/at/
   19136          107 :     reference at(const typename object_t::key_type& key)
   19137              :     {
   19138              :         // at only works for objects
   19139          107 :         if (JSON_HEDLEY_LIKELY(is_object()))
   19140              :         {
   19141              :             JSON_TRY
   19142              :             {
   19143          107 :                 return set_parent(m_value.object->at(key));
   19144              :             }
   19145            0 :             JSON_CATCH (std::out_of_range&)
   19146              :             {
   19147              :                 // create better exception explanation
   19148            0 :                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
   19149              :             }
   19150              :         }
   19151              :         else
   19152              :         {
   19153            0 :             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
   19154              :         }
   19155              :     }
   19156              : 
   19157              :     /// @brief access specified object element with bounds checking
   19158              :     /// @sa https://json.nlohmann.me/api/basic_json/at/
   19159          652 :     const_reference at(const typename object_t::key_type& key) const
   19160              :     {
   19161              :         // at only works for objects
   19162          652 :         if (JSON_HEDLEY_LIKELY(is_object()))
   19163              :         {
   19164              :             JSON_TRY
   19165              :             {
   19166          652 :                 return m_value.object->at(key);
   19167              :             }
   19168            0 :             JSON_CATCH (std::out_of_range&)
   19169              :             {
   19170              :                 // create better exception explanation
   19171            0 :                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
   19172              :             }
   19173              :         }
   19174              :         else
   19175              :         {
   19176            0 :             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
   19177              :         }
   19178              :     }
   19179              : 
   19180              :     /// @brief access specified array element
   19181              :     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
   19182              :     reference operator[](size_type idx)
   19183              :     {
   19184              :         // implicitly convert null value to an empty array
   19185              :         if (is_null())
   19186              :         {
   19187              :             m_type = value_t::array;
   19188              :             m_value.array = create<array_t>();
   19189              :             assert_invariant();
   19190              :         }
   19191              : 
   19192              :         // operator[] only works for arrays
   19193              :         if (JSON_HEDLEY_LIKELY(is_array()))
   19194              :         {
   19195              :             // fill up array with null values if given idx is outside range
   19196              :             if (idx >= m_value.array->size())
   19197              :             {
   19198              : #if JSON_DIAGNOSTICS
   19199              :                 // remember array size & capacity before resizing
   19200              :                 const auto old_size = m_value.array->size();
   19201              :                 const auto old_capacity = m_value.array->capacity();
   19202              : #endif
   19203              :                 m_value.array->resize(idx + 1);
   19204              : 
   19205              : #if JSON_DIAGNOSTICS
   19206              :                 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
   19207              :                 {
   19208              :                     // capacity has changed: update all parents
   19209              :                     set_parents();
   19210              :                 }
   19211              :                 else
   19212              :                 {
   19213              :                     // set parent for values added above
   19214              :                     set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
   19215              :                 }
   19216              : #endif
   19217              :                 assert_invariant();
   19218              :             }
   19219              : 
   19220              :             return m_value.array->operator[](idx);
   19221              :         }
   19222              : 
   19223              :         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
   19224              :     }
   19225              : 
   19226              :     /// @brief access specified array element
   19227              :     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
   19228            2 :     const_reference operator[](size_type idx) const
   19229              :     {
   19230              :         // const operator[] only works for arrays
   19231            2 :         if (JSON_HEDLEY_LIKELY(is_array()))
   19232              :         {
   19233            2 :             return m_value.array->operator[](idx);
   19234              :         }
   19235              : 
   19236            0 :         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
   19237              :     }
   19238              : 
   19239              :     /// @brief access specified object element
   19240              :     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
   19241              :     reference operator[](const typename object_t::key_type& key)
   19242              :     {
   19243              :         // implicitly convert null value to an empty object
   19244              :         if (is_null())
   19245              :         {
   19246              :             m_type = value_t::object;
   19247              :             m_value.object = create<object_t>();
   19248              :             assert_invariant();
   19249              :         }
   19250              : 
   19251              :         // operator[] only works for objects
   19252              :         if (JSON_HEDLEY_LIKELY(is_object()))
   19253              :         {
   19254              :             return set_parent(m_value.object->operator[](key));
   19255              :         }
   19256              : 
   19257              :         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
   19258              :     }
   19259              : 
   19260              :     /// @brief access specified object element
   19261              :     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
   19262              :     const_reference operator[](const typename object_t::key_type& key) const
   19263              :     {
   19264              :         // const operator[] only works for objects
   19265              :         if (JSON_HEDLEY_LIKELY(is_object()))
   19266              :         {
   19267              :             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
   19268              :             return m_value.object->find(key)->second;
   19269              :         }
   19270              : 
   19271              :         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
   19272              :     }
   19273              : 
   19274              :     /// @brief access specified object element
   19275              :     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
   19276              :     template<typename T>
   19277              :     JSON_HEDLEY_NON_NULL(2)
   19278           54 :     reference operator[](T* key)
   19279              :     {
   19280              :         // implicitly convert null to object
   19281           54 :         if (is_null())
   19282              :         {
   19283            0 :             m_type = value_t::object;
   19284            0 :             m_value = value_t::object;
   19285              :             assert_invariant();
   19286              :         }
   19287              : 
   19288              :         // at only works for objects
   19289           54 :         if (JSON_HEDLEY_LIKELY(is_object()))
   19290              :         {
   19291          108 :             return set_parent(m_value.object->operator[](key));
   19292              :         }
   19293              : 
   19294            0 :         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
   19295              :     }
   19296              : 
   19297              :     /// @brief access specified object element
   19298              :     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
   19299              :     template<typename T>
   19300              :     JSON_HEDLEY_NON_NULL(2)
   19301              :     const_reference operator[](T* key) const
   19302              :     {
   19303              :         // at only works for objects
   19304              :         if (JSON_HEDLEY_LIKELY(is_object()))
   19305              :         {
   19306              :             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
   19307              :             return m_value.object->find(key)->second;
   19308              :         }
   19309              : 
   19310              :         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
   19311              :     }
   19312              : 
   19313              :     /// @brief access specified object element with default value
   19314              :     /// @sa https://json.nlohmann.me/api/basic_json/value/
   19315              :     /// using std::is_convertible in a std::enable_if will fail when using explicit conversions
   19316              :     template < class ValueType, typename std::enable_if <
   19317              :                    detail::is_getable<basic_json_t, ValueType>::value
   19318              :                    && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
   19319              :     ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
   19320              :     {
   19321              :         // at only works for objects
   19322              :         if (JSON_HEDLEY_LIKELY(is_object()))
   19323              :         {
   19324              :             // if key is found, return value and given default value otherwise
   19325              :             const auto it = find(key);
   19326              :             if (it != end())
   19327              :             {
   19328              :                 return it->template get<ValueType>();
   19329              :             }
   19330              : 
   19331              :             return default_value;
   19332              :         }
   19333              : 
   19334              :         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
   19335              :     }
   19336              : 
   19337              :     /// @brief access specified object element with default value
   19338              :     /// @sa https://json.nlohmann.me/api/basic_json/value/
   19339              :     /// overload for a default value of type const char*
   19340              :     string_t value(const typename object_t::key_type& key, const char* default_value) const
   19341              :     {
   19342              :         return value(key, string_t(default_value));
   19343              :     }
   19344              : 
   19345              :     /// @brief access specified object element via JSON Pointer with default value
   19346              :     /// @sa https://json.nlohmann.me/api/basic_json/value/
   19347              :     template<class ValueType, typename std::enable_if<
   19348              :                  detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
   19349              :     ValueType value(const json_pointer& ptr, const ValueType& default_value) const
   19350              :     {
   19351              :         // at only works for objects
   19352              :         if (JSON_HEDLEY_LIKELY(is_object()))
   19353              :         {
   19354              :             // if pointer resolves a value, return it or use default value
   19355              :             JSON_TRY
   19356              :             {
   19357              :                 return ptr.get_checked(this).template get<ValueType>();
   19358              :             }
   19359              :             JSON_INTERNAL_CATCH (out_of_range&)
   19360              :             {
   19361              :                 return default_value;
   19362              :             }
   19363              :         }
   19364              : 
   19365              :         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
   19366              :     }
   19367              : 
   19368              :     /// @brief access specified object element via JSON Pointer with default value
   19369              :     /// @sa https://json.nlohmann.me/api/basic_json/value/
   19370              :     /// overload for a default value of type const char*
   19371              :     JSON_HEDLEY_NON_NULL(3)
   19372              :     string_t value(const json_pointer& ptr, const char* default_value) const
   19373              :     {
   19374              :         return value(ptr, string_t(default_value));
   19375              :     }
   19376              : 
   19377              :     /// @brief access the first element
   19378              :     /// @sa https://json.nlohmann.me/api/basic_json/front/
   19379              :     reference front()
   19380              :     {
   19381              :         return *begin();
   19382              :     }
   19383              : 
   19384              :     /// @brief access the first element
   19385              :     /// @sa https://json.nlohmann.me/api/basic_json/front/
   19386              :     const_reference front() const
   19387              :     {
   19388              :         return *cbegin();
   19389              :     }
   19390              : 
   19391              :     /// @brief access the last element
   19392              :     /// @sa https://json.nlohmann.me/api/basic_json/back/
   19393              :     reference back()
   19394              :     {
   19395              :         auto tmp = end();
   19396              :         --tmp;
   19397              :         return *tmp;
   19398              :     }
   19399              : 
   19400              :     /// @brief access the last element
   19401              :     /// @sa https://json.nlohmann.me/api/basic_json/back/
   19402              :     const_reference back() const
   19403              :     {
   19404              :         auto tmp = cend();
   19405              :         --tmp;
   19406              :         return *tmp;
   19407              :     }
   19408              : 
   19409              :     /// @brief remove element given an iterator
   19410              :     /// @sa https://json.nlohmann.me/api/basic_json/erase/
   19411              :     template < class IteratorType, typename std::enable_if <
   19412              :                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
   19413              :                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
   19414              :                = 0 >
   19415            0 :     IteratorType erase(IteratorType pos)
   19416              :     {
   19417              :         // make sure iterator fits the current value
   19418            0 :         if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
   19419              :         {
   19420            0 :             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
   19421              :         }
   19422              : 
   19423            0 :         IteratorType result = end();
   19424              : 
   19425            0 :         switch (m_type)
   19426              :         {
   19427            0 :             case value_t::boolean:
   19428              :             case value_t::number_float:
   19429              :             case value_t::number_integer:
   19430              :             case value_t::number_unsigned:
   19431              :             case value_t::string:
   19432              :             case value_t::binary:
   19433              :             {
   19434            0 :                 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
   19435              :                 {
   19436            0 :                     JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
   19437              :                 }
   19438              : 
   19439            0 :                 if (is_string())
   19440              :                 {
   19441              :                     AllocatorType<string_t> alloc;
   19442            0 :                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
   19443            0 :                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
   19444            0 :                     m_value.string = nullptr;
   19445              :                 }
   19446            0 :                 else if (is_binary())
   19447              :                 {
   19448              :                     AllocatorType<binary_t> alloc;
   19449            0 :                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
   19450            0 :                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
   19451            0 :                     m_value.binary = nullptr;
   19452              :                 }
   19453              : 
   19454            0 :                 m_type = value_t::null;
   19455              :                 assert_invariant();
   19456              :                 break;
   19457              :             }
   19458              : 
   19459            0 :             case value_t::object:
   19460              :             {
   19461            0 :                 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
   19462            0 :                 break;
   19463              :             }
   19464              : 
   19465            0 :             case value_t::array:
   19466              :             {
   19467            0 :                 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
   19468            0 :                 break;
   19469              :             }
   19470              : 
   19471            0 :             case value_t::null:
   19472              :             case value_t::discarded:
   19473              :             default:
   19474            0 :                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
   19475              :         }
   19476              : 
   19477            0 :         return result;
   19478              :     }
   19479              : 
   19480              :     /// @brief remove elements given an iterator range
   19481              :     /// @sa https://json.nlohmann.me/api/basic_json/erase/
   19482              :     template < class IteratorType, typename std::enable_if <
   19483              :                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
   19484              :                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
   19485              :                = 0 >
   19486              :     IteratorType erase(IteratorType first, IteratorType last)
   19487              :     {
   19488              :         // make sure iterator fits the current value
   19489              :         if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
   19490              :         {
   19491              :             JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
   19492              :         }
   19493              : 
   19494              :         IteratorType result = end();
   19495              : 
   19496              :         switch (m_type)
   19497              :         {
   19498              :             case value_t::boolean:
   19499              :             case value_t::number_float:
   19500              :             case value_t::number_integer:
   19501              :             case value_t::number_unsigned:
   19502              :             case value_t::string:
   19503              :             case value_t::binary:
   19504              :             {
   19505              :                 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
   19506              :                                        || !last.m_it.primitive_iterator.is_end()))
   19507              :                 {
   19508              :                     JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
   19509              :                 }
   19510              : 
   19511              :                 if (is_string())
   19512              :                 {
   19513              :                     AllocatorType<string_t> alloc;
   19514              :                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
   19515              :                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
   19516              :                     m_value.string = nullptr;
   19517              :                 }
   19518              :                 else if (is_binary())
   19519              :                 {
   19520              :                     AllocatorType<binary_t> alloc;
   19521              :                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
   19522              :                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
   19523              :                     m_value.binary = nullptr;
   19524              :                 }
   19525              : 
   19526              :                 m_type = value_t::null;
   19527              :                 assert_invariant();
   19528              :                 break;
   19529              :             }
   19530              : 
   19531              :             case value_t::object:
   19532              :             {
   19533              :                 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
   19534              :                                               last.m_it.object_iterator);
   19535              :                 break;
   19536              :             }
   19537              : 
   19538              :             case value_t::array:
   19539              :             {
   19540              :                 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
   19541              :                                              last.m_it.array_iterator);
   19542              :                 break;
   19543              :             }
   19544              : 
   19545              :             case value_t::null:
   19546              :             case value_t::discarded:
   19547              :             default:
   19548              :                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
   19549              :         }
   19550              : 
   19551              :         return result;
   19552              :     }
   19553              : 
   19554              :     /// @brief remove element from a JSON object given a key
   19555              :     /// @sa https://json.nlohmann.me/api/basic_json/erase/
   19556              :     size_type erase(const typename object_t::key_type& key)
   19557              :     {
   19558              :         // this erase only works for objects
   19559              :         if (JSON_HEDLEY_LIKELY(is_object()))
   19560              :         {
   19561              :             return m_value.object->erase(key);
   19562              :         }
   19563              : 
   19564              :         JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
   19565              :     }
   19566              : 
   19567              :     /// @brief remove element from a JSON array given an index
   19568              :     /// @sa https://json.nlohmann.me/api/basic_json/erase/
   19569              :     void erase(const size_type idx)
   19570              :     {
   19571              :         // this erase only works for arrays
   19572              :         if (JSON_HEDLEY_LIKELY(is_array()))
   19573              :         {
   19574              :             if (JSON_HEDLEY_UNLIKELY(idx >= size()))
   19575              :             {
   19576              :                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
   19577              :             }
   19578              : 
   19579              :             m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
   19580              :         }
   19581              :         else
   19582              :         {
   19583              :             JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
   19584              :         }
   19585              :     }
   19586              : 
   19587              :     /// @}
   19588              : 
   19589              : 
   19590              :     ////////////
   19591              :     // lookup //
   19592              :     ////////////
   19593              : 
   19594              :     /// @name lookup
   19595              :     /// @{
   19596              : 
   19597              :     /// @brief find an element in a JSON object
   19598              :     /// @sa https://json.nlohmann.me/api/basic_json/find/
   19599              :     template<typename KeyT>
   19600          216 :     iterator find(KeyT&& key)
   19601              :     {
   19602          216 :         auto result = end();
   19603              : 
   19604          216 :         if (is_object())
   19605              :         {
   19606          216 :             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
   19607              :         }
   19608              : 
   19609          216 :         return result;
   19610              :     }
   19611              : 
   19612              :     /// @brief find an element in a JSON object
   19613              :     /// @sa https://json.nlohmann.me/api/basic_json/find/
   19614              :     template<typename KeyT>
   19615              :     const_iterator find(KeyT&& key) const
   19616              :     {
   19617              :         auto result = cend();
   19618              : 
   19619              :         if (is_object())
   19620              :         {
   19621              :             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
   19622              :         }
   19623              : 
   19624              :         return result;
   19625              :     }
   19626              : 
   19627              :     /// @brief returns the number of occurrences of a key in a JSON object
   19628              :     /// @sa https://json.nlohmann.me/api/basic_json/count/
   19629              :     template<typename KeyT>
   19630              :     size_type count(KeyT&& key) const
   19631              :     {
   19632              :         // return 0 for all nonobject types
   19633              :         return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
   19634              :     }
   19635              : 
   19636              :     /// @brief check the existence of an element in a JSON object
   19637              :     /// @sa https://json.nlohmann.me/api/basic_json/contains/
   19638              :     template < typename KeyT, typename std::enable_if <
   19639              :                    !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
   19640              :     bool contains(KeyT && key) const
   19641              :     {
   19642          911 :         return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
   19643              :     }
   19644              : 
   19645              :     /// @brief check the existence of an element in a JSON object given a JSON pointer
   19646              :     /// @sa https://json.nlohmann.me/api/basic_json/contains/
   19647              :     bool contains(const json_pointer& ptr) const
   19648              :     {
   19649              :         return ptr.contains(this);
   19650              :     }
   19651              : 
   19652              :     /// @}
   19653              : 
   19654              : 
   19655              :     ///////////////
   19656              :     // iterators //
   19657              :     ///////////////
   19658              : 
   19659              :     /// @name iterators
   19660              :     /// @{
   19661              : 
   19662              :     /// @brief returns an iterator to the first element
   19663              :     /// @sa https://json.nlohmann.me/api/basic_json/begin/
   19664            2 :     iterator begin() noexcept
   19665              :     {
   19666              :         iterator result(this);
   19667              :         result.set_begin();
   19668            2 :         return result;
   19669              :     }
   19670              : 
   19671              :     /// @brief returns an iterator to the first element
   19672              :     /// @sa https://json.nlohmann.me/api/basic_json/begin/
   19673              :     const_iterator begin() const noexcept
   19674              :     {
   19675          147 :         return cbegin();
   19676              :     }
   19677              : 
   19678              :     /// @brief returns a const iterator to the first element
   19679              :     /// @sa https://json.nlohmann.me/api/basic_json/cbegin/
   19680          147 :     const_iterator cbegin() const noexcept
   19681              :     {
   19682              :         const_iterator result(this);
   19683              :         result.set_begin();
   19684          147 :         return result;
   19685              :     }
   19686              : 
   19687              :     /// @brief returns an iterator to one past the last element
   19688              :     /// @sa https://json.nlohmann.me/api/basic_json/end/
   19689          434 :     iterator end() noexcept
   19690              :     {
   19691              :         iterator result(this);
   19692              :         result.set_end();
   19693          434 :         return result;
   19694              :     }
   19695              : 
   19696              :     /// @brief returns an iterator to one past the last element
   19697              :     /// @sa https://json.nlohmann.me/api/basic_json/end/
   19698              :     const_iterator end() const noexcept
   19699              :     {
   19700          147 :         return cend();
   19701              :     }
   19702              : 
   19703              :     /// @brief returns an iterator to one past the last element
   19704              :     /// @sa https://json.nlohmann.me/api/basic_json/cend/
   19705          147 :     const_iterator cend() const noexcept
   19706              :     {
   19707              :         const_iterator result(this);
   19708              :         result.set_end();
   19709          147 :         return result;
   19710              :     }
   19711              : 
   19712              :     /// @brief returns an iterator to the reverse-beginning
   19713              :     /// @sa https://json.nlohmann.me/api/basic_json/rbegin/
   19714              :     reverse_iterator rbegin() noexcept
   19715              :     {
   19716              :         return reverse_iterator(end());
   19717              :     }
   19718              : 
   19719              :     /// @brief returns an iterator to the reverse-beginning
   19720              :     /// @sa https://json.nlohmann.me/api/basic_json/rbegin/
   19721              :     const_reverse_iterator rbegin() const noexcept
   19722              :     {
   19723              :         return crbegin();
   19724              :     }
   19725              : 
   19726              :     /// @brief returns an iterator to the reverse-end
   19727              :     /// @sa https://json.nlohmann.me/api/basic_json/rend/
   19728              :     reverse_iterator rend() noexcept
   19729              :     {
   19730              :         return reverse_iterator(begin());
   19731              :     }
   19732              : 
   19733              :     /// @brief returns an iterator to the reverse-end
   19734              :     /// @sa https://json.nlohmann.me/api/basic_json/rend/
   19735              :     const_reverse_iterator rend() const noexcept
   19736              :     {
   19737              :         return crend();
   19738              :     }
   19739              : 
   19740              :     /// @brief returns a const reverse iterator to the last element
   19741              :     /// @sa https://json.nlohmann.me/api/basic_json/crbegin/
   19742              :     const_reverse_iterator crbegin() const noexcept
   19743              :     {
   19744              :         return const_reverse_iterator(cend());
   19745              :     }
   19746              : 
   19747              :     /// @brief returns a const reverse iterator to one before the first
   19748              :     /// @sa https://json.nlohmann.me/api/basic_json/crend/
   19749              :     const_reverse_iterator crend() const noexcept
   19750              :     {
   19751              :         return const_reverse_iterator(cbegin());
   19752              :     }
   19753              : 
   19754              :   public:
   19755              :     /// @brief wrapper to access iterator member functions in range-based for
   19756              :     /// @sa https://json.nlohmann.me/api/basic_json/items/
   19757              :     /// @deprecated This function is deprecated since 3.1.0 and will be removed in
   19758              :     ///             version 4.0.0 of the library. Please use @ref items() instead;
   19759              :     ///             that is, replace `json::iterator_wrapper(j)` with `j.items()`.
   19760              :     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
   19761              :     static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
   19762              :     {
   19763              :         return ref.items();
   19764              :     }
   19765              : 
   19766              :     /// @brief wrapper to access iterator member functions in range-based for
   19767              :     /// @sa https://json.nlohmann.me/api/basic_json/items/
   19768              :     /// @deprecated This function is deprecated since 3.1.0 and will be removed in
   19769              :     ///         version 4.0.0 of the library. Please use @ref items() instead;
   19770              :     ///         that is, replace `json::iterator_wrapper(j)` with `j.items()`.
   19771              :     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
   19772              :     static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
   19773              :     {
   19774              :         return ref.items();
   19775              :     }
   19776              : 
   19777              :     /// @brief helper to access iterator member functions in range-based for
   19778              :     /// @sa https://json.nlohmann.me/api/basic_json/items/
   19779              :     iteration_proxy<iterator> items() noexcept
   19780              :     {
   19781              :         return iteration_proxy<iterator>(*this);
   19782              :     }
   19783              : 
   19784              :     /// @brief helper to access iterator member functions in range-based for
   19785              :     /// @sa https://json.nlohmann.me/api/basic_json/items/
   19786              :     iteration_proxy<const_iterator> items() const noexcept
   19787              :     {
   19788              :         return iteration_proxy<const_iterator>(*this);
   19789              :     }
   19790              : 
   19791              :     /// @}
   19792              : 
   19793              : 
   19794              :     //////////////
   19795              :     // capacity //
   19796              :     //////////////
   19797              : 
   19798              :     /// @name capacity
   19799              :     /// @{
   19800              : 
   19801              :     /// @brief checks whether the container is empty.
   19802              :     /// @sa https://json.nlohmann.me/api/basic_json/empty/
   19803              :     bool empty() const noexcept
   19804              :     {
   19805              :         switch (m_type)
   19806              :         {
   19807              :             case value_t::null:
   19808              :             {
   19809              :                 // null values are empty
   19810              :                 return true;
   19811              :             }
   19812              : 
   19813              :             case value_t::array:
   19814              :             {
   19815              :                 // delegate call to array_t::empty()
   19816              :                 return m_value.array->empty();
   19817              :             }
   19818              : 
   19819              :             case value_t::object:
   19820              :             {
   19821              :                 // delegate call to object_t::empty()
   19822              :                 return m_value.object->empty();
   19823              :             }
   19824              : 
   19825              :             case value_t::string:
   19826              :             case value_t::boolean:
   19827              :             case value_t::number_integer:
   19828              :             case value_t::number_unsigned:
   19829              :             case value_t::number_float:
   19830              :             case value_t::binary:
   19831              :             case value_t::discarded:
   19832              :             default:
   19833              :             {
   19834              :                 // all other types are nonempty
   19835              :                 return false;
   19836              :             }
   19837              :         }
   19838              :     }
   19839              : 
   19840              :     /// @brief returns the number of elements
   19841              :     /// @sa https://json.nlohmann.me/api/basic_json/size/
   19842              :     size_type size() const noexcept
   19843              :     {
   19844          147 :         switch (m_type)
   19845              :         {
   19846              :             case value_t::null:
   19847              :             {
   19848              :                 // null values are empty
   19849              :                 return 0;
   19850              :             }
   19851              : 
   19852          147 :             case value_t::array:
   19853              :             {
   19854              :                 // delegate call to array_t::size()
   19855          147 :                 return m_value.array->size();
   19856              :             }
   19857              : 
   19858            0 :             case value_t::object:
   19859              :             {
   19860              :                 // delegate call to object_t::size()
   19861            0 :                 return m_value.object->size();
   19862              :             }
   19863              : 
   19864            0 :             case value_t::string:
   19865              :             case value_t::boolean:
   19866              :             case value_t::number_integer:
   19867              :             case value_t::number_unsigned:
   19868              :             case value_t::number_float:
   19869              :             case value_t::binary:
   19870              :             case value_t::discarded:
   19871              :             default:
   19872              :             {
   19873              :                 // all other types have size 1
   19874            0 :                 return 1;
   19875              :             }
   19876              :         }
   19877              :     }
   19878              : 
   19879              :     /// @brief returns the maximum possible number of elements
   19880              :     /// @sa https://json.nlohmann.me/api/basic_json/max_size/
   19881              :     size_type max_size() const noexcept
   19882              :     {
   19883            0 :         switch (m_type)
   19884              :         {
   19885              :             case value_t::array:
   19886              :             {
   19887              :                 // delegate call to array_t::max_size()
   19888              :                 return m_value.array->max_size();
   19889              :             }
   19890              : 
   19891            0 :             case value_t::object:
   19892              :             {
   19893              :                 // delegate call to object_t::max_size()
   19894            0 :                 return m_value.object->max_size();
   19895              :             }
   19896              : 
   19897              :             case value_t::null:
   19898              :             case value_t::string:
   19899              :             case value_t::boolean:
   19900              :             case value_t::number_integer:
   19901              :             case value_t::number_unsigned:
   19902              :             case value_t::number_float:
   19903              :             case value_t::binary:
   19904              :             case value_t::discarded:
   19905              :             default:
   19906              :             {
   19907              :                 // all other types have max_size() == size()
   19908              :                 return size();
   19909              :             }
   19910              :         }
   19911              :     }
   19912              : 
   19913              :     /// @}
   19914              : 
   19915              : 
   19916              :     ///////////////
   19917              :     // modifiers //
   19918              :     ///////////////
   19919              : 
   19920              :     /// @name modifiers
   19921              :     /// @{
   19922              : 
   19923              :     /// @brief clears the contents
   19924              :     /// @sa https://json.nlohmann.me/api/basic_json/clear/
   19925              :     void clear() noexcept
   19926              :     {
   19927              :         switch (m_type)
   19928              :         {
   19929              :             case value_t::number_integer:
   19930              :             {
   19931              :                 m_value.number_integer = 0;
   19932              :                 break;
   19933              :             }
   19934              : 
   19935              :             case value_t::number_unsigned:
   19936              :             {
   19937              :                 m_value.number_unsigned = 0;
   19938              :                 break;
   19939              :             }
   19940              : 
   19941              :             case value_t::number_float:
   19942              :             {
   19943              :                 m_value.number_float = 0.0;
   19944              :                 break;
   19945              :             }
   19946              : 
   19947              :             case value_t::boolean:
   19948              :             {
   19949              :                 m_value.boolean = false;
   19950              :                 break;
   19951              :             }
   19952              : 
   19953              :             case value_t::string:
   19954              :             {
   19955              :                 m_value.string->clear();
   19956              :                 break;
   19957              :             }
   19958              : 
   19959              :             case value_t::binary:
   19960              :             {
   19961              :                 m_value.binary->clear();
   19962              :                 break;
   19963              :             }
   19964              : 
   19965              :             case value_t::array:
   19966              :             {
   19967              :                 m_value.array->clear();
   19968              :                 break;
   19969              :             }
   19970              : 
   19971              :             case value_t::object:
   19972              :             {
   19973              :                 m_value.object->clear();
   19974              :                 break;
   19975              :             }
   19976              : 
   19977              :             case value_t::null:
   19978              :             case value_t::discarded:
   19979              :             default:
   19980              :                 break;
   19981              :         }
   19982              :     }
   19983              : 
   19984              :     /// @brief add an object to an array
   19985              :     /// @sa https://json.nlohmann.me/api/basic_json/push_back/
   19986              :     void push_back(basic_json&& val)
   19987              :     {
   19988              :         // push_back only works for null objects or arrays
   19989              :         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
   19990              :         {
   19991              :             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
   19992              :         }
   19993              : 
   19994              :         // transform null object into an array
   19995              :         if (is_null())
   19996              :         {
   19997              :             m_type = value_t::array;
   19998              :             m_value = value_t::array;
   19999              :             assert_invariant();
   20000              :         }
   20001              : 
   20002              :         // add element to array (move semantics)
   20003              :         const auto old_capacity = m_value.array->capacity();
   20004              :         m_value.array->push_back(std::move(val));
   20005              :         set_parent(m_value.array->back(), old_capacity);
   20006              :         // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
   20007              :     }
   20008              : 
   20009              :     /// @brief add an object to an array
   20010              :     /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
   20011              :     reference operator+=(basic_json&& val)
   20012              :     {
   20013              :         push_back(std::move(val));
   20014              :         return *this;
   20015              :     }
   20016              : 
   20017              :     /// @brief add an object to an array
   20018              :     /// @sa https://json.nlohmann.me/api/basic_json/push_back/
   20019              :     void push_back(const basic_json& val)
   20020              :     {
   20021              :         // push_back only works for null objects or arrays
   20022              :         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
   20023              :         {
   20024              :             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
   20025              :         }
   20026              : 
   20027              :         // transform null object into an array
   20028              :         if (is_null())
   20029              :         {
   20030              :             m_type = value_t::array;
   20031              :             m_value = value_t::array;
   20032              :             assert_invariant();
   20033              :         }
   20034              : 
   20035              :         // add element to array
   20036              :         const auto old_capacity = m_value.array->capacity();
   20037              :         m_value.array->push_back(val);
   20038              :         set_parent(m_value.array->back(), old_capacity);
   20039              :     }
   20040              : 
   20041              :     /// @brief add an object to an array
   20042              :     /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
   20043              :     reference operator+=(const basic_json& val)
   20044              :     {
   20045              :         push_back(val);
   20046              :         return *this;
   20047              :     }
   20048              : 
   20049              :     /// @brief add an object to an object
   20050              :     /// @sa https://json.nlohmann.me/api/basic_json/push_back/
   20051              :     void push_back(const typename object_t::value_type& val)
   20052              :     {
   20053              :         // push_back only works for null objects or objects
   20054              :         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
   20055              :         {
   20056              :             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
   20057              :         }
   20058              : 
   20059              :         // transform null object into an object
   20060              :         if (is_null())
   20061              :         {
   20062              :             m_type = value_t::object;
   20063              :             m_value = value_t::object;
   20064              :             assert_invariant();
   20065              :         }
   20066              : 
   20067              :         // add element to object
   20068              :         auto res = m_value.object->insert(val);
   20069              :         set_parent(res.first->second);
   20070              :     }
   20071              : 
   20072              :     /// @brief add an object to an object
   20073              :     /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
   20074              :     reference operator+=(const typename object_t::value_type& val)
   20075              :     {
   20076              :         push_back(val);
   20077              :         return *this;
   20078              :     }
   20079              : 
   20080              :     /// @brief add an object to an object
   20081              :     /// @sa https://json.nlohmann.me/api/basic_json/push_back/
   20082              :     void push_back(initializer_list_t init)
   20083              :     {
   20084              :         if (is_object() && init.size() == 2 && (*init.begin())->is_string())
   20085              :         {
   20086              :             basic_json&& key = init.begin()->moved_or_copied();
   20087              :             push_back(typename object_t::value_type(
   20088              :                           std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
   20089              :         }
   20090              :         else
   20091              :         {
   20092              :             push_back(basic_json(init));
   20093              :         }
   20094              :     }
   20095              : 
   20096              :     /// @brief add an object to an object
   20097              :     /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
   20098              :     reference operator+=(initializer_list_t init)
   20099              :     {
   20100              :         push_back(init);
   20101              :         return *this;
   20102              :     }
   20103              : 
   20104              :     /// @brief add an object to an array
   20105              :     /// @sa https://json.nlohmann.me/api/basic_json/emplace_back/
   20106              :     template<class... Args>
   20107              :     reference emplace_back(Args&& ... args)
   20108              :     {
   20109              :         // emplace_back only works for null objects or arrays
   20110              :         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
   20111              :         {
   20112              :             JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
   20113              :         }
   20114              : 
   20115              :         // transform null object into an array
   20116              :         if (is_null())
   20117              :         {
   20118              :             m_type = value_t::array;
   20119              :             m_value = value_t::array;
   20120              :             assert_invariant();
   20121              :         }
   20122              : 
   20123              :         // add element to array (perfect forwarding)
   20124              :         const auto old_capacity = m_value.array->capacity();
   20125              :         m_value.array->emplace_back(std::forward<Args>(args)...);
   20126              :         return set_parent(m_value.array->back(), old_capacity);
   20127              :     }
   20128              : 
   20129              :     /// @brief add an object to an object if key does not exist
   20130              :     /// @sa https://json.nlohmann.me/api/basic_json/emplace/
   20131              :     template<class... Args>
   20132              :     std::pair<iterator, bool> emplace(Args&& ... args)
   20133              :     {
   20134              :         // emplace only works for null objects or arrays
   20135              :         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
   20136              :         {
   20137              :             JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
   20138              :         }
   20139              : 
   20140              :         // transform null object into an object
   20141              :         if (is_null())
   20142              :         {
   20143              :             m_type = value_t::object;
   20144              :             m_value = value_t::object;
   20145              :             assert_invariant();
   20146              :         }
   20147              : 
   20148              :         // add element to array (perfect forwarding)
   20149              :         auto res = m_value.object->emplace(std::forward<Args>(args)...);
   20150              :         set_parent(res.first->second);
   20151              : 
   20152              :         // create result iterator and set iterator to the result of emplace
   20153              :         auto it = begin();
   20154              :         it.m_it.object_iterator = res.first;
   20155              : 
   20156              :         // return pair of iterator and boolean
   20157              :         return {it, res.second};
   20158              :     }
   20159              : 
   20160              :     /// Helper for insertion of an iterator
   20161              :     /// @note: This uses std::distance to support GCC 4.8,
   20162              :     ///        see https://github.com/nlohmann/json/pull/1257
   20163              :     template<typename... Args>
   20164              :     iterator insert_iterator(const_iterator pos, Args&& ... args)
   20165              :     {
   20166              :         iterator result(this);
   20167              :         JSON_ASSERT(m_value.array != nullptr);
   20168              : 
   20169              :         auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
   20170              :         m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
   20171              :         result.m_it.array_iterator = m_value.array->begin() + insert_pos;
   20172              : 
   20173              :         // This could have been written as:
   20174              :         // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
   20175              :         // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
   20176              : 
   20177              :         set_parents();
   20178              :         return result;
   20179              :     }
   20180              : 
   20181              :     /// @brief inserts element into array
   20182              :     /// @sa https://json.nlohmann.me/api/basic_json/insert/
   20183              :     iterator insert(const_iterator pos, const basic_json& val)
   20184              :     {
   20185              :         // insert only works for arrays
   20186              :         if (JSON_HEDLEY_LIKELY(is_array()))
   20187              :         {
   20188              :             // check if iterator pos fits to this JSON value
   20189              :             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
   20190              :             {
   20191              :                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
   20192              :             }
   20193              : 
   20194              :             // insert to array and return iterator
   20195              :             return insert_iterator(pos, val);
   20196              :         }
   20197              : 
   20198              :         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
   20199              :     }
   20200              : 
   20201              :     /// @brief inserts element into array
   20202              :     /// @sa https://json.nlohmann.me/api/basic_json/insert/
   20203              :     iterator insert(const_iterator pos, basic_json&& val)
   20204              :     {
   20205              :         return insert(pos, val);
   20206              :     }
   20207              : 
   20208              :     /// @brief inserts copies of element into array
   20209              :     /// @sa https://json.nlohmann.me/api/basic_json/insert/
   20210              :     iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
   20211              :     {
   20212              :         // insert only works for arrays
   20213              :         if (JSON_HEDLEY_LIKELY(is_array()))
   20214              :         {
   20215              :             // check if iterator pos fits to this JSON value
   20216              :             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
   20217              :             {
   20218              :                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
   20219              :             }
   20220              : 
   20221              :             // insert to array and return iterator
   20222              :             return insert_iterator(pos, cnt, val);
   20223              :         }
   20224              : 
   20225              :         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
   20226              :     }
   20227              : 
   20228              :     /// @brief inserts range of elements into array
   20229              :     /// @sa https://json.nlohmann.me/api/basic_json/insert/
   20230              :     iterator insert(const_iterator pos, const_iterator first, const_iterator last)
   20231              :     {
   20232              :         // insert only works for arrays
   20233              :         if (JSON_HEDLEY_UNLIKELY(!is_array()))
   20234              :         {
   20235              :             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
   20236              :         }
   20237              : 
   20238              :         // check if iterator pos fits to this JSON value
   20239              :         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
   20240              :         {
   20241              :             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
   20242              :         }
   20243              : 
   20244              :         // check if range iterators belong to the same JSON object
   20245              :         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
   20246              :         {
   20247              :             JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
   20248              :         }
   20249              : 
   20250              :         if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
   20251              :         {
   20252              :             JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
   20253              :         }
   20254              : 
   20255              :         // insert to array and return iterator
   20256              :         return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
   20257              :     }
   20258              : 
   20259              :     /// @brief inserts elements from initializer list into array
   20260              :     /// @sa https://json.nlohmann.me/api/basic_json/insert/
   20261              :     iterator insert(const_iterator pos, initializer_list_t ilist)
   20262              :     {
   20263              :         // insert only works for arrays
   20264              :         if (JSON_HEDLEY_UNLIKELY(!is_array()))
   20265              :         {
   20266              :             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
   20267              :         }
   20268              : 
   20269              :         // check if iterator pos fits to this JSON value
   20270              :         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
   20271              :         {
   20272              :             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
   20273              :         }
   20274              : 
   20275              :         // insert to array and return iterator
   20276              :         return insert_iterator(pos, ilist.begin(), ilist.end());
   20277              :     }
   20278              : 
   20279              :     /// @brief inserts range of elements into object
   20280              :     /// @sa https://json.nlohmann.me/api/basic_json/insert/
   20281              :     void insert(const_iterator first, const_iterator last)
   20282              :     {
   20283              :         // insert only works for objects
   20284              :         if (JSON_HEDLEY_UNLIKELY(!is_object()))
   20285              :         {
   20286              :             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
   20287              :         }
   20288              : 
   20289              :         // check if range iterators belong to the same JSON object
   20290              :         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
   20291              :         {
   20292              :             JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
   20293              :         }
   20294              : 
   20295              :         // passed iterators must belong to objects
   20296              :         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
   20297              :         {
   20298              :             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
   20299              :         }
   20300              : 
   20301              :         m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
   20302              :     }
   20303              : 
   20304              :     /// @brief updates a JSON object from another object, overwriting existing keys
   20305              :     /// @sa https://json.nlohmann.me/api/basic_json/update/
   20306              :     void update(const_reference j, bool merge_objects = false)
   20307              :     {
   20308              :         update(j.begin(), j.end(), merge_objects);
   20309              :     }
   20310              : 
   20311              :     /// @brief updates a JSON object from another object, overwriting existing keys
   20312              :     /// @sa https://json.nlohmann.me/api/basic_json/update/
   20313              :     void update(const_iterator first, const_iterator last, bool merge_objects = false)
   20314              :     {
   20315              :         // implicitly convert null value to an empty object
   20316              :         if (is_null())
   20317              :         {
   20318              :             m_type = value_t::object;
   20319              :             m_value.object = create<object_t>();
   20320              :             assert_invariant();
   20321              :         }
   20322              : 
   20323              :         if (JSON_HEDLEY_UNLIKELY(!is_object()))
   20324              :         {
   20325              :             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
   20326              :         }
   20327              : 
   20328              :         // check if range iterators belong to the same JSON object
   20329              :         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
   20330              :         {
   20331              :             JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
   20332              :         }
   20333              : 
   20334              :         // passed iterators must belong to objects
   20335              :         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
   20336              :         {
   20337              :             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(first.m_object->type_name()), *first.m_object));
   20338              :         }
   20339              : 
   20340              :         for (auto it = first; it != last; ++it)
   20341              :         {
   20342              :             if (merge_objects && it.value().is_object())
   20343              :             {
   20344              :                 auto it2 = m_value.object->find(it.key());
   20345              :                 if (it2 != m_value.object->end())
   20346              :                 {
   20347              :                     it2->second.update(it.value(), true);
   20348              :                     continue;
   20349              :                 }
   20350              :             }
   20351              :             m_value.object->operator[](it.key()) = it.value();
   20352              : #if JSON_DIAGNOSTICS
   20353              :             m_value.object->operator[](it.key()).m_parent = this;
   20354              : #endif
   20355              :         }
   20356              :     }
   20357              : 
   20358              :     /// @brief exchanges the values
   20359              :     /// @sa https://json.nlohmann.me/api/basic_json/swap/
   20360              :     void swap(reference other) noexcept (
   20361              :         std::is_nothrow_move_constructible<value_t>::value&&
   20362              :         std::is_nothrow_move_assignable<value_t>::value&&
   20363              :         std::is_nothrow_move_constructible<json_value>::value&&
   20364              :         std::is_nothrow_move_assignable<json_value>::value
   20365              :     )
   20366              :     {
   20367              :         std::swap(m_type, other.m_type);
   20368              :         std::swap(m_value, other.m_value);
   20369              : 
   20370              :         set_parents();
   20371              :         other.set_parents();
   20372              :         assert_invariant();
   20373              :     }
   20374              : 
   20375              :     /// @brief exchanges the values
   20376              :     /// @sa https://json.nlohmann.me/api/basic_json/swap/
   20377              :     friend void swap(reference left, reference right) noexcept (
   20378              :         std::is_nothrow_move_constructible<value_t>::value&&
   20379              :         std::is_nothrow_move_assignable<value_t>::value&&
   20380              :         std::is_nothrow_move_constructible<json_value>::value&&
   20381              :         std::is_nothrow_move_assignable<json_value>::value
   20382              :     )
   20383              :     {
   20384              :         left.swap(right);
   20385              :     }
   20386              : 
   20387              :     /// @brief exchanges the values
   20388              :     /// @sa https://json.nlohmann.me/api/basic_json/swap/
   20389              :     void swap(array_t& other) // NOLINT(bugprone-exception-escape)
   20390              :     {
   20391              :         // swap only works for arrays
   20392              :         if (JSON_HEDLEY_LIKELY(is_array()))
   20393              :         {
   20394              :             std::swap(*(m_value.array), other);
   20395              :         }
   20396              :         else
   20397              :         {
   20398              :             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
   20399              :         }
   20400              :     }
   20401              : 
   20402              :     /// @brief exchanges the values
   20403              :     /// @sa https://json.nlohmann.me/api/basic_json/swap/
   20404              :     void swap(object_t& other) // NOLINT(bugprone-exception-escape)
   20405              :     {
   20406              :         // swap only works for objects
   20407              :         if (JSON_HEDLEY_LIKELY(is_object()))
   20408              :         {
   20409              :             std::swap(*(m_value.object), other);
   20410              :         }
   20411              :         else
   20412              :         {
   20413              :             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
   20414              :         }
   20415              :     }
   20416              : 
   20417              :     /// @brief exchanges the values
   20418              :     /// @sa https://json.nlohmann.me/api/basic_json/swap/
   20419              :     void swap(string_t& other) // NOLINT(bugprone-exception-escape)
   20420              :     {
   20421              :         // swap only works for strings
   20422              :         if (JSON_HEDLEY_LIKELY(is_string()))
   20423              :         {
   20424              :             std::swap(*(m_value.string), other);
   20425              :         }
   20426              :         else
   20427              :         {
   20428              :             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
   20429              :         }
   20430              :     }
   20431              : 
   20432              :     /// @brief exchanges the values
   20433              :     /// @sa https://json.nlohmann.me/api/basic_json/swap/
   20434              :     void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
   20435              :     {
   20436              :         // swap only works for strings
   20437              :         if (JSON_HEDLEY_LIKELY(is_binary()))
   20438              :         {
   20439              :             std::swap(*(m_value.binary), other);
   20440              :         }
   20441              :         else
   20442              :         {
   20443              :             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
   20444              :         }
   20445              :     }
   20446              : 
   20447              :     /// @brief exchanges the values
   20448              :     /// @sa https://json.nlohmann.me/api/basic_json/swap/
   20449              :     void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
   20450              :     {
   20451              :         // swap only works for strings
   20452              :         if (JSON_HEDLEY_LIKELY(is_binary()))
   20453              :         {
   20454              :             std::swap(*(m_value.binary), other);
   20455              :         }
   20456              :         else
   20457              :         {
   20458              :             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
   20459              :         }
   20460              :     }
   20461              : 
   20462              :     /// @}
   20463              : 
   20464              :   public:
   20465              :     //////////////////////////////////////////
   20466              :     // lexicographical comparison operators //
   20467              :     //////////////////////////////////////////
   20468              : 
   20469              :     /// @name lexicographical comparison operators
   20470              :     /// @{
   20471              : 
   20472              :     /// @brief comparison: equal
   20473              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
   20474              :     friend bool operator==(const_reference lhs, const_reference rhs) noexcept
   20475              :     {
   20476              : #ifdef __GNUC__
   20477              : #pragma GCC diagnostic push
   20478              : #pragma GCC diagnostic ignored "-Wfloat-equal"
   20479              : #endif
   20480              :         const auto lhs_type = lhs.type();
   20481              :         const auto rhs_type = rhs.type();
   20482              : 
   20483              :         if (lhs_type == rhs_type)
   20484              :         {
   20485              :             switch (lhs_type)
   20486              :             {
   20487              :                 case value_t::array:
   20488              :                     return *lhs.m_value.array == *rhs.m_value.array;
   20489              : 
   20490              :                 case value_t::object:
   20491              :                     return *lhs.m_value.object == *rhs.m_value.object;
   20492              : 
   20493              :                 case value_t::null:
   20494              :                     return true;
   20495              : 
   20496              :                 case value_t::string:
   20497              :                     return *lhs.m_value.string == *rhs.m_value.string;
   20498              : 
   20499              :                 case value_t::boolean:
   20500              :                     return lhs.m_value.boolean == rhs.m_value.boolean;
   20501              : 
   20502              :                 case value_t::number_integer:
   20503              :                     return lhs.m_value.number_integer == rhs.m_value.number_integer;
   20504              : 
   20505              :                 case value_t::number_unsigned:
   20506              :                     return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
   20507              : 
   20508              :                 case value_t::number_float:
   20509              :                     return lhs.m_value.number_float == rhs.m_value.number_float;
   20510              : 
   20511              :                 case value_t::binary:
   20512              :                     return *lhs.m_value.binary == *rhs.m_value.binary;
   20513              : 
   20514              :                 case value_t::discarded:
   20515              :                 default:
   20516              :                     return false;
   20517              :             }
   20518              :         }
   20519              :         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
   20520              :         {
   20521              :             return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
   20522              :         }
   20523              :         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
   20524              :         {
   20525              :             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
   20526              :         }
   20527              :         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
   20528              :         {
   20529              :             return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
   20530              :         }
   20531              :         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
   20532              :         {
   20533              :             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
   20534              :         }
   20535              :         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
   20536              :         {
   20537              :             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
   20538              :         }
   20539              :         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
   20540              :         {
   20541              :             return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
   20542              :         }
   20543              : 
   20544              :         return false;
   20545              : #ifdef __GNUC__
   20546              : #pragma GCC diagnostic pop
   20547              : #endif
   20548              :     }
   20549              : 
   20550              :     /// @brief comparison: equal
   20551              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
   20552              :     template<typename ScalarType, typename std::enable_if<
   20553              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20554              :     friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
   20555              :     {
   20556              :         return lhs == basic_json(rhs);
   20557              :     }
   20558              : 
   20559              :     /// @brief comparison: equal
   20560              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
   20561              :     template<typename ScalarType, typename std::enable_if<
   20562              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20563              :     friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
   20564              :     {
   20565              :         return basic_json(lhs) == rhs;
   20566              :     }
   20567              : 
   20568              :     /// @brief comparison: not equal
   20569              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
   20570              :     friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
   20571              :     {
   20572              :         return !(lhs == rhs);
   20573              :     }
   20574              : 
   20575              :     /// @brief comparison: not equal
   20576              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
   20577              :     template<typename ScalarType, typename std::enable_if<
   20578              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20579              :     friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
   20580              :     {
   20581              :         return lhs != basic_json(rhs);
   20582              :     }
   20583              : 
   20584              :     /// @brief comparison: not equal
   20585              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
   20586              :     template<typename ScalarType, typename std::enable_if<
   20587              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20588              :     friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
   20589              :     {
   20590              :         return basic_json(lhs) != rhs;
   20591              :     }
   20592              : 
   20593              :     /// @brief comparison: less than
   20594              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
   20595            1 :     friend bool operator<(const_reference lhs, const_reference rhs) noexcept
   20596              :     {
   20597              :         const auto lhs_type = lhs.type();
   20598              :         const auto rhs_type = rhs.type();
   20599              : 
   20600            1 :         if (lhs_type == rhs_type)
   20601              :         {
   20602            0 :             switch (lhs_type)
   20603              :             {
   20604            0 :                 case value_t::array:
   20605              :                     // note parentheses are necessary, see
   20606              :                     // https://github.com/nlohmann/json/issues/1530
   20607            0 :                     return (*lhs.m_value.array) < (*rhs.m_value.array);
   20608              : 
   20609            0 :                 case value_t::object:
   20610            0 :                     return (*lhs.m_value.object) < (*rhs.m_value.object);
   20611              : 
   20612              :                 case value_t::null:
   20613              :                     return false;
   20614              : 
   20615            0 :                 case value_t::string:
   20616            0 :                     return (*lhs.m_value.string) < (*rhs.m_value.string);
   20617              : 
   20618            0 :                 case value_t::boolean:
   20619            0 :                     return (lhs.m_value.boolean) < (rhs.m_value.boolean);
   20620              : 
   20621            0 :                 case value_t::number_integer:
   20622            0 :                     return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
   20623              : 
   20624            0 :                 case value_t::number_unsigned:
   20625            0 :                     return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
   20626              : 
   20627            0 :                 case value_t::number_float:
   20628            0 :                     return (lhs.m_value.number_float) < (rhs.m_value.number_float);
   20629              : 
   20630            0 :                 case value_t::binary:
   20631            0 :                     return (*lhs.m_value.binary) < (*rhs.m_value.binary);
   20632              : 
   20633              :                 case value_t::discarded:
   20634              :                 default:
   20635              :                     return false;
   20636              :             }
   20637              :         }
   20638            1 :         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
   20639              :         {
   20640            0 :             return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
   20641              :         }
   20642            1 :         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
   20643              :         {
   20644            0 :             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
   20645              :         }
   20646            1 :         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
   20647              :         {
   20648            1 :             return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
   20649              :         }
   20650            0 :         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
   20651              :         {
   20652            0 :             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
   20653              :         }
   20654            0 :         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
   20655              :         {
   20656            0 :             return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
   20657              :         }
   20658            0 :         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
   20659              :         {
   20660            0 :             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
   20661              :         }
   20662              : 
   20663              :         // We only reach this line if we cannot compare values. In that case,
   20664              :         // we compare types. Note we have to call the operator explicitly,
   20665              :         // because MSVC has problems otherwise.
   20666              :         return operator<(lhs_type, rhs_type);
   20667              :     }
   20668              : 
   20669              :     /// @brief comparison: less than
   20670              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
   20671              :     template<typename ScalarType, typename std::enable_if<
   20672              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20673              :     friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
   20674              :     {
   20675              :         return lhs < basic_json(rhs);
   20676              :     }
   20677              : 
   20678              :     /// @brief comparison: less than
   20679              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
   20680              :     template<typename ScalarType, typename std::enable_if<
   20681              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20682              :     friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
   20683              :     {
   20684              :         return basic_json(lhs) < rhs;
   20685              :     }
   20686              : 
   20687              :     /// @brief comparison: less than or equal
   20688              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
   20689              :     friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
   20690              :     {
   20691            1 :         return !(rhs < lhs);
   20692              :     }
   20693              : 
   20694              :     /// @brief comparison: less than or equal
   20695              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
   20696              :     template<typename ScalarType, typename std::enable_if<
   20697              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20698              :     friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
   20699              :     {
   20700              :         return lhs <= basic_json(rhs);
   20701              :     }
   20702              : 
   20703              :     /// @brief comparison: less than or equal
   20704              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
   20705              :     template<typename ScalarType, typename std::enable_if<
   20706              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20707              :     friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
   20708              :     {
   20709              :         return basic_json(lhs) <= rhs;
   20710              :     }
   20711              : 
   20712              :     /// @brief comparison: greater than
   20713              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
   20714              :     friend bool operator>(const_reference lhs, const_reference rhs) noexcept
   20715              :     {
   20716              :         return !(lhs <= rhs);
   20717              :     }
   20718              : 
   20719              :     /// @brief comparison: greater than
   20720              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
   20721              :     template<typename ScalarType, typename std::enable_if<
   20722              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20723              :     friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
   20724              :     {
   20725              :         return lhs > basic_json(rhs);
   20726              :     }
   20727              : 
   20728              :     /// @brief comparison: greater than
   20729              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
   20730              :     template<typename ScalarType, typename std::enable_if<
   20731              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20732            1 :     friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
   20733              :     {
   20734            1 :         return basic_json(lhs) > rhs;
   20735              :     }
   20736              : 
   20737              :     /// @brief comparison: greater than or equal
   20738              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
   20739              :     friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
   20740              :     {
   20741              :         return !(lhs < rhs);
   20742              :     }
   20743              : 
   20744              :     /// @brief comparison: greater than or equal
   20745              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
   20746              :     template<typename ScalarType, typename std::enable_if<
   20747              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20748              :     friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
   20749              :     {
   20750              :         return lhs >= basic_json(rhs);
   20751              :     }
   20752              : 
   20753              :     /// @brief comparison: greater than or equal
   20754              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
   20755              :     template<typename ScalarType, typename std::enable_if<
   20756              :                  std::is_scalar<ScalarType>::value, int>::type = 0>
   20757              :     friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
   20758              :     {
   20759              :         return basic_json(lhs) >= rhs;
   20760              :     }
   20761              : 
   20762              :     /// @}
   20763              : 
   20764              :     ///////////////////
   20765              :     // serialization //
   20766              :     ///////////////////
   20767              : 
   20768              :     /// @name serialization
   20769              :     /// @{
   20770              : #ifndef JSON_NO_IO
   20771              :     /// @brief serialize to stream
   20772              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/
   20773              :     friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
   20774              :     {
   20775              :         // read width member and use it as indentation parameter if nonzero
   20776              :         const bool pretty_print = o.width() > 0;
   20777              :         const auto indentation = pretty_print ? o.width() : 0;
   20778              : 
   20779              :         // reset width to 0 for subsequent calls to this stream
   20780              :         o.width(0);
   20781              : 
   20782              :         // do the actual serialization
   20783              :         serializer s(detail::output_adapter<char>(o), o.fill());
   20784              :         s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
   20785              :         return o;
   20786              :     }
   20787              : 
   20788              :     /// @brief serialize to stream
   20789              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/
   20790              :     /// @deprecated This function is deprecated since 3.0.0 and will be removed in
   20791              :     ///             version 4.0.0 of the library. Please use
   20792              :     ///             operator<<(std::ostream&, const basic_json&) instead; that is,
   20793              :     ///             replace calls like `j >> o;` with `o << j;`.
   20794              :     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
   20795              :     friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
   20796              :     {
   20797              :         return o << j;
   20798              :     }
   20799              : #endif  // JSON_NO_IO
   20800              :     /// @}
   20801              : 
   20802              : 
   20803              :     /////////////////////
   20804              :     // deserialization //
   20805              :     /////////////////////
   20806              : 
   20807              :     /// @name deserialization
   20808              :     /// @{
   20809              : 
   20810              :     /// @brief deserialize from a compatible input
   20811              :     /// @sa https://json.nlohmann.me/api/basic_json/parse/
   20812              :     template<typename InputType>
   20813              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   20814              :     static basic_json parse(InputType&& i,
   20815              :                             const parser_callback_t cb = nullptr,
   20816              :                             const bool allow_exceptions = true,
   20817              :                             const bool ignore_comments = false)
   20818              :     {
   20819              :         basic_json result;
   20820              :         parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
   20821              :         return result;
   20822              :     }
   20823              : 
   20824              :     /// @brief deserialize from a pair of character iterators
   20825              :     /// @sa https://json.nlohmann.me/api/basic_json/parse/
   20826              :     template<typename IteratorType>
   20827              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   20828              :     static basic_json parse(IteratorType first,
   20829              :                             IteratorType last,
   20830              :                             const parser_callback_t cb = nullptr,
   20831              :                             const bool allow_exceptions = true,
   20832              :                             const bool ignore_comments = false)
   20833              :     {
   20834              :         basic_json result;
   20835              :         parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
   20836              :         return result;
   20837              :     }
   20838              : 
   20839              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   20840              :     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
   20841              :     static basic_json parse(detail::span_input_adapter&& i,
   20842              :                             const parser_callback_t cb = nullptr,
   20843              :                             const bool allow_exceptions = true,
   20844              :                             const bool ignore_comments = false)
   20845              :     {
   20846              :         basic_json result;
   20847              :         parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
   20848              :         return result;
   20849              :     }
   20850              : 
   20851              :     /// @brief check if the input is valid JSON
   20852              :     /// @sa https://json.nlohmann.me/api/basic_json/accept/
   20853              :     template<typename InputType>
   20854              :     static bool accept(InputType&& i,
   20855              :                        const bool ignore_comments = false)
   20856              :     {
   20857              :         return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
   20858              :     }
   20859              : 
   20860              :     /// @brief check if the input is valid JSON
   20861              :     /// @sa https://json.nlohmann.me/api/basic_json/accept/
   20862              :     template<typename IteratorType>
   20863              :     static bool accept(IteratorType first, IteratorType last,
   20864              :                        const bool ignore_comments = false)
   20865              :     {
   20866              :         return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
   20867              :     }
   20868              : 
   20869              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   20870              :     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
   20871              :     static bool accept(detail::span_input_adapter&& i,
   20872              :                        const bool ignore_comments = false)
   20873              :     {
   20874              :         return parser(i.get(), nullptr, false, ignore_comments).accept(true);
   20875              :     }
   20876              : 
   20877              :     /// @brief generate SAX events
   20878              :     /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
   20879              :     template <typename InputType, typename SAX>
   20880              :     JSON_HEDLEY_NON_NULL(2)
   20881              :     static bool sax_parse(InputType&& i, SAX* sax,
   20882              :                           input_format_t format = input_format_t::json,
   20883              :                           const bool strict = true,
   20884              :                           const bool ignore_comments = false)
   20885              :     {
   20886              :         auto ia = detail::input_adapter(std::forward<InputType>(i));
   20887              :         return format == input_format_t::json
   20888              :                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
   20889              :                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
   20890              :     }
   20891              : 
   20892              :     /// @brief generate SAX events
   20893              :     /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
   20894              :     template<class IteratorType, class SAX>
   20895              :     JSON_HEDLEY_NON_NULL(3)
   20896              :     static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
   20897              :                           input_format_t format = input_format_t::json,
   20898              :                           const bool strict = true,
   20899              :                           const bool ignore_comments = false)
   20900              :     {
   20901              :         auto ia = detail::input_adapter(std::move(first), std::move(last));
   20902              :         return format == input_format_t::json
   20903              :                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
   20904              :                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
   20905              :     }
   20906              : 
   20907              :     /// @brief generate SAX events
   20908              :     /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
   20909              :     /// @deprecated This function is deprecated since 3.8.0 and will be removed in
   20910              :     ///             version 4.0.0 of the library. Please use
   20911              :     ///             sax_parse(ptr, ptr + len) instead.
   20912              :     template <typename SAX>
   20913              :     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
   20914              :     JSON_HEDLEY_NON_NULL(2)
   20915              :     static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
   20916              :                           input_format_t format = input_format_t::json,
   20917              :                           const bool strict = true,
   20918              :                           const bool ignore_comments = false)
   20919              :     {
   20920              :         auto ia = i.get();
   20921              :         return format == input_format_t::json
   20922              :                // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
   20923              :                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
   20924              :                // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
   20925              :                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
   20926              :     }
   20927              : #ifndef JSON_NO_IO
   20928              :     /// @brief deserialize from stream
   20929              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
   20930              :     /// @deprecated This stream operator is deprecated since 3.0.0 and will be removed in
   20931              :     ///             version 4.0.0 of the library. Please use
   20932              :     ///             operator>>(std::istream&, basic_json&) instead; that is,
   20933              :     ///             replace calls like `j << i;` with `i >> j;`.
   20934              :     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
   20935              :     friend std::istream& operator<<(basic_json& j, std::istream& i)
   20936              :     {
   20937              :         return operator>>(i, j);
   20938              :     }
   20939              : 
   20940              :     /// @brief deserialize from stream
   20941              :     /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
   20942           33 :     friend std::istream& operator>>(std::istream& i, basic_json& j)
   20943              :     {
   20944           33 :         parser(detail::input_adapter(i)).parse(false, j);
   20945           33 :         return i;
   20946              :     }
   20947              : #endif  // JSON_NO_IO
   20948              :     /// @}
   20949              : 
   20950              :     ///////////////////////////
   20951              :     // convenience functions //
   20952              :     ///////////////////////////
   20953              : 
   20954              :     /// @brief return the type as string
   20955              :     /// @sa https://json.nlohmann.me/api/basic_json/type_name/
   20956              :     JSON_HEDLEY_RETURNS_NON_NULL
   20957              :     const char* type_name() const noexcept
   20958              :     {
   20959            0 :         switch (m_type)
   20960              :         {
   20961              :             case value_t::null:
   20962              :                 return "null";
   20963            0 :             case value_t::object:
   20964            0 :                 return "object";
   20965            0 :             case value_t::array:
   20966            0 :                 return "array";
   20967            0 :             case value_t::string:
   20968            0 :                 return "string";
   20969            0 :             case value_t::boolean:
   20970            0 :                 return "boolean";
   20971            0 :             case value_t::binary:
   20972            0 :                 return "binary";
   20973            0 :             case value_t::discarded:
   20974            0 :                 return "discarded";
   20975            0 :             case value_t::number_integer:
   20976              :             case value_t::number_unsigned:
   20977              :             case value_t::number_float:
   20978              :             default:
   20979            0 :                 return "number";
   20980              :         }
   20981              :     }
   20982              : 
   20983              : 
   20984              :   JSON_PRIVATE_UNLESS_TESTED:
   20985              :     //////////////////////
   20986              :     // member variables //
   20987              :     //////////////////////
   20988              : 
   20989              :     /// the type of the current element
   20990              :     value_t m_type = value_t::null;
   20991              : 
   20992              :     /// the value of the current element
   20993              :     json_value m_value = {};
   20994              : 
   20995              : #if JSON_DIAGNOSTICS
   20996              :     /// a pointer to a parent value (for debugging purposes)
   20997              :     basic_json* m_parent = nullptr;
   20998              : #endif
   20999              : 
   21000              :     //////////////////////////////////////////
   21001              :     // binary serialization/deserialization //
   21002              :     //////////////////////////////////////////
   21003              : 
   21004              :     /// @name binary serialization/deserialization support
   21005              :     /// @{
   21006              : 
   21007              :   public:
   21008              :     /// @brief create a CBOR serialization of a given JSON value
   21009              :     /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
   21010              :     static std::vector<std::uint8_t> to_cbor(const basic_json& j)
   21011              :     {
   21012              :         std::vector<std::uint8_t> result;
   21013              :         to_cbor(j, result);
   21014              :         return result;
   21015              :     }
   21016              : 
   21017              :     /// @brief create a CBOR serialization of a given JSON value
   21018              :     /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
   21019              :     static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
   21020              :     {
   21021              :         binary_writer<std::uint8_t>(o).write_cbor(j);
   21022              :     }
   21023              : 
   21024              :     /// @brief create a CBOR serialization of a given JSON value
   21025              :     /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
   21026              :     static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
   21027              :     {
   21028              :         binary_writer<char>(o).write_cbor(j);
   21029              :     }
   21030              : 
   21031              :     /// @brief create a MessagePack serialization of a given JSON value
   21032              :     /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
   21033              :     static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
   21034              :     {
   21035              :         std::vector<std::uint8_t> result;
   21036              :         to_msgpack(j, result);
   21037              :         return result;
   21038              :     }
   21039              : 
   21040              :     /// @brief create a MessagePack serialization of a given JSON value
   21041              :     /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
   21042              :     static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
   21043              :     {
   21044              :         binary_writer<std::uint8_t>(o).write_msgpack(j);
   21045              :     }
   21046              : 
   21047              :     /// @brief create a MessagePack serialization of a given JSON value
   21048              :     /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
   21049              :     static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
   21050              :     {
   21051              :         binary_writer<char>(o).write_msgpack(j);
   21052              :     }
   21053              : 
   21054              :     /// @brief create a UBJSON serialization of a given JSON value
   21055              :     /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
   21056              :     static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
   21057              :             const bool use_size = false,
   21058              :             const bool use_type = false)
   21059              :     {
   21060              :         std::vector<std::uint8_t> result;
   21061              :         to_ubjson(j, result, use_size, use_type);
   21062              :         return result;
   21063              :     }
   21064              : 
   21065              :     /// @brief create a UBJSON serialization of a given JSON value
   21066              :     /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
   21067              :     static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
   21068              :                           const bool use_size = false, const bool use_type = false)
   21069              :     {
   21070              :         binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
   21071              :     }
   21072              : 
   21073              :     /// @brief create a UBJSON serialization of a given JSON value
   21074              :     /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
   21075              :     static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
   21076              :                           const bool use_size = false, const bool use_type = false)
   21077              :     {
   21078              :         binary_writer<char>(o).write_ubjson(j, use_size, use_type);
   21079              :     }
   21080              : 
   21081              :     /// @brief create a BSON serialization of a given JSON value
   21082              :     /// @sa https://json.nlohmann.me/api/basic_json/to_bson/
   21083              :     static std::vector<std::uint8_t> to_bson(const basic_json& j)
   21084              :     {
   21085              :         std::vector<std::uint8_t> result;
   21086              :         to_bson(j, result);
   21087              :         return result;
   21088              :     }
   21089              : 
   21090              :     /// @brief create a BSON serialization of a given JSON value
   21091              :     /// @sa https://json.nlohmann.me/api/basic_json/to_bson/
   21092              :     static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
   21093              :     {
   21094              :         binary_writer<std::uint8_t>(o).write_bson(j);
   21095              :     }
   21096              : 
   21097              :     /// @brief create a BSON serialization of a given JSON value
   21098              :     /// @sa https://json.nlohmann.me/api/basic_json/to_bson/
   21099              :     static void to_bson(const basic_json& j, detail::output_adapter<char> o)
   21100              :     {
   21101              :         binary_writer<char>(o).write_bson(j);
   21102              :     }
   21103              : 
   21104              :     /// @brief create a JSON value from an input in CBOR format
   21105              :     /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/
   21106              :     template<typename InputType>
   21107              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21108              :     static basic_json from_cbor(InputType&& i,
   21109              :                                 const bool strict = true,
   21110              :                                 const bool allow_exceptions = true,
   21111              :                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
   21112              :     {
   21113              :         basic_json result;
   21114              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21115              :         auto ia = detail::input_adapter(std::forward<InputType>(i));
   21116              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
   21117              :         return res ? result : basic_json(value_t::discarded);
   21118              :     }
   21119              : 
   21120              :     /// @brief create a JSON value from an input in CBOR format
   21121              :     /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/
   21122              :     template<typename IteratorType>
   21123              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21124              :     static basic_json from_cbor(IteratorType first, IteratorType last,
   21125              :                                 const bool strict = true,
   21126              :                                 const bool allow_exceptions = true,
   21127              :                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
   21128              :     {
   21129              :         basic_json result;
   21130              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21131              :         auto ia = detail::input_adapter(std::move(first), std::move(last));
   21132              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
   21133              :         return res ? result : basic_json(value_t::discarded);
   21134              :     }
   21135              : 
   21136              :     template<typename T>
   21137              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21138              :     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
   21139              :     static basic_json from_cbor(const T* ptr, std::size_t len,
   21140              :                                 const bool strict = true,
   21141              :                                 const bool allow_exceptions = true,
   21142              :                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
   21143              :     {
   21144              :         return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
   21145              :     }
   21146              : 
   21147              : 
   21148              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21149              :     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
   21150              :     static basic_json from_cbor(detail::span_input_adapter&& i,
   21151              :                                 const bool strict = true,
   21152              :                                 const bool allow_exceptions = true,
   21153              :                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
   21154              :     {
   21155              :         basic_json result;
   21156              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21157              :         auto ia = i.get();
   21158              :         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
   21159              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
   21160              :         return res ? result : basic_json(value_t::discarded);
   21161              :     }
   21162              : 
   21163              :     /// @brief create a JSON value from an input in MessagePack format
   21164              :     /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/
   21165              :     template<typename InputType>
   21166              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21167              :     static basic_json from_msgpack(InputType&& i,
   21168              :                                    const bool strict = true,
   21169              :                                    const bool allow_exceptions = true)
   21170              :     {
   21171              :         basic_json result;
   21172              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21173              :         auto ia = detail::input_adapter(std::forward<InputType>(i));
   21174              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
   21175              :         return res ? result : basic_json(value_t::discarded);
   21176              :     }
   21177              : 
   21178              :     /// @brief create a JSON value from an input in MessagePack format
   21179              :     /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/
   21180              :     template<typename IteratorType>
   21181              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21182              :     static basic_json from_msgpack(IteratorType first, IteratorType last,
   21183              :                                    const bool strict = true,
   21184              :                                    const bool allow_exceptions = true)
   21185              :     {
   21186              :         basic_json result;
   21187              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21188              :         auto ia = detail::input_adapter(std::move(first), std::move(last));
   21189              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
   21190              :         return res ? result : basic_json(value_t::discarded);
   21191              :     }
   21192              : 
   21193              :     template<typename T>
   21194              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21195              :     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
   21196              :     static basic_json from_msgpack(const T* ptr, std::size_t len,
   21197              :                                    const bool strict = true,
   21198              :                                    const bool allow_exceptions = true)
   21199              :     {
   21200              :         return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
   21201              :     }
   21202              : 
   21203              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21204              :     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
   21205              :     static basic_json from_msgpack(detail::span_input_adapter&& i,
   21206              :                                    const bool strict = true,
   21207              :                                    const bool allow_exceptions = true)
   21208              :     {
   21209              :         basic_json result;
   21210              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21211              :         auto ia = i.get();
   21212              :         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
   21213              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
   21214              :         return res ? result : basic_json(value_t::discarded);
   21215              :     }
   21216              : 
   21217              :     /// @brief create a JSON value from an input in UBJSON format
   21218              :     /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/
   21219              :     template<typename InputType>
   21220              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21221              :     static basic_json from_ubjson(InputType&& i,
   21222              :                                   const bool strict = true,
   21223              :                                   const bool allow_exceptions = true)
   21224              :     {
   21225              :         basic_json result;
   21226              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21227              :         auto ia = detail::input_adapter(std::forward<InputType>(i));
   21228              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
   21229              :         return res ? result : basic_json(value_t::discarded);
   21230              :     }
   21231              : 
   21232              :     /// @brief create a JSON value from an input in UBJSON format
   21233              :     /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/
   21234              :     template<typename IteratorType>
   21235              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21236              :     static basic_json from_ubjson(IteratorType first, IteratorType last,
   21237              :                                   const bool strict = true,
   21238              :                                   const bool allow_exceptions = true)
   21239              :     {
   21240              :         basic_json result;
   21241              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21242              :         auto ia = detail::input_adapter(std::move(first), std::move(last));
   21243              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
   21244              :         return res ? result : basic_json(value_t::discarded);
   21245              :     }
   21246              : 
   21247              :     template<typename T>
   21248              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21249              :     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
   21250              :     static basic_json from_ubjson(const T* ptr, std::size_t len,
   21251              :                                   const bool strict = true,
   21252              :                                   const bool allow_exceptions = true)
   21253              :     {
   21254              :         return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
   21255              :     }
   21256              : 
   21257              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21258              :     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
   21259              :     static basic_json from_ubjson(detail::span_input_adapter&& i,
   21260              :                                   const bool strict = true,
   21261              :                                   const bool allow_exceptions = true)
   21262              :     {
   21263              :         basic_json result;
   21264              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21265              :         auto ia = i.get();
   21266              :         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
   21267              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
   21268              :         return res ? result : basic_json(value_t::discarded);
   21269              :     }
   21270              : 
   21271              :     /// @brief create a JSON value from an input in BSON format
   21272              :     /// @sa https://json.nlohmann.me/api/basic_json/from_bson/
   21273              :     template<typename InputType>
   21274              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21275              :     static basic_json from_bson(InputType&& i,
   21276              :                                 const bool strict = true,
   21277              :                                 const bool allow_exceptions = true)
   21278              :     {
   21279              :         basic_json result;
   21280              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21281              :         auto ia = detail::input_adapter(std::forward<InputType>(i));
   21282              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
   21283              :         return res ? result : basic_json(value_t::discarded);
   21284              :     }
   21285              : 
   21286              :     /// @brief create a JSON value from an input in BSON format
   21287              :     /// @sa https://json.nlohmann.me/api/basic_json/from_bson/
   21288              :     template<typename IteratorType>
   21289              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21290              :     static basic_json from_bson(IteratorType first, IteratorType last,
   21291              :                                 const bool strict = true,
   21292              :                                 const bool allow_exceptions = true)
   21293              :     {
   21294              :         basic_json result;
   21295              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21296              :         auto ia = detail::input_adapter(std::move(first), std::move(last));
   21297              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
   21298              :         return res ? result : basic_json(value_t::discarded);
   21299              :     }
   21300              : 
   21301              :     template<typename T>
   21302              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21303              :     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
   21304              :     static basic_json from_bson(const T* ptr, std::size_t len,
   21305              :                                 const bool strict = true,
   21306              :                                 const bool allow_exceptions = true)
   21307              :     {
   21308              :         return from_bson(ptr, ptr + len, strict, allow_exceptions);
   21309              :     }
   21310              : 
   21311              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21312              :     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
   21313              :     static basic_json from_bson(detail::span_input_adapter&& i,
   21314              :                                 const bool strict = true,
   21315              :                                 const bool allow_exceptions = true)
   21316              :     {
   21317              :         basic_json result;
   21318              :         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
   21319              :         auto ia = i.get();
   21320              :         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
   21321              :         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
   21322              :         return res ? result : basic_json(value_t::discarded);
   21323              :     }
   21324              :     /// @}
   21325              : 
   21326              :     //////////////////////////
   21327              :     // JSON Pointer support //
   21328              :     //////////////////////////
   21329              : 
   21330              :     /// @name JSON Pointer functions
   21331              :     /// @{
   21332              : 
   21333              :     /// @brief access specified element via JSON Pointer
   21334              :     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
   21335              :     reference operator[](const json_pointer& ptr)
   21336              :     {
   21337              :         return ptr.get_unchecked(this);
   21338              :     }
   21339              : 
   21340              :     /// @brief access specified element via JSON Pointer
   21341              :     /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
   21342              :     const_reference operator[](const json_pointer& ptr) const
   21343              :     {
   21344              :         return ptr.get_unchecked(this);
   21345              :     }
   21346              : 
   21347              :     /// @brief access specified element via JSON Pointer
   21348              :     /// @sa https://json.nlohmann.me/api/basic_json/at/
   21349              :     reference at(const json_pointer& ptr)
   21350              :     {
   21351              :         return ptr.get_checked(this);
   21352              :     }
   21353              : 
   21354              :     /// @brief access specified element via JSON Pointer
   21355              :     /// @sa https://json.nlohmann.me/api/basic_json/at/
   21356              :     const_reference at(const json_pointer& ptr) const
   21357              :     {
   21358              :         return ptr.get_checked(this);
   21359              :     }
   21360              : 
   21361              :     /// @brief return flattened JSON value
   21362              :     /// @sa https://json.nlohmann.me/api/basic_json/flatten/
   21363              :     basic_json flatten() const
   21364              :     {
   21365              :         basic_json result(value_t::object);
   21366              :         json_pointer::flatten("", *this, result);
   21367              :         return result;
   21368              :     }
   21369              : 
   21370              :     /// @brief unflatten a previously flattened JSON value
   21371              :     /// @sa https://json.nlohmann.me/api/basic_json/unflatten/
   21372              :     basic_json unflatten() const
   21373              :     {
   21374              :         return json_pointer::unflatten(*this);
   21375              :     }
   21376              : 
   21377              :     /// @}
   21378              : 
   21379              :     //////////////////////////
   21380              :     // JSON Patch functions //
   21381              :     //////////////////////////
   21382              : 
   21383              :     /// @name JSON Patch functions
   21384              :     /// @{
   21385              : 
   21386              :     /// @brief applies a JSON patch
   21387              :     /// @sa https://json.nlohmann.me/api/basic_json/patch/
   21388              :     basic_json patch(const basic_json& json_patch) const
   21389              :     {
   21390              :         // make a working copy to apply the patch to
   21391              :         basic_json result = *this;
   21392              : 
   21393              :         // the valid JSON Patch operations
   21394              :         enum class patch_operations {add, remove, replace, move, copy, test, invalid};
   21395              : 
   21396              :         const auto get_op = [](const std::string & op)
   21397              :         {
   21398              :             if (op == "add")
   21399              :             {
   21400              :                 return patch_operations::add;
   21401              :             }
   21402              :             if (op == "remove")
   21403              :             {
   21404              :                 return patch_operations::remove;
   21405              :             }
   21406              :             if (op == "replace")
   21407              :             {
   21408              :                 return patch_operations::replace;
   21409              :             }
   21410              :             if (op == "move")
   21411              :             {
   21412              :                 return patch_operations::move;
   21413              :             }
   21414              :             if (op == "copy")
   21415              :             {
   21416              :                 return patch_operations::copy;
   21417              :             }
   21418              :             if (op == "test")
   21419              :             {
   21420              :                 return patch_operations::test;
   21421              :             }
   21422              : 
   21423              :             return patch_operations::invalid;
   21424              :         };
   21425              : 
   21426              :         // wrapper for "add" operation; add value at ptr
   21427              :         const auto operation_add = [&result](json_pointer & ptr, basic_json val)
   21428              :         {
   21429              :             // adding to the root of the target document means replacing it
   21430              :             if (ptr.empty())
   21431              :             {
   21432              :                 result = val;
   21433              :                 return;
   21434              :             }
   21435              : 
   21436              :             // make sure the top element of the pointer exists
   21437              :             json_pointer top_pointer = ptr.top();
   21438              :             if (top_pointer != ptr)
   21439              :             {
   21440              :                 result.at(top_pointer);
   21441              :             }
   21442              : 
   21443              :             // get reference to parent of JSON pointer ptr
   21444              :             const auto last_path = ptr.back();
   21445              :             ptr.pop_back();
   21446              :             basic_json& parent = result[ptr];
   21447              : 
   21448              :             switch (parent.m_type)
   21449              :             {
   21450              :                 case value_t::null:
   21451              :                 case value_t::object:
   21452              :                 {
   21453              :                     // use operator[] to add value
   21454              :                     parent[last_path] = val;
   21455              :                     break;
   21456              :                 }
   21457              : 
   21458              :                 case value_t::array:
   21459              :                 {
   21460              :                     if (last_path == "-")
   21461              :                     {
   21462              :                         // special case: append to back
   21463              :                         parent.push_back(val);
   21464              :                     }
   21465              :                     else
   21466              :                     {
   21467              :                         const auto idx = json_pointer::array_index(last_path);
   21468              :                         if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
   21469              :                         {
   21470              :                             // avoid undefined behavior
   21471              :                             JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
   21472              :                         }
   21473              : 
   21474              :                         // default case: insert add offset
   21475              :                         parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
   21476              :                     }
   21477              :                     break;
   21478              :                 }
   21479              : 
   21480              :                 // if there exists a parent it cannot be primitive
   21481              :                 case value_t::string: // LCOV_EXCL_LINE
   21482              :                 case value_t::boolean: // LCOV_EXCL_LINE
   21483              :                 case value_t::number_integer: // LCOV_EXCL_LINE
   21484              :                 case value_t::number_unsigned: // LCOV_EXCL_LINE
   21485              :                 case value_t::number_float: // LCOV_EXCL_LINE
   21486              :                 case value_t::binary: // LCOV_EXCL_LINE
   21487              :                 case value_t::discarded: // LCOV_EXCL_LINE
   21488              :                 default:            // LCOV_EXCL_LINE
   21489              :                     JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
   21490              :             }
   21491              :         };
   21492              : 
   21493              :         // wrapper for "remove" operation; remove value at ptr
   21494              :         const auto operation_remove = [this, &result](json_pointer & ptr)
   21495              :         {
   21496              :             // get reference to parent of JSON pointer ptr
   21497              :             const auto last_path = ptr.back();
   21498              :             ptr.pop_back();
   21499              :             basic_json& parent = result.at(ptr);
   21500              : 
   21501              :             // remove child
   21502              :             if (parent.is_object())
   21503              :             {
   21504              :                 // perform range check
   21505              :                 auto it = parent.find(last_path);
   21506              :                 if (JSON_HEDLEY_LIKELY(it != parent.end()))
   21507              :                 {
   21508              :                     parent.erase(it);
   21509              :                 }
   21510              :                 else
   21511              :                 {
   21512              :                     JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
   21513              :                 }
   21514              :             }
   21515              :             else if (parent.is_array())
   21516              :             {
   21517              :                 // note erase performs range check
   21518              :                 parent.erase(json_pointer::array_index(last_path));
   21519              :             }
   21520              :         };
   21521              : 
   21522              :         // type check: top level value must be an array
   21523              :         if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
   21524              :         {
   21525              :             JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
   21526              :         }
   21527              : 
   21528              :         // iterate and apply the operations
   21529              :         for (const auto& val : json_patch)
   21530              :         {
   21531              :             // wrapper to get a value for an operation
   21532              :             const auto get_value = [&val](const std::string & op,
   21533              :                                           const std::string & member,
   21534              :                                           bool string_type) -> basic_json &
   21535              :             {
   21536              :                 // find value
   21537              :                 auto it = val.m_value.object->find(member);
   21538              : 
   21539              :                 // context-sensitive error message
   21540              :                 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
   21541              : 
   21542              :                 // check if desired value is present
   21543              :                 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
   21544              :                 {
   21545              :                     // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
   21546              :                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
   21547              :                 }
   21548              : 
   21549              :                 // check if result is of type string
   21550              :                 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
   21551              :                 {
   21552              :                     // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
   21553              :                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
   21554              :                 }
   21555              : 
   21556              :                 // no error: return value
   21557              :                 return it->second;
   21558              :             };
   21559              : 
   21560              :             // type check: every element of the array must be an object
   21561              :             if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
   21562              :             {
   21563              :                 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
   21564              :             }
   21565              : 
   21566              :             // collect mandatory members
   21567              :             const auto op = get_value("op", "op", true).template get<std::string>();
   21568              :             const auto path = get_value(op, "path", true).template get<std::string>();
   21569              :             json_pointer ptr(path);
   21570              : 
   21571              :             switch (get_op(op))
   21572              :             {
   21573              :                 case patch_operations::add:
   21574              :                 {
   21575              :                     operation_add(ptr, get_value("add", "value", false));
   21576              :                     break;
   21577              :                 }
   21578              : 
   21579              :                 case patch_operations::remove:
   21580              :                 {
   21581              :                     operation_remove(ptr);
   21582              :                     break;
   21583              :                 }
   21584              : 
   21585              :                 case patch_operations::replace:
   21586              :                 {
   21587              :                     // the "path" location must exist - use at()
   21588              :                     result.at(ptr) = get_value("replace", "value", false);
   21589              :                     break;
   21590              :                 }
   21591              : 
   21592              :                 case patch_operations::move:
   21593              :                 {
   21594              :                     const auto from_path = get_value("move", "from", true).template get<std::string>();
   21595              :                     json_pointer from_ptr(from_path);
   21596              : 
   21597              :                     // the "from" location must exist - use at()
   21598              :                     basic_json v = result.at(from_ptr);
   21599              : 
   21600              :                     // The move operation is functionally identical to a
   21601              :                     // "remove" operation on the "from" location, followed
   21602              :                     // immediately by an "add" operation at the target
   21603              :                     // location with the value that was just removed.
   21604              :                     operation_remove(from_ptr);
   21605              :                     operation_add(ptr, v);
   21606              :                     break;
   21607              :                 }
   21608              : 
   21609              :                 case patch_operations::copy:
   21610              :                 {
   21611              :                     const auto from_path = get_value("copy", "from", true).template get<std::string>();
   21612              :                     const json_pointer from_ptr(from_path);
   21613              : 
   21614              :                     // the "from" location must exist - use at()
   21615              :                     basic_json v = result.at(from_ptr);
   21616              : 
   21617              :                     // The copy is functionally identical to an "add"
   21618              :                     // operation at the target location using the value
   21619              :                     // specified in the "from" member.
   21620              :                     operation_add(ptr, v);
   21621              :                     break;
   21622              :                 }
   21623              : 
   21624              :                 case patch_operations::test:
   21625              :                 {
   21626              :                     bool success = false;
   21627              :                     JSON_TRY
   21628              :                     {
   21629              :                         // check if "value" matches the one at "path"
   21630              :                         // the "path" location must exist - use at()
   21631              :                         success = (result.at(ptr) == get_value("test", "value", false));
   21632              :                     }
   21633              :                     JSON_INTERNAL_CATCH (out_of_range&)
   21634              :                     {
   21635              :                         // ignore out of range errors: success remains false
   21636              :                     }
   21637              : 
   21638              :                     // throw an exception if test fails
   21639              :                     if (JSON_HEDLEY_UNLIKELY(!success))
   21640              :                     {
   21641              :                         JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
   21642              :                     }
   21643              : 
   21644              :                     break;
   21645              :                 }
   21646              : 
   21647              :                 case patch_operations::invalid:
   21648              :                 default:
   21649              :                 {
   21650              :                     // op must be "add", "remove", "replace", "move", "copy", or
   21651              :                     // "test"
   21652              :                     JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
   21653              :                 }
   21654              :             }
   21655              :         }
   21656              : 
   21657              :         return result;
   21658              :     }
   21659              : 
   21660              :     /// @brief creates a diff as a JSON patch
   21661              :     /// @sa https://json.nlohmann.me/api/basic_json/diff/
   21662              :     JSON_HEDLEY_WARN_UNUSED_RESULT
   21663              :     static basic_json diff(const basic_json& source, const basic_json& target,
   21664              :                            const std::string& path = "")
   21665              :     {
   21666              :         // the patch
   21667              :         basic_json result(value_t::array);
   21668              : 
   21669              :         // if the values are the same, return empty patch
   21670              :         if (source == target)
   21671              :         {
   21672              :             return result;
   21673              :         }
   21674              : 
   21675              :         if (source.type() != target.type())
   21676              :         {
   21677              :             // different types: replace value
   21678              :             result.push_back(
   21679              :             {
   21680              :                 {"op", "replace"}, {"path", path}, {"value", target}
   21681              :             });
   21682              :             return result;
   21683              :         }
   21684              : 
   21685              :         switch (source.type())
   21686              :         {
   21687              :             case value_t::array:
   21688              :             {
   21689              :                 // first pass: traverse common elements
   21690              :                 std::size_t i = 0;
   21691              :                 while (i < source.size() && i < target.size())
   21692              :                 {
   21693              :                     // recursive call to compare array values at index i
   21694              :                     auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
   21695              :                     result.insert(result.end(), temp_diff.begin(), temp_diff.end());
   21696              :                     ++i;
   21697              :                 }
   21698              : 
   21699              :                 // We now reached the end of at least one array
   21700              :                 // in a second pass, traverse the remaining elements
   21701              : 
   21702              :                 // remove my remaining elements
   21703              :                 const auto end_index = static_cast<difference_type>(result.size());
   21704              :                 while (i < source.size())
   21705              :                 {
   21706              :                     // add operations in reverse order to avoid invalid
   21707              :                     // indices
   21708              :                     result.insert(result.begin() + end_index, object(
   21709              :                     {
   21710              :                         {"op", "remove"},
   21711              :                         {"path", path + "/" + std::to_string(i)}
   21712              :                     }));
   21713              :                     ++i;
   21714              :                 }
   21715              : 
   21716              :                 // add other remaining elements
   21717              :                 while (i < target.size())
   21718              :                 {
   21719              :                     result.push_back(
   21720              :                     {
   21721              :                         {"op", "add"},
   21722              :                         {"path", path + "/-"},
   21723              :                         {"value", target[i]}
   21724              :                     });
   21725              :                     ++i;
   21726              :                 }
   21727              : 
   21728              :                 break;
   21729              :             }
   21730              : 
   21731              :             case value_t::object:
   21732              :             {
   21733              :                 // first pass: traverse this object's elements
   21734              :                 for (auto it = source.cbegin(); it != source.cend(); ++it)
   21735              :                 {
   21736              :                     // escape the key name to be used in a JSON patch
   21737              :                     const auto path_key = path + "/" + detail::escape(it.key());
   21738              : 
   21739              :                     if (target.find(it.key()) != target.end())
   21740              :                     {
   21741              :                         // recursive call to compare object values at key it
   21742              :                         auto temp_diff = diff(it.value(), target[it.key()], path_key);
   21743              :                         result.insert(result.end(), temp_diff.begin(), temp_diff.end());
   21744              :                     }
   21745              :                     else
   21746              :                     {
   21747              :                         // found a key that is not in o -> remove it
   21748              :                         result.push_back(object(
   21749              :                         {
   21750              :                             {"op", "remove"}, {"path", path_key}
   21751              :                         }));
   21752              :                     }
   21753              :                 }
   21754              : 
   21755              :                 // second pass: traverse other object's elements
   21756              :                 for (auto it = target.cbegin(); it != target.cend(); ++it)
   21757              :                 {
   21758              :                     if (source.find(it.key()) == source.end())
   21759              :                     {
   21760              :                         // found a key that is not in this -> add it
   21761              :                         const auto path_key = path + "/" + detail::escape(it.key());
   21762              :                         result.push_back(
   21763              :                         {
   21764              :                             {"op", "add"}, {"path", path_key},
   21765              :                             {"value", it.value()}
   21766              :                         });
   21767              :                     }
   21768              :                 }
   21769              : 
   21770              :                 break;
   21771              :             }
   21772              : 
   21773              :             case value_t::null:
   21774              :             case value_t::string:
   21775              :             case value_t::boolean:
   21776              :             case value_t::number_integer:
   21777              :             case value_t::number_unsigned:
   21778              :             case value_t::number_float:
   21779              :             case value_t::binary:
   21780              :             case value_t::discarded:
   21781              :             default:
   21782              :             {
   21783              :                 // both primitive type: replace value
   21784              :                 result.push_back(
   21785              :                 {
   21786              :                     {"op", "replace"}, {"path", path}, {"value", target}
   21787              :                 });
   21788              :                 break;
   21789              :             }
   21790              :         }
   21791              : 
   21792              :         return result;
   21793              :     }
   21794              : 
   21795              :     /// @}
   21796              : 
   21797              :     ////////////////////////////////
   21798              :     // JSON Merge Patch functions //
   21799              :     ////////////////////////////////
   21800              : 
   21801              :     /// @name JSON Merge Patch functions
   21802              :     /// @{
   21803              : 
   21804              :     /// @brief applies a JSON Merge Patch
   21805              :     /// @sa https://json.nlohmann.me/api/basic_json/merge_patch/
   21806              :     void merge_patch(const basic_json& apply_patch)
   21807              :     {
   21808              :         if (apply_patch.is_object())
   21809              :         {
   21810              :             if (!is_object())
   21811              :             {
   21812              :                 *this = object();
   21813              :             }
   21814              :             for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
   21815              :             {
   21816              :                 if (it.value().is_null())
   21817              :                 {
   21818              :                     erase(it.key());
   21819              :                 }
   21820              :                 else
   21821              :                 {
   21822              :                     operator[](it.key()).merge_patch(it.value());
   21823              :                 }
   21824              :             }
   21825              :         }
   21826              :         else
   21827              :         {
   21828              :             *this = apply_patch;
   21829              :         }
   21830              :     }
   21831              : 
   21832              :     /// @}
   21833              : };
   21834              : 
   21835              : /// @brief user-defined to_string function for JSON values
   21836              : /// @sa https://json.nlohmann.me/api/basic_json/to_string/
   21837              : NLOHMANN_BASIC_JSON_TPL_DECLARATION
   21838              : std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
   21839              : {
   21840              :     return j.dump();
   21841              : }
   21842              : 
   21843              : } // namespace nlohmann
   21844              : 
   21845              : ///////////////////////
   21846              : // nonmember support //
   21847              : ///////////////////////
   21848              : 
   21849              : namespace std // NOLINT(cert-dcl58-cpp)
   21850              : {
   21851              : 
   21852              : /// @brief hash value for JSON objects
   21853              : /// @sa https://json.nlohmann.me/api/basic_json/std_hash/
   21854              : NLOHMANN_BASIC_JSON_TPL_DECLARATION
   21855              : struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL>
   21856              : {
   21857              :     std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
   21858              :     {
   21859              :         return nlohmann::detail::hash(j);
   21860              :     }
   21861              : };
   21862              : 
   21863              : // specialization for std::less<value_t>
   21864              : template<>
   21865              : struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
   21866              : {
   21867              :     /*!
   21868              :     @brief compare two value_t enum values
   21869              :     @since version 3.0.0
   21870              :     */
   21871              :     bool operator()(nlohmann::detail::value_t lhs,
   21872              :                     nlohmann::detail::value_t rhs) const noexcept
   21873              :     {
   21874              :         return nlohmann::detail::operator<(lhs, rhs);
   21875              :     }
   21876              : };
   21877              : 
   21878              : // C++20 prohibit function specialization in the std namespace.
   21879              : #ifndef JSON_HAS_CPP_20
   21880              : 
   21881              : /// @brief exchanges the values of two JSON objects
   21882              : /// @sa https://json.nlohmann.me/api/basic_json/std_swap/
   21883              : NLOHMANN_BASIC_JSON_TPL_DECLARATION
   21884              : inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept(  // NOLINT(readability-inconsistent-declaration-parameter-name)
   21885              :     is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&&                          // NOLINT(misc-redundant-expression)
   21886              :     is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
   21887              : {
   21888              :     j1.swap(j2);
   21889              : }
   21890              : 
   21891              : #endif
   21892              : 
   21893              : } // namespace std
   21894              : 
   21895              : /// @brief user-defined string literal for JSON values
   21896              : /// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/
   21897              : JSON_HEDLEY_NON_NULL(1)
   21898              : inline nlohmann::json operator "" _json(const char* s, std::size_t n)
   21899              : {
   21900              :     return nlohmann::json::parse(s, s + n);
   21901              : }
   21902              : 
   21903              : /// @brief user-defined string literal for JSON pointer
   21904              : /// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/
   21905              : JSON_HEDLEY_NON_NULL(1)
   21906              : inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
   21907              : {
   21908              :     return nlohmann::json::json_pointer(std::string(s, n));
   21909              : }
   21910              : 
   21911              : // #include <nlohmann/detail/macro_unscope.hpp>
   21912              : 
   21913              : 
   21914              : // restore clang diagnostic settings
   21915              : #if defined(__clang__)
   21916              :     #pragma clang diagnostic pop
   21917              : #endif
   21918              : 
   21919              : // clean up
   21920              : #undef JSON_ASSERT
   21921              : #undef JSON_INTERNAL_CATCH
   21922              : #undef JSON_CATCH
   21923              : #undef JSON_THROW
   21924              : #undef JSON_TRY
   21925              : #undef JSON_PRIVATE_UNLESS_TESTED
   21926              : #undef JSON_HAS_CPP_11
   21927              : #undef JSON_HAS_CPP_14
   21928              : #undef JSON_HAS_CPP_17
   21929              : #undef JSON_HAS_CPP_20
   21930              : #undef JSON_HAS_FILESYSTEM
   21931              : #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
   21932              : #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
   21933              : #undef NLOHMANN_BASIC_JSON_TPL
   21934              : #undef JSON_EXPLICIT
   21935              : #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
   21936              : 
   21937              : // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
   21938              : 
   21939              : 
   21940              : #undef JSON_HEDLEY_ALWAYS_INLINE
   21941              : #undef JSON_HEDLEY_ARM_VERSION
   21942              : #undef JSON_HEDLEY_ARM_VERSION_CHECK
   21943              : #undef JSON_HEDLEY_ARRAY_PARAM
   21944              : #undef JSON_HEDLEY_ASSUME
   21945              : #undef JSON_HEDLEY_BEGIN_C_DECLS
   21946              : #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
   21947              : #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
   21948              : #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
   21949              : #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
   21950              : #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
   21951              : #undef JSON_HEDLEY_CLANG_HAS_FEATURE
   21952              : #undef JSON_HEDLEY_CLANG_HAS_WARNING
   21953              : #undef JSON_HEDLEY_COMPCERT_VERSION
   21954              : #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
   21955              : #undef JSON_HEDLEY_CONCAT
   21956              : #undef JSON_HEDLEY_CONCAT3
   21957              : #undef JSON_HEDLEY_CONCAT3_EX
   21958              : #undef JSON_HEDLEY_CONCAT_EX
   21959              : #undef JSON_HEDLEY_CONST
   21960              : #undef JSON_HEDLEY_CONSTEXPR
   21961              : #undef JSON_HEDLEY_CONST_CAST
   21962              : #undef JSON_HEDLEY_CPP_CAST
   21963              : #undef JSON_HEDLEY_CRAY_VERSION
   21964              : #undef JSON_HEDLEY_CRAY_VERSION_CHECK
   21965              : #undef JSON_HEDLEY_C_DECL
   21966              : #undef JSON_HEDLEY_DEPRECATED
   21967              : #undef JSON_HEDLEY_DEPRECATED_FOR
   21968              : #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
   21969              : #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
   21970              : #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
   21971              : #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
   21972              : #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
   21973              : #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
   21974              : #undef JSON_HEDLEY_DIAGNOSTIC_POP
   21975              : #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
   21976              : #undef JSON_HEDLEY_DMC_VERSION
   21977              : #undef JSON_HEDLEY_DMC_VERSION_CHECK
   21978              : #undef JSON_HEDLEY_EMPTY_BASES
   21979              : #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
   21980              : #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
   21981              : #undef JSON_HEDLEY_END_C_DECLS
   21982              : #undef JSON_HEDLEY_FLAGS
   21983              : #undef JSON_HEDLEY_FLAGS_CAST
   21984              : #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
   21985              : #undef JSON_HEDLEY_GCC_HAS_BUILTIN
   21986              : #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
   21987              : #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
   21988              : #undef JSON_HEDLEY_GCC_HAS_EXTENSION
   21989              : #undef JSON_HEDLEY_GCC_HAS_FEATURE
   21990              : #undef JSON_HEDLEY_GCC_HAS_WARNING
   21991              : #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
   21992              : #undef JSON_HEDLEY_GCC_VERSION
   21993              : #undef JSON_HEDLEY_GCC_VERSION_CHECK
   21994              : #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
   21995              : #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
   21996              : #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
   21997              : #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
   21998              : #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
   21999              : #undef JSON_HEDLEY_GNUC_HAS_FEATURE
   22000              : #undef JSON_HEDLEY_GNUC_HAS_WARNING
   22001              : #undef JSON_HEDLEY_GNUC_VERSION
   22002              : #undef JSON_HEDLEY_GNUC_VERSION_CHECK
   22003              : #undef JSON_HEDLEY_HAS_ATTRIBUTE
   22004              : #undef JSON_HEDLEY_HAS_BUILTIN
   22005              : #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
   22006              : #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
   22007              : #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
   22008              : #undef JSON_HEDLEY_HAS_EXTENSION
   22009              : #undef JSON_HEDLEY_HAS_FEATURE
   22010              : #undef JSON_HEDLEY_HAS_WARNING
   22011              : #undef JSON_HEDLEY_IAR_VERSION
   22012              : #undef JSON_HEDLEY_IAR_VERSION_CHECK
   22013              : #undef JSON_HEDLEY_IBM_VERSION
   22014              : #undef JSON_HEDLEY_IBM_VERSION_CHECK
   22015              : #undef JSON_HEDLEY_IMPORT
   22016              : #undef JSON_HEDLEY_INLINE
   22017              : #undef JSON_HEDLEY_INTEL_CL_VERSION
   22018              : #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
   22019              : #undef JSON_HEDLEY_INTEL_VERSION
   22020              : #undef JSON_HEDLEY_INTEL_VERSION_CHECK
   22021              : #undef JSON_HEDLEY_IS_CONSTANT
   22022              : #undef JSON_HEDLEY_IS_CONSTEXPR_
   22023              : #undef JSON_HEDLEY_LIKELY
   22024              : #undef JSON_HEDLEY_MALLOC
   22025              : #undef JSON_HEDLEY_MCST_LCC_VERSION
   22026              : #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
   22027              : #undef JSON_HEDLEY_MESSAGE
   22028              : #undef JSON_HEDLEY_MSVC_VERSION
   22029              : #undef JSON_HEDLEY_MSVC_VERSION_CHECK
   22030              : #undef JSON_HEDLEY_NEVER_INLINE
   22031              : #undef JSON_HEDLEY_NON_NULL
   22032              : #undef JSON_HEDLEY_NO_ESCAPE
   22033              : #undef JSON_HEDLEY_NO_RETURN
   22034              : #undef JSON_HEDLEY_NO_THROW
   22035              : #undef JSON_HEDLEY_NULL
   22036              : #undef JSON_HEDLEY_PELLES_VERSION
   22037              : #undef JSON_HEDLEY_PELLES_VERSION_CHECK
   22038              : #undef JSON_HEDLEY_PGI_VERSION
   22039              : #undef JSON_HEDLEY_PGI_VERSION_CHECK
   22040              : #undef JSON_HEDLEY_PREDICT
   22041              : #undef JSON_HEDLEY_PRINTF_FORMAT
   22042              : #undef JSON_HEDLEY_PRIVATE
   22043              : #undef JSON_HEDLEY_PUBLIC
   22044              : #undef JSON_HEDLEY_PURE
   22045              : #undef JSON_HEDLEY_REINTERPRET_CAST
   22046              : #undef JSON_HEDLEY_REQUIRE
   22047              : #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
   22048              : #undef JSON_HEDLEY_REQUIRE_MSG
   22049              : #undef JSON_HEDLEY_RESTRICT
   22050              : #undef JSON_HEDLEY_RETURNS_NON_NULL
   22051              : #undef JSON_HEDLEY_SENTINEL
   22052              : #undef JSON_HEDLEY_STATIC_ASSERT
   22053              : #undef JSON_HEDLEY_STATIC_CAST
   22054              : #undef JSON_HEDLEY_STRINGIFY
   22055              : #undef JSON_HEDLEY_STRINGIFY_EX
   22056              : #undef JSON_HEDLEY_SUNPRO_VERSION
   22057              : #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
   22058              : #undef JSON_HEDLEY_TINYC_VERSION
   22059              : #undef JSON_HEDLEY_TINYC_VERSION_CHECK
   22060              : #undef JSON_HEDLEY_TI_ARMCL_VERSION
   22061              : #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
   22062              : #undef JSON_HEDLEY_TI_CL2000_VERSION
   22063              : #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
   22064              : #undef JSON_HEDLEY_TI_CL430_VERSION
   22065              : #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
   22066              : #undef JSON_HEDLEY_TI_CL6X_VERSION
   22067              : #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
   22068              : #undef JSON_HEDLEY_TI_CL7X_VERSION
   22069              : #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
   22070              : #undef JSON_HEDLEY_TI_CLPRU_VERSION
   22071              : #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
   22072              : #undef JSON_HEDLEY_TI_VERSION
   22073              : #undef JSON_HEDLEY_TI_VERSION_CHECK
   22074              : #undef JSON_HEDLEY_UNAVAILABLE
   22075              : #undef JSON_HEDLEY_UNLIKELY
   22076              : #undef JSON_HEDLEY_UNPREDICTABLE
   22077              : #undef JSON_HEDLEY_UNREACHABLE
   22078              : #undef JSON_HEDLEY_UNREACHABLE_RETURN
   22079              : #undef JSON_HEDLEY_VERSION
   22080              : #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
   22081              : #undef JSON_HEDLEY_VERSION_DECODE_MINOR
   22082              : #undef JSON_HEDLEY_VERSION_DECODE_REVISION
   22083              : #undef JSON_HEDLEY_VERSION_ENCODE
   22084              : #undef JSON_HEDLEY_WARNING
   22085              : #undef JSON_HEDLEY_WARN_UNUSED_RESULT
   22086              : #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
   22087              : #undef JSON_HEDLEY_FALL_THROUGH
   22088              : 
   22089              : 
   22090              : 
   22091              : #endif  // INCLUDE_NLOHMANN_JSON_HPP_
        

Generated by: LCOV version 2.0-1