git repos / blockattack-game

blame: source/code/Libs/include/nlohmann/json.hpp

normal view · raw

2660ccea Poul Sander 2023-09-22 19:25 1
/*
2660ccea Poul Sander 2023-09-22 19:25 2
    __ _____ _____ _____
2660ccea Poul Sander 2023-09-22 19:25 3
 __|  |   __|     |   | |  JSON for Modern C++
2660ccea Poul Sander 2023-09-22 19:25 4
|  |  |__   |  |  | | | |  version 3.7.3
2660ccea Poul Sander 2023-09-22 19:25 5
|_____|_____|_____|_|___|  https://github.com/nlohmann/json
2660ccea Poul Sander 2023-09-22 19:25 6
2660ccea Poul Sander 2023-09-22 19:25 7
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
2660ccea Poul Sander 2023-09-22 19:25 8
SPDX-License-Identifier: MIT
2660ccea Poul Sander 2023-09-22 19:25 9
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
2660ccea Poul Sander 2023-09-22 19:25 10
2660ccea Poul Sander 2023-09-22 19:25 11
Permission is hereby  granted, free of charge, to any  person obtaining a copy
2660ccea Poul Sander 2023-09-22 19:25 12
of this software and associated  documentation files (the "Software"), to deal
2660ccea Poul Sander 2023-09-22 19:25 13
in the Software  without restriction, including without  limitation the rights
2660ccea Poul Sander 2023-09-22 19:25 14
to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
2660ccea Poul Sander 2023-09-22 19:25 15
copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
2660ccea Poul Sander 2023-09-22 19:25 16
furnished to do so, subject to the following conditions:
2660ccea Poul Sander 2023-09-22 19:25 17
2660ccea Poul Sander 2023-09-22 19:25 18
The above copyright notice and this permission notice shall be included in all
2660ccea Poul Sander 2023-09-22 19:25 19
copies or substantial portions of the Software.
2660ccea Poul Sander 2023-09-22 19:25 20
2660ccea Poul Sander 2023-09-22 19:25 21
THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
2660ccea Poul Sander 2023-09-22 19:25 22
IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
2660ccea Poul Sander 2023-09-22 19:25 23
FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
2660ccea Poul Sander 2023-09-22 19:25 24
AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
2660ccea Poul Sander 2023-09-22 19:25 25
LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2660ccea Poul Sander 2023-09-22 19:25 26
OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
2660ccea Poul Sander 2023-09-22 19:25 27
SOFTWARE.
2660ccea Poul Sander 2023-09-22 19:25 28
*/
2660ccea Poul Sander 2023-09-22 19:25 29
2660ccea Poul Sander 2023-09-22 19:25 30
#ifndef INCLUDE_NLOHMANN_JSON_HPP_
2660ccea Poul Sander 2023-09-22 19:25 31
#define INCLUDE_NLOHMANN_JSON_HPP_
2660ccea Poul Sander 2023-09-22 19:25 32
2660ccea Poul Sander 2023-09-22 19:25 33
#define NLOHMANN_JSON_VERSION_MAJOR 3
2660ccea Poul Sander 2023-09-22 19:25 34
#define NLOHMANN_JSON_VERSION_MINOR 7
2660ccea Poul Sander 2023-09-22 19:25 35
#define NLOHMANN_JSON_VERSION_PATCH 3
2660ccea Poul Sander 2023-09-22 19:25 36
2660ccea Poul Sander 2023-09-22 19:25 37
#include <algorithm> // all_of, find, for_each
2660ccea Poul Sander 2023-09-22 19:25 38
#include <cassert> // assert
2660ccea Poul Sander 2023-09-22 19:25 39
#include <ciso646> // and, not, or
2660ccea Poul Sander 2023-09-22 19:25 40
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
2660ccea Poul Sander 2023-09-22 19:25 41
#include <functional> // hash, less
2660ccea Poul Sander 2023-09-22 19:25 42
#include <initializer_list> // initializer_list
2660ccea Poul Sander 2023-09-22 19:25 43
#include <iosfwd> // istream, ostream
2660ccea Poul Sander 2023-09-22 19:25 44
#include <iterator> // random_access_iterator_tag
2660ccea Poul Sander 2023-09-22 19:25 45
#include <memory> // unique_ptr
2660ccea Poul Sander 2023-09-22 19:25 46
#include <numeric> // accumulate
2660ccea Poul Sander 2023-09-22 19:25 47
#include <string> // string, stoi, to_string
2660ccea Poul Sander 2023-09-22 19:25 48
#include <utility> // declval, forward, move, pair, swap
2660ccea Poul Sander 2023-09-22 19:25 49
#include <vector> // vector
2660ccea Poul Sander 2023-09-22 19:25 50
2660ccea Poul Sander 2023-09-22 19:25 51
// #include <nlohmann/adl_serializer.hpp>
2660ccea Poul Sander 2023-09-22 19:25 52
2660ccea Poul Sander 2023-09-22 19:25 53
2660ccea Poul Sander 2023-09-22 19:25 54
#include <utility>
2660ccea Poul Sander 2023-09-22 19:25 55
2660ccea Poul Sander 2023-09-22 19:25 56
// #include <nlohmann/detail/conversions/from_json.hpp>
2660ccea Poul Sander 2023-09-22 19:25 57
2660ccea Poul Sander 2023-09-22 19:25 58
2660ccea Poul Sander 2023-09-22 19:25 59
#include <algorithm> // transform
2660ccea Poul Sander 2023-09-22 19:25 60
#include <array> // array
2660ccea Poul Sander 2023-09-22 19:25 61
#include <ciso646> // and, not
2660ccea Poul Sander 2023-09-22 19:25 62
#include <forward_list> // forward_list
2660ccea Poul Sander 2023-09-22 19:25 63
#include <iterator> // inserter, front_inserter, end
2660ccea Poul Sander 2023-09-22 19:25 64
#include <map> // map
2660ccea Poul Sander 2023-09-22 19:25 65
#include <string> // string
2660ccea Poul Sander 2023-09-22 19:25 66
#include <tuple> // tuple, make_tuple
2660ccea Poul Sander 2023-09-22 19:25 67
#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
2660ccea Poul Sander 2023-09-22 19:25 68
#include <unordered_map> // unordered_map
2660ccea Poul Sander 2023-09-22 19:25 69
#include <utility> // pair, declval
2660ccea Poul Sander 2023-09-22 19:25 70
#include <valarray> // valarray
2660ccea Poul Sander 2023-09-22 19:25 71
2660ccea Poul Sander 2023-09-22 19:25 72
// #include <nlohmann/detail/exceptions.hpp>
2660ccea Poul Sander 2023-09-22 19:25 73
2660ccea Poul Sander 2023-09-22 19:25 74
2660ccea Poul Sander 2023-09-22 19:25 75
#include <exception> // exception
2660ccea Poul Sander 2023-09-22 19:25 76
#include <stdexcept> // runtime_error
2660ccea Poul Sander 2023-09-22 19:25 77
#include <string> // to_string
2660ccea Poul Sander 2023-09-22 19:25 78
2660ccea Poul Sander 2023-09-22 19:25 79
// #include <nlohmann/detail/input/position_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 80
2660ccea Poul Sander 2023-09-22 19:25 81
2660ccea Poul Sander 2023-09-22 19:25 82
#include <cstddef> // size_t
2660ccea Poul Sander 2023-09-22 19:25 83
2660ccea Poul Sander 2023-09-22 19:25 84
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 85
{
2660ccea Poul Sander 2023-09-22 19:25 86
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 87
{
2660ccea Poul Sander 2023-09-22 19:25 88
/// struct to capture the start position of the current token
2660ccea Poul Sander 2023-09-22 19:25 89
struct position_t
2660ccea Poul Sander 2023-09-22 19:25 90
{
2660ccea Poul Sander 2023-09-22 19:25 91
    /// the total number of characters read
2660ccea Poul Sander 2023-09-22 19:25 92
    std::size_t chars_read_total = 0;
2660ccea Poul Sander 2023-09-22 19:25 93
    /// the number of characters read in the current line
2660ccea Poul Sander 2023-09-22 19:25 94
    std::size_t chars_read_current_line = 0;
2660ccea Poul Sander 2023-09-22 19:25 95
    /// the number of lines read
2660ccea Poul Sander 2023-09-22 19:25 96
    std::size_t lines_read = 0;
2660ccea Poul Sander 2023-09-22 19:25 97
2660ccea Poul Sander 2023-09-22 19:25 98
    /// conversion to size_t to preserve SAX interface
2660ccea Poul Sander 2023-09-22 19:25 99
    constexpr operator size_t() const
2660ccea Poul Sander 2023-09-22 19:25 100
    {
2660ccea Poul Sander 2023-09-22 19:25 101
        return chars_read_total;
2660ccea Poul Sander 2023-09-22 19:25 102
    }
2660ccea Poul Sander 2023-09-22 19:25 103
};
2660ccea Poul Sander 2023-09-22 19:25 104
2660ccea Poul Sander 2023-09-22 19:25 105
} // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 106
} // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 107
2660ccea Poul Sander 2023-09-22 19:25 108
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 109
2660ccea Poul Sander 2023-09-22 19:25 110
2660ccea Poul Sander 2023-09-22 19:25 111
#include <utility> // pair
2660ccea Poul Sander 2023-09-22 19:25 112
// #include <nlohmann/thirdparty/hedley/hedley.hpp>
2660ccea Poul Sander 2023-09-22 19:25 113
/* Hedley - https://nemequ.github.io/hedley
2660ccea Poul Sander 2023-09-22 19:25 114
 * Created by Evan Nemerson <evan@nemerson.com>
2660ccea Poul Sander 2023-09-22 19:25 115
 *
2660ccea Poul Sander 2023-09-22 19:25 116
 * To the extent possible under law, the author(s) have dedicated all
2660ccea Poul Sander 2023-09-22 19:25 117
 * copyright and related and neighboring rights to this software to
2660ccea Poul Sander 2023-09-22 19:25 118
 * the public domain worldwide. This software is distributed without
2660ccea Poul Sander 2023-09-22 19:25 119
 * any warranty.
2660ccea Poul Sander 2023-09-22 19:25 120
 *
2660ccea Poul Sander 2023-09-22 19:25 121
 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
2660ccea Poul Sander 2023-09-22 19:25 122
 * SPDX-License-Identifier: CC0-1.0
2660ccea Poul Sander 2023-09-22 19:25 123
 */
2660ccea Poul Sander 2023-09-22 19:25 124
2660ccea Poul Sander 2023-09-22 19:25 125
#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 11)
2660ccea Poul Sander 2023-09-22 19:25 126
#if defined(JSON_HEDLEY_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 127
    #undef JSON_HEDLEY_VERSION
2660ccea Poul Sander 2023-09-22 19:25 128
#endif
2660ccea Poul Sander 2023-09-22 19:25 129
#define JSON_HEDLEY_VERSION 11
2660ccea Poul Sander 2023-09-22 19:25 130
2660ccea Poul Sander 2023-09-22 19:25 131
#if defined(JSON_HEDLEY_STRINGIFY_EX)
2660ccea Poul Sander 2023-09-22 19:25 132
    #undef JSON_HEDLEY_STRINGIFY_EX
2660ccea Poul Sander 2023-09-22 19:25 133
#endif
2660ccea Poul Sander 2023-09-22 19:25 134
#define JSON_HEDLEY_STRINGIFY_EX(x) #x
2660ccea Poul Sander 2023-09-22 19:25 135
2660ccea Poul Sander 2023-09-22 19:25 136
#if defined(JSON_HEDLEY_STRINGIFY)
2660ccea Poul Sander 2023-09-22 19:25 137
    #undef JSON_HEDLEY_STRINGIFY
2660ccea Poul Sander 2023-09-22 19:25 138
#endif
2660ccea Poul Sander 2023-09-22 19:25 139
#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
2660ccea Poul Sander 2023-09-22 19:25 140
2660ccea Poul Sander 2023-09-22 19:25 141
#if defined(JSON_HEDLEY_CONCAT_EX)
2660ccea Poul Sander 2023-09-22 19:25 142
    #undef JSON_HEDLEY_CONCAT_EX
2660ccea Poul Sander 2023-09-22 19:25 143
#endif
2660ccea Poul Sander 2023-09-22 19:25 144
#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
2660ccea Poul Sander 2023-09-22 19:25 145
2660ccea Poul Sander 2023-09-22 19:25 146
#if defined(JSON_HEDLEY_CONCAT)
2660ccea Poul Sander 2023-09-22 19:25 147
    #undef JSON_HEDLEY_CONCAT
2660ccea Poul Sander 2023-09-22 19:25 148
#endif
2660ccea Poul Sander 2023-09-22 19:25 149
#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
2660ccea Poul Sander 2023-09-22 19:25 150
2660ccea Poul Sander 2023-09-22 19:25 151
#if defined(JSON_HEDLEY_VERSION_ENCODE)
2660ccea Poul Sander 2023-09-22 19:25 152
    #undef JSON_HEDLEY_VERSION_ENCODE
2660ccea Poul Sander 2023-09-22 19:25 153
#endif
2660ccea Poul Sander 2023-09-22 19:25 154
#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
2660ccea Poul Sander 2023-09-22 19:25 155
2660ccea Poul Sander 2023-09-22 19:25 156
#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
2660ccea Poul Sander 2023-09-22 19:25 157
    #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
2660ccea Poul Sander 2023-09-22 19:25 158
#endif
2660ccea Poul Sander 2023-09-22 19:25 159
#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
2660ccea Poul Sander 2023-09-22 19:25 160
2660ccea Poul Sander 2023-09-22 19:25 161
#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
2660ccea Poul Sander 2023-09-22 19:25 162
    #undef JSON_HEDLEY_VERSION_DECODE_MINOR
2660ccea Poul Sander 2023-09-22 19:25 163
#endif
2660ccea Poul Sander 2023-09-22 19:25 164
#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
2660ccea Poul Sander 2023-09-22 19:25 165
2660ccea Poul Sander 2023-09-22 19:25 166
#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
2660ccea Poul Sander 2023-09-22 19:25 167
    #undef JSON_HEDLEY_VERSION_DECODE_REVISION
2660ccea Poul Sander 2023-09-22 19:25 168
#endif
2660ccea Poul Sander 2023-09-22 19:25 169
#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
2660ccea Poul Sander 2023-09-22 19:25 170
2660ccea Poul Sander 2023-09-22 19:25 171
#if defined(JSON_HEDLEY_GNUC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 172
    #undef JSON_HEDLEY_GNUC_VERSION
2660ccea Poul Sander 2023-09-22 19:25 173
#endif
2660ccea Poul Sander 2023-09-22 19:25 174
#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
2660ccea Poul Sander 2023-09-22 19:25 175
    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
2660ccea Poul Sander 2023-09-22 19:25 176
#elif defined(__GNUC__)
2660ccea Poul Sander 2023-09-22 19:25 177
    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
2660ccea Poul Sander 2023-09-22 19:25 178
#endif
2660ccea Poul Sander 2023-09-22 19:25 179
2660ccea Poul Sander 2023-09-22 19:25 180
#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 181
    #undef JSON_HEDLEY_GNUC_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 182
#endif
2660ccea Poul Sander 2023-09-22 19:25 183
#if defined(JSON_HEDLEY_GNUC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 184
    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 185
#else
2660ccea Poul Sander 2023-09-22 19:25 186
    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 187
#endif
2660ccea Poul Sander 2023-09-22 19:25 188
2660ccea Poul Sander 2023-09-22 19:25 189
#if defined(JSON_HEDLEY_MSVC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 190
    #undef JSON_HEDLEY_MSVC_VERSION
2660ccea Poul Sander 2023-09-22 19:25 191
#endif
2660ccea Poul Sander 2023-09-22 19:25 192
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)
2660ccea Poul Sander 2023-09-22 19:25 193
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
2660ccea Poul Sander 2023-09-22 19:25 194
#elif defined(_MSC_FULL_VER)
2660ccea Poul Sander 2023-09-22 19:25 195
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
2660ccea Poul Sander 2023-09-22 19:25 196
#elif defined(_MSC_VER)
2660ccea Poul Sander 2023-09-22 19:25 197
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
2660ccea Poul Sander 2023-09-22 19:25 198
#endif
2660ccea Poul Sander 2023-09-22 19:25 199
2660ccea Poul Sander 2023-09-22 19:25 200
#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 201
    #undef JSON_HEDLEY_MSVC_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 202
#endif
2660ccea Poul Sander 2023-09-22 19:25 203
#if !defined(_MSC_VER)
2660ccea Poul Sander 2023-09-22 19:25 204
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 205
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
2660ccea Poul Sander 2023-09-22 19:25 206
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
2660ccea Poul Sander 2023-09-22 19:25 207
#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
2660ccea Poul Sander 2023-09-22 19:25 208
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
2660ccea Poul Sander 2023-09-22 19:25 209
#else
2660ccea Poul Sander 2023-09-22 19:25 210
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
2660ccea Poul Sander 2023-09-22 19:25 211
#endif
2660ccea Poul Sander 2023-09-22 19:25 212
2660ccea Poul Sander 2023-09-22 19:25 213
#if defined(JSON_HEDLEY_INTEL_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 214
    #undef JSON_HEDLEY_INTEL_VERSION
2660ccea Poul Sander 2023-09-22 19:25 215
#endif
2660ccea Poul Sander 2023-09-22 19:25 216
#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
2660ccea Poul Sander 2023-09-22 19:25 217
    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
2660ccea Poul Sander 2023-09-22 19:25 218
#elif defined(__INTEL_COMPILER)
2660ccea Poul Sander 2023-09-22 19:25 219
    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
2660ccea Poul Sander 2023-09-22 19:25 220
#endif
2660ccea Poul Sander 2023-09-22 19:25 221
2660ccea Poul Sander 2023-09-22 19:25 222
#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 223
    #undef JSON_HEDLEY_INTEL_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 224
#endif
2660ccea Poul Sander 2023-09-22 19:25 225
#if defined(JSON_HEDLEY_INTEL_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 226
    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 227
#else
2660ccea Poul Sander 2023-09-22 19:25 228
    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 229
#endif
2660ccea Poul Sander 2023-09-22 19:25 230
2660ccea Poul Sander 2023-09-22 19:25 231
#if defined(JSON_HEDLEY_PGI_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 232
    #undef JSON_HEDLEY_PGI_VERSION
2660ccea Poul Sander 2023-09-22 19:25 233
#endif
2660ccea Poul Sander 2023-09-22 19:25 234
#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
2660ccea Poul Sander 2023-09-22 19:25 235
    #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
2660ccea Poul Sander 2023-09-22 19:25 236
#endif
2660ccea Poul Sander 2023-09-22 19:25 237
2660ccea Poul Sander 2023-09-22 19:25 238
#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 239
    #undef JSON_HEDLEY_PGI_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 240
#endif
2660ccea Poul Sander 2023-09-22 19:25 241
#if defined(JSON_HEDLEY_PGI_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 242
    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 243
#else
2660ccea Poul Sander 2023-09-22 19:25 244
    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 245
#endif
2660ccea Poul Sander 2023-09-22 19:25 246
2660ccea Poul Sander 2023-09-22 19:25 247
#if defined(JSON_HEDLEY_SUNPRO_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 248
    #undef JSON_HEDLEY_SUNPRO_VERSION
2660ccea Poul Sander 2023-09-22 19:25 249
#endif
2660ccea Poul Sander 2023-09-22 19:25 250
#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
2660ccea Poul Sander 2023-09-22 19:25 251
    #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)
2660ccea Poul Sander 2023-09-22 19:25 252
#elif defined(__SUNPRO_C)
2660ccea Poul Sander 2023-09-22 19:25 253
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
2660ccea Poul Sander 2023-09-22 19:25 254
#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
2660ccea Poul Sander 2023-09-22 19:25 255
    #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)
2660ccea Poul Sander 2023-09-22 19:25 256
#elif defined(__SUNPRO_CC)
2660ccea Poul Sander 2023-09-22 19:25 257
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
2660ccea Poul Sander 2023-09-22 19:25 258
#endif
2660ccea Poul Sander 2023-09-22 19:25 259
2660ccea Poul Sander 2023-09-22 19:25 260
#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 261
    #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 262
#endif
2660ccea Poul Sander 2023-09-22 19:25 263
#if defined(JSON_HEDLEY_SUNPRO_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 264
    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 265
#else
2660ccea Poul Sander 2023-09-22 19:25 266
    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 267
#endif
2660ccea Poul Sander 2023-09-22 19:25 268
2660ccea Poul Sander 2023-09-22 19:25 269
#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 270
    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
2660ccea Poul Sander 2023-09-22 19:25 271
#endif
2660ccea Poul Sander 2023-09-22 19:25 272
#if defined(__EMSCRIPTEN__)
2660ccea Poul Sander 2023-09-22 19:25 273
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
2660ccea Poul Sander 2023-09-22 19:25 274
#endif
2660ccea Poul Sander 2023-09-22 19:25 275
2660ccea Poul Sander 2023-09-22 19:25 276
#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 277
    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 278
#endif
2660ccea Poul Sander 2023-09-22 19:25 279
#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 280
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 281
#else
2660ccea Poul Sander 2023-09-22 19:25 282
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 283
#endif
2660ccea Poul Sander 2023-09-22 19:25 284
2660ccea Poul Sander 2023-09-22 19:25 285
#if defined(JSON_HEDLEY_ARM_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 286
    #undef JSON_HEDLEY_ARM_VERSION
2660ccea Poul Sander 2023-09-22 19:25 287
#endif
2660ccea Poul Sander 2023-09-22 19:25 288
#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 289
    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
2660ccea Poul Sander 2023-09-22 19:25 290
#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 291
    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
2660ccea Poul Sander 2023-09-22 19:25 292
#endif
2660ccea Poul Sander 2023-09-22 19:25 293
2660ccea Poul Sander 2023-09-22 19:25 294
#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 295
    #undef JSON_HEDLEY_ARM_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 296
#endif
2660ccea Poul Sander 2023-09-22 19:25 297
#if defined(JSON_HEDLEY_ARM_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 298
    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 299
#else
2660ccea Poul Sander 2023-09-22 19:25 300
    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 301
#endif
2660ccea Poul Sander 2023-09-22 19:25 302
2660ccea Poul Sander 2023-09-22 19:25 303
#if defined(JSON_HEDLEY_IBM_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 304
    #undef JSON_HEDLEY_IBM_VERSION
2660ccea Poul Sander 2023-09-22 19:25 305
#endif
2660ccea Poul Sander 2023-09-22 19:25 306
#if defined(__ibmxl__)
2660ccea Poul Sander 2023-09-22 19:25 307
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
2660ccea Poul Sander 2023-09-22 19:25 308
#elif defined(__xlC__) && defined(__xlC_ver__)
2660ccea Poul Sander 2023-09-22 19:25 309
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
2660ccea Poul Sander 2023-09-22 19:25 310
#elif defined(__xlC__)
2660ccea Poul Sander 2023-09-22 19:25 311
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
2660ccea Poul Sander 2023-09-22 19:25 312
#endif
2660ccea Poul Sander 2023-09-22 19:25 313
2660ccea Poul Sander 2023-09-22 19:25 314
#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 315
    #undef JSON_HEDLEY_IBM_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 316
#endif
2660ccea Poul Sander 2023-09-22 19:25 317
#if defined(JSON_HEDLEY_IBM_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 318
    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 319
#else
2660ccea Poul Sander 2023-09-22 19:25 320
    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 321
#endif
2660ccea Poul Sander 2023-09-22 19:25 322
2660ccea Poul Sander 2023-09-22 19:25 323
#if defined(JSON_HEDLEY_TI_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 324
    #undef JSON_HEDLEY_TI_VERSION
2660ccea Poul Sander 2023-09-22 19:25 325
#endif
2660ccea Poul Sander 2023-09-22 19:25 326
#if defined(__TI_COMPILER_VERSION__)
2660ccea Poul Sander 2023-09-22 19:25 327
    #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
2660ccea Poul Sander 2023-09-22 19:25 328
#endif
2660ccea Poul Sander 2023-09-22 19:25 329
2660ccea Poul Sander 2023-09-22 19:25 330
#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 331
    #undef JSON_HEDLEY_TI_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 332
#endif
2660ccea Poul Sander 2023-09-22 19:25 333
#if defined(JSON_HEDLEY_TI_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 334
    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 335
#else
2660ccea Poul Sander 2023-09-22 19:25 336
    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 337
#endif
2660ccea Poul Sander 2023-09-22 19:25 338
2660ccea Poul Sander 2023-09-22 19:25 339
#if defined(JSON_HEDLEY_CRAY_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 340
    #undef JSON_HEDLEY_CRAY_VERSION
2660ccea Poul Sander 2023-09-22 19:25 341
#endif
2660ccea Poul Sander 2023-09-22 19:25 342
#if defined(_CRAYC)
2660ccea Poul Sander 2023-09-22 19:25 343
    #if defined(_RELEASE_PATCHLEVEL)
2660ccea Poul Sander 2023-09-22 19:25 344
        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
2660ccea Poul Sander 2023-09-22 19:25 345
    #else
2660ccea Poul Sander 2023-09-22 19:25 346
        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
2660ccea Poul Sander 2023-09-22 19:25 347
    #endif
2660ccea Poul Sander 2023-09-22 19:25 348
#endif
2660ccea Poul Sander 2023-09-22 19:25 349
2660ccea Poul Sander 2023-09-22 19:25 350
#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 351
    #undef JSON_HEDLEY_CRAY_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 352
#endif
2660ccea Poul Sander 2023-09-22 19:25 353
#if defined(JSON_HEDLEY_CRAY_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 354
    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 355
#else
2660ccea Poul Sander 2023-09-22 19:25 356
    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 357
#endif
2660ccea Poul Sander 2023-09-22 19:25 358
2660ccea Poul Sander 2023-09-22 19:25 359
#if defined(JSON_HEDLEY_IAR_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 360
    #undef JSON_HEDLEY_IAR_VERSION
2660ccea Poul Sander 2023-09-22 19:25 361
#endif
2660ccea Poul Sander 2023-09-22 19:25 362
#if defined(__IAR_SYSTEMS_ICC__)
2660ccea Poul Sander 2023-09-22 19:25 363
    #if __VER__ > 1000
2660ccea Poul Sander 2023-09-22 19:25 364
        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
2660ccea Poul Sander 2023-09-22 19:25 365
    #else
2660ccea Poul Sander 2023-09-22 19:25 366
        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
2660ccea Poul Sander 2023-09-22 19:25 367
    #endif
2660ccea Poul Sander 2023-09-22 19:25 368
#endif
2660ccea Poul Sander 2023-09-22 19:25 369
2660ccea Poul Sander 2023-09-22 19:25 370
#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 371
    #undef JSON_HEDLEY_IAR_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 372
#endif
2660ccea Poul Sander 2023-09-22 19:25 373
#if defined(JSON_HEDLEY_IAR_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 374
    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 375
#else
2660ccea Poul Sander 2023-09-22 19:25 376
    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 377
#endif
2660ccea Poul Sander 2023-09-22 19:25 378
2660ccea Poul Sander 2023-09-22 19:25 379
#if defined(JSON_HEDLEY_TINYC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 380
    #undef JSON_HEDLEY_TINYC_VERSION
2660ccea Poul Sander 2023-09-22 19:25 381
#endif
2660ccea Poul Sander 2023-09-22 19:25 382
#if defined(__TINYC__)
2660ccea Poul Sander 2023-09-22 19:25 383
    #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
2660ccea Poul Sander 2023-09-22 19:25 384
#endif
2660ccea Poul Sander 2023-09-22 19:25 385
2660ccea Poul Sander 2023-09-22 19:25 386
#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 387
    #undef JSON_HEDLEY_TINYC_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 388
#endif
2660ccea Poul Sander 2023-09-22 19:25 389
#if defined(JSON_HEDLEY_TINYC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 390
    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 391
#else
2660ccea Poul Sander 2023-09-22 19:25 392
    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 393
#endif
2660ccea Poul Sander 2023-09-22 19:25 394
2660ccea Poul Sander 2023-09-22 19:25 395
#if defined(JSON_HEDLEY_DMC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 396
    #undef JSON_HEDLEY_DMC_VERSION
2660ccea Poul Sander 2023-09-22 19:25 397
#endif
2660ccea Poul Sander 2023-09-22 19:25 398
#if defined(__DMC__)
2660ccea Poul Sander 2023-09-22 19:25 399
    #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
2660ccea Poul Sander 2023-09-22 19:25 400
#endif
2660ccea Poul Sander 2023-09-22 19:25 401
2660ccea Poul Sander 2023-09-22 19:25 402
#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 403
    #undef JSON_HEDLEY_DMC_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 404
#endif
2660ccea Poul Sander 2023-09-22 19:25 405
#if defined(JSON_HEDLEY_DMC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 406
    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 407
#else
2660ccea Poul Sander 2023-09-22 19:25 408
    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 409
#endif
2660ccea Poul Sander 2023-09-22 19:25 410
2660ccea Poul Sander 2023-09-22 19:25 411
#if defined(JSON_HEDLEY_COMPCERT_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 412
    #undef JSON_HEDLEY_COMPCERT_VERSION
2660ccea Poul Sander 2023-09-22 19:25 413
#endif
2660ccea Poul Sander 2023-09-22 19:25 414
#if defined(__COMPCERT_VERSION__)
2660ccea Poul Sander 2023-09-22 19:25 415
    #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
2660ccea Poul Sander 2023-09-22 19:25 416
#endif
2660ccea Poul Sander 2023-09-22 19:25 417
2660ccea Poul Sander 2023-09-22 19:25 418
#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 419
    #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 420
#endif
2660ccea Poul Sander 2023-09-22 19:25 421
#if defined(JSON_HEDLEY_COMPCERT_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 422
    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 423
#else
2660ccea Poul Sander 2023-09-22 19:25 424
    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 425
#endif
2660ccea Poul Sander 2023-09-22 19:25 426
2660ccea Poul Sander 2023-09-22 19:25 427
#if defined(JSON_HEDLEY_PELLES_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 428
    #undef JSON_HEDLEY_PELLES_VERSION
2660ccea Poul Sander 2023-09-22 19:25 429
#endif
2660ccea Poul Sander 2023-09-22 19:25 430
#if defined(__POCC__)
2660ccea Poul Sander 2023-09-22 19:25 431
    #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
2660ccea Poul Sander 2023-09-22 19:25 432
#endif
2660ccea Poul Sander 2023-09-22 19:25 433
2660ccea Poul Sander 2023-09-22 19:25 434
#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 435
    #undef JSON_HEDLEY_PELLES_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 436
#endif
2660ccea Poul Sander 2023-09-22 19:25 437
#if defined(JSON_HEDLEY_PELLES_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 438
    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 439
#else
2660ccea Poul Sander 2023-09-22 19:25 440
    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 441
#endif
2660ccea Poul Sander 2023-09-22 19:25 442
2660ccea Poul Sander 2023-09-22 19:25 443
#if defined(JSON_HEDLEY_GCC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 444
    #undef JSON_HEDLEY_GCC_VERSION
2660ccea Poul Sander 2023-09-22 19:25 445
#endif
2660ccea Poul Sander 2023-09-22 19:25 446
#if \
2660ccea Poul Sander 2023-09-22 19:25 447
    defined(JSON_HEDLEY_GNUC_VERSION) && \
2660ccea Poul Sander 2023-09-22 19:25 448
    !defined(__clang__) && \
2660ccea Poul Sander 2023-09-22 19:25 449
    !defined(JSON_HEDLEY_INTEL_VERSION) && \
2660ccea Poul Sander 2023-09-22 19:25 450
    !defined(JSON_HEDLEY_PGI_VERSION) && \
2660ccea Poul Sander 2023-09-22 19:25 451
    !defined(JSON_HEDLEY_ARM_VERSION) && \
2660ccea Poul Sander 2023-09-22 19:25 452
    !defined(JSON_HEDLEY_TI_VERSION) && \
2660ccea Poul Sander 2023-09-22 19:25 453
    !defined(__COMPCERT__)
2660ccea Poul Sander 2023-09-22 19:25 454
    #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
2660ccea Poul Sander 2023-09-22 19:25 455
#endif
2660ccea Poul Sander 2023-09-22 19:25 456
2660ccea Poul Sander 2023-09-22 19:25 457
#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 458
    #undef JSON_HEDLEY_GCC_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 459
#endif
2660ccea Poul Sander 2023-09-22 19:25 460
#if defined(JSON_HEDLEY_GCC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 461
    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
2660ccea Poul Sander 2023-09-22 19:25 462
#else
2660ccea Poul Sander 2023-09-22 19:25 463
    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 464
#endif
2660ccea Poul Sander 2023-09-22 19:25 465
2660ccea Poul Sander 2023-09-22 19:25 466
#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 467
    #undef JSON_HEDLEY_HAS_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 468
#endif
2660ccea Poul Sander 2023-09-22 19:25 469
#if defined(__has_attribute)
2660ccea Poul Sander 2023-09-22 19:25 470
    #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
2660ccea Poul Sander 2023-09-22 19:25 471
#else
2660ccea Poul Sander 2023-09-22 19:25 472
    #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
2660ccea Poul Sander 2023-09-22 19:25 473
#endif
2660ccea Poul Sander 2023-09-22 19:25 474
2660ccea Poul Sander 2023-09-22 19:25 475
#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 476
    #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 477
#endif
2660ccea Poul Sander 2023-09-22 19:25 478
#if defined(__has_attribute)
2660ccea Poul Sander 2023-09-22 19:25 479
    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
2660ccea Poul Sander 2023-09-22 19:25 480
#else
2660ccea Poul Sander 2023-09-22 19:25 481
    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 482
#endif
2660ccea Poul Sander 2023-09-22 19:25 483
2660ccea Poul Sander 2023-09-22 19:25 484
#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 485
    #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 486
#endif
2660ccea Poul Sander 2023-09-22 19:25 487
#if defined(__has_attribute)
2660ccea Poul Sander 2023-09-22 19:25 488
    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
2660ccea Poul Sander 2023-09-22 19:25 489
#else
2660ccea Poul Sander 2023-09-22 19:25 490
    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 491
#endif
2660ccea Poul Sander 2023-09-22 19:25 492
2660ccea Poul Sander 2023-09-22 19:25 493
#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 494
    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 495
#endif
2660ccea Poul Sander 2023-09-22 19:25 496
#if \
2660ccea Poul Sander 2023-09-22 19:25 497
    defined(__has_cpp_attribute) && \
2660ccea Poul Sander 2023-09-22 19:25 498
    defined(__cplusplus) && \
2660ccea Poul Sander 2023-09-22 19:25 499
    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
2660ccea Poul Sander 2023-09-22 19:25 500
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
2660ccea Poul Sander 2023-09-22 19:25 501
#else
2660ccea Poul Sander 2023-09-22 19:25 502
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
2660ccea Poul Sander 2023-09-22 19:25 503
#endif
2660ccea Poul Sander 2023-09-22 19:25 504
2660ccea Poul Sander 2023-09-22 19:25 505
#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
2660ccea Poul Sander 2023-09-22 19:25 506
    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
2660ccea Poul Sander 2023-09-22 19:25 507
#endif
2660ccea Poul Sander 2023-09-22 19:25 508
#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
2660ccea Poul Sander 2023-09-22 19:25 509
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
2660ccea Poul Sander 2023-09-22 19:25 510
#elif \
2660ccea Poul Sander 2023-09-22 19:25 511
    !defined(JSON_HEDLEY_PGI_VERSION) && \
2660ccea Poul Sander 2023-09-22 19:25 512
    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
2660ccea Poul Sander 2023-09-22 19:25 513
    (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
2660ccea Poul Sander 2023-09-22 19:25 514
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
2660ccea Poul Sander 2023-09-22 19:25 515
#else
2660ccea Poul Sander 2023-09-22 19:25 516
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
2660ccea Poul Sander 2023-09-22 19:25 517
#endif
2660ccea Poul Sander 2023-09-22 19:25 518
2660ccea Poul Sander 2023-09-22 19:25 519
#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 520
    #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 521
#endif
2660ccea Poul Sander 2023-09-22 19:25 522
#if defined(__has_cpp_attribute) && defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 523
    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
2660ccea Poul Sander 2023-09-22 19:25 524
#else
2660ccea Poul Sander 2023-09-22 19:25 525
    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 526
#endif
2660ccea Poul Sander 2023-09-22 19:25 527
2660ccea Poul Sander 2023-09-22 19:25 528
#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 529
    #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 530
#endif
2660ccea Poul Sander 2023-09-22 19:25 531
#if defined(__has_cpp_attribute) && defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 532
    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
2660ccea Poul Sander 2023-09-22 19:25 533
#else
2660ccea Poul Sander 2023-09-22 19:25 534
    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 535
#endif
2660ccea Poul Sander 2023-09-22 19:25 536
2660ccea Poul Sander 2023-09-22 19:25 537
#if defined(JSON_HEDLEY_HAS_BUILTIN)
2660ccea Poul Sander 2023-09-22 19:25 538
    #undef JSON_HEDLEY_HAS_BUILTIN
2660ccea Poul Sander 2023-09-22 19:25 539
#endif
2660ccea Poul Sander 2023-09-22 19:25 540
#if defined(__has_builtin)
2660ccea Poul Sander 2023-09-22 19:25 541
    #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
2660ccea Poul Sander 2023-09-22 19:25 542
#else
2660ccea Poul Sander 2023-09-22 19:25 543
    #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
2660ccea Poul Sander 2023-09-22 19:25 544
#endif
2660ccea Poul Sander 2023-09-22 19:25 545
2660ccea Poul Sander 2023-09-22 19:25 546
#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
2660ccea Poul Sander 2023-09-22 19:25 547
    #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
2660ccea Poul Sander 2023-09-22 19:25 548
#endif
2660ccea Poul Sander 2023-09-22 19:25 549
#if defined(__has_builtin)
2660ccea Poul Sander 2023-09-22 19:25 550
    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
2660ccea Poul Sander 2023-09-22 19:25 551
#else
2660ccea Poul Sander 2023-09-22 19:25 552
    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 553
#endif
2660ccea Poul Sander 2023-09-22 19:25 554
2660ccea Poul Sander 2023-09-22 19:25 555
#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
2660ccea Poul Sander 2023-09-22 19:25 556
    #undef JSON_HEDLEY_GCC_HAS_BUILTIN
2660ccea Poul Sander 2023-09-22 19:25 557
#endif
2660ccea Poul Sander 2023-09-22 19:25 558
#if defined(__has_builtin)
2660ccea Poul Sander 2023-09-22 19:25 559
    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
2660ccea Poul Sander 2023-09-22 19:25 560
#else
2660ccea Poul Sander 2023-09-22 19:25 561
    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 562
#endif
2660ccea Poul Sander 2023-09-22 19:25 563
2660ccea Poul Sander 2023-09-22 19:25 564
#if defined(JSON_HEDLEY_HAS_FEATURE)
2660ccea Poul Sander 2023-09-22 19:25 565
    #undef JSON_HEDLEY_HAS_FEATURE
2660ccea Poul Sander 2023-09-22 19:25 566
#endif
2660ccea Poul Sander 2023-09-22 19:25 567
#if defined(__has_feature)
2660ccea Poul Sander 2023-09-22 19:25 568
    #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
2660ccea Poul Sander 2023-09-22 19:25 569
#else
2660ccea Poul Sander 2023-09-22 19:25 570
    #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
2660ccea Poul Sander 2023-09-22 19:25 571
#endif
2660ccea Poul Sander 2023-09-22 19:25 572
2660ccea Poul Sander 2023-09-22 19:25 573
#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
2660ccea Poul Sander 2023-09-22 19:25 574
    #undef JSON_HEDLEY_GNUC_HAS_FEATURE
2660ccea Poul Sander 2023-09-22 19:25 575
#endif
2660ccea Poul Sander 2023-09-22 19:25 576
#if defined(__has_feature)
2660ccea Poul Sander 2023-09-22 19:25 577
    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
2660ccea Poul Sander 2023-09-22 19:25 578
#else
2660ccea Poul Sander 2023-09-22 19:25 579
    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 580
#endif
2660ccea Poul Sander 2023-09-22 19:25 581
2660ccea Poul Sander 2023-09-22 19:25 582
#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
2660ccea Poul Sander 2023-09-22 19:25 583
    #undef JSON_HEDLEY_GCC_HAS_FEATURE
2660ccea Poul Sander 2023-09-22 19:25 584
#endif
2660ccea Poul Sander 2023-09-22 19:25 585
#if defined(__has_feature)
2660ccea Poul Sander 2023-09-22 19:25 586
    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
2660ccea Poul Sander 2023-09-22 19:25 587
#else
2660ccea Poul Sander 2023-09-22 19:25 588
    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 589
#endif
2660ccea Poul Sander 2023-09-22 19:25 590
2660ccea Poul Sander 2023-09-22 19:25 591
#if defined(JSON_HEDLEY_HAS_EXTENSION)
2660ccea Poul Sander 2023-09-22 19:25 592
    #undef JSON_HEDLEY_HAS_EXTENSION
2660ccea Poul Sander 2023-09-22 19:25 593
#endif
2660ccea Poul Sander 2023-09-22 19:25 594
#if defined(__has_extension)
2660ccea Poul Sander 2023-09-22 19:25 595
    #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
2660ccea Poul Sander 2023-09-22 19:25 596
#else
2660ccea Poul Sander 2023-09-22 19:25 597
    #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
2660ccea Poul Sander 2023-09-22 19:25 598
#endif
2660ccea Poul Sander 2023-09-22 19:25 599
2660ccea Poul Sander 2023-09-22 19:25 600
#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
2660ccea Poul Sander 2023-09-22 19:25 601
    #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
2660ccea Poul Sander 2023-09-22 19:25 602
#endif
2660ccea Poul Sander 2023-09-22 19:25 603
#if defined(__has_extension)
2660ccea Poul Sander 2023-09-22 19:25 604
    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
2660ccea Poul Sander 2023-09-22 19:25 605
#else
2660ccea Poul Sander 2023-09-22 19:25 606
    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 607
#endif
2660ccea Poul Sander 2023-09-22 19:25 608
2660ccea Poul Sander 2023-09-22 19:25 609
#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
2660ccea Poul Sander 2023-09-22 19:25 610
    #undef JSON_HEDLEY_GCC_HAS_EXTENSION
2660ccea Poul Sander 2023-09-22 19:25 611
#endif
2660ccea Poul Sander 2023-09-22 19:25 612
#if defined(__has_extension)
2660ccea Poul Sander 2023-09-22 19:25 613
    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
2660ccea Poul Sander 2023-09-22 19:25 614
#else
2660ccea Poul Sander 2023-09-22 19:25 615
    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 616
#endif
2660ccea Poul Sander 2023-09-22 19:25 617
2660ccea Poul Sander 2023-09-22 19:25 618
#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 619
    #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 620
#endif
2660ccea Poul Sander 2023-09-22 19:25 621
#if defined(__has_declspec_attribute)
2660ccea Poul Sander 2023-09-22 19:25 622
    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
2660ccea Poul Sander 2023-09-22 19:25 623
#else
2660ccea Poul Sander 2023-09-22 19:25 624
    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
2660ccea Poul Sander 2023-09-22 19:25 625
#endif
2660ccea Poul Sander 2023-09-22 19:25 626
2660ccea Poul Sander 2023-09-22 19:25 627
#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 628
    #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 629
#endif
2660ccea Poul Sander 2023-09-22 19:25 630
#if defined(__has_declspec_attribute)
2660ccea Poul Sander 2023-09-22 19:25 631
    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
2660ccea Poul Sander 2023-09-22 19:25 632
#else
2660ccea Poul Sander 2023-09-22 19:25 633
    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 634
#endif
2660ccea Poul Sander 2023-09-22 19:25 635
2660ccea Poul Sander 2023-09-22 19:25 636
#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 637
    #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 638
#endif
2660ccea Poul Sander 2023-09-22 19:25 639
#if defined(__has_declspec_attribute)
2660ccea Poul Sander 2023-09-22 19:25 640
    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
2660ccea Poul Sander 2023-09-22 19:25 641
#else
2660ccea Poul Sander 2023-09-22 19:25 642
    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 643
#endif
2660ccea Poul Sander 2023-09-22 19:25 644
2660ccea Poul Sander 2023-09-22 19:25 645
#if defined(JSON_HEDLEY_HAS_WARNING)
2660ccea Poul Sander 2023-09-22 19:25 646
    #undef JSON_HEDLEY_HAS_WARNING
2660ccea Poul Sander 2023-09-22 19:25 647
#endif
2660ccea Poul Sander 2023-09-22 19:25 648
#if defined(__has_warning)
2660ccea Poul Sander 2023-09-22 19:25 649
    #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
2660ccea Poul Sander 2023-09-22 19:25 650
#else
2660ccea Poul Sander 2023-09-22 19:25 651
    #define JSON_HEDLEY_HAS_WARNING(warning) (0)
2660ccea Poul Sander 2023-09-22 19:25 652
#endif
2660ccea Poul Sander 2023-09-22 19:25 653
2660ccea Poul Sander 2023-09-22 19:25 654
#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
2660ccea Poul Sander 2023-09-22 19:25 655
    #undef JSON_HEDLEY_GNUC_HAS_WARNING
2660ccea Poul Sander 2023-09-22 19:25 656
#endif
2660ccea Poul Sander 2023-09-22 19:25 657
#if defined(__has_warning)
2660ccea Poul Sander 2023-09-22 19:25 658
    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
2660ccea Poul Sander 2023-09-22 19:25 659
#else
2660ccea Poul Sander 2023-09-22 19:25 660
    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 661
#endif
2660ccea Poul Sander 2023-09-22 19:25 662
2660ccea Poul Sander 2023-09-22 19:25 663
#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
2660ccea Poul Sander 2023-09-22 19:25 664
    #undef JSON_HEDLEY_GCC_HAS_WARNING
2660ccea Poul Sander 2023-09-22 19:25 665
#endif
2660ccea Poul Sander 2023-09-22 19:25 666
#if defined(__has_warning)
2660ccea Poul Sander 2023-09-22 19:25 667
    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
2660ccea Poul Sander 2023-09-22 19:25 668
#else
2660ccea Poul Sander 2023-09-22 19:25 669
    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 670
#endif
2660ccea Poul Sander 2023-09-22 19:25 671
2660ccea Poul Sander 2023-09-22 19:25 672
/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
2660ccea Poul Sander 2023-09-22 19:25 673
   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
2660ccea Poul Sander 2023-09-22 19:25 674
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
2660ccea Poul Sander 2023-09-22 19:25 675
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
2660ccea Poul Sander 2023-09-22 19:25 676
#endif
2660ccea Poul Sander 2023-09-22 19:25 677
#if defined(__cplusplus) && JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
2660ccea Poul Sander 2023-09-22 19:25 678
#  define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
2660ccea Poul Sander 2023-09-22 19:25 679
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
2660ccea Poul Sander 2023-09-22 19:25 680
    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
2660ccea Poul Sander 2023-09-22 19:25 681
    xpr \
2660ccea Poul Sander 2023-09-22 19:25 682
    JSON_HEDLEY_DIAGNOSTIC_POP
2660ccea Poul Sander 2023-09-22 19:25 683
#else
2660ccea Poul Sander 2023-09-22 19:25 684
#  define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
2660ccea Poul Sander 2023-09-22 19:25 685
#endif
2660ccea Poul Sander 2023-09-22 19:25 686
2660ccea Poul Sander 2023-09-22 19:25 687
#if \
2660ccea Poul Sander 2023-09-22 19:25 688
    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
2660ccea Poul Sander 2023-09-22 19:25 689
    defined(__clang__) || \
2660ccea Poul Sander 2023-09-22 19:25 690
    JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 691
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 692
    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 693
    JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2660ccea Poul Sander 2023-09-22 19:25 694
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 695
    JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 696
    JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 697
    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
2660ccea Poul Sander 2023-09-22 19:25 698
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 699
    (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
2660ccea Poul Sander 2023-09-22 19:25 700
    #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
2660ccea Poul Sander 2023-09-22 19:25 701
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
2660ccea Poul Sander 2023-09-22 19:25 702
    #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
2660ccea Poul Sander 2023-09-22 19:25 703
#else
2660ccea Poul Sander 2023-09-22 19:25 704
    #define JSON_HEDLEY_PRAGMA(value)
2660ccea Poul Sander 2023-09-22 19:25 705
#endif
2660ccea Poul Sander 2023-09-22 19:25 706
2660ccea Poul Sander 2023-09-22 19:25 707
#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
2660ccea Poul Sander 2023-09-22 19:25 708
    #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
2660ccea Poul Sander 2023-09-22 19:25 709
#endif
2660ccea Poul Sander 2023-09-22 19:25 710
#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
2660ccea Poul Sander 2023-09-22 19:25 711
    #undef JSON_HEDLEY_DIAGNOSTIC_POP
2660ccea Poul Sander 2023-09-22 19:25 712
#endif
2660ccea Poul Sander 2023-09-22 19:25 713
#if defined(__clang__)
2660ccea Poul Sander 2023-09-22 19:25 714
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
2660ccea Poul Sander 2023-09-22 19:25 715
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
2660ccea Poul Sander 2023-09-22 19:25 716
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2660ccea Poul Sander 2023-09-22 19:25 717
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
2660ccea Poul Sander 2023-09-22 19:25 718
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
2660ccea Poul Sander 2023-09-22 19:25 719
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
2660ccea Poul Sander 2023-09-22 19:25 720
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
2660ccea Poul Sander 2023-09-22 19:25 721
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
2660ccea Poul Sander 2023-09-22 19:25 722
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
2660ccea Poul Sander 2023-09-22 19:25 723
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
2660ccea Poul Sander 2023-09-22 19:25 724
    #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
2660ccea Poul Sander 2023-09-22 19:25 725
#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
2660ccea Poul Sander 2023-09-22 19:25 726
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
2660ccea Poul Sander 2023-09-22 19:25 727
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
2660ccea Poul Sander 2023-09-22 19:25 728
#elif JSON_HEDLEY_TI_VERSION_CHECK(8,1,0)
2660ccea Poul Sander 2023-09-22 19:25 729
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
2660ccea Poul Sander 2023-09-22 19:25 730
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
2660ccea Poul Sander 2023-09-22 19:25 731
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
2660ccea Poul Sander 2023-09-22 19:25 732
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
2660ccea Poul Sander 2023-09-22 19:25 733
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
2660ccea Poul Sander 2023-09-22 19:25 734
#else
2660ccea Poul Sander 2023-09-22 19:25 735
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH
2660ccea Poul Sander 2023-09-22 19:25 736
    #define JSON_HEDLEY_DIAGNOSTIC_POP
2660ccea Poul Sander 2023-09-22 19:25 737
#endif
2660ccea Poul Sander 2023-09-22 19:25 738
2660ccea Poul Sander 2023-09-22 19:25 739
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
2660ccea Poul Sander 2023-09-22 19:25 740
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
2660ccea Poul Sander 2023-09-22 19:25 741
#endif
2660ccea Poul Sander 2023-09-22 19:25 742
#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
2660ccea Poul Sander 2023-09-22 19:25 743
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
2660ccea Poul Sander 2023-09-22 19:25 744
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2660ccea Poul Sander 2023-09-22 19:25 745
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
2660ccea Poul Sander 2023-09-22 19:25 746
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
2660ccea Poul Sander 2023-09-22 19:25 747
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
2660ccea Poul Sander 2023-09-22 19:25 748
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
2660ccea Poul Sander 2023-09-22 19:25 749
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
2660ccea Poul Sander 2023-09-22 19:25 750
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
2660ccea Poul Sander 2023-09-22 19:25 751
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
2660ccea Poul Sander 2023-09-22 19:25 752
#elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0)
2660ccea Poul Sander 2023-09-22 19:25 753
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
2660ccea Poul Sander 2023-09-22 19:25 754
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 755
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
2660ccea Poul Sander 2023-09-22 19:25 756
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 757
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
2660ccea Poul Sander 2023-09-22 19:25 758
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2660ccea Poul Sander 2023-09-22 19:25 759
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
2660ccea Poul Sander 2023-09-22 19:25 760
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
2660ccea Poul Sander 2023-09-22 19:25 761
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
2660ccea Poul Sander 2023-09-22 19:25 762
#else
2660ccea Poul Sander 2023-09-22 19:25 763
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
2660ccea Poul Sander 2023-09-22 19:25 764
#endif
2660ccea Poul Sander 2023-09-22 19:25 765
2660ccea Poul Sander 2023-09-22 19:25 766
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
2660ccea Poul Sander 2023-09-22 19:25 767
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
2660ccea Poul Sander 2023-09-22 19:25 768
#endif
2660ccea Poul Sander 2023-09-22 19:25 769
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2660ccea Poul Sander 2023-09-22 19:25 770
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
2660ccea Poul Sander 2023-09-22 19:25 771
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2660ccea Poul Sander 2023-09-22 19:25 772
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
2660ccea Poul Sander 2023-09-22 19:25 773
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
2660ccea Poul Sander 2023-09-22 19:25 774
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
2660ccea Poul Sander 2023-09-22 19:25 775
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
2660ccea Poul Sander 2023-09-22 19:25 776
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
2660ccea Poul Sander 2023-09-22 19:25 777
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
2660ccea Poul Sander 2023-09-22 19:25 778
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
2660ccea Poul Sander 2023-09-22 19:25 779
#elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0)
2660ccea Poul Sander 2023-09-22 19:25 780
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
2660ccea Poul Sander 2023-09-22 19:25 781
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2660ccea Poul Sander 2023-09-22 19:25 782
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
2660ccea Poul Sander 2023-09-22 19:25 783
#else
2660ccea Poul Sander 2023-09-22 19:25 784
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
2660ccea Poul Sander 2023-09-22 19:25 785
#endif
2660ccea Poul Sander 2023-09-22 19:25 786
2660ccea Poul Sander 2023-09-22 19:25 787
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
2660ccea Poul Sander 2023-09-22 19:25 788
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
2660ccea Poul Sander 2023-09-22 19:25 789
#endif
2660ccea Poul Sander 2023-09-22 19:25 790
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
2660ccea Poul Sander 2023-09-22 19:25 791
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
2660ccea Poul Sander 2023-09-22 19:25 792
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
2660ccea Poul Sander 2023-09-22 19:25 793
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
2660ccea Poul Sander 2023-09-22 19:25 794
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
2660ccea Poul Sander 2023-09-22 19:25 795
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
2660ccea Poul Sander 2023-09-22 19:25 796
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
2660ccea Poul Sander 2023-09-22 19:25 797
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
2660ccea Poul Sander 2023-09-22 19:25 798
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
2660ccea Poul Sander 2023-09-22 19:25 799
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
2660ccea Poul Sander 2023-09-22 19:25 800
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 801
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
2660ccea Poul Sander 2023-09-22 19:25 802
#elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0)
2660ccea Poul Sander 2023-09-22 19:25 803
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
2660ccea Poul Sander 2023-09-22 19:25 804
#else
2660ccea Poul Sander 2023-09-22 19:25 805
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
2660ccea Poul Sander 2023-09-22 19:25 806
#endif
2660ccea Poul Sander 2023-09-22 19:25 807
2660ccea Poul Sander 2023-09-22 19:25 808
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
2660ccea Poul Sander 2023-09-22 19:25 809
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
2660ccea Poul Sander 2023-09-22 19:25 810
#endif
2660ccea Poul Sander 2023-09-22 19:25 811
#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
2660ccea Poul Sander 2023-09-22 19:25 812
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
2660ccea Poul Sander 2023-09-22 19:25 813
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2660ccea Poul Sander 2023-09-22 19:25 814
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
2660ccea Poul Sander 2023-09-22 19:25 815
#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
2660ccea Poul Sander 2023-09-22 19:25 816
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
2660ccea Poul Sander 2023-09-22 19:25 817
#else
2660ccea Poul Sander 2023-09-22 19:25 818
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
2660ccea Poul Sander 2023-09-22 19:25 819
#endif
2660ccea Poul Sander 2023-09-22 19:25 820
2660ccea Poul Sander 2023-09-22 19:25 821
#if defined(JSON_HEDLEY_DEPRECATED)
2660ccea Poul Sander 2023-09-22 19:25 822
    #undef JSON_HEDLEY_DEPRECATED
2660ccea Poul Sander 2023-09-22 19:25 823
#endif
2660ccea Poul Sander 2023-09-22 19:25 824
#if defined(JSON_HEDLEY_DEPRECATED_FOR)
2660ccea Poul Sander 2023-09-22 19:25 825
    #undef JSON_HEDLEY_DEPRECATED_FOR
2660ccea Poul Sander 2023-09-22 19:25 826
#endif
2660ccea Poul Sander 2023-09-22 19:25 827
#if defined(__cplusplus) && (__cplusplus >= 201402L)
2660ccea Poul Sander 2023-09-22 19:25 828
    #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
2660ccea Poul Sander 2023-09-22 19:25 829
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
2660ccea Poul Sander 2023-09-22 19:25 830
#elif \
2660ccea Poul Sander 2023-09-22 19:25 831
    JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
2660ccea Poul Sander 2023-09-22 19:25 832
    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
2660ccea Poul Sander 2023-09-22 19:25 833
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 834
    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
2660ccea Poul Sander 2023-09-22 19:25 835
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
2660ccea Poul Sander 2023-09-22 19:25 836
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
2660ccea Poul Sander 2023-09-22 19:25 837
    JSON_HEDLEY_TI_VERSION_CHECK(8,3,0)
2660ccea Poul Sander 2023-09-22 19:25 838
    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
2660ccea Poul Sander 2023-09-22 19:25 839
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
2660ccea Poul Sander 2023-09-22 19:25 840
#elif \
2660ccea Poul Sander 2023-09-22 19:25 841
    JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
2660ccea Poul Sander 2023-09-22 19:25 842
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 843
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 844
    JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 845
    (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
2660ccea Poul Sander 2023-09-22 19:25 846
    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
2660ccea Poul Sander 2023-09-22 19:25 847
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
2660ccea Poul Sander 2023-09-22 19:25 848
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0)
2660ccea Poul Sander 2023-09-22 19:25 849
    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
2660ccea Poul Sander 2023-09-22 19:25 850
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
2660ccea Poul Sander 2023-09-22 19:25 851
#elif \
2660ccea Poul Sander 2023-09-22 19:25 852
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
2660ccea Poul Sander 2023-09-22 19:25 853
    JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0)
2660ccea Poul Sander 2023-09-22 19:25 854
    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
2660ccea Poul Sander 2023-09-22 19:25 855
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
2660ccea Poul Sander 2023-09-22 19:25 856
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2660ccea Poul Sander 2023-09-22 19:25 857
    #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
2660ccea Poul Sander 2023-09-22 19:25 858
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
2660ccea Poul Sander 2023-09-22 19:25 859
#else
2660ccea Poul Sander 2023-09-22 19:25 860
    #define JSON_HEDLEY_DEPRECATED(since)
2660ccea Poul Sander 2023-09-22 19:25 861
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
2660ccea Poul Sander 2023-09-22 19:25 862
#endif
2660ccea Poul Sander 2023-09-22 19:25 863
2660ccea Poul Sander 2023-09-22 19:25 864
#if defined(JSON_HEDLEY_UNAVAILABLE)
2660ccea Poul Sander 2023-09-22 19:25 865
    #undef JSON_HEDLEY_UNAVAILABLE
2660ccea Poul Sander 2023-09-22 19:25 866
#endif
2660ccea Poul Sander 2023-09-22 19:25 867
#if \
2660ccea Poul Sander 2023-09-22 19:25 868
    JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
2660ccea Poul Sander 2023-09-22 19:25 869
    JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
2660ccea Poul Sander 2023-09-22 19:25 870
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2660ccea Poul Sander 2023-09-22 19:25 871
    #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
2660ccea Poul Sander 2023-09-22 19:25 872
#else
2660ccea Poul Sander 2023-09-22 19:25 873
    #define JSON_HEDLEY_UNAVAILABLE(available_since)
2660ccea Poul Sander 2023-09-22 19:25 874
#endif
2660ccea Poul Sander 2023-09-22 19:25 875
2660ccea Poul Sander 2023-09-22 19:25 876
#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
2660ccea Poul Sander 2023-09-22 19:25 877
    #undef JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 878
#endif
2660ccea Poul Sander 2023-09-22 19:25 879
#if defined(__cplusplus) && (__cplusplus >= 201703L)
2660ccea Poul Sander 2023-09-22 19:25 880
    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
2660ccea Poul Sander 2023-09-22 19:25 881
#elif \
2660ccea Poul Sander 2023-09-22 19:25 882
    JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
2660ccea Poul Sander 2023-09-22 19:25 883
    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2660ccea Poul Sander 2023-09-22 19:25 884
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 885
    JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 886
    (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
2660ccea Poul Sander 2023-09-22 19:25 887
    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
2660ccea Poul Sander 2023-09-22 19:25 888
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
2660ccea Poul Sander 2023-09-22 19:25 889
    #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
2660ccea Poul Sander 2023-09-22 19:25 890
#elif defined(_Check_return_) /* SAL */
2660ccea Poul Sander 2023-09-22 19:25 891
    #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
2660ccea Poul Sander 2023-09-22 19:25 892
#else
2660ccea Poul Sander 2023-09-22 19:25 893
    #define JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 894
#endif
2660ccea Poul Sander 2023-09-22 19:25 895
2660ccea Poul Sander 2023-09-22 19:25 896
#if defined(JSON_HEDLEY_SENTINEL)
2660ccea Poul Sander 2023-09-22 19:25 897
    #undef JSON_HEDLEY_SENTINEL
2660ccea Poul Sander 2023-09-22 19:25 898
#endif
2660ccea Poul Sander 2023-09-22 19:25 899
#if \
2660ccea Poul Sander 2023-09-22 19:25 900
    JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
2660ccea Poul Sander 2023-09-22 19:25 901
    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 902
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 903
    JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
2660ccea Poul Sander 2023-09-22 19:25 904
    #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
2660ccea Poul Sander 2023-09-22 19:25 905
#else
2660ccea Poul Sander 2023-09-22 19:25 906
    #define JSON_HEDLEY_SENTINEL(position)
2660ccea Poul Sander 2023-09-22 19:25 907
#endif
2660ccea Poul Sander 2023-09-22 19:25 908
2660ccea Poul Sander 2023-09-22 19:25 909
#if defined(JSON_HEDLEY_NO_RETURN)
2660ccea Poul Sander 2023-09-22 19:25 910
    #undef JSON_HEDLEY_NO_RETURN
2660ccea Poul Sander 2023-09-22 19:25 911
#endif
2660ccea Poul Sander 2023-09-22 19:25 912
#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2660ccea Poul Sander 2023-09-22 19:25 913
    #define JSON_HEDLEY_NO_RETURN __noreturn
2660ccea Poul Sander 2023-09-22 19:25 914
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2660ccea Poul Sander 2023-09-22 19:25 915
    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
2660ccea Poul Sander 2023-09-22 19:25 916
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
2660ccea Poul Sander 2023-09-22 19:25 917
    #define JSON_HEDLEY_NO_RETURN _Noreturn
2660ccea Poul Sander 2023-09-22 19:25 918
#elif defined(__cplusplus) && (__cplusplus >= 201103L)
2660ccea Poul Sander 2023-09-22 19:25 919
    #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
2660ccea Poul Sander 2023-09-22 19:25 920
#elif \
2660ccea Poul Sander 2023-09-22 19:25 921
    JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
2660ccea Poul Sander 2023-09-22 19:25 922
    JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
2660ccea Poul Sander 2023-09-22 19:25 923
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
2660ccea Poul Sander 2023-09-22 19:25 924
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 925
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 926
    JSON_HEDLEY_TI_VERSION_CHECK(18,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 927
    (JSON_HEDLEY_TI_VERSION_CHECK(17,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
2660ccea Poul Sander 2023-09-22 19:25 928
    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
2660ccea Poul Sander 2023-09-22 19:25 929
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
2660ccea Poul Sander 2023-09-22 19:25 930
    #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
2660ccea Poul Sander 2023-09-22 19:25 931
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
2660ccea Poul Sander 2023-09-22 19:25 932
    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
2660ccea Poul Sander 2023-09-22 19:25 933
#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 934
    #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
2660ccea Poul Sander 2023-09-22 19:25 935
#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
2660ccea Poul Sander 2023-09-22 19:25 936
    #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
2660ccea Poul Sander 2023-09-22 19:25 937
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
2660ccea Poul Sander 2023-09-22 19:25 938
    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
2660ccea Poul Sander 2023-09-22 19:25 939
#else
2660ccea Poul Sander 2023-09-22 19:25 940
    #define JSON_HEDLEY_NO_RETURN
2660ccea Poul Sander 2023-09-22 19:25 941
#endif
2660ccea Poul Sander 2023-09-22 19:25 942
2660ccea Poul Sander 2023-09-22 19:25 943
#if defined(JSON_HEDLEY_NO_ESCAPE)
2660ccea Poul Sander 2023-09-22 19:25 944
    #undef JSON_HEDLEY_NO_ESCAPE
2660ccea Poul Sander 2023-09-22 19:25 945
#endif
2660ccea Poul Sander 2023-09-22 19:25 946
#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
2660ccea Poul Sander 2023-09-22 19:25 947
    #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
2660ccea Poul Sander 2023-09-22 19:25 948
#else
2660ccea Poul Sander 2023-09-22 19:25 949
    #define JSON_HEDLEY_NO_ESCAPE
2660ccea Poul Sander 2023-09-22 19:25 950
#endif
2660ccea Poul Sander 2023-09-22 19:25 951
2660ccea Poul Sander 2023-09-22 19:25 952
#if defined(JSON_HEDLEY_UNREACHABLE)
2660ccea Poul Sander 2023-09-22 19:25 953
    #undef JSON_HEDLEY_UNREACHABLE
2660ccea Poul Sander 2023-09-22 19:25 954
#endif
2660ccea Poul Sander 2023-09-22 19:25 955
#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
2660ccea Poul Sander 2023-09-22 19:25 956
    #undef JSON_HEDLEY_UNREACHABLE_RETURN
2660ccea Poul Sander 2023-09-22 19:25 957
#endif
2660ccea Poul Sander 2023-09-22 19:25 958
#if \
2660ccea Poul Sander 2023-09-22 19:25 959
    (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
2660ccea Poul Sander 2023-09-22 19:25 960
    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
2660ccea Poul Sander 2023-09-22 19:25 961
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 962
    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
2660ccea Poul Sander 2023-09-22 19:25 963
    #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
2660ccea Poul Sander 2023-09-22 19:25 964
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
2660ccea Poul Sander 2023-09-22 19:25 965
    #define JSON_HEDLEY_UNREACHABLE() __assume(0)
2660ccea Poul Sander 2023-09-22 19:25 966
#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0)
2660ccea Poul Sander 2023-09-22 19:25 967
    #if defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 968
        #define JSON_HEDLEY_UNREACHABLE() std::_nassert(0)
2660ccea Poul Sander 2023-09-22 19:25 969
    #else
2660ccea Poul Sander 2023-09-22 19:25 970
        #define JSON_HEDLEY_UNREACHABLE() _nassert(0)
2660ccea Poul Sander 2023-09-22 19:25 971
    #endif
2660ccea Poul Sander 2023-09-22 19:25 972
    #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value
2660ccea Poul Sander 2023-09-22 19:25 973
#elif defined(EXIT_FAILURE)
2660ccea Poul Sander 2023-09-22 19:25 974
    #define JSON_HEDLEY_UNREACHABLE() abort()
2660ccea Poul Sander 2023-09-22 19:25 975
#else
2660ccea Poul Sander 2023-09-22 19:25 976
    #define JSON_HEDLEY_UNREACHABLE()
2660ccea Poul Sander 2023-09-22 19:25 977
    #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value
2660ccea Poul Sander 2023-09-22 19:25 978
#endif
2660ccea Poul Sander 2023-09-22 19:25 979
#if !defined(JSON_HEDLEY_UNREACHABLE_RETURN)
2660ccea Poul Sander 2023-09-22 19:25 980
    #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
2660ccea Poul Sander 2023-09-22 19:25 981
#endif
2660ccea Poul Sander 2023-09-22 19:25 982
2660ccea Poul Sander 2023-09-22 19:25 983
#if defined(JSON_HEDLEY_ASSUME)
2660ccea Poul Sander 2023-09-22 19:25 984
    #undef JSON_HEDLEY_ASSUME
2660ccea Poul Sander 2023-09-22 19:25 985
#endif
2660ccea Poul Sander 2023-09-22 19:25 986
#if \
2660ccea Poul Sander 2023-09-22 19:25 987
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
2660ccea Poul Sander 2023-09-22 19:25 988
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2660ccea Poul Sander 2023-09-22 19:25 989
    #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
2660ccea Poul Sander 2023-09-22 19:25 990
#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
2660ccea Poul Sander 2023-09-22 19:25 991
    #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
2660ccea Poul Sander 2023-09-22 19:25 992
#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0)
2660ccea Poul Sander 2023-09-22 19:25 993
    #if defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 994
        #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
2660ccea Poul Sander 2023-09-22 19:25 995
    #else
2660ccea Poul Sander 2023-09-22 19:25 996
        #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
2660ccea Poul Sander 2023-09-22 19:25 997
    #endif
2660ccea Poul Sander 2023-09-22 19:25 998
#elif \
2660ccea Poul Sander 2023-09-22 19:25 999
    (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && !defined(JSON_HEDLEY_ARM_VERSION)) || \
2660ccea Poul Sander 2023-09-22 19:25 1000
    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1001
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1002
    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
2660ccea Poul Sander 2023-09-22 19:25 1003
    #define JSON_HEDLEY_ASSUME(expr) ((void) ((expr) ? 1 : (__builtin_unreachable(), 1)))
2660ccea Poul Sander 2023-09-22 19:25 1004
#else
2660ccea Poul Sander 2023-09-22 19:25 1005
    #define JSON_HEDLEY_ASSUME(expr) ((void) (expr))
2660ccea Poul Sander 2023-09-22 19:25 1006
#endif
2660ccea Poul Sander 2023-09-22 19:25 1007
2660ccea Poul Sander 2023-09-22 19:25 1008
JSON_HEDLEY_DIAGNOSTIC_PUSH
2660ccea Poul Sander 2023-09-22 19:25 1009
#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
2660ccea Poul Sander 2023-09-22 19:25 1010
    #pragma clang diagnostic ignored "-Wpedantic"
2660ccea Poul Sander 2023-09-22 19:25 1011
#endif
2660ccea Poul Sander 2023-09-22 19:25 1012
#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1013
    #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
2660ccea Poul Sander 2023-09-22 19:25 1014
#endif
2660ccea Poul Sander 2023-09-22 19:25 1015
#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1016
    #if defined(__clang__)
2660ccea Poul Sander 2023-09-22 19:25 1017
        #pragma clang diagnostic ignored "-Wvariadic-macros"
2660ccea Poul Sander 2023-09-22 19:25 1018
    #elif defined(JSON_HEDLEY_GCC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 1019
        #pragma GCC diagnostic ignored "-Wvariadic-macros"
2660ccea Poul Sander 2023-09-22 19:25 1020
    #endif
2660ccea Poul Sander 2023-09-22 19:25 1021
#endif
2660ccea Poul Sander 2023-09-22 19:25 1022
#if defined(JSON_HEDLEY_NON_NULL)
2660ccea Poul Sander 2023-09-22 19:25 1023
    #undef JSON_HEDLEY_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 1024
#endif
2660ccea Poul Sander 2023-09-22 19:25 1025
#if \
2660ccea Poul Sander 2023-09-22 19:25 1026
    JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
2660ccea Poul Sander 2023-09-22 19:25 1027
    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1028
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1029
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
2660ccea Poul Sander 2023-09-22 19:25 1030
    #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
2660ccea Poul Sander 2023-09-22 19:25 1031
#else
2660ccea Poul Sander 2023-09-22 19:25 1032
    #define JSON_HEDLEY_NON_NULL(...)
2660ccea Poul Sander 2023-09-22 19:25 1033
#endif
2660ccea Poul Sander 2023-09-22 19:25 1034
JSON_HEDLEY_DIAGNOSTIC_POP
2660ccea Poul Sander 2023-09-22 19:25 1035
2660ccea Poul Sander 2023-09-22 19:25 1036
#if defined(JSON_HEDLEY_PRINTF_FORMAT)
2660ccea Poul Sander 2023-09-22 19:25 1037
    #undef JSON_HEDLEY_PRINTF_FORMAT
2660ccea Poul Sander 2023-09-22 19:25 1038
#endif
2660ccea Poul Sander 2023-09-22 19:25 1039
#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
2660ccea Poul Sander 2023-09-22 19:25 1040
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
2660ccea Poul Sander 2023-09-22 19:25 1041
#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
2660ccea Poul Sander 2023-09-22 19:25 1042
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
2660ccea Poul Sander 2023-09-22 19:25 1043
#elif \
2660ccea Poul Sander 2023-09-22 19:25 1044
    JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
2660ccea Poul Sander 2023-09-22 19:25 1045
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1046
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1047
    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1048
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1049
    JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1050
    (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
2660ccea Poul Sander 2023-09-22 19:25 1051
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
2660ccea Poul Sander 2023-09-22 19:25 1052
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1053
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
2660ccea Poul Sander 2023-09-22 19:25 1054
#else
2660ccea Poul Sander 2023-09-22 19:25 1055
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
2660ccea Poul Sander 2023-09-22 19:25 1056
#endif
2660ccea Poul Sander 2023-09-22 19:25 1057
2660ccea Poul Sander 2023-09-22 19:25 1058
#if defined(JSON_HEDLEY_CONSTEXPR)
2660ccea Poul Sander 2023-09-22 19:25 1059
    #undef JSON_HEDLEY_CONSTEXPR
2660ccea Poul Sander 2023-09-22 19:25 1060
#endif
2660ccea Poul Sander 2023-09-22 19:25 1061
#if defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1062
    #if __cplusplus >= 201103L
2660ccea Poul Sander 2023-09-22 19:25 1063
        #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
2660ccea Poul Sander 2023-09-22 19:25 1064
    #endif
2660ccea Poul Sander 2023-09-22 19:25 1065
#endif
2660ccea Poul Sander 2023-09-22 19:25 1066
#if !defined(JSON_HEDLEY_CONSTEXPR)
2660ccea Poul Sander 2023-09-22 19:25 1067
    #define JSON_HEDLEY_CONSTEXPR
2660ccea Poul Sander 2023-09-22 19:25 1068
#endif
2660ccea Poul Sander 2023-09-22 19:25 1069
2660ccea Poul Sander 2023-09-22 19:25 1070
#if defined(JSON_HEDLEY_PREDICT)
2660ccea Poul Sander 2023-09-22 19:25 1071
    #undef JSON_HEDLEY_PREDICT
2660ccea Poul Sander 2023-09-22 19:25 1072
#endif
2660ccea Poul Sander 2023-09-22 19:25 1073
#if defined(JSON_HEDLEY_LIKELY)
2660ccea Poul Sander 2023-09-22 19:25 1074
    #undef JSON_HEDLEY_LIKELY
2660ccea Poul Sander 2023-09-22 19:25 1075
#endif
2660ccea Poul Sander 2023-09-22 19:25 1076
#if defined(JSON_HEDLEY_UNLIKELY)
2660ccea Poul Sander 2023-09-22 19:25 1077
    #undef JSON_HEDLEY_UNLIKELY
2660ccea Poul Sander 2023-09-22 19:25 1078
#endif
2660ccea Poul Sander 2023-09-22 19:25 1079
#if defined(JSON_HEDLEY_UNPREDICTABLE)
2660ccea Poul Sander 2023-09-22 19:25 1080
    #undef JSON_HEDLEY_UNPREDICTABLE
2660ccea Poul Sander 2023-09-22 19:25 1081
#endif
2660ccea Poul Sander 2023-09-22 19:25 1082
#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
2660ccea Poul Sander 2023-09-22 19:25 1083
    #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable(!!(expr))
2660ccea Poul Sander 2023-09-22 19:25 1084
#endif
2660ccea Poul Sander 2023-09-22 19:25 1085
#if \
2660ccea Poul Sander 2023-09-22 19:25 1086
  JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \
2660ccea Poul Sander 2023-09-22 19:25 1087
  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1088
#  define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(expr, value, probability)
2660ccea Poul Sander 2023-09-22 19:25 1089
#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1, probability)
2660ccea Poul Sander 2023-09-22 19:25 1090
#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0, probability)
2660ccea Poul Sander 2023-09-22 19:25 1091
#  define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
2660ccea Poul Sander 2023-09-22 19:25 1092
#  define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
2660ccea Poul Sander 2023-09-22 19:25 1093
#if !defined(JSON_HEDLEY_BUILTIN_UNPREDICTABLE)
2660ccea Poul Sander 2023-09-22 19:25 1094
    #define JSON_HEDLEY_BUILTIN_UNPREDICTABLE(expr) __builtin_expect_with_probability(!!(expr), 1, 0.5)
2660ccea Poul Sander 2023-09-22 19:25 1095
#endif
2660ccea Poul Sander 2023-09-22 19:25 1096
#elif \
2660ccea Poul Sander 2023-09-22 19:25 1097
  JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \
2660ccea Poul Sander 2023-09-22 19:25 1098
  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1099
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1100
  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
2660ccea Poul Sander 2023-09-22 19:25 1101
  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1102
  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1103
  JSON_HEDLEY_TI_VERSION_CHECK(6,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1104
  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27)
2660ccea Poul Sander 2023-09-22 19:25 1105
#  define JSON_HEDLEY_PREDICT(expr, expected, probability) \
2660ccea Poul Sander 2023-09-22 19:25 1106
    (((probability) >= 0.9) ? __builtin_expect(!!(expr), (expected)) : (((void) (expected)), !!(expr)))
2660ccea Poul Sander 2023-09-22 19:25 1107
#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
2660ccea Poul Sander 2023-09-22 19:25 1108
    (__extension__ ({ \
2660ccea Poul Sander 2023-09-22 19:25 1109
        JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \
2660ccea Poul Sander 2023-09-22 19:25 1110
        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
2660ccea Poul Sander 2023-09-22 19:25 1111
    }))
2660ccea Poul Sander 2023-09-22 19:25 1112
#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
2660ccea Poul Sander 2023-09-22 19:25 1113
    (__extension__ ({ \
2660ccea Poul Sander 2023-09-22 19:25 1114
        JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \
2660ccea Poul Sander 2023-09-22 19:25 1115
        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
2660ccea Poul Sander 2023-09-22 19:25 1116
    }))
2660ccea Poul Sander 2023-09-22 19:25 1117
#  define JSON_HEDLEY_LIKELY(expr)   __builtin_expect(!!(expr), 1)
2660ccea Poul Sander 2023-09-22 19:25 1118
#  define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
2660ccea Poul Sander 2023-09-22 19:25 1119
#else
2660ccea Poul Sander 2023-09-22 19:25 1120
#  define JSON_HEDLEY_PREDICT(expr, expected, probability) (((void) (expected)), !!(expr))
2660ccea Poul Sander 2023-09-22 19:25 1121
#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
2660ccea Poul Sander 2023-09-22 19:25 1122
#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
2660ccea Poul Sander 2023-09-22 19:25 1123
#  define JSON_HEDLEY_LIKELY(expr) (!!(expr))
2660ccea Poul Sander 2023-09-22 19:25 1124
#  define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
2660ccea Poul Sander 2023-09-22 19:25 1125
#endif
2660ccea Poul Sander 2023-09-22 19:25 1126
#if !defined(JSON_HEDLEY_UNPREDICTABLE)
2660ccea Poul Sander 2023-09-22 19:25 1127
    #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
2660ccea Poul Sander 2023-09-22 19:25 1128
#endif
2660ccea Poul Sander 2023-09-22 19:25 1129
2660ccea Poul Sander 2023-09-22 19:25 1130
#if defined(JSON_HEDLEY_MALLOC)
2660ccea Poul Sander 2023-09-22 19:25 1131
    #undef JSON_HEDLEY_MALLOC
2660ccea Poul Sander 2023-09-22 19:25 1132
#endif
2660ccea Poul Sander 2023-09-22 19:25 1133
#if \
2660ccea Poul Sander 2023-09-22 19:25 1134
    JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
2660ccea Poul Sander 2023-09-22 19:25 1135
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1136
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1137
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1138
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1139
    JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1140
    JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1141
    (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
2660ccea Poul Sander 2023-09-22 19:25 1142
    #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
2660ccea Poul Sander 2023-09-22 19:25 1143
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
2660ccea Poul Sander 2023-09-22 19:25 1144
    #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
2660ccea Poul Sander 2023-09-22 19:25 1145
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0)
2660ccea Poul Sander 2023-09-22 19:25 1146
    #define JSON_HEDLEY_MALLOC __declspec(restrict)
2660ccea Poul Sander 2023-09-22 19:25 1147
#else
2660ccea Poul Sander 2023-09-22 19:25 1148
    #define JSON_HEDLEY_MALLOC
2660ccea Poul Sander 2023-09-22 19:25 1149
#endif
2660ccea Poul Sander 2023-09-22 19:25 1150
2660ccea Poul Sander 2023-09-22 19:25 1151
#if defined(JSON_HEDLEY_PURE)
2660ccea Poul Sander 2023-09-22 19:25 1152
    #undef JSON_HEDLEY_PURE
2660ccea Poul Sander 2023-09-22 19:25 1153
#endif
2660ccea Poul Sander 2023-09-22 19:25 1154
#if \
2660ccea Poul Sander 2023-09-22 19:25 1155
    JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
2660ccea Poul Sander 2023-09-22 19:25 1156
    JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1157
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1158
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1159
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1160
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1161
    JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1162
    (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
2660ccea Poul Sander 2023-09-22 19:25 1163
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
2660ccea Poul Sander 2023-09-22 19:25 1164
    #define JSON_HEDLEY_PURE __attribute__((__pure__))
2660ccea Poul Sander 2023-09-22 19:25 1165
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
2660ccea Poul Sander 2023-09-22 19:25 1166
    #define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
2660ccea Poul Sander 2023-09-22 19:25 1167
#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1168
    #define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
2660ccea Poul Sander 2023-09-22 19:25 1169
#else
2660ccea Poul Sander 2023-09-22 19:25 1170
    #define JSON_HEDLEY_PURE
2660ccea Poul Sander 2023-09-22 19:25 1171
#endif
2660ccea Poul Sander 2023-09-22 19:25 1172
2660ccea Poul Sander 2023-09-22 19:25 1173
#if defined(JSON_HEDLEY_CONST)
2660ccea Poul Sander 2023-09-22 19:25 1174
    #undef JSON_HEDLEY_CONST
2660ccea Poul Sander 2023-09-22 19:25 1175
#endif
2660ccea Poul Sander 2023-09-22 19:25 1176
#if \
2660ccea Poul Sander 2023-09-22 19:25 1177
    JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
2660ccea Poul Sander 2023-09-22 19:25 1178
    JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1179
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1180
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1181
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1182
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1183
    JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1184
    (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
2660ccea Poul Sander 2023-09-22 19:25 1185
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
2660ccea Poul Sander 2023-09-22 19:25 1186
    #define JSON_HEDLEY_CONST __attribute__((__const__))
2660ccea Poul Sander 2023-09-22 19:25 1187
#elif \
2660ccea Poul Sander 2023-09-22 19:25 1188
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
2660ccea Poul Sander 2023-09-22 19:25 1189
    #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
2660ccea Poul Sander 2023-09-22 19:25 1190
#else
2660ccea Poul Sander 2023-09-22 19:25 1191
    #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
2660ccea Poul Sander 2023-09-22 19:25 1192
#endif
2660ccea Poul Sander 2023-09-22 19:25 1193
2660ccea Poul Sander 2023-09-22 19:25 1194
#if defined(JSON_HEDLEY_RESTRICT)
2660ccea Poul Sander 2023-09-22 19:25 1195
    #undef JSON_HEDLEY_RESTRICT
2660ccea Poul Sander 2023-09-22 19:25 1196
#endif
2660ccea Poul Sander 2023-09-22 19:25 1197
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1198
    #define JSON_HEDLEY_RESTRICT restrict
2660ccea Poul Sander 2023-09-22 19:25 1199
#elif \
2660ccea Poul Sander 2023-09-22 19:25 1200
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1201
    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1202
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1203
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1204
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1205
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1206
    JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1207
    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
2660ccea Poul Sander 2023-09-22 19:25 1208
    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1209
    defined(__clang__)
2660ccea Poul Sander 2023-09-22 19:25 1210
    #define JSON_HEDLEY_RESTRICT __restrict
2660ccea Poul Sander 2023-09-22 19:25 1211
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1212
    #define JSON_HEDLEY_RESTRICT _Restrict
2660ccea Poul Sander 2023-09-22 19:25 1213
#else
2660ccea Poul Sander 2023-09-22 19:25 1214
    #define JSON_HEDLEY_RESTRICT
2660ccea Poul Sander 2023-09-22 19:25 1215
#endif
2660ccea Poul Sander 2023-09-22 19:25 1216
2660ccea Poul Sander 2023-09-22 19:25 1217
#if defined(JSON_HEDLEY_INLINE)
2660ccea Poul Sander 2023-09-22 19:25 1218
    #undef JSON_HEDLEY_INLINE
2660ccea Poul Sander 2023-09-22 19:25 1219
#endif
2660ccea Poul Sander 2023-09-22 19:25 1220
#if \
2660ccea Poul Sander 2023-09-22 19:25 1221
    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
2660ccea Poul Sander 2023-09-22 19:25 1222
    (defined(__cplusplus) && (__cplusplus >= 199711L))
2660ccea Poul Sander 2023-09-22 19:25 1223
    #define JSON_HEDLEY_INLINE inline
2660ccea Poul Sander 2023-09-22 19:25 1224
#elif \
2660ccea Poul Sander 2023-09-22 19:25 1225
    defined(JSON_HEDLEY_GCC_VERSION) || \
2660ccea Poul Sander 2023-09-22 19:25 1226
    JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
2660ccea Poul Sander 2023-09-22 19:25 1227
    #define JSON_HEDLEY_INLINE __inline__
2660ccea Poul Sander 2023-09-22 19:25 1228
#elif \
2660ccea Poul Sander 2023-09-22 19:25 1229
    JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1230
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1231
    JSON_HEDLEY_TI_VERSION_CHECK(8,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1232
    #define JSON_HEDLEY_INLINE __inline
2660ccea Poul Sander 2023-09-22 19:25 1233
#else
2660ccea Poul Sander 2023-09-22 19:25 1234
    #define JSON_HEDLEY_INLINE
2660ccea Poul Sander 2023-09-22 19:25 1235
#endif
2660ccea Poul Sander 2023-09-22 19:25 1236
2660ccea Poul Sander 2023-09-22 19:25 1237
#if defined(JSON_HEDLEY_ALWAYS_INLINE)
2660ccea Poul Sander 2023-09-22 19:25 1238
    #undef JSON_HEDLEY_ALWAYS_INLINE
2660ccea Poul Sander 2023-09-22 19:25 1239
#endif
2660ccea Poul Sander 2023-09-22 19:25 1240
#if \
2660ccea Poul Sander 2023-09-22 19:25 1241
    JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
2660ccea Poul Sander 2023-09-22 19:25 1242
    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1243
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1244
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1245
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1246
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1247
    JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1248
    (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
2660ccea Poul Sander 2023-09-22 19:25 1249
    #define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
2660ccea Poul Sander 2023-09-22 19:25 1250
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1251
    #define JSON_HEDLEY_ALWAYS_INLINE __forceinline
2660ccea Poul Sander 2023-09-22 19:25 1252
#elif JSON_HEDLEY_TI_VERSION_CHECK(7,0,0) && defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1253
    #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
2660ccea Poul Sander 2023-09-22 19:25 1254
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1255
    #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
2660ccea Poul Sander 2023-09-22 19:25 1256
#else
2660ccea Poul Sander 2023-09-22 19:25 1257
    #define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
2660ccea Poul Sander 2023-09-22 19:25 1258
#endif
2660ccea Poul Sander 2023-09-22 19:25 1259
2660ccea Poul Sander 2023-09-22 19:25 1260
#if defined(JSON_HEDLEY_NEVER_INLINE)
2660ccea Poul Sander 2023-09-22 19:25 1261
    #undef JSON_HEDLEY_NEVER_INLINE
2660ccea Poul Sander 2023-09-22 19:25 1262
#endif
2660ccea Poul Sander 2023-09-22 19:25 1263
#if \
2660ccea Poul Sander 2023-09-22 19:25 1264
    JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
2660ccea Poul Sander 2023-09-22 19:25 1265
    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1266
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1267
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1268
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1269
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1270
    JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1271
    (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
2660ccea Poul Sander 2023-09-22 19:25 1272
    #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
2660ccea Poul Sander 2023-09-22 19:25 1273
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
2660ccea Poul Sander 2023-09-22 19:25 1274
    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
2660ccea Poul Sander 2023-09-22 19:25 1275
#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
2660ccea Poul Sander 2023-09-22 19:25 1276
    #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
2660ccea Poul Sander 2023-09-22 19:25 1277
#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1278
    #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
2660ccea Poul Sander 2023-09-22 19:25 1279
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1280
    #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
2660ccea Poul Sander 2023-09-22 19:25 1281
#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
2660ccea Poul Sander 2023-09-22 19:25 1282
    #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
2660ccea Poul Sander 2023-09-22 19:25 1283
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1284
    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
2660ccea Poul Sander 2023-09-22 19:25 1285
#else
2660ccea Poul Sander 2023-09-22 19:25 1286
    #define JSON_HEDLEY_NEVER_INLINE
2660ccea Poul Sander 2023-09-22 19:25 1287
#endif
2660ccea Poul Sander 2023-09-22 19:25 1288
2660ccea Poul Sander 2023-09-22 19:25 1289
#if defined(JSON_HEDLEY_PRIVATE)
2660ccea Poul Sander 2023-09-22 19:25 1290
    #undef JSON_HEDLEY_PRIVATE
2660ccea Poul Sander 2023-09-22 19:25 1291
#endif
2660ccea Poul Sander 2023-09-22 19:25 1292
#if defined(JSON_HEDLEY_PUBLIC)
2660ccea Poul Sander 2023-09-22 19:25 1293
    #undef JSON_HEDLEY_PUBLIC
2660ccea Poul Sander 2023-09-22 19:25 1294
#endif
2660ccea Poul Sander 2023-09-22 19:25 1295
#if defined(JSON_HEDLEY_IMPORT)
2660ccea Poul Sander 2023-09-22 19:25 1296
    #undef JSON_HEDLEY_IMPORT
2660ccea Poul Sander 2023-09-22 19:25 1297
#endif
2660ccea Poul Sander 2023-09-22 19:25 1298
#if defined(_WIN32) || defined(__CYGWIN__)
2660ccea Poul Sander 2023-09-22 19:25 1299
    #define JSON_HEDLEY_PRIVATE
2660ccea Poul Sander 2023-09-22 19:25 1300
    #define JSON_HEDLEY_PUBLIC   __declspec(dllexport)
2660ccea Poul Sander 2023-09-22 19:25 1301
    #define JSON_HEDLEY_IMPORT   __declspec(dllimport)
2660ccea Poul Sander 2023-09-22 19:25 1302
#else
2660ccea Poul Sander 2023-09-22 19:25 1303
    #if \
2660ccea Poul Sander 2023-09-22 19:25 1304
        JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
2660ccea Poul Sander 2023-09-22 19:25 1305
        JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1306
        JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1307
        JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1308
        JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1309
        JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1310
        JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1311
        (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_EABI__) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
2660ccea Poul Sander 2023-09-22 19:25 1312
        #define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
2660ccea Poul Sander 2023-09-22 19:25 1313
        #define JSON_HEDLEY_PUBLIC  __attribute__((__visibility__("default")))
2660ccea Poul Sander 2023-09-22 19:25 1314
    #else
2660ccea Poul Sander 2023-09-22 19:25 1315
        #define JSON_HEDLEY_PRIVATE
2660ccea Poul Sander 2023-09-22 19:25 1316
        #define JSON_HEDLEY_PUBLIC
2660ccea Poul Sander 2023-09-22 19:25 1317
    #endif
2660ccea Poul Sander 2023-09-22 19:25 1318
    #define JSON_HEDLEY_IMPORT    extern
2660ccea Poul Sander 2023-09-22 19:25 1319
#endif
2660ccea Poul Sander 2023-09-22 19:25 1320
2660ccea Poul Sander 2023-09-22 19:25 1321
#if defined(JSON_HEDLEY_NO_THROW)
2660ccea Poul Sander 2023-09-22 19:25 1322
    #undef JSON_HEDLEY_NO_THROW
2660ccea Poul Sander 2023-09-22 19:25 1323
#endif
2660ccea Poul Sander 2023-09-22 19:25 1324
#if \
2660ccea Poul Sander 2023-09-22 19:25 1325
    JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
2660ccea Poul Sander 2023-09-22 19:25 1326
    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1327
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1328
    #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
2660ccea Poul Sander 2023-09-22 19:25 1329
#elif \
2660ccea Poul Sander 2023-09-22 19:25 1330
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1331
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
2660ccea Poul Sander 2023-09-22 19:25 1332
    #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
2660ccea Poul Sander 2023-09-22 19:25 1333
#else
2660ccea Poul Sander 2023-09-22 19:25 1334
    #define JSON_HEDLEY_NO_THROW
2660ccea Poul Sander 2023-09-22 19:25 1335
#endif
2660ccea Poul Sander 2023-09-22 19:25 1336
2660ccea Poul Sander 2023-09-22 19:25 1337
#if defined(JSON_HEDLEY_FALL_THROUGH)
2660ccea Poul Sander 2023-09-22 19:25 1338
    #undef JSON_HEDLEY_FALL_THROUGH
2660ccea Poul Sander 2023-09-22 19:25 1339
#endif
2660ccea Poul Sander 2023-09-22 19:25 1340
#if JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(fallthrough,7,0,0) && !defined(JSON_HEDLEY_PGI_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 1341
    #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
2660ccea Poul Sander 2023-09-22 19:25 1342
#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
2660ccea Poul Sander 2023-09-22 19:25 1343
    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
2660ccea Poul Sander 2023-09-22 19:25 1344
#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
2660ccea Poul Sander 2023-09-22 19:25 1345
    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
2660ccea Poul Sander 2023-09-22 19:25 1346
#elif defined(__fallthrough) /* SAL */
2660ccea Poul Sander 2023-09-22 19:25 1347
    #define JSON_HEDLEY_FALL_THROUGH __fallthrough
2660ccea Poul Sander 2023-09-22 19:25 1348
#else
2660ccea Poul Sander 2023-09-22 19:25 1349
    #define JSON_HEDLEY_FALL_THROUGH
2660ccea Poul Sander 2023-09-22 19:25 1350
#endif
2660ccea Poul Sander 2023-09-22 19:25 1351
2660ccea Poul Sander 2023-09-22 19:25 1352
#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
2660ccea Poul Sander 2023-09-22 19:25 1353
    #undef JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 1354
#endif
2660ccea Poul Sander 2023-09-22 19:25 1355
#if \
2660ccea Poul Sander 2023-09-22 19:25 1356
    JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
2660ccea Poul Sander 2023-09-22 19:25 1357
    JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
2660ccea Poul Sander 2023-09-22 19:25 1358
    #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
2660ccea Poul Sander 2023-09-22 19:25 1359
#elif defined(_Ret_notnull_) /* SAL */
2660ccea Poul Sander 2023-09-22 19:25 1360
    #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
2660ccea Poul Sander 2023-09-22 19:25 1361
#else
2660ccea Poul Sander 2023-09-22 19:25 1362
    #define JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 1363
#endif
2660ccea Poul Sander 2023-09-22 19:25 1364
2660ccea Poul Sander 2023-09-22 19:25 1365
#if defined(JSON_HEDLEY_ARRAY_PARAM)
2660ccea Poul Sander 2023-09-22 19:25 1366
    #undef JSON_HEDLEY_ARRAY_PARAM
2660ccea Poul Sander 2023-09-22 19:25 1367
#endif
2660ccea Poul Sander 2023-09-22 19:25 1368
#if \
2660ccea Poul Sander 2023-09-22 19:25 1369
    defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
2660ccea Poul Sander 2023-09-22 19:25 1370
    !defined(__STDC_NO_VLA__) && \
2660ccea Poul Sander 2023-09-22 19:25 1371
    !defined(__cplusplus) && \
2660ccea Poul Sander 2023-09-22 19:25 1372
    !defined(JSON_HEDLEY_PGI_VERSION) && \
2660ccea Poul Sander 2023-09-22 19:25 1373
    !defined(JSON_HEDLEY_TINYC_VERSION)
2660ccea Poul Sander 2023-09-22 19:25 1374
    #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
2660ccea Poul Sander 2023-09-22 19:25 1375
#else
2660ccea Poul Sander 2023-09-22 19:25 1376
    #define JSON_HEDLEY_ARRAY_PARAM(name)
2660ccea Poul Sander 2023-09-22 19:25 1377
#endif
2660ccea Poul Sander 2023-09-22 19:25 1378
2660ccea Poul Sander 2023-09-22 19:25 1379
#if defined(JSON_HEDLEY_IS_CONSTANT)
2660ccea Poul Sander 2023-09-22 19:25 1380
    #undef JSON_HEDLEY_IS_CONSTANT
2660ccea Poul Sander 2023-09-22 19:25 1381
#endif
2660ccea Poul Sander 2023-09-22 19:25 1382
#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
2660ccea Poul Sander 2023-09-22 19:25 1383
    #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
2660ccea Poul Sander 2023-09-22 19:25 1384
#endif
2660ccea Poul Sander 2023-09-22 19:25 1385
/* JSON_HEDLEY_IS_CONSTEXPR_ is for
2660ccea Poul Sander 2023-09-22 19:25 1386
   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
2660ccea Poul Sander 2023-09-22 19:25 1387
#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2660ccea Poul Sander 2023-09-22 19:25 1388
    #undef JSON_HEDLEY_IS_CONSTEXPR_
2660ccea Poul Sander 2023-09-22 19:25 1389
#endif
2660ccea Poul Sander 2023-09-22 19:25 1390
#if \
2660ccea Poul Sander 2023-09-22 19:25 1391
    JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
2660ccea Poul Sander 2023-09-22 19:25 1392
    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1393
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1394
    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
2660ccea Poul Sander 2023-09-22 19:25 1395
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1396
    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1397
    JSON_HEDLEY_TI_VERSION_CHECK(6,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1398
    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
2660ccea Poul Sander 2023-09-22 19:25 1399
    JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
2660ccea Poul Sander 2023-09-22 19:25 1400
    #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
2660ccea Poul Sander 2023-09-22 19:25 1401
#endif
2660ccea Poul Sander 2023-09-22 19:25 1402
#if !defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1403
#  if \
2660ccea Poul Sander 2023-09-22 19:25 1404
       JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
2660ccea Poul Sander 2023-09-22 19:25 1405
       JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1406
       JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1407
       JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1408
       JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1409
       JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1410
       JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
2660ccea Poul Sander 2023-09-22 19:25 1411
#if defined(__INTPTR_TYPE__)
2660ccea Poul Sander 2023-09-22 19:25 1412
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
2660ccea Poul Sander 2023-09-22 19:25 1413
#else
2660ccea Poul Sander 2023-09-22 19:25 1414
    #include <stdint.h>
2660ccea Poul Sander 2023-09-22 19:25 1415
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
2660ccea Poul Sander 2023-09-22 19:25 1416
#endif
2660ccea Poul Sander 2023-09-22 19:25 1417
#  elif \
2660ccea Poul Sander 2023-09-22 19:25 1418
       (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && !defined(JSON_HEDLEY_SUNPRO_VERSION) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
2660ccea Poul Sander 2023-09-22 19:25 1419
       JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
2660ccea Poul Sander 2023-09-22 19:25 1420
       JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1421
       JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1422
       JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1423
       JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
2660ccea Poul Sander 2023-09-22 19:25 1424
#if defined(__INTPTR_TYPE__)
2660ccea Poul Sander 2023-09-22 19:25 1425
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
2660ccea Poul Sander 2023-09-22 19:25 1426
#else
2660ccea Poul Sander 2023-09-22 19:25 1427
    #include <stdint.h>
2660ccea Poul Sander 2023-09-22 19:25 1428
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
2660ccea Poul Sander 2023-09-22 19:25 1429
#endif
2660ccea Poul Sander 2023-09-22 19:25 1430
#  elif \
2660ccea Poul Sander 2023-09-22 19:25 1431
       defined(JSON_HEDLEY_GCC_VERSION) || \
2660ccea Poul Sander 2023-09-22 19:25 1432
       defined(JSON_HEDLEY_INTEL_VERSION) || \
2660ccea Poul Sander 2023-09-22 19:25 1433
       defined(JSON_HEDLEY_TINYC_VERSION) || \
2660ccea Poul Sander 2023-09-22 19:25 1434
       defined(JSON_HEDLEY_TI_VERSION) || \
2660ccea Poul Sander 2023-09-22 19:25 1435
       defined(__clang__)
2660ccea Poul Sander 2023-09-22 19:25 1436
#    define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2660ccea Poul Sander 2023-09-22 19:25 1437
        sizeof(void) != \
2660ccea Poul Sander 2023-09-22 19:25 1438
        sizeof(*( \
2660ccea Poul Sander 2023-09-22 19:25 1439
                  1 ? \
2660ccea Poul Sander 2023-09-22 19:25 1440
                  ((void*) ((expr) * 0L) ) : \
2660ccea Poul Sander 2023-09-22 19:25 1441
((struct { char v[sizeof(void) * 2]; } *) 1) \
2660ccea Poul Sander 2023-09-22 19:25 1442
                ) \
2660ccea Poul Sander 2023-09-22 19:25 1443
              ) \
2660ccea Poul Sander 2023-09-22 19:25 1444
                                            )
2660ccea Poul Sander 2023-09-22 19:25 1445
#  endif
2660ccea Poul Sander 2023-09-22 19:25 1446
#endif
2660ccea Poul Sander 2023-09-22 19:25 1447
#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2660ccea Poul Sander 2023-09-22 19:25 1448
    #if !defined(JSON_HEDLEY_IS_CONSTANT)
2660ccea Poul Sander 2023-09-22 19:25 1449
        #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2660ccea Poul Sander 2023-09-22 19:25 1450
    #endif
2660ccea Poul Sander 2023-09-22 19:25 1451
    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2660ccea Poul Sander 2023-09-22 19:25 1452
#else
2660ccea Poul Sander 2023-09-22 19:25 1453
    #if !defined(JSON_HEDLEY_IS_CONSTANT)
2660ccea Poul Sander 2023-09-22 19:25 1454
        #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2660ccea Poul Sander 2023-09-22 19:25 1455
    #endif
2660ccea Poul Sander 2023-09-22 19:25 1456
    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2660ccea Poul Sander 2023-09-22 19:25 1457
#endif
2660ccea Poul Sander 2023-09-22 19:25 1458
2660ccea Poul Sander 2023-09-22 19:25 1459
#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2660ccea Poul Sander 2023-09-22 19:25 1460
    #undef JSON_HEDLEY_BEGIN_C_DECLS
2660ccea Poul Sander 2023-09-22 19:25 1461
#endif
2660ccea Poul Sander 2023-09-22 19:25 1462
#if defined(JSON_HEDLEY_END_C_DECLS)
2660ccea Poul Sander 2023-09-22 19:25 1463
    #undef JSON_HEDLEY_END_C_DECLS
2660ccea Poul Sander 2023-09-22 19:25 1464
#endif
2660ccea Poul Sander 2023-09-22 19:25 1465
#if defined(JSON_HEDLEY_C_DECL)
2660ccea Poul Sander 2023-09-22 19:25 1466
    #undef JSON_HEDLEY_C_DECL
2660ccea Poul Sander 2023-09-22 19:25 1467
#endif
2660ccea Poul Sander 2023-09-22 19:25 1468
#if defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1469
    #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2660ccea Poul Sander 2023-09-22 19:25 1470
    #define JSON_HEDLEY_END_C_DECLS }
2660ccea Poul Sander 2023-09-22 19:25 1471
    #define JSON_HEDLEY_C_DECL extern "C"
2660ccea Poul Sander 2023-09-22 19:25 1472
#else
2660ccea Poul Sander 2023-09-22 19:25 1473
    #define JSON_HEDLEY_BEGIN_C_DECLS
2660ccea Poul Sander 2023-09-22 19:25 1474
    #define JSON_HEDLEY_END_C_DECLS
2660ccea Poul Sander 2023-09-22 19:25 1475
    #define JSON_HEDLEY_C_DECL
2660ccea Poul Sander 2023-09-22 19:25 1476
#endif
2660ccea Poul Sander 2023-09-22 19:25 1477
2660ccea Poul Sander 2023-09-22 19:25 1478
#if defined(JSON_HEDLEY_STATIC_ASSERT)
2660ccea Poul Sander 2023-09-22 19:25 1479
    #undef JSON_HEDLEY_STATIC_ASSERT
2660ccea Poul Sander 2023-09-22 19:25 1480
#endif
2660ccea Poul Sander 2023-09-22 19:25 1481
#if \
2660ccea Poul Sander 2023-09-22 19:25 1482
  !defined(__cplusplus) && ( \
2660ccea Poul Sander 2023-09-22 19:25 1483
      (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2660ccea Poul Sander 2023-09-22 19:25 1484
      JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \
2660ccea Poul Sander 2023-09-22 19:25 1485
      JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1486
      JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1487
      defined(_Static_assert) \
2660ccea Poul Sander 2023-09-22 19:25 1488
    )
2660ccea Poul Sander 2023-09-22 19:25 1489
#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2660ccea Poul Sander 2023-09-22 19:25 1490
#elif \
2660ccea Poul Sander 2023-09-22 19:25 1491
  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2660ccea Poul Sander 2023-09-22 19:25 1492
  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1493
  (defined(__cplusplus) && JSON_HEDLEY_TI_VERSION_CHECK(8,3,0))
2660ccea Poul Sander 2023-09-22 19:25 1494
#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2660ccea Poul Sander 2023-09-22 19:25 1495
#else
2660ccea Poul Sander 2023-09-22 19:25 1496
#  define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2660ccea Poul Sander 2023-09-22 19:25 1497
#endif
2660ccea Poul Sander 2023-09-22 19:25 1498
2660ccea Poul Sander 2023-09-22 19:25 1499
#if defined(JSON_HEDLEY_CONST_CAST)
2660ccea Poul Sander 2023-09-22 19:25 1500
    #undef JSON_HEDLEY_CONST_CAST
2660ccea Poul Sander 2023-09-22 19:25 1501
#endif
2660ccea Poul Sander 2023-09-22 19:25 1502
#if defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1503
#  define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
2660ccea Poul Sander 2023-09-22 19:25 1504
#elif \
2660ccea Poul Sander 2023-09-22 19:25 1505
  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
2660ccea Poul Sander 2023-09-22 19:25 1506
  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1507
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1508
#  define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
2660ccea Poul Sander 2023-09-22 19:25 1509
        JSON_HEDLEY_DIAGNOSTIC_PUSH \
2660ccea Poul Sander 2023-09-22 19:25 1510
        JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
2660ccea Poul Sander 2023-09-22 19:25 1511
        ((T) (expr)); \
2660ccea Poul Sander 2023-09-22 19:25 1512
        JSON_HEDLEY_DIAGNOSTIC_POP \
2660ccea Poul Sander 2023-09-22 19:25 1513
    }))
2660ccea Poul Sander 2023-09-22 19:25 1514
#else
2660ccea Poul Sander 2023-09-22 19:25 1515
#  define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
2660ccea Poul Sander 2023-09-22 19:25 1516
#endif
2660ccea Poul Sander 2023-09-22 19:25 1517
2660ccea Poul Sander 2023-09-22 19:25 1518
#if defined(JSON_HEDLEY_REINTERPRET_CAST)
2660ccea Poul Sander 2023-09-22 19:25 1519
    #undef JSON_HEDLEY_REINTERPRET_CAST
2660ccea Poul Sander 2023-09-22 19:25 1520
#endif
2660ccea Poul Sander 2023-09-22 19:25 1521
#if defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1522
    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
2660ccea Poul Sander 2023-09-22 19:25 1523
#else
2660ccea Poul Sander 2023-09-22 19:25 1524
    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (*((T*) &(expr)))
2660ccea Poul Sander 2023-09-22 19:25 1525
#endif
2660ccea Poul Sander 2023-09-22 19:25 1526
2660ccea Poul Sander 2023-09-22 19:25 1527
#if defined(JSON_HEDLEY_STATIC_CAST)
2660ccea Poul Sander 2023-09-22 19:25 1528
    #undef JSON_HEDLEY_STATIC_CAST
2660ccea Poul Sander 2023-09-22 19:25 1529
#endif
2660ccea Poul Sander 2023-09-22 19:25 1530
#if defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1531
    #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
2660ccea Poul Sander 2023-09-22 19:25 1532
#else
2660ccea Poul Sander 2023-09-22 19:25 1533
    #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
2660ccea Poul Sander 2023-09-22 19:25 1534
#endif
2660ccea Poul Sander 2023-09-22 19:25 1535
2660ccea Poul Sander 2023-09-22 19:25 1536
#if defined(JSON_HEDLEY_CPP_CAST)
2660ccea Poul Sander 2023-09-22 19:25 1537
    #undef JSON_HEDLEY_CPP_CAST
2660ccea Poul Sander 2023-09-22 19:25 1538
#endif
2660ccea Poul Sander 2023-09-22 19:25 1539
#if defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1540
    #define JSON_HEDLEY_CPP_CAST(T, expr) static_cast<T>(expr)
2660ccea Poul Sander 2023-09-22 19:25 1541
#else
2660ccea Poul Sander 2023-09-22 19:25 1542
    #define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
2660ccea Poul Sander 2023-09-22 19:25 1543
#endif
2660ccea Poul Sander 2023-09-22 19:25 1544
2660ccea Poul Sander 2023-09-22 19:25 1545
#if defined(JSON_HEDLEY_NULL)
2660ccea Poul Sander 2023-09-22 19:25 1546
    #undef JSON_HEDLEY_NULL
2660ccea Poul Sander 2023-09-22 19:25 1547
#endif
2660ccea Poul Sander 2023-09-22 19:25 1548
#if defined(__cplusplus)
2660ccea Poul Sander 2023-09-22 19:25 1549
    #if __cplusplus >= 201103L
2660ccea Poul Sander 2023-09-22 19:25 1550
        #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2660ccea Poul Sander 2023-09-22 19:25 1551
    #elif defined(NULL)
2660ccea Poul Sander 2023-09-22 19:25 1552
        #define JSON_HEDLEY_NULL NULL
2660ccea Poul Sander 2023-09-22 19:25 1553
    #else
2660ccea Poul Sander 2023-09-22 19:25 1554
        #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2660ccea Poul Sander 2023-09-22 19:25 1555
    #endif
2660ccea Poul Sander 2023-09-22 19:25 1556
#elif defined(NULL)
2660ccea Poul Sander 2023-09-22 19:25 1557
    #define JSON_HEDLEY_NULL NULL
2660ccea Poul Sander 2023-09-22 19:25 1558
#else
2660ccea Poul Sander 2023-09-22 19:25 1559
    #define JSON_HEDLEY_NULL ((void*) 0)
2660ccea Poul Sander 2023-09-22 19:25 1560
#endif
2660ccea Poul Sander 2023-09-22 19:25 1561
2660ccea Poul Sander 2023-09-22 19:25 1562
#if defined(JSON_HEDLEY_MESSAGE)
2660ccea Poul Sander 2023-09-22 19:25 1563
    #undef JSON_HEDLEY_MESSAGE
2660ccea Poul Sander 2023-09-22 19:25 1564
#endif
2660ccea Poul Sander 2023-09-22 19:25 1565
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2660ccea Poul Sander 2023-09-22 19:25 1566
#  define JSON_HEDLEY_MESSAGE(msg) \
2660ccea Poul Sander 2023-09-22 19:25 1567
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
2660ccea Poul Sander 2023-09-22 19:25 1568
    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2660ccea Poul Sander 2023-09-22 19:25 1569
    JSON_HEDLEY_PRAGMA(message msg) \
2660ccea Poul Sander 2023-09-22 19:25 1570
    JSON_HEDLEY_DIAGNOSTIC_POP
2660ccea Poul Sander 2023-09-22 19:25 1571
#elif \
2660ccea Poul Sander 2023-09-22 19:25 1572
  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1573
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1574
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2660ccea Poul Sander 2023-09-22 19:25 1575
#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1576
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2660ccea Poul Sander 2023-09-22 19:25 1577
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1578
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2660ccea Poul Sander 2023-09-22 19:25 1579
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1580
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2660ccea Poul Sander 2023-09-22 19:25 1581
#else
2660ccea Poul Sander 2023-09-22 19:25 1582
#  define JSON_HEDLEY_MESSAGE(msg)
2660ccea Poul Sander 2023-09-22 19:25 1583
#endif
2660ccea Poul Sander 2023-09-22 19:25 1584
2660ccea Poul Sander 2023-09-22 19:25 1585
#if defined(JSON_HEDLEY_WARNING)
2660ccea Poul Sander 2023-09-22 19:25 1586
    #undef JSON_HEDLEY_WARNING
2660ccea Poul Sander 2023-09-22 19:25 1587
#endif
2660ccea Poul Sander 2023-09-22 19:25 1588
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2660ccea Poul Sander 2023-09-22 19:25 1589
#  define JSON_HEDLEY_WARNING(msg) \
2660ccea Poul Sander 2023-09-22 19:25 1590
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
2660ccea Poul Sander 2023-09-22 19:25 1591
    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2660ccea Poul Sander 2023-09-22 19:25 1592
    JSON_HEDLEY_PRAGMA(clang warning msg) \
2660ccea Poul Sander 2023-09-22 19:25 1593
    JSON_HEDLEY_DIAGNOSTIC_POP
2660ccea Poul Sander 2023-09-22 19:25 1594
#elif \
2660ccea Poul Sander 2023-09-22 19:25 1595
  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2660ccea Poul Sander 2023-09-22 19:25 1596
  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0)
2660ccea Poul Sander 2023-09-22 19:25 1597
#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2660ccea Poul Sander 2023-09-22 19:25 1598
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1599
#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2660ccea Poul Sander 2023-09-22 19:25 1600
#else
2660ccea Poul Sander 2023-09-22 19:25 1601
#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2660ccea Poul Sander 2023-09-22 19:25 1602
#endif
2660ccea Poul Sander 2023-09-22 19:25 1603
2660ccea Poul Sander 2023-09-22 19:25 1604
#if defined(JSON_HEDLEY_REQUIRE)
2660ccea Poul Sander 2023-09-22 19:25 1605
    #undef JSON_HEDLEY_REQUIRE
2660ccea Poul Sander 2023-09-22 19:25 1606
#endif
2660ccea Poul Sander 2023-09-22 19:25 1607
#if defined(JSON_HEDLEY_REQUIRE_MSG)
2660ccea Poul Sander 2023-09-22 19:25 1608
    #undef JSON_HEDLEY_REQUIRE_MSG
2660ccea Poul Sander 2023-09-22 19:25 1609
#endif
2660ccea Poul Sander 2023-09-22 19:25 1610
#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2660ccea Poul Sander 2023-09-22 19:25 1611
#  if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2660ccea Poul Sander 2023-09-22 19:25 1612
#    define JSON_HEDLEY_REQUIRE(expr) \
2660ccea Poul Sander 2023-09-22 19:25 1613
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
2660ccea Poul Sander 2023-09-22 19:25 1614
    _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2660ccea Poul Sander 2023-09-22 19:25 1615
    __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2660ccea Poul Sander 2023-09-22 19:25 1616
    JSON_HEDLEY_DIAGNOSTIC_POP
2660ccea Poul Sander 2023-09-22 19:25 1617
#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2660ccea Poul Sander 2023-09-22 19:25 1618
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
2660ccea Poul Sander 2023-09-22 19:25 1619
    _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2660ccea Poul Sander 2023-09-22 19:25 1620
    __attribute__((diagnose_if(!(expr), msg, "error"))) \
2660ccea Poul Sander 2023-09-22 19:25 1621
    JSON_HEDLEY_DIAGNOSTIC_POP
2660ccea Poul Sander 2023-09-22 19:25 1622
#  else
2660ccea Poul Sander 2023-09-22 19:25 1623
#    define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2660ccea Poul Sander 2023-09-22 19:25 1624
#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2660ccea Poul Sander 2023-09-22 19:25 1625
#  endif
2660ccea Poul Sander 2023-09-22 19:25 1626
#else
2660ccea Poul Sander 2023-09-22 19:25 1627
#  define JSON_HEDLEY_REQUIRE(expr)
2660ccea Poul Sander 2023-09-22 19:25 1628
#  define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2660ccea Poul Sander 2023-09-22 19:25 1629
#endif
2660ccea Poul Sander 2023-09-22 19:25 1630
2660ccea Poul Sander 2023-09-22 19:25 1631
#if defined(JSON_HEDLEY_FLAGS)
2660ccea Poul Sander 2023-09-22 19:25 1632
    #undef JSON_HEDLEY_FLAGS
2660ccea Poul Sander 2023-09-22 19:25 1633
#endif
2660ccea Poul Sander 2023-09-22 19:25 1634
#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
2660ccea Poul Sander 2023-09-22 19:25 1635
    #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2660ccea Poul Sander 2023-09-22 19:25 1636
#endif
2660ccea Poul Sander 2023-09-22 19:25 1637
2660ccea Poul Sander 2023-09-22 19:25 1638
#if defined(JSON_HEDLEY_FLAGS_CAST)
2660ccea Poul Sander 2023-09-22 19:25 1639
    #undef JSON_HEDLEY_FLAGS_CAST
2660ccea Poul Sander 2023-09-22 19:25 1640
#endif
2660ccea Poul Sander 2023-09-22 19:25 1641
#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1642
#  define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2660ccea Poul Sander 2023-09-22 19:25 1643
        JSON_HEDLEY_DIAGNOSTIC_PUSH \
2660ccea Poul Sander 2023-09-22 19:25 1644
        _Pragma("warning(disable:188)") \
2660ccea Poul Sander 2023-09-22 19:25 1645
        ((T) (expr)); \
2660ccea Poul Sander 2023-09-22 19:25 1646
        JSON_HEDLEY_DIAGNOSTIC_POP \
2660ccea Poul Sander 2023-09-22 19:25 1647
    }))
2660ccea Poul Sander 2023-09-22 19:25 1648
#else
2660ccea Poul Sander 2023-09-22 19:25 1649
#  define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2660ccea Poul Sander 2023-09-22 19:25 1650
#endif
2660ccea Poul Sander 2023-09-22 19:25 1651
2660ccea Poul Sander 2023-09-22 19:25 1652
#if defined(JSON_HEDLEY_EMPTY_BASES)
2660ccea Poul Sander 2023-09-22 19:25 1653
    #undef JSON_HEDLEY_EMPTY_BASES
2660ccea Poul Sander 2023-09-22 19:25 1654
#endif
2660ccea Poul Sander 2023-09-22 19:25 1655
#if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)
2660ccea Poul Sander 2023-09-22 19:25 1656
    #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2660ccea Poul Sander 2023-09-22 19:25 1657
#else
2660ccea Poul Sander 2023-09-22 19:25 1658
    #define JSON_HEDLEY_EMPTY_BASES
2660ccea Poul Sander 2023-09-22 19:25 1659
#endif
2660ccea Poul Sander 2023-09-22 19:25 1660
2660ccea Poul Sander 2023-09-22 19:25 1661
/* Remaining macros are deprecated. */
2660ccea Poul Sander 2023-09-22 19:25 1662
2660ccea Poul Sander 2023-09-22 19:25 1663
#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 1664
    #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 1665
#endif
2660ccea Poul Sander 2023-09-22 19:25 1666
#if defined(__clang__)
2660ccea Poul Sander 2023-09-22 19:25 1667
    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2660ccea Poul Sander 2023-09-22 19:25 1668
#else
2660ccea Poul Sander 2023-09-22 19:25 1669
    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2660ccea Poul Sander 2023-09-22 19:25 1670
#endif
2660ccea Poul Sander 2023-09-22 19:25 1671
2660ccea Poul Sander 2023-09-22 19:25 1672
#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 1673
    #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 1674
#endif
2660ccea Poul Sander 2023-09-22 19:25 1675
#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2660ccea Poul Sander 2023-09-22 19:25 1676
2660ccea Poul Sander 2023-09-22 19:25 1677
#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 1678
    #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 1679
#endif
2660ccea Poul Sander 2023-09-22 19:25 1680
#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2660ccea Poul Sander 2023-09-22 19:25 1681
2660ccea Poul Sander 2023-09-22 19:25 1682
#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2660ccea Poul Sander 2023-09-22 19:25 1683
    #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2660ccea Poul Sander 2023-09-22 19:25 1684
#endif
2660ccea Poul Sander 2023-09-22 19:25 1685
#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2660ccea Poul Sander 2023-09-22 19:25 1686
2660ccea Poul Sander 2023-09-22 19:25 1687
#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2660ccea Poul Sander 2023-09-22 19:25 1688
    #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2660ccea Poul Sander 2023-09-22 19:25 1689
#endif
2660ccea Poul Sander 2023-09-22 19:25 1690
#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2660ccea Poul Sander 2023-09-22 19:25 1691
2660ccea Poul Sander 2023-09-22 19:25 1692
#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2660ccea Poul Sander 2023-09-22 19:25 1693
    #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2660ccea Poul Sander 2023-09-22 19:25 1694
#endif
2660ccea Poul Sander 2023-09-22 19:25 1695
#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2660ccea Poul Sander 2023-09-22 19:25 1696
2660ccea Poul Sander 2023-09-22 19:25 1697
#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2660ccea Poul Sander 2023-09-22 19:25 1698
    #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 1699
#endif
2660ccea Poul Sander 2023-09-22 19:25 1700
#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2660ccea Poul Sander 2023-09-22 19:25 1701
2660ccea Poul Sander 2023-09-22 19:25 1702
#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2660ccea Poul Sander 2023-09-22 19:25 1703
    #undef JSON_HEDLEY_CLANG_HAS_WARNING
2660ccea Poul Sander 2023-09-22 19:25 1704
#endif
2660ccea Poul Sander 2023-09-22 19:25 1705
#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2660ccea Poul Sander 2023-09-22 19:25 1706
2660ccea Poul Sander 2023-09-22 19:25 1707
#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2660ccea Poul Sander 2023-09-22 19:25 1708
2660ccea Poul Sander 2023-09-22 19:25 1709
2660ccea Poul Sander 2023-09-22 19:25 1710
// This file contains all internal macro definitions
2660ccea Poul Sander 2023-09-22 19:25 1711
// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2660ccea Poul Sander 2023-09-22 19:25 1712
2660ccea Poul Sander 2023-09-22 19:25 1713
// exclude unsupported compilers
2660ccea Poul Sander 2023-09-22 19:25 1714
#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2660ccea Poul Sander 2023-09-22 19:25 1715
    #if defined(__clang__)
2660ccea Poul Sander 2023-09-22 19:25 1716
        #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2660ccea Poul Sander 2023-09-22 19:25 1717
            #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2660ccea Poul Sander 2023-09-22 19:25 1718
        #endif
2660ccea Poul Sander 2023-09-22 19:25 1719
    #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2660ccea Poul Sander 2023-09-22 19:25 1720
        #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2660ccea Poul Sander 2023-09-22 19:25 1721
            #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2660ccea Poul Sander 2023-09-22 19:25 1722
        #endif
2660ccea Poul Sander 2023-09-22 19:25 1723
    #endif
2660ccea Poul Sander 2023-09-22 19:25 1724
#endif
2660ccea Poul Sander 2023-09-22 19:25 1725
2660ccea Poul Sander 2023-09-22 19:25 1726
// C++ language standard detection
2660ccea Poul Sander 2023-09-22 19:25 1727
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2660ccea Poul Sander 2023-09-22 19:25 1728
    #define JSON_HAS_CPP_17
2660ccea Poul Sander 2023-09-22 19:25 1729
    #define JSON_HAS_CPP_14
2660ccea Poul Sander 2023-09-22 19:25 1730
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2660ccea Poul Sander 2023-09-22 19:25 1731
    #define JSON_HAS_CPP_14
2660ccea Poul Sander 2023-09-22 19:25 1732
#endif
2660ccea Poul Sander 2023-09-22 19:25 1733
2660ccea Poul Sander 2023-09-22 19:25 1734
// disable float-equal warnings on GCC/clang
2660ccea Poul Sander 2023-09-22 19:25 1735
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2660ccea Poul Sander 2023-09-22 19:25 1736
    #pragma GCC diagnostic push
2660ccea Poul Sander 2023-09-22 19:25 1737
    #pragma GCC diagnostic ignored "-Wfloat-equal"
2660ccea Poul Sander 2023-09-22 19:25 1738
#endif
2660ccea Poul Sander 2023-09-22 19:25 1739
2660ccea Poul Sander 2023-09-22 19:25 1740
// disable documentation warnings on clang
2660ccea Poul Sander 2023-09-22 19:25 1741
#if defined(__clang__)
2660ccea Poul Sander 2023-09-22 19:25 1742
    #pragma GCC diagnostic push
2660ccea Poul Sander 2023-09-22 19:25 1743
    #pragma GCC diagnostic ignored "-Wdocumentation"
2660ccea Poul Sander 2023-09-22 19:25 1744
#endif
2660ccea Poul Sander 2023-09-22 19:25 1745
2660ccea Poul Sander 2023-09-22 19:25 1746
// allow to disable exceptions
2660ccea Poul Sander 2023-09-22 19:25 1747
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2660ccea Poul Sander 2023-09-22 19:25 1748
    #define JSON_THROW(exception) throw exception
2660ccea Poul Sander 2023-09-22 19:25 1749
    #define JSON_TRY try
2660ccea Poul Sander 2023-09-22 19:25 1750
    #define JSON_CATCH(exception) catch(exception)
2660ccea Poul Sander 2023-09-22 19:25 1751
    #define JSON_INTERNAL_CATCH(exception) catch(exception)
2660ccea Poul Sander 2023-09-22 19:25 1752
#else
2660ccea Poul Sander 2023-09-22 19:25 1753
    #include <cstdlib>
2660ccea Poul Sander 2023-09-22 19:25 1754
    #define JSON_THROW(exception) std::abort()
2660ccea Poul Sander 2023-09-22 19:25 1755
    #define JSON_TRY if(true)
2660ccea Poul Sander 2023-09-22 19:25 1756
    #define JSON_CATCH(exception) if(false)
2660ccea Poul Sander 2023-09-22 19:25 1757
    #define JSON_INTERNAL_CATCH(exception) if(false)
2660ccea Poul Sander 2023-09-22 19:25 1758
#endif
2660ccea Poul Sander 2023-09-22 19:25 1759
2660ccea Poul Sander 2023-09-22 19:25 1760
// override exception macros
2660ccea Poul Sander 2023-09-22 19:25 1761
#if defined(JSON_THROW_USER)
2660ccea Poul Sander 2023-09-22 19:25 1762
    #undef JSON_THROW
2660ccea Poul Sander 2023-09-22 19:25 1763
    #define JSON_THROW JSON_THROW_USER
2660ccea Poul Sander 2023-09-22 19:25 1764
#endif
2660ccea Poul Sander 2023-09-22 19:25 1765
#if defined(JSON_TRY_USER)
2660ccea Poul Sander 2023-09-22 19:25 1766
    #undef JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 1767
    #define JSON_TRY JSON_TRY_USER
2660ccea Poul Sander 2023-09-22 19:25 1768
#endif
2660ccea Poul Sander 2023-09-22 19:25 1769
#if defined(JSON_CATCH_USER)
2660ccea Poul Sander 2023-09-22 19:25 1770
    #undef JSON_CATCH
2660ccea Poul Sander 2023-09-22 19:25 1771
    #define JSON_CATCH JSON_CATCH_USER
2660ccea Poul Sander 2023-09-22 19:25 1772
    #undef JSON_INTERNAL_CATCH
2660ccea Poul Sander 2023-09-22 19:25 1773
    #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2660ccea Poul Sander 2023-09-22 19:25 1774
#endif
2660ccea Poul Sander 2023-09-22 19:25 1775
#if defined(JSON_INTERNAL_CATCH_USER)
2660ccea Poul Sander 2023-09-22 19:25 1776
    #undef JSON_INTERNAL_CATCH
2660ccea Poul Sander 2023-09-22 19:25 1777
    #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2660ccea Poul Sander 2023-09-22 19:25 1778
#endif
2660ccea Poul Sander 2023-09-22 19:25 1779
2660ccea Poul Sander 2023-09-22 19:25 1780
/*!
2660ccea Poul Sander 2023-09-22 19:25 1781
@brief macro to briefly define a mapping between an enum and JSON
2660ccea Poul Sander 2023-09-22 19:25 1782
@def NLOHMANN_JSON_SERIALIZE_ENUM
2660ccea Poul Sander 2023-09-22 19:25 1783
@since version 3.4.0
2660ccea Poul Sander 2023-09-22 19:25 1784
*/
2660ccea Poul Sander 2023-09-22 19:25 1785
#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                            \
2660ccea Poul Sander 2023-09-22 19:25 1786
    template<typename BasicJsonType>                                                            \
2660ccea Poul Sander 2023-09-22 19:25 1787
    inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                   \
2660ccea Poul Sander 2023-09-22 19:25 1788
    {                                                                                           \
2660ccea Poul Sander 2023-09-22 19:25 1789
        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2660ccea Poul Sander 2023-09-22 19:25 1790
        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2660ccea Poul Sander 2023-09-22 19:25 1791
        auto it = std::find_if(std::begin(m), std::end(m),                                      \
2660ccea Poul Sander 2023-09-22 19:25 1792
                               [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool  \
2660ccea Poul Sander 2023-09-22 19:25 1793
        {                                                                                       \
2660ccea Poul Sander 2023-09-22 19:25 1794
            return ej_pair.first == e;                                                          \
2660ccea Poul Sander 2023-09-22 19:25 1795
        });                                                                                     \
2660ccea Poul Sander 2023-09-22 19:25 1796
        j = ((it != std::end(m)) ? it : std::begin(m))->second;                                 \
2660ccea Poul Sander 2023-09-22 19:25 1797
    }                                                                                           \
2660ccea Poul Sander 2023-09-22 19:25 1798
    template<typename BasicJsonType>                                                            \
2660ccea Poul Sander 2023-09-22 19:25 1799
    inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                 \
2660ccea Poul Sander 2023-09-22 19:25 1800
    {                                                                                           \
2660ccea Poul Sander 2023-09-22 19:25 1801
        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2660ccea Poul Sander 2023-09-22 19:25 1802
        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2660ccea Poul Sander 2023-09-22 19:25 1803
        auto it = std::find_if(std::begin(m), std::end(m),                                      \
2660ccea Poul Sander 2023-09-22 19:25 1804
                               [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2660ccea Poul Sander 2023-09-22 19:25 1805
        {                                                                                       \
2660ccea Poul Sander 2023-09-22 19:25 1806
            return ej_pair.second == j;                                                         \
2660ccea Poul Sander 2023-09-22 19:25 1807
        });                                                                                     \
2660ccea Poul Sander 2023-09-22 19:25 1808
        e = ((it != std::end(m)) ? it : std::begin(m))->first;                                  \
2660ccea Poul Sander 2023-09-22 19:25 1809
    }
2660ccea Poul Sander 2023-09-22 19:25 1810
2660ccea Poul Sander 2023-09-22 19:25 1811
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2660ccea Poul Sander 2023-09-22 19:25 1812
// may be removed in the future once the class is split.
2660ccea Poul Sander 2023-09-22 19:25 1813
2660ccea Poul Sander 2023-09-22 19:25 1814
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
2660ccea Poul Sander 2023-09-22 19:25 1815
    template<template<typename, typename, typename...> class ObjectType,   \
2660ccea Poul Sander 2023-09-22 19:25 1816
             template<typename, typename...> class ArrayType,              \
2660ccea Poul Sander 2023-09-22 19:25 1817
             class StringType, class BooleanType, class NumberIntegerType, \
2660ccea Poul Sander 2023-09-22 19:25 1818
             class NumberUnsignedType, class NumberFloatType,              \
2660ccea Poul Sander 2023-09-22 19:25 1819
             template<typename> class AllocatorType,                       \
2660ccea Poul Sander 2023-09-22 19:25 1820
             template<typename, typename = void> class JSONSerializer>
2660ccea Poul Sander 2023-09-22 19:25 1821
2660ccea Poul Sander 2023-09-22 19:25 1822
#define NLOHMANN_BASIC_JSON_TPL                                            \
2660ccea Poul Sander 2023-09-22 19:25 1823
    basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
2660ccea Poul Sander 2023-09-22 19:25 1824
    NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
2660ccea Poul Sander 2023-09-22 19:25 1825
    AllocatorType, JSONSerializer>
2660ccea Poul Sander 2023-09-22 19:25 1826
2660ccea Poul Sander 2023-09-22 19:25 1827
2660ccea Poul Sander 2023-09-22 19:25 1828
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 1829
{
2660ccea Poul Sander 2023-09-22 19:25 1830
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 1831
{
2660ccea Poul Sander 2023-09-22 19:25 1832
////////////////
2660ccea Poul Sander 2023-09-22 19:25 1833
// exceptions //
2660ccea Poul Sander 2023-09-22 19:25 1834
////////////////
2660ccea Poul Sander 2023-09-22 19:25 1835
2660ccea Poul Sander 2023-09-22 19:25 1836
/*!
2660ccea Poul Sander 2023-09-22 19:25 1837
@brief general exception of the @ref basic_json class
2660ccea Poul Sander 2023-09-22 19:25 1838
2660ccea Poul Sander 2023-09-22 19:25 1839
This class is an extension of `std::exception` objects with a member @a id for
2660ccea Poul Sander 2023-09-22 19:25 1840
exception ids. It is used as the base class for all exceptions thrown by the
2660ccea Poul Sander 2023-09-22 19:25 1841
@ref basic_json class. This class can hence be used as "wildcard" to catch
2660ccea Poul Sander 2023-09-22 19:25 1842
exceptions.
2660ccea Poul Sander 2023-09-22 19:25 1843
2660ccea Poul Sander 2023-09-22 19:25 1844
Subclasses:
2660ccea Poul Sander 2023-09-22 19:25 1845
- @ref parse_error for exceptions indicating a parse error
2660ccea Poul Sander 2023-09-22 19:25 1846
- @ref invalid_iterator for exceptions indicating errors with iterators
2660ccea Poul Sander 2023-09-22 19:25 1847
- @ref type_error for exceptions indicating executing a member function with
2660ccea Poul Sander 2023-09-22 19:25 1848
                  a wrong type
2660ccea Poul Sander 2023-09-22 19:25 1849
- @ref out_of_range for exceptions indicating access out of the defined range
2660ccea Poul Sander 2023-09-22 19:25 1850
- @ref other_error for exceptions indicating other library errors
2660ccea Poul Sander 2023-09-22 19:25 1851
2660ccea Poul Sander 2023-09-22 19:25 1852
@internal
2660ccea Poul Sander 2023-09-22 19:25 1853
@note To have nothrow-copy-constructible exceptions, we internally use
2660ccea Poul Sander 2023-09-22 19:25 1854
      `std::runtime_error` which can cope with arbitrary-length error messages.
2660ccea Poul Sander 2023-09-22 19:25 1855
      Intermediate strings are built with static functions and then passed to
2660ccea Poul Sander 2023-09-22 19:25 1856
      the actual constructor.
2660ccea Poul Sander 2023-09-22 19:25 1857
@endinternal
2660ccea Poul Sander 2023-09-22 19:25 1858
2660ccea Poul Sander 2023-09-22 19:25 1859
@liveexample{The following code shows how arbitrary library exceptions can be
2660ccea Poul Sander 2023-09-22 19:25 1860
caught.,exception}
2660ccea Poul Sander 2023-09-22 19:25 1861
2660ccea Poul Sander 2023-09-22 19:25 1862
@since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 1863
*/
2660ccea Poul Sander 2023-09-22 19:25 1864
class exception : public std::exception
2660ccea Poul Sander 2023-09-22 19:25 1865
{
2660ccea Poul Sander 2023-09-22 19:25 1866
  public:
2660ccea Poul Sander 2023-09-22 19:25 1867
    /// returns the explanatory string
2660ccea Poul Sander 2023-09-22 19:25 1868
    JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 1869
    const char* what() const noexcept override
2660ccea Poul Sander 2023-09-22 19:25 1870
    {
2660ccea Poul Sander 2023-09-22 19:25 1871
        return m.what();
2660ccea Poul Sander 2023-09-22 19:25 1872
    }
2660ccea Poul Sander 2023-09-22 19:25 1873
2660ccea Poul Sander 2023-09-22 19:25 1874
    /// the id of the exception
2660ccea Poul Sander 2023-09-22 19:25 1875
    const int id;
2660ccea Poul Sander 2023-09-22 19:25 1876
2660ccea Poul Sander 2023-09-22 19:25 1877
  protected:
2660ccea Poul Sander 2023-09-22 19:25 1878
    JSON_HEDLEY_NON_NULL(3)
2660ccea Poul Sander 2023-09-22 19:25 1879
    exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2660ccea Poul Sander 2023-09-22 19:25 1880
2660ccea Poul Sander 2023-09-22 19:25 1881
    static std::string name(const std::string& ename, int id_)
2660ccea Poul Sander 2023-09-22 19:25 1882
    {
2660ccea Poul Sander 2023-09-22 19:25 1883
        return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2660ccea Poul Sander 2023-09-22 19:25 1884
    }
2660ccea Poul Sander 2023-09-22 19:25 1885
2660ccea Poul Sander 2023-09-22 19:25 1886
  private:
2660ccea Poul Sander 2023-09-22 19:25 1887
    /// an exception object as storage for error messages
2660ccea Poul Sander 2023-09-22 19:25 1888
    std::runtime_error m;
2660ccea Poul Sander 2023-09-22 19:25 1889
};
2660ccea Poul Sander 2023-09-22 19:25 1890
2660ccea Poul Sander 2023-09-22 19:25 1891
/*!
2660ccea Poul Sander 2023-09-22 19:25 1892
@brief exception indicating a parse error
2660ccea Poul Sander 2023-09-22 19:25 1893
2660ccea Poul Sander 2023-09-22 19:25 1894
This exception is thrown by the library when a parse error occurs. Parse errors
2660ccea Poul Sander 2023-09-22 19:25 1895
can occur during the deserialization of JSON text, CBOR, MessagePack, as well
2660ccea Poul Sander 2023-09-22 19:25 1896
as when using JSON Patch.
2660ccea Poul Sander 2023-09-22 19:25 1897
2660ccea Poul Sander 2023-09-22 19:25 1898
Member @a byte holds the byte index of the last read character in the input
2660ccea Poul Sander 2023-09-22 19:25 1899
file.
2660ccea Poul Sander 2023-09-22 19:25 1900
2660ccea Poul Sander 2023-09-22 19:25 1901
Exceptions have ids 1xx.
2660ccea Poul Sander 2023-09-22 19:25 1902
2660ccea Poul Sander 2023-09-22 19:25 1903
name / id                      | example message | description
2660ccea Poul Sander 2023-09-22 19:25 1904
------------------------------ | --------------- | -------------------------
2660ccea Poul Sander 2023-09-22 19:25 1905
json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position.
2660ccea Poul Sander 2023-09-22 19:25 1906
json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
2660ccea Poul Sander 2023-09-22 19:25 1907
json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
2660ccea Poul Sander 2023-09-22 19:25 1908
json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.
2660ccea Poul Sander 2023-09-22 19:25 1909
json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.
2660ccea Poul Sander 2023-09-22 19:25 1910
json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.
2660ccea Poul Sander 2023-09-22 19:25 1911
json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.
2660ccea Poul Sander 2023-09-22 19:25 1912
json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences.
2660ccea Poul Sander 2023-09-22 19:25 1913
json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
2660ccea Poul Sander 2023-09-22 19:25 1914
json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
2660ccea Poul Sander 2023-09-22 19:25 1915
json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
2660ccea Poul Sander 2023-09-22 19:25 1916
json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
2660ccea Poul Sander 2023-09-22 19:25 1917
json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
2660ccea Poul Sander 2023-09-22 19:25 1918
2660ccea Poul Sander 2023-09-22 19:25 1919
@note For an input with n bytes, 1 is the index of the first character and n+1
2660ccea Poul Sander 2023-09-22 19:25 1920
      is the index of the terminating null byte or the end of file. This also
2660ccea Poul Sander 2023-09-22 19:25 1921
      holds true when reading a byte vector (CBOR or MessagePack).
2660ccea Poul Sander 2023-09-22 19:25 1922
2660ccea Poul Sander 2023-09-22 19:25 1923
@liveexample{The following code shows how a `parse_error` exception can be
2660ccea Poul Sander 2023-09-22 19:25 1924
caught.,parse_error}
2660ccea Poul Sander 2023-09-22 19:25 1925
2660ccea Poul Sander 2023-09-22 19:25 1926
@sa - @ref exception for the base class of the library exceptions
2660ccea Poul Sander 2023-09-22 19:25 1927
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
2660ccea Poul Sander 2023-09-22 19:25 1928
@sa - @ref type_error for exceptions indicating executing a member function with
2660ccea Poul Sander 2023-09-22 19:25 1929
                    a wrong type
2660ccea Poul Sander 2023-09-22 19:25 1930
@sa - @ref out_of_range for exceptions indicating access out of the defined range
2660ccea Poul Sander 2023-09-22 19:25 1931
@sa - @ref other_error for exceptions indicating other library errors
2660ccea Poul Sander 2023-09-22 19:25 1932
2660ccea Poul Sander 2023-09-22 19:25 1933
@since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 1934
*/
2660ccea Poul Sander 2023-09-22 19:25 1935
class parse_error : public exception
2660ccea Poul Sander 2023-09-22 19:25 1936
{
2660ccea Poul Sander 2023-09-22 19:25 1937
  public:
2660ccea Poul Sander 2023-09-22 19:25 1938
    /*!
2660ccea Poul Sander 2023-09-22 19:25 1939
    @brief create a parse error exception
2660ccea Poul Sander 2023-09-22 19:25 1940
    @param[in] id_       the id of the exception
2660ccea Poul Sander 2023-09-22 19:25 1941
    @param[in] pos       the position where the error occurred (or with
2660ccea Poul Sander 2023-09-22 19:25 1942
                         chars_read_total=0 if the position cannot be
2660ccea Poul Sander 2023-09-22 19:25 1943
                         determined)
2660ccea Poul Sander 2023-09-22 19:25 1944
    @param[in] what_arg  the explanatory string
2660ccea Poul Sander 2023-09-22 19:25 1945
    @return parse_error object
2660ccea Poul Sander 2023-09-22 19:25 1946
    */
2660ccea Poul Sander 2023-09-22 19:25 1947
    static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
2660ccea Poul Sander 2023-09-22 19:25 1948
    {
2660ccea Poul Sander 2023-09-22 19:25 1949
        std::string w = exception::name("parse_error", id_) + "parse error" +
2660ccea Poul Sander 2023-09-22 19:25 1950
                        position_string(pos) + ": " + what_arg;
2660ccea Poul Sander 2023-09-22 19:25 1951
        return parse_error(id_, pos.chars_read_total, w.c_str());
2660ccea Poul Sander 2023-09-22 19:25 1952
    }
2660ccea Poul Sander 2023-09-22 19:25 1953
2660ccea Poul Sander 2023-09-22 19:25 1954
    static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
2660ccea Poul Sander 2023-09-22 19:25 1955
    {
2660ccea Poul Sander 2023-09-22 19:25 1956
        std::string w = exception::name("parse_error", id_) + "parse error" +
2660ccea Poul Sander 2023-09-22 19:25 1957
                        (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2660ccea Poul Sander 2023-09-22 19:25 1958
                        ": " + what_arg;
2660ccea Poul Sander 2023-09-22 19:25 1959
        return parse_error(id_, byte_, w.c_str());
2660ccea Poul Sander 2023-09-22 19:25 1960
    }
2660ccea Poul Sander 2023-09-22 19:25 1961
2660ccea Poul Sander 2023-09-22 19:25 1962
    /*!
2660ccea Poul Sander 2023-09-22 19:25 1963
    @brief byte index of the parse error
2660ccea Poul Sander 2023-09-22 19:25 1964
2660ccea Poul Sander 2023-09-22 19:25 1965
    The byte index of the last read character in the input file.
2660ccea Poul Sander 2023-09-22 19:25 1966
2660ccea Poul Sander 2023-09-22 19:25 1967
    @note For an input with n bytes, 1 is the index of the first character and
2660ccea Poul Sander 2023-09-22 19:25 1968
          n+1 is the index of the terminating null byte or the end of file.
2660ccea Poul Sander 2023-09-22 19:25 1969
          This also holds true when reading a byte vector (CBOR or MessagePack).
2660ccea Poul Sander 2023-09-22 19:25 1970
    */
2660ccea Poul Sander 2023-09-22 19:25 1971
    const std::size_t byte;
2660ccea Poul Sander 2023-09-22 19:25 1972
2660ccea Poul Sander 2023-09-22 19:25 1973
  private:
2660ccea Poul Sander 2023-09-22 19:25 1974
    parse_error(int id_, std::size_t byte_, const char* what_arg)
2660ccea Poul Sander 2023-09-22 19:25 1975
        : exception(id_, what_arg), byte(byte_) {}
2660ccea Poul Sander 2023-09-22 19:25 1976
2660ccea Poul Sander 2023-09-22 19:25 1977
    static std::string position_string(const position_t& pos)
2660ccea Poul Sander 2023-09-22 19:25 1978
    {
2660ccea Poul Sander 2023-09-22 19:25 1979
        return " at line " + std::to_string(pos.lines_read + 1) +
2660ccea Poul Sander 2023-09-22 19:25 1980
               ", column " + std::to_string(pos.chars_read_current_line);
2660ccea Poul Sander 2023-09-22 19:25 1981
    }
2660ccea Poul Sander 2023-09-22 19:25 1982
};
2660ccea Poul Sander 2023-09-22 19:25 1983
2660ccea Poul Sander 2023-09-22 19:25 1984
/*!
2660ccea Poul Sander 2023-09-22 19:25 1985
@brief exception indicating errors with iterators
2660ccea Poul Sander 2023-09-22 19:25 1986
2660ccea Poul Sander 2023-09-22 19:25 1987
This exception is thrown if iterators passed to a library function do not match
2660ccea Poul Sander 2023-09-22 19:25 1988
the expected semantics.
2660ccea Poul Sander 2023-09-22 19:25 1989
2660ccea Poul Sander 2023-09-22 19:25 1990
Exceptions have ids 2xx.
2660ccea Poul Sander 2023-09-22 19:25 1991
2660ccea Poul Sander 2023-09-22 19:25 1992
name / id                           | example message | description
2660ccea Poul Sander 2023-09-22 19:25 1993
----------------------------------- | --------------- | -------------------------
2660ccea Poul Sander 2023-09-22 19:25 1994
json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
2660ccea Poul Sander 2023-09-22 19:25 1995
json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
2660ccea Poul Sander 2023-09-22 19:25 1996
json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
2660ccea Poul Sander 2023-09-22 19:25 1997
json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid.
2660ccea Poul Sander 2023-09-22 19:25 1998
json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.
2660ccea Poul Sander 2023-09-22 19:25 1999
json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.
2660ccea Poul Sander 2023-09-22 19:25 2000
json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
2660ccea Poul Sander 2023-09-22 19:25 2001
json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
2660ccea Poul Sander 2023-09-22 19:25 2002
json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
2660ccea Poul Sander 2023-09-22 19:25 2003
json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
2660ccea Poul Sander 2023-09-22 19:25 2004
json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to.
2660ccea Poul Sander 2023-09-22 19:25 2005
json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
2660ccea Poul Sander 2023-09-22 19:25 2006
json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
2660ccea Poul Sander 2023-09-22 19:25 2007
json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin().
2660ccea Poul Sander 2023-09-22 19:25 2008
2660ccea Poul Sander 2023-09-22 19:25 2009
@liveexample{The following code shows how an `invalid_iterator` exception can be
2660ccea Poul Sander 2023-09-22 19:25 2010
caught.,invalid_iterator}
2660ccea Poul Sander 2023-09-22 19:25 2011
2660ccea Poul Sander 2023-09-22 19:25 2012
@sa - @ref exception for the base class of the library exceptions
2660ccea Poul Sander 2023-09-22 19:25 2013
@sa - @ref parse_error for exceptions indicating a parse error
2660ccea Poul Sander 2023-09-22 19:25 2014
@sa - @ref type_error for exceptions indicating executing a member function with
2660ccea Poul Sander 2023-09-22 19:25 2015
                    a wrong type
2660ccea Poul Sander 2023-09-22 19:25 2016
@sa - @ref out_of_range for exceptions indicating access out of the defined range
2660ccea Poul Sander 2023-09-22 19:25 2017
@sa - @ref other_error for exceptions indicating other library errors
2660ccea Poul Sander 2023-09-22 19:25 2018
2660ccea Poul Sander 2023-09-22 19:25 2019
@since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 2020
*/
2660ccea Poul Sander 2023-09-22 19:25 2021
class invalid_iterator : public exception
2660ccea Poul Sander 2023-09-22 19:25 2022
{
2660ccea Poul Sander 2023-09-22 19:25 2023
  public:
2660ccea Poul Sander 2023-09-22 19:25 2024
    static invalid_iterator create(int id_, const std::string& what_arg)
2660ccea Poul Sander 2023-09-22 19:25 2025
    {
2660ccea Poul Sander 2023-09-22 19:25 2026
        std::string w = exception::name("invalid_iterator", id_) + what_arg;
2660ccea Poul Sander 2023-09-22 19:25 2027
        return invalid_iterator(id_, w.c_str());
2660ccea Poul Sander 2023-09-22 19:25 2028
    }
2660ccea Poul Sander 2023-09-22 19:25 2029
2660ccea Poul Sander 2023-09-22 19:25 2030
  private:
2660ccea Poul Sander 2023-09-22 19:25 2031
    JSON_HEDLEY_NON_NULL(3)
2660ccea Poul Sander 2023-09-22 19:25 2032
    invalid_iterator(int id_, const char* what_arg)
2660ccea Poul Sander 2023-09-22 19:25 2033
        : exception(id_, what_arg) {}
2660ccea Poul Sander 2023-09-22 19:25 2034
};
2660ccea Poul Sander 2023-09-22 19:25 2035
2660ccea Poul Sander 2023-09-22 19:25 2036
/*!
2660ccea Poul Sander 2023-09-22 19:25 2037
@brief exception indicating executing a member function with a wrong type
2660ccea Poul Sander 2023-09-22 19:25 2038
2660ccea Poul Sander 2023-09-22 19:25 2039
This exception is thrown in case of a type error; that is, a library function is
2660ccea Poul Sander 2023-09-22 19:25 2040
executed on a JSON value whose type does not match the expected semantics.
2660ccea Poul Sander 2023-09-22 19:25 2041
2660ccea Poul Sander 2023-09-22 19:25 2042
Exceptions have ids 3xx.
2660ccea Poul Sander 2023-09-22 19:25 2043
2660ccea Poul Sander 2023-09-22 19:25 2044
name / id                     | example message | description
2660ccea Poul Sander 2023-09-22 19:25 2045
----------------------------- | --------------- | -------------------------
2660ccea Poul Sander 2023-09-22 19:25 2046
json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
2660ccea Poul Sander 2023-09-22 19:25 2047
json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
2660ccea Poul Sander 2023-09-22 19:25 2048
json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &.
2660ccea Poul Sander 2023-09-22 19:25 2049
json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
2660ccea Poul Sander 2023-09-22 19:25 2050
json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
2660ccea Poul Sander 2023-09-22 19:25 2051
json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
2660ccea Poul Sander 2023-09-22 19:25 2052
json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
2660ccea Poul Sander 2023-09-22 19:25 2053
json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types.
2660ccea Poul Sander 2023-09-22 19:25 2054
json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
2660ccea Poul Sander 2023-09-22 19:25 2055
json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
2660ccea Poul Sander 2023-09-22 19:25 2056
json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
2660ccea Poul Sander 2023-09-22 19:25 2057
json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
2660ccea Poul Sander 2023-09-22 19:25 2058
json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.
2660ccea Poul Sander 2023-09-22 19:25 2059
json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
2660ccea Poul Sander 2023-09-22 19:25 2060
json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.
2660ccea Poul Sander 2023-09-22 19:25 2061
json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |
2660ccea Poul Sander 2023-09-22 19:25 2062
json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) |
2660ccea Poul Sander 2023-09-22 19:25 2063
2660ccea Poul Sander 2023-09-22 19:25 2064
@liveexample{The following code shows how a `type_error` exception can be
2660ccea Poul Sander 2023-09-22 19:25 2065
caught.,type_error}
2660ccea Poul Sander 2023-09-22 19:25 2066
2660ccea Poul Sander 2023-09-22 19:25 2067
@sa - @ref exception for the base class of the library exceptions
2660ccea Poul Sander 2023-09-22 19:25 2068
@sa - @ref parse_error for exceptions indicating a parse error
2660ccea Poul Sander 2023-09-22 19:25 2069
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
2660ccea Poul Sander 2023-09-22 19:25 2070
@sa - @ref out_of_range for exceptions indicating access out of the defined range
2660ccea Poul Sander 2023-09-22 19:25 2071
@sa - @ref other_error for exceptions indicating other library errors
2660ccea Poul Sander 2023-09-22 19:25 2072
2660ccea Poul Sander 2023-09-22 19:25 2073
@since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 2074
*/
2660ccea Poul Sander 2023-09-22 19:25 2075
class type_error : public exception
2660ccea Poul Sander 2023-09-22 19:25 2076
{
2660ccea Poul Sander 2023-09-22 19:25 2077
  public:
2660ccea Poul Sander 2023-09-22 19:25 2078
    static type_error create(int id_, const std::string& what_arg)
2660ccea Poul Sander 2023-09-22 19:25 2079
    {
2660ccea Poul Sander 2023-09-22 19:25 2080
        std::string w = exception::name("type_error", id_) + what_arg;
2660ccea Poul Sander 2023-09-22 19:25 2081
        return type_error(id_, w.c_str());
2660ccea Poul Sander 2023-09-22 19:25 2082
    }
2660ccea Poul Sander 2023-09-22 19:25 2083
2660ccea Poul Sander 2023-09-22 19:25 2084
  private:
2660ccea Poul Sander 2023-09-22 19:25 2085
    JSON_HEDLEY_NON_NULL(3)
2660ccea Poul Sander 2023-09-22 19:25 2086
    type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2660ccea Poul Sander 2023-09-22 19:25 2087
};
2660ccea Poul Sander 2023-09-22 19:25 2088
2660ccea Poul Sander 2023-09-22 19:25 2089
/*!
2660ccea Poul Sander 2023-09-22 19:25 2090
@brief exception indicating access out of the defined range
2660ccea Poul Sander 2023-09-22 19:25 2091
2660ccea Poul Sander 2023-09-22 19:25 2092
This exception is thrown in case a library function is called on an input
2660ccea Poul Sander 2023-09-22 19:25 2093
parameter that exceeds the expected range, for instance in case of array
2660ccea Poul Sander 2023-09-22 19:25 2094
indices or nonexisting object keys.
2660ccea Poul Sander 2023-09-22 19:25 2095
2660ccea Poul Sander 2023-09-22 19:25 2096
Exceptions have ids 4xx.
2660ccea Poul Sander 2023-09-22 19:25 2097
2660ccea Poul Sander 2023-09-22 19:25 2098
name / id                       | example message | description
2660ccea Poul Sander 2023-09-22 19:25 2099
------------------------------- | --------------- | -------------------------
2660ccea Poul Sander 2023-09-22 19:25 2100
json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
2660ccea Poul Sander 2023-09-22 19:25 2101
json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
2660ccea Poul Sander 2023-09-22 19:25 2102
json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
2660ccea Poul Sander 2023-09-22 19:25 2103
json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
2660ccea Poul Sander 2023-09-22 19:25 2104
json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 2105
json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
2660ccea Poul Sander 2023-09-22 19:25 2106
json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. |
2660ccea Poul Sander 2023-09-22 19:25 2107
json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
2660ccea Poul Sander 2023-09-22 19:25 2108
json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string |
2660ccea Poul Sander 2023-09-22 19:25 2109
2660ccea Poul Sander 2023-09-22 19:25 2110
@liveexample{The following code shows how an `out_of_range` exception can be
2660ccea Poul Sander 2023-09-22 19:25 2111
caught.,out_of_range}
2660ccea Poul Sander 2023-09-22 19:25 2112
2660ccea Poul Sander 2023-09-22 19:25 2113
@sa - @ref exception for the base class of the library exceptions
2660ccea Poul Sander 2023-09-22 19:25 2114
@sa - @ref parse_error for exceptions indicating a parse error
2660ccea Poul Sander 2023-09-22 19:25 2115
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
2660ccea Poul Sander 2023-09-22 19:25 2116
@sa - @ref type_error for exceptions indicating executing a member function with
2660ccea Poul Sander 2023-09-22 19:25 2117
                    a wrong type
2660ccea Poul Sander 2023-09-22 19:25 2118
@sa - @ref other_error for exceptions indicating other library errors
2660ccea Poul Sander 2023-09-22 19:25 2119
2660ccea Poul Sander 2023-09-22 19:25 2120
@since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 2121
*/
2660ccea Poul Sander 2023-09-22 19:25 2122
class out_of_range : public exception
2660ccea Poul Sander 2023-09-22 19:25 2123
{
2660ccea Poul Sander 2023-09-22 19:25 2124
  public:
2660ccea Poul Sander 2023-09-22 19:25 2125
    static out_of_range create(int id_, const std::string& what_arg)
2660ccea Poul Sander 2023-09-22 19:25 2126
    {
2660ccea Poul Sander 2023-09-22 19:25 2127
        std::string w = exception::name("out_of_range", id_) + what_arg;
2660ccea Poul Sander 2023-09-22 19:25 2128
        return out_of_range(id_, w.c_str());
2660ccea Poul Sander 2023-09-22 19:25 2129
    }
2660ccea Poul Sander 2023-09-22 19:25 2130
2660ccea Poul Sander 2023-09-22 19:25 2131
  private:
2660ccea Poul Sander 2023-09-22 19:25 2132
    JSON_HEDLEY_NON_NULL(3)
2660ccea Poul Sander 2023-09-22 19:25 2133
    out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2660ccea Poul Sander 2023-09-22 19:25 2134
};
2660ccea Poul Sander 2023-09-22 19:25 2135
2660ccea Poul Sander 2023-09-22 19:25 2136
/*!
2660ccea Poul Sander 2023-09-22 19:25 2137
@brief exception indicating other library errors
2660ccea Poul Sander 2023-09-22 19:25 2138
2660ccea Poul Sander 2023-09-22 19:25 2139
This exception is thrown in case of errors that cannot be classified with the
2660ccea Poul Sander 2023-09-22 19:25 2140
other exception types.
2660ccea Poul Sander 2023-09-22 19:25 2141
2660ccea Poul Sander 2023-09-22 19:25 2142
Exceptions have ids 5xx.
2660ccea Poul Sander 2023-09-22 19:25 2143
2660ccea Poul Sander 2023-09-22 19:25 2144
name / id                      | example message | description
2660ccea Poul Sander 2023-09-22 19:25 2145
------------------------------ | --------------- | -------------------------
2660ccea Poul Sander 2023-09-22 19:25 2146
json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
2660ccea Poul Sander 2023-09-22 19:25 2147
2660ccea Poul Sander 2023-09-22 19:25 2148
@sa - @ref exception for the base class of the library exceptions
2660ccea Poul Sander 2023-09-22 19:25 2149
@sa - @ref parse_error for exceptions indicating a parse error
2660ccea Poul Sander 2023-09-22 19:25 2150
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
2660ccea Poul Sander 2023-09-22 19:25 2151
@sa - @ref type_error for exceptions indicating executing a member function with
2660ccea Poul Sander 2023-09-22 19:25 2152
                    a wrong type
2660ccea Poul Sander 2023-09-22 19:25 2153
@sa - @ref out_of_range for exceptions indicating access out of the defined range
2660ccea Poul Sander 2023-09-22 19:25 2154
2660ccea Poul Sander 2023-09-22 19:25 2155
@liveexample{The following code shows how an `other_error` exception can be
2660ccea Poul Sander 2023-09-22 19:25 2156
caught.,other_error}
2660ccea Poul Sander 2023-09-22 19:25 2157
2660ccea Poul Sander 2023-09-22 19:25 2158
@since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 2159
*/
2660ccea Poul Sander 2023-09-22 19:25 2160
class other_error : public exception
2660ccea Poul Sander 2023-09-22 19:25 2161
{
2660ccea Poul Sander 2023-09-22 19:25 2162
  public:
2660ccea Poul Sander 2023-09-22 19:25 2163
    static other_error create(int id_, const std::string& what_arg)
2660ccea Poul Sander 2023-09-22 19:25 2164
    {
2660ccea Poul Sander 2023-09-22 19:25 2165
        std::string w = exception::name("other_error", id_) + what_arg;
2660ccea Poul Sander 2023-09-22 19:25 2166
        return other_error(id_, w.c_str());
2660ccea Poul Sander 2023-09-22 19:25 2167
    }
2660ccea Poul Sander 2023-09-22 19:25 2168
2660ccea Poul Sander 2023-09-22 19:25 2169
  private:
2660ccea Poul Sander 2023-09-22 19:25 2170
    JSON_HEDLEY_NON_NULL(3)
2660ccea Poul Sander 2023-09-22 19:25 2171
    other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2660ccea Poul Sander 2023-09-22 19:25 2172
};
2660ccea Poul Sander 2023-09-22 19:25 2173
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2174
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2175
2660ccea Poul Sander 2023-09-22 19:25 2176
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2177
2660ccea Poul Sander 2023-09-22 19:25 2178
// #include <nlohmann/detail/meta/cpp_future.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2179
2660ccea Poul Sander 2023-09-22 19:25 2180
2660ccea Poul Sander 2023-09-22 19:25 2181
#include <ciso646> // not
2660ccea Poul Sander 2023-09-22 19:25 2182
#include <cstddef> // size_t
2660ccea Poul Sander 2023-09-22 19:25 2183
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2660ccea Poul Sander 2023-09-22 19:25 2184
2660ccea Poul Sander 2023-09-22 19:25 2185
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2186
{
2660ccea Poul Sander 2023-09-22 19:25 2187
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2188
{
2660ccea Poul Sander 2023-09-22 19:25 2189
// alias templates to reduce boilerplate
2660ccea Poul Sander 2023-09-22 19:25 2190
template<bool B, typename T = void>
2660ccea Poul Sander 2023-09-22 19:25 2191
using enable_if_t = typename std::enable_if<B, T>::type;
2660ccea Poul Sander 2023-09-22 19:25 2192
2660ccea Poul Sander 2023-09-22 19:25 2193
template<typename T>
2660ccea Poul Sander 2023-09-22 19:25 2194
using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2660ccea Poul Sander 2023-09-22 19:25 2195
2660ccea Poul Sander 2023-09-22 19:25 2196
// implementation of C++14 index_sequence and affiliates
2660ccea Poul Sander 2023-09-22 19:25 2197
// source: https://stackoverflow.com/a/32223343
2660ccea Poul Sander 2023-09-22 19:25 2198
template<std::size_t... Ints>
2660ccea Poul Sander 2023-09-22 19:25 2199
struct index_sequence
2660ccea Poul Sander 2023-09-22 19:25 2200
{
2660ccea Poul Sander 2023-09-22 19:25 2201
    using type = index_sequence;
2660ccea Poul Sander 2023-09-22 19:25 2202
    using value_type = std::size_t;
2660ccea Poul Sander 2023-09-22 19:25 2203
    static constexpr std::size_t size() noexcept
2660ccea Poul Sander 2023-09-22 19:25 2204
    {
2660ccea Poul Sander 2023-09-22 19:25 2205
        return sizeof...(Ints);
2660ccea Poul Sander 2023-09-22 19:25 2206
    }
2660ccea Poul Sander 2023-09-22 19:25 2207
};
2660ccea Poul Sander 2023-09-22 19:25 2208
2660ccea Poul Sander 2023-09-22 19:25 2209
template<class Sequence1, class Sequence2>
2660ccea Poul Sander 2023-09-22 19:25 2210
struct merge_and_renumber;
2660ccea Poul Sander 2023-09-22 19:25 2211
2660ccea Poul Sander 2023-09-22 19:25 2212
template<std::size_t... I1, std::size_t... I2>
2660ccea Poul Sander 2023-09-22 19:25 2213
struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2660ccea Poul Sander 2023-09-22 19:25 2214
        : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2660ccea Poul Sander 2023-09-22 19:25 2215
2660ccea Poul Sander 2023-09-22 19:25 2216
template<std::size_t N>
2660ccea Poul Sander 2023-09-22 19:25 2217
struct make_index_sequence
2660ccea Poul Sander 2023-09-22 19:25 2218
    : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2660ccea Poul Sander 2023-09-22 19:25 2219
      typename make_index_sequence < N - N / 2 >::type > {};
2660ccea Poul Sander 2023-09-22 19:25 2220
2660ccea Poul Sander 2023-09-22 19:25 2221
template<> struct make_index_sequence<0> : index_sequence<> {};
2660ccea Poul Sander 2023-09-22 19:25 2222
template<> struct make_index_sequence<1> : index_sequence<0> {};
2660ccea Poul Sander 2023-09-22 19:25 2223
2660ccea Poul Sander 2023-09-22 19:25 2224
template<typename... Ts>
2660ccea Poul Sander 2023-09-22 19:25 2225
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2660ccea Poul Sander 2023-09-22 19:25 2226
2660ccea Poul Sander 2023-09-22 19:25 2227
// dispatch utility (taken from ranges-v3)
2660ccea Poul Sander 2023-09-22 19:25 2228
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2660ccea Poul Sander 2023-09-22 19:25 2229
template<> struct priority_tag<0> {};
2660ccea Poul Sander 2023-09-22 19:25 2230
2660ccea Poul Sander 2023-09-22 19:25 2231
// taken from ranges-v3
2660ccea Poul Sander 2023-09-22 19:25 2232
template<typename T>
2660ccea Poul Sander 2023-09-22 19:25 2233
struct static_const
2660ccea Poul Sander 2023-09-22 19:25 2234
{
2660ccea Poul Sander 2023-09-22 19:25 2235
    static constexpr T value{};
2660ccea Poul Sander 2023-09-22 19:25 2236
};
2660ccea Poul Sander 2023-09-22 19:25 2237
2660ccea Poul Sander 2023-09-22 19:25 2238
template<typename T>
2660ccea Poul Sander 2023-09-22 19:25 2239
constexpr T static_const<T>::value;
2660ccea Poul Sander 2023-09-22 19:25 2240
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2241
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2242
2660ccea Poul Sander 2023-09-22 19:25 2243
// #include <nlohmann/detail/meta/type_traits.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2244
2660ccea Poul Sander 2023-09-22 19:25 2245
2660ccea Poul Sander 2023-09-22 19:25 2246
#include <ciso646> // not
2660ccea Poul Sander 2023-09-22 19:25 2247
#include <limits> // numeric_limits
2660ccea Poul Sander 2023-09-22 19:25 2248
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2660ccea Poul Sander 2023-09-22 19:25 2249
#include <utility> // declval
2660ccea Poul Sander 2023-09-22 19:25 2250
2660ccea Poul Sander 2023-09-22 19:25 2251
// #include <nlohmann/detail/iterators/iterator_traits.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2252
2660ccea Poul Sander 2023-09-22 19:25 2253
2660ccea Poul Sander 2023-09-22 19:25 2254
#include <iterator> // random_access_iterator_tag
2660ccea Poul Sander 2023-09-22 19:25 2255
2660ccea Poul Sander 2023-09-22 19:25 2256
// #include <nlohmann/detail/meta/void_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2257
2660ccea Poul Sander 2023-09-22 19:25 2258
2660ccea Poul Sander 2023-09-22 19:25 2259
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2260
{
2660ccea Poul Sander 2023-09-22 19:25 2261
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2262
{
2660ccea Poul Sander 2023-09-22 19:25 2263
template <typename ...Ts> struct make_void
2660ccea Poul Sander 2023-09-22 19:25 2264
{
2660ccea Poul Sander 2023-09-22 19:25 2265
    using type = void;
2660ccea Poul Sander 2023-09-22 19:25 2266
};
2660ccea Poul Sander 2023-09-22 19:25 2267
template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
2660ccea Poul Sander 2023-09-22 19:25 2268
} // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2269
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2270
2660ccea Poul Sander 2023-09-22 19:25 2271
// #include <nlohmann/detail/meta/cpp_future.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2272
2660ccea Poul Sander 2023-09-22 19:25 2273
2660ccea Poul Sander 2023-09-22 19:25 2274
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2275
{
2660ccea Poul Sander 2023-09-22 19:25 2276
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2277
{
2660ccea Poul Sander 2023-09-22 19:25 2278
template <typename It, typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2279
struct iterator_types {};
2660ccea Poul Sander 2023-09-22 19:25 2280
2660ccea Poul Sander 2023-09-22 19:25 2281
template <typename It>
2660ccea Poul Sander 2023-09-22 19:25 2282
struct iterator_types <
2660ccea Poul Sander 2023-09-22 19:25 2283
    It,
2660ccea Poul Sander 2023-09-22 19:25 2284
    void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2660ccea Poul Sander 2023-09-22 19:25 2285
    typename It::reference, typename It::iterator_category >>
2660ccea Poul Sander 2023-09-22 19:25 2286
{
2660ccea Poul Sander 2023-09-22 19:25 2287
    using difference_type = typename It::difference_type;
2660ccea Poul Sander 2023-09-22 19:25 2288
    using value_type = typename It::value_type;
2660ccea Poul Sander 2023-09-22 19:25 2289
    using pointer = typename It::pointer;
2660ccea Poul Sander 2023-09-22 19:25 2290
    using reference = typename It::reference;
2660ccea Poul Sander 2023-09-22 19:25 2291
    using iterator_category = typename It::iterator_category;
2660ccea Poul Sander 2023-09-22 19:25 2292
};
2660ccea Poul Sander 2023-09-22 19:25 2293
2660ccea Poul Sander 2023-09-22 19:25 2294
// This is required as some compilers implement std::iterator_traits in a way that
2660ccea Poul Sander 2023-09-22 19:25 2295
// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2660ccea Poul Sander 2023-09-22 19:25 2296
template <typename T, typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2297
struct iterator_traits
2660ccea Poul Sander 2023-09-22 19:25 2298
{
2660ccea Poul Sander 2023-09-22 19:25 2299
};
2660ccea Poul Sander 2023-09-22 19:25 2300
2660ccea Poul Sander 2023-09-22 19:25 2301
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2302
struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2660ccea Poul Sander 2023-09-22 19:25 2303
            : iterator_types<T>
2660ccea Poul Sander 2023-09-22 19:25 2304
{
2660ccea Poul Sander 2023-09-22 19:25 2305
};
2660ccea Poul Sander 2023-09-22 19:25 2306
2660ccea Poul Sander 2023-09-22 19:25 2307
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2308
struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2660ccea Poul Sander 2023-09-22 19:25 2309
{
2660ccea Poul Sander 2023-09-22 19:25 2310
    using iterator_category = std::random_access_iterator_tag;
2660ccea Poul Sander 2023-09-22 19:25 2311
    using value_type = T;
2660ccea Poul Sander 2023-09-22 19:25 2312
    using difference_type = ptrdiff_t;
2660ccea Poul Sander 2023-09-22 19:25 2313
    using pointer = T*;
2660ccea Poul Sander 2023-09-22 19:25 2314
    using reference = T&;
2660ccea Poul Sander 2023-09-22 19:25 2315
};
2660ccea Poul Sander 2023-09-22 19:25 2316
} // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2317
} // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2318
2660ccea Poul Sander 2023-09-22 19:25 2319
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2320
2660ccea Poul Sander 2023-09-22 19:25 2321
// #include <nlohmann/detail/meta/cpp_future.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2322
2660ccea Poul Sander 2023-09-22 19:25 2323
// #include <nlohmann/detail/meta/detected.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2324
2660ccea Poul Sander 2023-09-22 19:25 2325
2660ccea Poul Sander 2023-09-22 19:25 2326
#include <type_traits>
2660ccea Poul Sander 2023-09-22 19:25 2327
2660ccea Poul Sander 2023-09-22 19:25 2328
// #include <nlohmann/detail/meta/void_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2329
2660ccea Poul Sander 2023-09-22 19:25 2330
2660ccea Poul Sander 2023-09-22 19:25 2331
// http://en.cppreference.com/w/cpp/experimental/is_detected
2660ccea Poul Sander 2023-09-22 19:25 2332
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2333
{
2660ccea Poul Sander 2023-09-22 19:25 2334
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2335
{
2660ccea Poul Sander 2023-09-22 19:25 2336
struct nonesuch
2660ccea Poul Sander 2023-09-22 19:25 2337
{
2660ccea Poul Sander 2023-09-22 19:25 2338
    nonesuch() = delete;
2660ccea Poul Sander 2023-09-22 19:25 2339
    ~nonesuch() = delete;
2660ccea Poul Sander 2023-09-22 19:25 2340
    nonesuch(nonesuch const&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 2341
    nonesuch(nonesuch const&&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 2342
    void operator=(nonesuch const&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 2343
    void operator=(nonesuch&&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 2344
};
2660ccea Poul Sander 2023-09-22 19:25 2345
2660ccea Poul Sander 2023-09-22 19:25 2346
template <class Default,
2660ccea Poul Sander 2023-09-22 19:25 2347
          class AlwaysVoid,
2660ccea Poul Sander 2023-09-22 19:25 2348
          template <class...> class Op,
2660ccea Poul Sander 2023-09-22 19:25 2349
          class... Args>
2660ccea Poul Sander 2023-09-22 19:25 2350
struct detector
2660ccea Poul Sander 2023-09-22 19:25 2351
{
2660ccea Poul Sander 2023-09-22 19:25 2352
    using value_t = std::false_type;
2660ccea Poul Sander 2023-09-22 19:25 2353
    using type = Default;
2660ccea Poul Sander 2023-09-22 19:25 2354
};
2660ccea Poul Sander 2023-09-22 19:25 2355
2660ccea Poul Sander 2023-09-22 19:25 2356
template <class Default, template <class...> class Op, class... Args>
2660ccea Poul Sander 2023-09-22 19:25 2357
struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2660ccea Poul Sander 2023-09-22 19:25 2358
{
2660ccea Poul Sander 2023-09-22 19:25 2359
    using value_t = std::true_type;
2660ccea Poul Sander 2023-09-22 19:25 2360
    using type = Op<Args...>;
2660ccea Poul Sander 2023-09-22 19:25 2361
};
2660ccea Poul Sander 2023-09-22 19:25 2362
2660ccea Poul Sander 2023-09-22 19:25 2363
template <template <class...> class Op, class... Args>
2660ccea Poul Sander 2023-09-22 19:25 2364
using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2660ccea Poul Sander 2023-09-22 19:25 2365
2660ccea Poul Sander 2023-09-22 19:25 2366
template <template <class...> class Op, class... Args>
2660ccea Poul Sander 2023-09-22 19:25 2367
using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2660ccea Poul Sander 2023-09-22 19:25 2368
2660ccea Poul Sander 2023-09-22 19:25 2369
template <class Default, template <class...> class Op, class... Args>
2660ccea Poul Sander 2023-09-22 19:25 2370
using detected_or = detector<Default, void, Op, Args...>;
2660ccea Poul Sander 2023-09-22 19:25 2371
2660ccea Poul Sander 2023-09-22 19:25 2372
template <class Default, template <class...> class Op, class... Args>
2660ccea Poul Sander 2023-09-22 19:25 2373
using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2660ccea Poul Sander 2023-09-22 19:25 2374
2660ccea Poul Sander 2023-09-22 19:25 2375
template <class Expected, template <class...> class Op, class... Args>
2660ccea Poul Sander 2023-09-22 19:25 2376
using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2660ccea Poul Sander 2023-09-22 19:25 2377
2660ccea Poul Sander 2023-09-22 19:25 2378
template <class To, template <class...> class Op, class... Args>
2660ccea Poul Sander 2023-09-22 19:25 2379
using is_detected_convertible =
2660ccea Poul Sander 2023-09-22 19:25 2380
    std::is_convertible<detected_t<Op, Args...>, To>;
2660ccea Poul Sander 2023-09-22 19:25 2381
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2382
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2383
2660ccea Poul Sander 2023-09-22 19:25 2384
// #include <nlohmann/json_fwd.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2385
#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2660ccea Poul Sander 2023-09-22 19:25 2386
#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2660ccea Poul Sander 2023-09-22 19:25 2387
2660ccea Poul Sander 2023-09-22 19:25 2388
#include <cstdint> // int64_t, uint64_t
2660ccea Poul Sander 2023-09-22 19:25 2389
#include <map> // map
2660ccea Poul Sander 2023-09-22 19:25 2390
#include <memory> // allocator
2660ccea Poul Sander 2023-09-22 19:25 2391
#include <string> // string
2660ccea Poul Sander 2023-09-22 19:25 2392
#include <vector> // vector
2660ccea Poul Sander 2023-09-22 19:25 2393
2660ccea Poul Sander 2023-09-22 19:25 2394
/*!
2660ccea Poul Sander 2023-09-22 19:25 2395
@brief namespace for Niels Lohmann
2660ccea Poul Sander 2023-09-22 19:25 2396
@see https://github.com/nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2397
@since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 2398
*/
2660ccea Poul Sander 2023-09-22 19:25 2399
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2400
{
2660ccea Poul Sander 2023-09-22 19:25 2401
/*!
2660ccea Poul Sander 2023-09-22 19:25 2402
@brief default JSONSerializer template argument
2660ccea Poul Sander 2023-09-22 19:25 2403
2660ccea Poul Sander 2023-09-22 19:25 2404
This serializer ignores the template arguments and uses ADL
2660ccea Poul Sander 2023-09-22 19:25 2405
([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
2660ccea Poul Sander 2023-09-22 19:25 2406
for serialization.
2660ccea Poul Sander 2023-09-22 19:25 2407
*/
2660ccea Poul Sander 2023-09-22 19:25 2408
template<typename T = void, typename SFINAE = void>
2660ccea Poul Sander 2023-09-22 19:25 2409
struct adl_serializer;
2660ccea Poul Sander 2023-09-22 19:25 2410
2660ccea Poul Sander 2023-09-22 19:25 2411
template<template<typename U, typename V, typename... Args> class ObjectType =
2660ccea Poul Sander 2023-09-22 19:25 2412
         std::map,
2660ccea Poul Sander 2023-09-22 19:25 2413
         template<typename U, typename... Args> class ArrayType = std::vector,
2660ccea Poul Sander 2023-09-22 19:25 2414
         class StringType = std::string, class BooleanType = bool,
2660ccea Poul Sander 2023-09-22 19:25 2415
         class NumberIntegerType = std::int64_t,
2660ccea Poul Sander 2023-09-22 19:25 2416
         class NumberUnsignedType = std::uint64_t,
2660ccea Poul Sander 2023-09-22 19:25 2417
         class NumberFloatType = double,
2660ccea Poul Sander 2023-09-22 19:25 2418
         template<typename U> class AllocatorType = std::allocator,
2660ccea Poul Sander 2023-09-22 19:25 2419
         template<typename T, typename SFINAE = void> class JSONSerializer =
2660ccea Poul Sander 2023-09-22 19:25 2420
         adl_serializer>
2660ccea Poul Sander 2023-09-22 19:25 2421
class basic_json;
2660ccea Poul Sander 2023-09-22 19:25 2422
2660ccea Poul Sander 2023-09-22 19:25 2423
/*!
2660ccea Poul Sander 2023-09-22 19:25 2424
@brief JSON Pointer
2660ccea Poul Sander 2023-09-22 19:25 2425
2660ccea Poul Sander 2023-09-22 19:25 2426
A JSON pointer defines a string syntax for identifying a specific value
2660ccea Poul Sander 2023-09-22 19:25 2427
within a JSON document. It can be used with functions `at` and
2660ccea Poul Sander 2023-09-22 19:25 2428
`operator[]`. Furthermore, JSON pointers are the base for JSON patches.
2660ccea Poul Sander 2023-09-22 19:25 2429
2660ccea Poul Sander 2023-09-22 19:25 2430
@sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
2660ccea Poul Sander 2023-09-22 19:25 2431
2660ccea Poul Sander 2023-09-22 19:25 2432
@since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 2433
*/
2660ccea Poul Sander 2023-09-22 19:25 2434
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 2435
class json_pointer;
2660ccea Poul Sander 2023-09-22 19:25 2436
2660ccea Poul Sander 2023-09-22 19:25 2437
/*!
2660ccea Poul Sander 2023-09-22 19:25 2438
@brief default JSON class
2660ccea Poul Sander 2023-09-22 19:25 2439
2660ccea Poul Sander 2023-09-22 19:25 2440
This type is the default specialization of the @ref basic_json class which
2660ccea Poul Sander 2023-09-22 19:25 2441
uses the standard template types.
2660ccea Poul Sander 2023-09-22 19:25 2442
2660ccea Poul Sander 2023-09-22 19:25 2443
@since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 2444
*/
2660ccea Poul Sander 2023-09-22 19:25 2445
using json = basic_json<>;
2660ccea Poul Sander 2023-09-22 19:25 2446
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2447
2660ccea Poul Sander 2023-09-22 19:25 2448
#endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
2660ccea Poul Sander 2023-09-22 19:25 2449
2660ccea Poul Sander 2023-09-22 19:25 2450
2660ccea Poul Sander 2023-09-22 19:25 2451
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2452
{
2660ccea Poul Sander 2023-09-22 19:25 2453
/*!
2660ccea Poul Sander 2023-09-22 19:25 2454
@brief detail namespace with internal helper functions
2660ccea Poul Sander 2023-09-22 19:25 2455
2660ccea Poul Sander 2023-09-22 19:25 2456
This namespace collects functions that should not be exposed,
2660ccea Poul Sander 2023-09-22 19:25 2457
implementations of some @ref basic_json methods, and meta-programming helpers.
2660ccea Poul Sander 2023-09-22 19:25 2458
2660ccea Poul Sander 2023-09-22 19:25 2459
@since version 2.1.0
2660ccea Poul Sander 2023-09-22 19:25 2460
*/
2660ccea Poul Sander 2023-09-22 19:25 2461
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2462
{
2660ccea Poul Sander 2023-09-22 19:25 2463
/////////////
2660ccea Poul Sander 2023-09-22 19:25 2464
// helpers //
2660ccea Poul Sander 2023-09-22 19:25 2465
/////////////
2660ccea Poul Sander 2023-09-22 19:25 2466
2660ccea Poul Sander 2023-09-22 19:25 2467
// Note to maintainers:
2660ccea Poul Sander 2023-09-22 19:25 2468
//
2660ccea Poul Sander 2023-09-22 19:25 2469
// Every trait in this file expects a non CV-qualified type.
2660ccea Poul Sander 2023-09-22 19:25 2470
// The only exceptions are in the 'aliases for detected' section
2660ccea Poul Sander 2023-09-22 19:25 2471
// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
2660ccea Poul Sander 2023-09-22 19:25 2472
//
2660ccea Poul Sander 2023-09-22 19:25 2473
// In this case, T has to be properly CV-qualified to constraint the function arguments
2660ccea Poul Sander 2023-09-22 19:25 2474
// (e.g. to_json(BasicJsonType&, const T&))
2660ccea Poul Sander 2023-09-22 19:25 2475
2660ccea Poul Sander 2023-09-22 19:25 2476
template<typename> struct is_basic_json : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2477
2660ccea Poul Sander 2023-09-22 19:25 2478
NLOHMANN_BASIC_JSON_TPL_DECLARATION
2660ccea Poul Sander 2023-09-22 19:25 2479
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
2660ccea Poul Sander 2023-09-22 19:25 2480
2660ccea Poul Sander 2023-09-22 19:25 2481
//////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 2482
// aliases for detected //
2660ccea Poul Sander 2023-09-22 19:25 2483
//////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 2484
2660ccea Poul Sander 2023-09-22 19:25 2485
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2486
using mapped_type_t = typename T::mapped_type;
2660ccea Poul Sander 2023-09-22 19:25 2487
2660ccea Poul Sander 2023-09-22 19:25 2488
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2489
using key_type_t = typename T::key_type;
2660ccea Poul Sander 2023-09-22 19:25 2490
2660ccea Poul Sander 2023-09-22 19:25 2491
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2492
using value_type_t = typename T::value_type;
2660ccea Poul Sander 2023-09-22 19:25 2493
2660ccea Poul Sander 2023-09-22 19:25 2494
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2495
using difference_type_t = typename T::difference_type;
2660ccea Poul Sander 2023-09-22 19:25 2496
2660ccea Poul Sander 2023-09-22 19:25 2497
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2498
using pointer_t = typename T::pointer;
2660ccea Poul Sander 2023-09-22 19:25 2499
2660ccea Poul Sander 2023-09-22 19:25 2500
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2501
using reference_t = typename T::reference;
2660ccea Poul Sander 2023-09-22 19:25 2502
2660ccea Poul Sander 2023-09-22 19:25 2503
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2504
using iterator_category_t = typename T::iterator_category;
2660ccea Poul Sander 2023-09-22 19:25 2505
2660ccea Poul Sander 2023-09-22 19:25 2506
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2507
using iterator_t = typename T::iterator;
2660ccea Poul Sander 2023-09-22 19:25 2508
2660ccea Poul Sander 2023-09-22 19:25 2509
template <typename T, typename... Args>
2660ccea Poul Sander 2023-09-22 19:25 2510
using to_json_function = decltype(T::to_json(std::declval<Args>()...));
2660ccea Poul Sander 2023-09-22 19:25 2511
2660ccea Poul Sander 2023-09-22 19:25 2512
template <typename T, typename... Args>
2660ccea Poul Sander 2023-09-22 19:25 2513
using from_json_function = decltype(T::from_json(std::declval<Args>()...));
2660ccea Poul Sander 2023-09-22 19:25 2514
2660ccea Poul Sander 2023-09-22 19:25 2515
template <typename T, typename U>
2660ccea Poul Sander 2023-09-22 19:25 2516
using get_template_function = decltype(std::declval<T>().template get<U>());
2660ccea Poul Sander 2023-09-22 19:25 2517
2660ccea Poul Sander 2023-09-22 19:25 2518
// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
2660ccea Poul Sander 2023-09-22 19:25 2519
template <typename BasicJsonType, typename T, typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2520
struct has_from_json : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2521
2660ccea Poul Sander 2023-09-22 19:25 2522
template <typename BasicJsonType, typename T>
2660ccea Poul Sander 2023-09-22 19:25 2523
struct has_from_json<BasicJsonType, T,
2660ccea Poul Sander 2023-09-22 19:25 2524
           enable_if_t<not is_basic_json<T>::value>>
2660ccea Poul Sander 2023-09-22 19:25 2525
{
2660ccea Poul Sander 2023-09-22 19:25 2526
    using serializer = typename BasicJsonType::template json_serializer<T, void>;
2660ccea Poul Sander 2023-09-22 19:25 2527
2660ccea Poul Sander 2023-09-22 19:25 2528
    static constexpr bool value =
2660ccea Poul Sander 2023-09-22 19:25 2529
        is_detected_exact<void, from_json_function, serializer,
2660ccea Poul Sander 2023-09-22 19:25 2530
        const BasicJsonType&, T&>::value;
2660ccea Poul Sander 2023-09-22 19:25 2531
};
2660ccea Poul Sander 2023-09-22 19:25 2532
2660ccea Poul Sander 2023-09-22 19:25 2533
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
2660ccea Poul Sander 2023-09-22 19:25 2534
// this overload is used for non-default-constructible user-defined-types
2660ccea Poul Sander 2023-09-22 19:25 2535
template <typename BasicJsonType, typename T, typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2536
struct has_non_default_from_json : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2537
2660ccea Poul Sander 2023-09-22 19:25 2538
template<typename BasicJsonType, typename T>
2660ccea Poul Sander 2023-09-22 19:25 2539
struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2660ccea Poul Sander 2023-09-22 19:25 2540
{
2660ccea Poul Sander 2023-09-22 19:25 2541
    using serializer = typename BasicJsonType::template json_serializer<T, void>;
2660ccea Poul Sander 2023-09-22 19:25 2542
2660ccea Poul Sander 2023-09-22 19:25 2543
    static constexpr bool value =
2660ccea Poul Sander 2023-09-22 19:25 2544
        is_detected_exact<T, from_json_function, serializer,
2660ccea Poul Sander 2023-09-22 19:25 2545
        const BasicJsonType&>::value;
2660ccea Poul Sander 2023-09-22 19:25 2546
};
2660ccea Poul Sander 2023-09-22 19:25 2547
2660ccea Poul Sander 2023-09-22 19:25 2548
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
2660ccea Poul Sander 2023-09-22 19:25 2549
// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
2660ccea Poul Sander 2023-09-22 19:25 2550
template <typename BasicJsonType, typename T, typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2551
struct has_to_json : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2552
2660ccea Poul Sander 2023-09-22 19:25 2553
template <typename BasicJsonType, typename T>
2660ccea Poul Sander 2023-09-22 19:25 2554
struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2660ccea Poul Sander 2023-09-22 19:25 2555
{
2660ccea Poul Sander 2023-09-22 19:25 2556
    using serializer = typename BasicJsonType::template json_serializer<T, void>;
2660ccea Poul Sander 2023-09-22 19:25 2557
2660ccea Poul Sander 2023-09-22 19:25 2558
    static constexpr bool value =
2660ccea Poul Sander 2023-09-22 19:25 2559
        is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
2660ccea Poul Sander 2023-09-22 19:25 2560
        T>::value;
2660ccea Poul Sander 2023-09-22 19:25 2561
};
2660ccea Poul Sander 2023-09-22 19:25 2562
2660ccea Poul Sander 2023-09-22 19:25 2563
2660ccea Poul Sander 2023-09-22 19:25 2564
///////////////////
2660ccea Poul Sander 2023-09-22 19:25 2565
// is_ functions //
2660ccea Poul Sander 2023-09-22 19:25 2566
///////////////////
2660ccea Poul Sander 2023-09-22 19:25 2567
2660ccea Poul Sander 2023-09-22 19:25 2568
template <typename T, typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2569
struct is_iterator_traits : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2570
2660ccea Poul Sander 2023-09-22 19:25 2571
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2572
struct is_iterator_traits<iterator_traits<T>>
2660ccea Poul Sander 2023-09-22 19:25 2573
{
2660ccea Poul Sander 2023-09-22 19:25 2574
  private:
2660ccea Poul Sander 2023-09-22 19:25 2575
    using traits = iterator_traits<T>;
2660ccea Poul Sander 2023-09-22 19:25 2576
2660ccea Poul Sander 2023-09-22 19:25 2577
  public:
2660ccea Poul Sander 2023-09-22 19:25 2578
    static constexpr auto value =
2660ccea Poul Sander 2023-09-22 19:25 2579
        is_detected<value_type_t, traits>::value &&
2660ccea Poul Sander 2023-09-22 19:25 2580
        is_detected<difference_type_t, traits>::value &&
2660ccea Poul Sander 2023-09-22 19:25 2581
        is_detected<pointer_t, traits>::value &&
2660ccea Poul Sander 2023-09-22 19:25 2582
        is_detected<iterator_category_t, traits>::value &&
2660ccea Poul Sander 2023-09-22 19:25 2583
        is_detected<reference_t, traits>::value;
2660ccea Poul Sander 2023-09-22 19:25 2584
};
2660ccea Poul Sander 2023-09-22 19:25 2585
2660ccea Poul Sander 2023-09-22 19:25 2586
// source: https://stackoverflow.com/a/37193089/4116453
2660ccea Poul Sander 2023-09-22 19:25 2587
2660ccea Poul Sander 2023-09-22 19:25 2588
template <typename T, typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2589
struct is_complete_type : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2590
2660ccea Poul Sander 2023-09-22 19:25 2591
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 2592
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
2660ccea Poul Sander 2023-09-22 19:25 2593
2660ccea Poul Sander 2023-09-22 19:25 2594
template <typename BasicJsonType, typename CompatibleObjectType,
2660ccea Poul Sander 2023-09-22 19:25 2595
          typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2596
struct is_compatible_object_type_impl : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2597
2660ccea Poul Sander 2023-09-22 19:25 2598
template <typename BasicJsonType, typename CompatibleObjectType>
2660ccea Poul Sander 2023-09-22 19:25 2599
struct is_compatible_object_type_impl <
2660ccea Poul Sander 2023-09-22 19:25 2600
    BasicJsonType, CompatibleObjectType,
2660ccea Poul Sander 2023-09-22 19:25 2601
    enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2602
    is_detected<key_type_t, CompatibleObjectType>::value >>
2660ccea Poul Sander 2023-09-22 19:25 2603
{
2660ccea Poul Sander 2023-09-22 19:25 2604
2660ccea Poul Sander 2023-09-22 19:25 2605
    using object_t = typename BasicJsonType::object_t;
2660ccea Poul Sander 2023-09-22 19:25 2606
2660ccea Poul Sander 2023-09-22 19:25 2607
    // macOS's is_constructible does not play well with nonesuch...
2660ccea Poul Sander 2023-09-22 19:25 2608
    static constexpr bool value =
2660ccea Poul Sander 2023-09-22 19:25 2609
        std::is_constructible<typename object_t::key_type,
2660ccea Poul Sander 2023-09-22 19:25 2610
        typename CompatibleObjectType::key_type>::value and
2660ccea Poul Sander 2023-09-22 19:25 2611
        std::is_constructible<typename object_t::mapped_type,
2660ccea Poul Sander 2023-09-22 19:25 2612
        typename CompatibleObjectType::mapped_type>::value;
2660ccea Poul Sander 2023-09-22 19:25 2613
};
2660ccea Poul Sander 2023-09-22 19:25 2614
2660ccea Poul Sander 2023-09-22 19:25 2615
template <typename BasicJsonType, typename CompatibleObjectType>
2660ccea Poul Sander 2023-09-22 19:25 2616
struct is_compatible_object_type
2660ccea Poul Sander 2023-09-22 19:25 2617
    : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
2660ccea Poul Sander 2023-09-22 19:25 2618
2660ccea Poul Sander 2023-09-22 19:25 2619
template <typename BasicJsonType, typename ConstructibleObjectType,
2660ccea Poul Sander 2023-09-22 19:25 2620
          typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2621
struct is_constructible_object_type_impl : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2622
2660ccea Poul Sander 2023-09-22 19:25 2623
template <typename BasicJsonType, typename ConstructibleObjectType>
2660ccea Poul Sander 2023-09-22 19:25 2624
struct is_constructible_object_type_impl <
2660ccea Poul Sander 2023-09-22 19:25 2625
    BasicJsonType, ConstructibleObjectType,
2660ccea Poul Sander 2023-09-22 19:25 2626
    enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2627
    is_detected<key_type_t, ConstructibleObjectType>::value >>
2660ccea Poul Sander 2023-09-22 19:25 2628
{
2660ccea Poul Sander 2023-09-22 19:25 2629
    using object_t = typename BasicJsonType::object_t;
2660ccea Poul Sander 2023-09-22 19:25 2630
2660ccea Poul Sander 2023-09-22 19:25 2631
    static constexpr bool value =
2660ccea Poul Sander 2023-09-22 19:25 2632
        (std::is_default_constructible<ConstructibleObjectType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2633
         (std::is_move_assignable<ConstructibleObjectType>::value or
2660ccea Poul Sander 2023-09-22 19:25 2634
          std::is_copy_assignable<ConstructibleObjectType>::value) and
2660ccea Poul Sander 2023-09-22 19:25 2635
         (std::is_constructible<typename ConstructibleObjectType::key_type,
2660ccea Poul Sander 2023-09-22 19:25 2636
          typename object_t::key_type>::value and
2660ccea Poul Sander 2023-09-22 19:25 2637
          std::is_same <
2660ccea Poul Sander 2023-09-22 19:25 2638
          typename object_t::mapped_type,
2660ccea Poul Sander 2023-09-22 19:25 2639
          typename ConstructibleObjectType::mapped_type >::value)) or
2660ccea Poul Sander 2023-09-22 19:25 2640
        (has_from_json<BasicJsonType,
2660ccea Poul Sander 2023-09-22 19:25 2641
         typename ConstructibleObjectType::mapped_type>::value or
2660ccea Poul Sander 2023-09-22 19:25 2642
         has_non_default_from_json <
2660ccea Poul Sander 2023-09-22 19:25 2643
         BasicJsonType,
2660ccea Poul Sander 2023-09-22 19:25 2644
         typename ConstructibleObjectType::mapped_type >::value);
2660ccea Poul Sander 2023-09-22 19:25 2645
};
2660ccea Poul Sander 2023-09-22 19:25 2646
2660ccea Poul Sander 2023-09-22 19:25 2647
template <typename BasicJsonType, typename ConstructibleObjectType>
2660ccea Poul Sander 2023-09-22 19:25 2648
struct is_constructible_object_type
2660ccea Poul Sander 2023-09-22 19:25 2649
    : is_constructible_object_type_impl<BasicJsonType,
2660ccea Poul Sander 2023-09-22 19:25 2650
      ConstructibleObjectType> {};
2660ccea Poul Sander 2023-09-22 19:25 2651
2660ccea Poul Sander 2023-09-22 19:25 2652
template <typename BasicJsonType, typename CompatibleStringType,
2660ccea Poul Sander 2023-09-22 19:25 2653
          typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2654
struct is_compatible_string_type_impl : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2655
2660ccea Poul Sander 2023-09-22 19:25 2656
template <typename BasicJsonType, typename CompatibleStringType>
2660ccea Poul Sander 2023-09-22 19:25 2657
struct is_compatible_string_type_impl <
2660ccea Poul Sander 2023-09-22 19:25 2658
    BasicJsonType, CompatibleStringType,
2660ccea Poul Sander 2023-09-22 19:25 2659
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
2660ccea Poul Sander 2023-09-22 19:25 2660
    value_type_t, CompatibleStringType>::value >>
2660ccea Poul Sander 2023-09-22 19:25 2661
{
2660ccea Poul Sander 2023-09-22 19:25 2662
    static constexpr auto value =
2660ccea Poul Sander 2023-09-22 19:25 2663
        std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
2660ccea Poul Sander 2023-09-22 19:25 2664
};
2660ccea Poul Sander 2023-09-22 19:25 2665
2660ccea Poul Sander 2023-09-22 19:25 2666
template <typename BasicJsonType, typename ConstructibleStringType>
2660ccea Poul Sander 2023-09-22 19:25 2667
struct is_compatible_string_type
2660ccea Poul Sander 2023-09-22 19:25 2668
    : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
2660ccea Poul Sander 2023-09-22 19:25 2669
2660ccea Poul Sander 2023-09-22 19:25 2670
template <typename BasicJsonType, typename ConstructibleStringType,
2660ccea Poul Sander 2023-09-22 19:25 2671
          typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2672
struct is_constructible_string_type_impl : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2673
2660ccea Poul Sander 2023-09-22 19:25 2674
template <typename BasicJsonType, typename ConstructibleStringType>
2660ccea Poul Sander 2023-09-22 19:25 2675
struct is_constructible_string_type_impl <
2660ccea Poul Sander 2023-09-22 19:25 2676
    BasicJsonType, ConstructibleStringType,
2660ccea Poul Sander 2023-09-22 19:25 2677
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
2660ccea Poul Sander 2023-09-22 19:25 2678
    value_type_t, ConstructibleStringType>::value >>
2660ccea Poul Sander 2023-09-22 19:25 2679
{
2660ccea Poul Sander 2023-09-22 19:25 2680
    static constexpr auto value =
2660ccea Poul Sander 2023-09-22 19:25 2681
        std::is_constructible<ConstructibleStringType,
2660ccea Poul Sander 2023-09-22 19:25 2682
        typename BasicJsonType::string_t>::value;
2660ccea Poul Sander 2023-09-22 19:25 2683
};
2660ccea Poul Sander 2023-09-22 19:25 2684
2660ccea Poul Sander 2023-09-22 19:25 2685
template <typename BasicJsonType, typename ConstructibleStringType>
2660ccea Poul Sander 2023-09-22 19:25 2686
struct is_constructible_string_type
2660ccea Poul Sander 2023-09-22 19:25 2687
    : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
2660ccea Poul Sander 2023-09-22 19:25 2688
2660ccea Poul Sander 2023-09-22 19:25 2689
template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2690
struct is_compatible_array_type_impl : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2691
2660ccea Poul Sander 2023-09-22 19:25 2692
template <typename BasicJsonType, typename CompatibleArrayType>
2660ccea Poul Sander 2023-09-22 19:25 2693
struct is_compatible_array_type_impl <
2660ccea Poul Sander 2023-09-22 19:25 2694
    BasicJsonType, CompatibleArrayType,
2660ccea Poul Sander 2023-09-22 19:25 2695
    enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2696
    is_detected<iterator_t, CompatibleArrayType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2697
// This is needed because json_reverse_iterator has a ::iterator type...
2660ccea Poul Sander 2023-09-22 19:25 2698
// Therefore it is detected as a CompatibleArrayType.
2660ccea Poul Sander 2023-09-22 19:25 2699
// The real fix would be to have an Iterable concept.
2660ccea Poul Sander 2023-09-22 19:25 2700
    not is_iterator_traits<
2660ccea Poul Sander 2023-09-22 19:25 2701
    iterator_traits<CompatibleArrayType>>::value >>
2660ccea Poul Sander 2023-09-22 19:25 2702
{
2660ccea Poul Sander 2023-09-22 19:25 2703
    static constexpr bool value =
2660ccea Poul Sander 2023-09-22 19:25 2704
        std::is_constructible<BasicJsonType,
2660ccea Poul Sander 2023-09-22 19:25 2705
        typename CompatibleArrayType::value_type>::value;
2660ccea Poul Sander 2023-09-22 19:25 2706
};
2660ccea Poul Sander 2023-09-22 19:25 2707
2660ccea Poul Sander 2023-09-22 19:25 2708
template <typename BasicJsonType, typename CompatibleArrayType>
2660ccea Poul Sander 2023-09-22 19:25 2709
struct is_compatible_array_type
2660ccea Poul Sander 2023-09-22 19:25 2710
    : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
2660ccea Poul Sander 2023-09-22 19:25 2711
2660ccea Poul Sander 2023-09-22 19:25 2712
template <typename BasicJsonType, typename ConstructibleArrayType, typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2713
struct is_constructible_array_type_impl : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2714
2660ccea Poul Sander 2023-09-22 19:25 2715
template <typename BasicJsonType, typename ConstructibleArrayType>
2660ccea Poul Sander 2023-09-22 19:25 2716
struct is_constructible_array_type_impl <
2660ccea Poul Sander 2023-09-22 19:25 2717
    BasicJsonType, ConstructibleArrayType,
2660ccea Poul Sander 2023-09-22 19:25 2718
    enable_if_t<std::is_same<ConstructibleArrayType,
2660ccea Poul Sander 2023-09-22 19:25 2719
    typename BasicJsonType::value_type>::value >>
2660ccea Poul Sander 2023-09-22 19:25 2720
            : std::true_type {};
2660ccea Poul Sander 2023-09-22 19:25 2721
2660ccea Poul Sander 2023-09-22 19:25 2722
template <typename BasicJsonType, typename ConstructibleArrayType>
2660ccea Poul Sander 2023-09-22 19:25 2723
struct is_constructible_array_type_impl <
2660ccea Poul Sander 2023-09-22 19:25 2724
    BasicJsonType, ConstructibleArrayType,
2660ccea Poul Sander 2023-09-22 19:25 2725
    enable_if_t<not std::is_same<ConstructibleArrayType,
2660ccea Poul Sander 2023-09-22 19:25 2726
    typename BasicJsonType::value_type>::value and
2660ccea Poul Sander 2023-09-22 19:25 2727
    std::is_default_constructible<ConstructibleArrayType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2728
(std::is_move_assignable<ConstructibleArrayType>::value or
2660ccea Poul Sander 2023-09-22 19:25 2729
 std::is_copy_assignable<ConstructibleArrayType>::value) and
2660ccea Poul Sander 2023-09-22 19:25 2730
is_detected<value_type_t, ConstructibleArrayType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2731
is_detected<iterator_t, ConstructibleArrayType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2732
is_complete_type<
2660ccea Poul Sander 2023-09-22 19:25 2733
detected_t<value_type_t, ConstructibleArrayType>>::value >>
2660ccea Poul Sander 2023-09-22 19:25 2734
{
2660ccea Poul Sander 2023-09-22 19:25 2735
    static constexpr bool value =
2660ccea Poul Sander 2023-09-22 19:25 2736
        // This is needed because json_reverse_iterator has a ::iterator type,
2660ccea Poul Sander 2023-09-22 19:25 2737
        // furthermore, std::back_insert_iterator (and other iterators) have a
2660ccea Poul Sander 2023-09-22 19:25 2738
        // base class `iterator`... Therefore it is detected as a
2660ccea Poul Sander 2023-09-22 19:25 2739
        // ConstructibleArrayType. The real fix would be to have an Iterable
2660ccea Poul Sander 2023-09-22 19:25 2740
        // concept.
2660ccea Poul Sander 2023-09-22 19:25 2741
        not is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value and
2660ccea Poul Sander 2023-09-22 19:25 2742
2660ccea Poul Sander 2023-09-22 19:25 2743
        (std::is_same<typename ConstructibleArrayType::value_type,
2660ccea Poul Sander 2023-09-22 19:25 2744
         typename BasicJsonType::array_t::value_type>::value or
2660ccea Poul Sander 2023-09-22 19:25 2745
         has_from_json<BasicJsonType,
2660ccea Poul Sander 2023-09-22 19:25 2746
         typename ConstructibleArrayType::value_type>::value or
2660ccea Poul Sander 2023-09-22 19:25 2747
         has_non_default_from_json <
2660ccea Poul Sander 2023-09-22 19:25 2748
         BasicJsonType, typename ConstructibleArrayType::value_type >::value);
2660ccea Poul Sander 2023-09-22 19:25 2749
};
2660ccea Poul Sander 2023-09-22 19:25 2750
2660ccea Poul Sander 2023-09-22 19:25 2751
template <typename BasicJsonType, typename ConstructibleArrayType>
2660ccea Poul Sander 2023-09-22 19:25 2752
struct is_constructible_array_type
2660ccea Poul Sander 2023-09-22 19:25 2753
    : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
2660ccea Poul Sander 2023-09-22 19:25 2754
2660ccea Poul Sander 2023-09-22 19:25 2755
template <typename RealIntegerType, typename CompatibleNumberIntegerType,
2660ccea Poul Sander 2023-09-22 19:25 2756
          typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2757
struct is_compatible_integer_type_impl : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2758
2660ccea Poul Sander 2023-09-22 19:25 2759
template <typename RealIntegerType, typename CompatibleNumberIntegerType>
2660ccea Poul Sander 2023-09-22 19:25 2760
struct is_compatible_integer_type_impl <
2660ccea Poul Sander 2023-09-22 19:25 2761
    RealIntegerType, CompatibleNumberIntegerType,
2660ccea Poul Sander 2023-09-22 19:25 2762
    enable_if_t<std::is_integral<RealIntegerType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2763
    std::is_integral<CompatibleNumberIntegerType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2764
    not std::is_same<bool, CompatibleNumberIntegerType>::value >>
2660ccea Poul Sander 2023-09-22 19:25 2765
{
2660ccea Poul Sander 2023-09-22 19:25 2766
    // is there an assert somewhere on overflows?
2660ccea Poul Sander 2023-09-22 19:25 2767
    using RealLimits = std::numeric_limits<RealIntegerType>;
2660ccea Poul Sander 2023-09-22 19:25 2768
    using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
2660ccea Poul Sander 2023-09-22 19:25 2769
2660ccea Poul Sander 2023-09-22 19:25 2770
    static constexpr auto value =
2660ccea Poul Sander 2023-09-22 19:25 2771
        std::is_constructible<RealIntegerType,
2660ccea Poul Sander 2023-09-22 19:25 2772
        CompatibleNumberIntegerType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2773
        CompatibleLimits::is_integer and
2660ccea Poul Sander 2023-09-22 19:25 2774
        RealLimits::is_signed == CompatibleLimits::is_signed;
2660ccea Poul Sander 2023-09-22 19:25 2775
};
2660ccea Poul Sander 2023-09-22 19:25 2776
2660ccea Poul Sander 2023-09-22 19:25 2777
template <typename RealIntegerType, typename CompatibleNumberIntegerType>
2660ccea Poul Sander 2023-09-22 19:25 2778
struct is_compatible_integer_type
2660ccea Poul Sander 2023-09-22 19:25 2779
    : is_compatible_integer_type_impl<RealIntegerType,
2660ccea Poul Sander 2023-09-22 19:25 2780
      CompatibleNumberIntegerType> {};
2660ccea Poul Sander 2023-09-22 19:25 2781
2660ccea Poul Sander 2023-09-22 19:25 2782
template <typename BasicJsonType, typename CompatibleType, typename = void>
2660ccea Poul Sander 2023-09-22 19:25 2783
struct is_compatible_type_impl: std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2784
2660ccea Poul Sander 2023-09-22 19:25 2785
template <typename BasicJsonType, typename CompatibleType>
2660ccea Poul Sander 2023-09-22 19:25 2786
struct is_compatible_type_impl <
2660ccea Poul Sander 2023-09-22 19:25 2787
    BasicJsonType, CompatibleType,
2660ccea Poul Sander 2023-09-22 19:25 2788
    enable_if_t<is_complete_type<CompatibleType>::value >>
2660ccea Poul Sander 2023-09-22 19:25 2789
{
2660ccea Poul Sander 2023-09-22 19:25 2790
    static constexpr bool value =
2660ccea Poul Sander 2023-09-22 19:25 2791
        has_to_json<BasicJsonType, CompatibleType>::value;
2660ccea Poul Sander 2023-09-22 19:25 2792
};
2660ccea Poul Sander 2023-09-22 19:25 2793
2660ccea Poul Sander 2023-09-22 19:25 2794
template <typename BasicJsonType, typename CompatibleType>
2660ccea Poul Sander 2023-09-22 19:25 2795
struct is_compatible_type
2660ccea Poul Sander 2023-09-22 19:25 2796
    : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
2660ccea Poul Sander 2023-09-22 19:25 2797
2660ccea Poul Sander 2023-09-22 19:25 2798
// https://en.cppreference.com/w/cpp/types/conjunction
2660ccea Poul Sander 2023-09-22 19:25 2799
template<class...> struct conjunction : std::true_type { };
2660ccea Poul Sander 2023-09-22 19:25 2800
template<class B1> struct conjunction<B1> : B1 { };
2660ccea Poul Sander 2023-09-22 19:25 2801
template<class B1, class... Bn>
2660ccea Poul Sander 2023-09-22 19:25 2802
struct conjunction<B1, Bn...>
2660ccea Poul Sander 2023-09-22 19:25 2803
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
2660ccea Poul Sander 2023-09-22 19:25 2804
2660ccea Poul Sander 2023-09-22 19:25 2805
template <typename T1, typename T2>
2660ccea Poul Sander 2023-09-22 19:25 2806
struct is_constructible_tuple : std::false_type {};
2660ccea Poul Sander 2023-09-22 19:25 2807
2660ccea Poul Sander 2023-09-22 19:25 2808
template <typename T1, typename... Args>
2660ccea Poul Sander 2023-09-22 19:25 2809
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
2660ccea Poul Sander 2023-09-22 19:25 2810
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2811
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2812
2660ccea Poul Sander 2023-09-22 19:25 2813
// #include <nlohmann/detail/value_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 2814
2660ccea Poul Sander 2023-09-22 19:25 2815
2660ccea Poul Sander 2023-09-22 19:25 2816
#include <array> // array
2660ccea Poul Sander 2023-09-22 19:25 2817
#include <ciso646> // and
2660ccea Poul Sander 2023-09-22 19:25 2818
#include <cstddef> // size_t
2660ccea Poul Sander 2023-09-22 19:25 2819
#include <cstdint> // uint8_t
2660ccea Poul Sander 2023-09-22 19:25 2820
#include <string> // string
2660ccea Poul Sander 2023-09-22 19:25 2821
2660ccea Poul Sander 2023-09-22 19:25 2822
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2823
{
2660ccea Poul Sander 2023-09-22 19:25 2824
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2825
{
2660ccea Poul Sander 2023-09-22 19:25 2826
///////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 2827
// JSON type enumeration //
2660ccea Poul Sander 2023-09-22 19:25 2828
///////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 2829
2660ccea Poul Sander 2023-09-22 19:25 2830
/*!
2660ccea Poul Sander 2023-09-22 19:25 2831
@brief the JSON type enumeration
2660ccea Poul Sander 2023-09-22 19:25 2832
2660ccea Poul Sander 2023-09-22 19:25 2833
This enumeration collects the different JSON types. It is internally used to
2660ccea Poul Sander 2023-09-22 19:25 2834
distinguish the stored values, and the functions @ref basic_json::is_null(),
2660ccea Poul Sander 2023-09-22 19:25 2835
@ref basic_json::is_object(), @ref basic_json::is_array(),
2660ccea Poul Sander 2023-09-22 19:25 2836
@ref basic_json::is_string(), @ref basic_json::is_boolean(),
2660ccea Poul Sander 2023-09-22 19:25 2837
@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
2660ccea Poul Sander 2023-09-22 19:25 2838
@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
2660ccea Poul Sander 2023-09-22 19:25 2839
@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
2660ccea Poul Sander 2023-09-22 19:25 2840
@ref basic_json::is_structured() rely on it.
2660ccea Poul Sander 2023-09-22 19:25 2841
2660ccea Poul Sander 2023-09-22 19:25 2842
@note There are three enumeration entries (number_integer, number_unsigned, and
2660ccea Poul Sander 2023-09-22 19:25 2843
number_float), because the library distinguishes these three types for numbers:
2660ccea Poul Sander 2023-09-22 19:25 2844
@ref basic_json::number_unsigned_t is used for unsigned integers,
2660ccea Poul Sander 2023-09-22 19:25 2845
@ref basic_json::number_integer_t is used for signed integers, and
2660ccea Poul Sander 2023-09-22 19:25 2846
@ref basic_json::number_float_t is used for floating-point numbers or to
2660ccea Poul Sander 2023-09-22 19:25 2847
approximate integers which do not fit in the limits of their respective type.
2660ccea Poul Sander 2023-09-22 19:25 2848
2660ccea Poul Sander 2023-09-22 19:25 2849
@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
2660ccea Poul Sander 2023-09-22 19:25 2850
value with the default value for a given type
2660ccea Poul Sander 2023-09-22 19:25 2851
2660ccea Poul Sander 2023-09-22 19:25 2852
@since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 2853
*/
2660ccea Poul Sander 2023-09-22 19:25 2854
enum class value_t : std::uint8_t
2660ccea Poul Sander 2023-09-22 19:25 2855
{
2660ccea Poul Sander 2023-09-22 19:25 2856
    null,             ///< null value
2660ccea Poul Sander 2023-09-22 19:25 2857
    object,           ///< object (unordered set of name/value pairs)
2660ccea Poul Sander 2023-09-22 19:25 2858
    array,            ///< array (ordered collection of values)
2660ccea Poul Sander 2023-09-22 19:25 2859
    string,           ///< string value
2660ccea Poul Sander 2023-09-22 19:25 2860
    boolean,          ///< boolean value
2660ccea Poul Sander 2023-09-22 19:25 2861
    number_integer,   ///< number value (signed integer)
2660ccea Poul Sander 2023-09-22 19:25 2862
    number_unsigned,  ///< number value (unsigned integer)
2660ccea Poul Sander 2023-09-22 19:25 2863
    number_float,     ///< number value (floating-point)
2660ccea Poul Sander 2023-09-22 19:25 2864
    discarded         ///< discarded by the the parser callback function
2660ccea Poul Sander 2023-09-22 19:25 2865
};
2660ccea Poul Sander 2023-09-22 19:25 2866
2660ccea Poul Sander 2023-09-22 19:25 2867
/*!
2660ccea Poul Sander 2023-09-22 19:25 2868
@brief comparison operator for JSON types
2660ccea Poul Sander 2023-09-22 19:25 2869
2660ccea Poul Sander 2023-09-22 19:25 2870
Returns an ordering that is similar to Python:
2660ccea Poul Sander 2023-09-22 19:25 2871
- order: null < boolean < number < object < array < string
2660ccea Poul Sander 2023-09-22 19:25 2872
- furthermore, each type is not smaller than itself
2660ccea Poul Sander 2023-09-22 19:25 2873
- discarded values are not comparable
2660ccea Poul Sander 2023-09-22 19:25 2874
2660ccea Poul Sander 2023-09-22 19:25 2875
@since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 2876
*/
2660ccea Poul Sander 2023-09-22 19:25 2877
inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 2878
{
2660ccea Poul Sander 2023-09-22 19:25 2879
    static constexpr std::array<std::uint8_t, 8> order = {{
2660ccea Poul Sander 2023-09-22 19:25 2880
            0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2660ccea Poul Sander 2023-09-22 19:25 2881
            1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
2660ccea Poul Sander 2023-09-22 19:25 2882
        }
2660ccea Poul Sander 2023-09-22 19:25 2883
    };
2660ccea Poul Sander 2023-09-22 19:25 2884
2660ccea Poul Sander 2023-09-22 19:25 2885
    const auto l_index = static_cast<std::size_t>(lhs);
2660ccea Poul Sander 2023-09-22 19:25 2886
    const auto r_index = static_cast<std::size_t>(rhs);
2660ccea Poul Sander 2023-09-22 19:25 2887
    return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
2660ccea Poul Sander 2023-09-22 19:25 2888
}
2660ccea Poul Sander 2023-09-22 19:25 2889
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2890
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2891
2660ccea Poul Sander 2023-09-22 19:25 2892
2660ccea Poul Sander 2023-09-22 19:25 2893
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 2894
{
2660ccea Poul Sander 2023-09-22 19:25 2895
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 2896
{
2660ccea Poul Sander 2023-09-22 19:25 2897
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 2898
void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
2660ccea Poul Sander 2023-09-22 19:25 2899
{
2660ccea Poul Sander 2023-09-22 19:25 2900
    if (JSON_HEDLEY_UNLIKELY(not j.is_null()))
2660ccea Poul Sander 2023-09-22 19:25 2901
    {
2660ccea Poul Sander 2023-09-22 19:25 2902
        JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 2903
    }
2660ccea Poul Sander 2023-09-22 19:25 2904
    n = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 2905
}
2660ccea Poul Sander 2023-09-22 19:25 2906
2660ccea Poul Sander 2023-09-22 19:25 2907
// overloads for basic_json template parameters
2660ccea Poul Sander 2023-09-22 19:25 2908
template<typename BasicJsonType, typename ArithmeticType,
2660ccea Poul Sander 2023-09-22 19:25 2909
         enable_if_t<std::is_arithmetic<ArithmeticType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2910
                     not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 2911
                     int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 2912
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
2660ccea Poul Sander 2023-09-22 19:25 2913
{
2660ccea Poul Sander 2023-09-22 19:25 2914
    switch (static_cast<value_t>(j))
2660ccea Poul Sander 2023-09-22 19:25 2915
    {
2660ccea Poul Sander 2023-09-22 19:25 2916
        case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 2917
        {
2660ccea Poul Sander 2023-09-22 19:25 2918
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
2660ccea Poul Sander 2023-09-22 19:25 2919
            break;
2660ccea Poul Sander 2023-09-22 19:25 2920
        }
2660ccea Poul Sander 2023-09-22 19:25 2921
        case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 2922
        {
2660ccea Poul Sander 2023-09-22 19:25 2923
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
2660ccea Poul Sander 2023-09-22 19:25 2924
            break;
2660ccea Poul Sander 2023-09-22 19:25 2925
        }
2660ccea Poul Sander 2023-09-22 19:25 2926
        case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 2927
        {
2660ccea Poul Sander 2023-09-22 19:25 2928
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
2660ccea Poul Sander 2023-09-22 19:25 2929
            break;
2660ccea Poul Sander 2023-09-22 19:25 2930
        }
2660ccea Poul Sander 2023-09-22 19:25 2931
2660ccea Poul Sander 2023-09-22 19:25 2932
        default:
2660ccea Poul Sander 2023-09-22 19:25 2933
            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 2934
    }
2660ccea Poul Sander 2023-09-22 19:25 2935
}
2660ccea Poul Sander 2023-09-22 19:25 2936
2660ccea Poul Sander 2023-09-22 19:25 2937
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 2938
void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
2660ccea Poul Sander 2023-09-22 19:25 2939
{
2660ccea Poul Sander 2023-09-22 19:25 2940
    if (JSON_HEDLEY_UNLIKELY(not j.is_boolean()))
2660ccea Poul Sander 2023-09-22 19:25 2941
    {
2660ccea Poul Sander 2023-09-22 19:25 2942
        JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 2943
    }
2660ccea Poul Sander 2023-09-22 19:25 2944
    b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
2660ccea Poul Sander 2023-09-22 19:25 2945
}
2660ccea Poul Sander 2023-09-22 19:25 2946
2660ccea Poul Sander 2023-09-22 19:25 2947
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 2948
void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
2660ccea Poul Sander 2023-09-22 19:25 2949
{
2660ccea Poul Sander 2023-09-22 19:25 2950
    if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
2660ccea Poul Sander 2023-09-22 19:25 2951
    {
2660ccea Poul Sander 2023-09-22 19:25 2952
        JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 2953
    }
2660ccea Poul Sander 2023-09-22 19:25 2954
    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
2660ccea Poul Sander 2023-09-22 19:25 2955
}
2660ccea Poul Sander 2023-09-22 19:25 2956
2660ccea Poul Sander 2023-09-22 19:25 2957
template <
2660ccea Poul Sander 2023-09-22 19:25 2958
    typename BasicJsonType, typename ConstructibleStringType,
2660ccea Poul Sander 2023-09-22 19:25 2959
    enable_if_t <
2660ccea Poul Sander 2023-09-22 19:25 2960
        is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
2660ccea Poul Sander 2023-09-22 19:25 2961
        not std::is_same<typename BasicJsonType::string_t,
2660ccea Poul Sander 2023-09-22 19:25 2962
                         ConstructibleStringType>::value,
2660ccea Poul Sander 2023-09-22 19:25 2963
        int > = 0 >
2660ccea Poul Sander 2023-09-22 19:25 2964
void from_json(const BasicJsonType& j, ConstructibleStringType& s)
2660ccea Poul Sander 2023-09-22 19:25 2965
{
2660ccea Poul Sander 2023-09-22 19:25 2966
    if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
2660ccea Poul Sander 2023-09-22 19:25 2967
    {
2660ccea Poul Sander 2023-09-22 19:25 2968
        JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 2969
    }
2660ccea Poul Sander 2023-09-22 19:25 2970
2660ccea Poul Sander 2023-09-22 19:25 2971
    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
2660ccea Poul Sander 2023-09-22 19:25 2972
}
2660ccea Poul Sander 2023-09-22 19:25 2973
2660ccea Poul Sander 2023-09-22 19:25 2974
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 2975
void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
2660ccea Poul Sander 2023-09-22 19:25 2976
{
2660ccea Poul Sander 2023-09-22 19:25 2977
    get_arithmetic_value(j, val);
2660ccea Poul Sander 2023-09-22 19:25 2978
}
2660ccea Poul Sander 2023-09-22 19:25 2979
2660ccea Poul Sander 2023-09-22 19:25 2980
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 2981
void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
2660ccea Poul Sander 2023-09-22 19:25 2982
{
2660ccea Poul Sander 2023-09-22 19:25 2983
    get_arithmetic_value(j, val);
2660ccea Poul Sander 2023-09-22 19:25 2984
}
2660ccea Poul Sander 2023-09-22 19:25 2985
2660ccea Poul Sander 2023-09-22 19:25 2986
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 2987
void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
2660ccea Poul Sander 2023-09-22 19:25 2988
{
2660ccea Poul Sander 2023-09-22 19:25 2989
    get_arithmetic_value(j, val);
2660ccea Poul Sander 2023-09-22 19:25 2990
}
2660ccea Poul Sander 2023-09-22 19:25 2991
2660ccea Poul Sander 2023-09-22 19:25 2992
template<typename BasicJsonType, typename EnumType,
2660ccea Poul Sander 2023-09-22 19:25 2993
         enable_if_t<std::is_enum<EnumType>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 2994
void from_json(const BasicJsonType& j, EnumType& e)
2660ccea Poul Sander 2023-09-22 19:25 2995
{
2660ccea Poul Sander 2023-09-22 19:25 2996
    typename std::underlying_type<EnumType>::type val;
2660ccea Poul Sander 2023-09-22 19:25 2997
    get_arithmetic_value(j, val);
2660ccea Poul Sander 2023-09-22 19:25 2998
    e = static_cast<EnumType>(val);
2660ccea Poul Sander 2023-09-22 19:25 2999
}
2660ccea Poul Sander 2023-09-22 19:25 3000
2660ccea Poul Sander 2023-09-22 19:25 3001
// forward_list doesn't have an insert method
2660ccea Poul Sander 2023-09-22 19:25 3002
template<typename BasicJsonType, typename T, typename Allocator,
2660ccea Poul Sander 2023-09-22 19:25 3003
         enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3004
void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
2660ccea Poul Sander 2023-09-22 19:25 3005
{
2660ccea Poul Sander 2023-09-22 19:25 3006
    if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
2660ccea Poul Sander 2023-09-22 19:25 3007
    {
2660ccea Poul Sander 2023-09-22 19:25 3008
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 3009
    }
2660ccea Poul Sander 2023-09-22 19:25 3010
    l.clear();
2660ccea Poul Sander 2023-09-22 19:25 3011
    std::transform(j.rbegin(), j.rend(),
2660ccea Poul Sander 2023-09-22 19:25 3012
                   std::front_inserter(l), [](const BasicJsonType & i)
2660ccea Poul Sander 2023-09-22 19:25 3013
    {
2660ccea Poul Sander 2023-09-22 19:25 3014
        return i.template get<T>();
2660ccea Poul Sander 2023-09-22 19:25 3015
    });
2660ccea Poul Sander 2023-09-22 19:25 3016
}
2660ccea Poul Sander 2023-09-22 19:25 3017
2660ccea Poul Sander 2023-09-22 19:25 3018
// valarray doesn't have an insert method
2660ccea Poul Sander 2023-09-22 19:25 3019
template<typename BasicJsonType, typename T,
2660ccea Poul Sander 2023-09-22 19:25 3020
         enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3021
void from_json(const BasicJsonType& j, std::valarray<T>& l)
2660ccea Poul Sander 2023-09-22 19:25 3022
{
2660ccea Poul Sander 2023-09-22 19:25 3023
    if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
2660ccea Poul Sander 2023-09-22 19:25 3024
    {
2660ccea Poul Sander 2023-09-22 19:25 3025
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 3026
    }
2660ccea Poul Sander 2023-09-22 19:25 3027
    l.resize(j.size());
2660ccea Poul Sander 2023-09-22 19:25 3028
    std::copy(j.begin(), j.end(), std::begin(l));
2660ccea Poul Sander 2023-09-22 19:25 3029
}
2660ccea Poul Sander 2023-09-22 19:25 3030
2660ccea Poul Sander 2023-09-22 19:25 3031
template <typename BasicJsonType, typename T, std::size_t N>
2660ccea Poul Sander 2023-09-22 19:25 3032
auto from_json(const BasicJsonType& j, T (&arr)[N])
2660ccea Poul Sander 2023-09-22 19:25 3033
-> decltype(j.template get<T>(), void())
2660ccea Poul Sander 2023-09-22 19:25 3034
{
2660ccea Poul Sander 2023-09-22 19:25 3035
    for (std::size_t i = 0; i < N; ++i)
2660ccea Poul Sander 2023-09-22 19:25 3036
    {
2660ccea Poul Sander 2023-09-22 19:25 3037
        arr[i] = j.at(i).template get<T>();
2660ccea Poul Sander 2023-09-22 19:25 3038
    }
2660ccea Poul Sander 2023-09-22 19:25 3039
}
2660ccea Poul Sander 2023-09-22 19:25 3040
2660ccea Poul Sander 2023-09-22 19:25 3041
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3042
void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 3043
{
2660ccea Poul Sander 2023-09-22 19:25 3044
    arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
2660ccea Poul Sander 2023-09-22 19:25 3045
}
2660ccea Poul Sander 2023-09-22 19:25 3046
2660ccea Poul Sander 2023-09-22 19:25 3047
template <typename BasicJsonType, typename T, std::size_t N>
2660ccea Poul Sander 2023-09-22 19:25 3048
auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
2660ccea Poul Sander 2023-09-22 19:25 3049
                          priority_tag<2> /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 3050
-> decltype(j.template get<T>(), void())
2660ccea Poul Sander 2023-09-22 19:25 3051
{
2660ccea Poul Sander 2023-09-22 19:25 3052
    for (std::size_t i = 0; i < N; ++i)
2660ccea Poul Sander 2023-09-22 19:25 3053
    {
2660ccea Poul Sander 2023-09-22 19:25 3054
        arr[i] = j.at(i).template get<T>();
2660ccea Poul Sander 2023-09-22 19:25 3055
    }
2660ccea Poul Sander 2023-09-22 19:25 3056
}
2660ccea Poul Sander 2023-09-22 19:25 3057
2660ccea Poul Sander 2023-09-22 19:25 3058
template<typename BasicJsonType, typename ConstructibleArrayType>
2660ccea Poul Sander 2023-09-22 19:25 3059
auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 3060
-> decltype(
2660ccea Poul Sander 2023-09-22 19:25 3061
    arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
2660ccea Poul Sander 2023-09-22 19:25 3062
    j.template get<typename ConstructibleArrayType::value_type>(),
2660ccea Poul Sander 2023-09-22 19:25 3063
    void())
2660ccea Poul Sander 2023-09-22 19:25 3064
{
2660ccea Poul Sander 2023-09-22 19:25 3065
    using std::end;
2660ccea Poul Sander 2023-09-22 19:25 3066
2660ccea Poul Sander 2023-09-22 19:25 3067
    ConstructibleArrayType ret;
2660ccea Poul Sander 2023-09-22 19:25 3068
    ret.reserve(j.size());
2660ccea Poul Sander 2023-09-22 19:25 3069
    std::transform(j.begin(), j.end(),
2660ccea Poul Sander 2023-09-22 19:25 3070
                   std::inserter(ret, end(ret)), [](const BasicJsonType & i)
2660ccea Poul Sander 2023-09-22 19:25 3071
    {
2660ccea Poul Sander 2023-09-22 19:25 3072
        // get<BasicJsonType>() returns *this, this won't call a from_json
2660ccea Poul Sander 2023-09-22 19:25 3073
        // method when value_type is BasicJsonType
2660ccea Poul Sander 2023-09-22 19:25 3074
        return i.template get<typename ConstructibleArrayType::value_type>();
2660ccea Poul Sander 2023-09-22 19:25 3075
    });
2660ccea Poul Sander 2023-09-22 19:25 3076
    arr = std::move(ret);
2660ccea Poul Sander 2023-09-22 19:25 3077
}
2660ccea Poul Sander 2023-09-22 19:25 3078
2660ccea Poul Sander 2023-09-22 19:25 3079
template <typename BasicJsonType, typename ConstructibleArrayType>
2660ccea Poul Sander 2023-09-22 19:25 3080
void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
2660ccea Poul Sander 2023-09-22 19:25 3081
                          priority_tag<0> /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 3082
{
2660ccea Poul Sander 2023-09-22 19:25 3083
    using std::end;
2660ccea Poul Sander 2023-09-22 19:25 3084
2660ccea Poul Sander 2023-09-22 19:25 3085
    ConstructibleArrayType ret;
2660ccea Poul Sander 2023-09-22 19:25 3086
    std::transform(
2660ccea Poul Sander 2023-09-22 19:25 3087
        j.begin(), j.end(), std::inserter(ret, end(ret)),
2660ccea Poul Sander 2023-09-22 19:25 3088
        [](const BasicJsonType & i)
2660ccea Poul Sander 2023-09-22 19:25 3089
    {
2660ccea Poul Sander 2023-09-22 19:25 3090
        // get<BasicJsonType>() returns *this, this won't call a from_json
2660ccea Poul Sander 2023-09-22 19:25 3091
        // method when value_type is BasicJsonType
2660ccea Poul Sander 2023-09-22 19:25 3092
        return i.template get<typename ConstructibleArrayType::value_type>();
2660ccea Poul Sander 2023-09-22 19:25 3093
    });
2660ccea Poul Sander 2023-09-22 19:25 3094
    arr = std::move(ret);
2660ccea Poul Sander 2023-09-22 19:25 3095
}
2660ccea Poul Sander 2023-09-22 19:25 3096
2660ccea Poul Sander 2023-09-22 19:25 3097
template <typename BasicJsonType, typename ConstructibleArrayType,
2660ccea Poul Sander 2023-09-22 19:25 3098
          enable_if_t <
2660ccea Poul Sander 2023-09-22 19:25 3099
              is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
2660ccea Poul Sander 2023-09-22 19:25 3100
              not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
2660ccea Poul Sander 2023-09-22 19:25 3101
              not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
2660ccea Poul Sander 2023-09-22 19:25 3102
              not is_basic_json<ConstructibleArrayType>::value,
2660ccea Poul Sander 2023-09-22 19:25 3103
              int > = 0 >
2660ccea Poul Sander 2023-09-22 19:25 3104
2660ccea Poul Sander 2023-09-22 19:25 3105
auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
2660ccea Poul Sander 2023-09-22 19:25 3106
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
2660ccea Poul Sander 2023-09-22 19:25 3107
j.template get<typename ConstructibleArrayType::value_type>(),
2660ccea Poul Sander 2023-09-22 19:25 3108
void())
2660ccea Poul Sander 2023-09-22 19:25 3109
{
2660ccea Poul Sander 2023-09-22 19:25 3110
    if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
2660ccea Poul Sander 2023-09-22 19:25 3111
    {
2660ccea Poul Sander 2023-09-22 19:25 3112
        JSON_THROW(type_error::create(302, "type must be array, but is " +
2660ccea Poul Sander 2023-09-22 19:25 3113
                                      std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 3114
    }
2660ccea Poul Sander 2023-09-22 19:25 3115
2660ccea Poul Sander 2023-09-22 19:25 3116
    from_json_array_impl(j, arr, priority_tag<3> {});
2660ccea Poul Sander 2023-09-22 19:25 3117
}
2660ccea Poul Sander 2023-09-22 19:25 3118
2660ccea Poul Sander 2023-09-22 19:25 3119
template<typename BasicJsonType, typename ConstructibleObjectType,
2660ccea Poul Sander 2023-09-22 19:25 3120
         enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3121
void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
2660ccea Poul Sander 2023-09-22 19:25 3122
{
2660ccea Poul Sander 2023-09-22 19:25 3123
    if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
2660ccea Poul Sander 2023-09-22 19:25 3124
    {
2660ccea Poul Sander 2023-09-22 19:25 3125
        JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 3126
    }
2660ccea Poul Sander 2023-09-22 19:25 3127
2660ccea Poul Sander 2023-09-22 19:25 3128
    ConstructibleObjectType ret;
2660ccea Poul Sander 2023-09-22 19:25 3129
    auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
2660ccea Poul Sander 2023-09-22 19:25 3130
    using value_type = typename ConstructibleObjectType::value_type;
2660ccea Poul Sander 2023-09-22 19:25 3131
    std::transform(
2660ccea Poul Sander 2023-09-22 19:25 3132
        inner_object->begin(), inner_object->end(),
2660ccea Poul Sander 2023-09-22 19:25 3133
        std::inserter(ret, ret.begin()),
2660ccea Poul Sander 2023-09-22 19:25 3134
        [](typename BasicJsonType::object_t::value_type const & p)
2660ccea Poul Sander 2023-09-22 19:25 3135
    {
2660ccea Poul Sander 2023-09-22 19:25 3136
        return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
2660ccea Poul Sander 2023-09-22 19:25 3137
    });
2660ccea Poul Sander 2023-09-22 19:25 3138
    obj = std::move(ret);
2660ccea Poul Sander 2023-09-22 19:25 3139
}
2660ccea Poul Sander 2023-09-22 19:25 3140
2660ccea Poul Sander 2023-09-22 19:25 3141
// overload for arithmetic types, not chosen for basic_json template arguments
2660ccea Poul Sander 2023-09-22 19:25 3142
// (BooleanType, etc..); note: Is it really necessary to provide explicit
2660ccea Poul Sander 2023-09-22 19:25 3143
// overloads for boolean_t etc. in case of a custom BooleanType which is not
2660ccea Poul Sander 2023-09-22 19:25 3144
// an arithmetic type?
2660ccea Poul Sander 2023-09-22 19:25 3145
template<typename BasicJsonType, typename ArithmeticType,
2660ccea Poul Sander 2023-09-22 19:25 3146
         enable_if_t <
2660ccea Poul Sander 2023-09-22 19:25 3147
             std::is_arithmetic<ArithmeticType>::value and
2660ccea Poul Sander 2023-09-22 19:25 3148
             not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
2660ccea Poul Sander 2023-09-22 19:25 3149
             not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
2660ccea Poul Sander 2023-09-22 19:25 3150
             not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
2660ccea Poul Sander 2023-09-22 19:25 3151
             not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 3152
             int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3153
void from_json(const BasicJsonType& j, ArithmeticType& val)
2660ccea Poul Sander 2023-09-22 19:25 3154
{
2660ccea Poul Sander 2023-09-22 19:25 3155
    switch (static_cast<value_t>(j))
2660ccea Poul Sander 2023-09-22 19:25 3156
    {
2660ccea Poul Sander 2023-09-22 19:25 3157
        case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 3158
        {
2660ccea Poul Sander 2023-09-22 19:25 3159
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
2660ccea Poul Sander 2023-09-22 19:25 3160
            break;
2660ccea Poul Sander 2023-09-22 19:25 3161
        }
2660ccea Poul Sander 2023-09-22 19:25 3162
        case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 3163
        {
2660ccea Poul Sander 2023-09-22 19:25 3164
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
2660ccea Poul Sander 2023-09-22 19:25 3165
            break;
2660ccea Poul Sander 2023-09-22 19:25 3166
        }
2660ccea Poul Sander 2023-09-22 19:25 3167
        case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 3168
        {
2660ccea Poul Sander 2023-09-22 19:25 3169
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
2660ccea Poul Sander 2023-09-22 19:25 3170
            break;
2660ccea Poul Sander 2023-09-22 19:25 3171
        }
2660ccea Poul Sander 2023-09-22 19:25 3172
        case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 3173
        {
2660ccea Poul Sander 2023-09-22 19:25 3174
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
2660ccea Poul Sander 2023-09-22 19:25 3175
            break;
2660ccea Poul Sander 2023-09-22 19:25 3176
        }
2660ccea Poul Sander 2023-09-22 19:25 3177
2660ccea Poul Sander 2023-09-22 19:25 3178
        default:
2660ccea Poul Sander 2023-09-22 19:25 3179
            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 3180
    }
2660ccea Poul Sander 2023-09-22 19:25 3181
}
2660ccea Poul Sander 2023-09-22 19:25 3182
2660ccea Poul Sander 2023-09-22 19:25 3183
template<typename BasicJsonType, typename A1, typename A2>
2660ccea Poul Sander 2023-09-22 19:25 3184
void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
2660ccea Poul Sander 2023-09-22 19:25 3185
{
2660ccea Poul Sander 2023-09-22 19:25 3186
    p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
2660ccea Poul Sander 2023-09-22 19:25 3187
}
2660ccea Poul Sander 2023-09-22 19:25 3188
2660ccea Poul Sander 2023-09-22 19:25 3189
template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
2660ccea Poul Sander 2023-09-22 19:25 3190
void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 3191
{
2660ccea Poul Sander 2023-09-22 19:25 3192
    t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
2660ccea Poul Sander 2023-09-22 19:25 3193
}
2660ccea Poul Sander 2023-09-22 19:25 3194
2660ccea Poul Sander 2023-09-22 19:25 3195
template<typename BasicJsonType, typename... Args>
2660ccea Poul Sander 2023-09-22 19:25 3196
void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
2660ccea Poul Sander 2023-09-22 19:25 3197
{
2660ccea Poul Sander 2023-09-22 19:25 3198
    from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
2660ccea Poul Sander 2023-09-22 19:25 3199
}
2660ccea Poul Sander 2023-09-22 19:25 3200
2660ccea Poul Sander 2023-09-22 19:25 3201
template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
2660ccea Poul Sander 2023-09-22 19:25 3202
          typename = enable_if_t<not std::is_constructible<
2660ccea Poul Sander 2023-09-22 19:25 3203
                                     typename BasicJsonType::string_t, Key>::value>>
2660ccea Poul Sander 2023-09-22 19:25 3204
void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
2660ccea Poul Sander 2023-09-22 19:25 3205
{
2660ccea Poul Sander 2023-09-22 19:25 3206
    if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
2660ccea Poul Sander 2023-09-22 19:25 3207
    {
2660ccea Poul Sander 2023-09-22 19:25 3208
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 3209
    }
2660ccea Poul Sander 2023-09-22 19:25 3210
    m.clear();
2660ccea Poul Sander 2023-09-22 19:25 3211
    for (const auto& p : j)
2660ccea Poul Sander 2023-09-22 19:25 3212
    {
2660ccea Poul Sander 2023-09-22 19:25 3213
        if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
2660ccea Poul Sander 2023-09-22 19:25 3214
        {
2660ccea Poul Sander 2023-09-22 19:25 3215
            JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 3216
        }
2660ccea Poul Sander 2023-09-22 19:25 3217
        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
2660ccea Poul Sander 2023-09-22 19:25 3218
    }
2660ccea Poul Sander 2023-09-22 19:25 3219
}
2660ccea Poul Sander 2023-09-22 19:25 3220
2660ccea Poul Sander 2023-09-22 19:25 3221
template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
2660ccea Poul Sander 2023-09-22 19:25 3222
          typename = enable_if_t<not std::is_constructible<
2660ccea Poul Sander 2023-09-22 19:25 3223
                                     typename BasicJsonType::string_t, Key>::value>>
2660ccea Poul Sander 2023-09-22 19:25 3224
void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
2660ccea Poul Sander 2023-09-22 19:25 3225
{
2660ccea Poul Sander 2023-09-22 19:25 3226
    if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
2660ccea Poul Sander 2023-09-22 19:25 3227
    {
2660ccea Poul Sander 2023-09-22 19:25 3228
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 3229
    }
2660ccea Poul Sander 2023-09-22 19:25 3230
    m.clear();
2660ccea Poul Sander 2023-09-22 19:25 3231
    for (const auto& p : j)
2660ccea Poul Sander 2023-09-22 19:25 3232
    {
2660ccea Poul Sander 2023-09-22 19:25 3233
        if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
2660ccea Poul Sander 2023-09-22 19:25 3234
        {
2660ccea Poul Sander 2023-09-22 19:25 3235
            JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 3236
        }
2660ccea Poul Sander 2023-09-22 19:25 3237
        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
2660ccea Poul Sander 2023-09-22 19:25 3238
    }
2660ccea Poul Sander 2023-09-22 19:25 3239
}
2660ccea Poul Sander 2023-09-22 19:25 3240
2660ccea Poul Sander 2023-09-22 19:25 3241
struct from_json_fn
2660ccea Poul Sander 2023-09-22 19:25 3242
{
2660ccea Poul Sander 2023-09-22 19:25 3243
    template<typename BasicJsonType, typename T>
2660ccea Poul Sander 2023-09-22 19:25 3244
    auto operator()(const BasicJsonType& j, T& val) const
2660ccea Poul Sander 2023-09-22 19:25 3245
    noexcept(noexcept(from_json(j, val)))
2660ccea Poul Sander 2023-09-22 19:25 3246
    -> decltype(from_json(j, val), void())
2660ccea Poul Sander 2023-09-22 19:25 3247
    {
2660ccea Poul Sander 2023-09-22 19:25 3248
        return from_json(j, val);
2660ccea Poul Sander 2023-09-22 19:25 3249
    }
2660ccea Poul Sander 2023-09-22 19:25 3250
};
2660ccea Poul Sander 2023-09-22 19:25 3251
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 3252
2660ccea Poul Sander 2023-09-22 19:25 3253
/// namespace to hold default `from_json` function
2660ccea Poul Sander 2023-09-22 19:25 3254
/// to see why this is required:
2660ccea Poul Sander 2023-09-22 19:25 3255
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
2660ccea Poul Sander 2023-09-22 19:25 3256
namespace
2660ccea Poul Sander 2023-09-22 19:25 3257
{
2660ccea Poul Sander 2023-09-22 19:25 3258
constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
2660ccea Poul Sander 2023-09-22 19:25 3259
} // namespace
2660ccea Poul Sander 2023-09-22 19:25 3260
} // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 3261
2660ccea Poul Sander 2023-09-22 19:25 3262
// #include <nlohmann/detail/conversions/to_json.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3263
2660ccea Poul Sander 2023-09-22 19:25 3264
2660ccea Poul Sander 2023-09-22 19:25 3265
#include <algorithm> // copy
2660ccea Poul Sander 2023-09-22 19:25 3266
#include <ciso646> // or, and, not
2660ccea Poul Sander 2023-09-22 19:25 3267
#include <iterator> // begin, end
2660ccea Poul Sander 2023-09-22 19:25 3268
#include <string> // string
2660ccea Poul Sander 2023-09-22 19:25 3269
#include <tuple> // tuple, get
2660ccea Poul Sander 2023-09-22 19:25 3270
#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
2660ccea Poul Sander 2023-09-22 19:25 3271
#include <utility> // move, forward, declval, pair
2660ccea Poul Sander 2023-09-22 19:25 3272
#include <valarray> // valarray
2660ccea Poul Sander 2023-09-22 19:25 3273
#include <vector> // vector
2660ccea Poul Sander 2023-09-22 19:25 3274
2660ccea Poul Sander 2023-09-22 19:25 3275
// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3276
2660ccea Poul Sander 2023-09-22 19:25 3277
2660ccea Poul Sander 2023-09-22 19:25 3278
#include <cstddef> // size_t
2660ccea Poul Sander 2023-09-22 19:25 3279
#include <iterator> // input_iterator_tag
2660ccea Poul Sander 2023-09-22 19:25 3280
#include <string> // string, to_string
2660ccea Poul Sander 2023-09-22 19:25 3281
#include <tuple> // tuple_size, get, tuple_element
2660ccea Poul Sander 2023-09-22 19:25 3282
2660ccea Poul Sander 2023-09-22 19:25 3283
// #include <nlohmann/detail/meta/type_traits.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3284
2660ccea Poul Sander 2023-09-22 19:25 3285
// #include <nlohmann/detail/value_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3286
2660ccea Poul Sander 2023-09-22 19:25 3287
2660ccea Poul Sander 2023-09-22 19:25 3288
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 3289
{
2660ccea Poul Sander 2023-09-22 19:25 3290
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 3291
{
2660ccea Poul Sander 2023-09-22 19:25 3292
template<typename string_type>
2660ccea Poul Sander 2023-09-22 19:25 3293
void int_to_string( string_type& target, std::size_t value )
2660ccea Poul Sander 2023-09-22 19:25 3294
{
2660ccea Poul Sander 2023-09-22 19:25 3295
    target = std::to_string(value);
2660ccea Poul Sander 2023-09-22 19:25 3296
}
2660ccea Poul Sander 2023-09-22 19:25 3297
template <typename IteratorType> class iteration_proxy_value
2660ccea Poul Sander 2023-09-22 19:25 3298
{
2660ccea Poul Sander 2023-09-22 19:25 3299
  public:
2660ccea Poul Sander 2023-09-22 19:25 3300
    using difference_type = std::ptrdiff_t;
2660ccea Poul Sander 2023-09-22 19:25 3301
    using value_type = iteration_proxy_value;
2660ccea Poul Sander 2023-09-22 19:25 3302
    using pointer = value_type * ;
2660ccea Poul Sander 2023-09-22 19:25 3303
    using reference = value_type & ;
2660ccea Poul Sander 2023-09-22 19:25 3304
    using iterator_category = std::input_iterator_tag;
2660ccea Poul Sander 2023-09-22 19:25 3305
    using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
2660ccea Poul Sander 2023-09-22 19:25 3306
2660ccea Poul Sander 2023-09-22 19:25 3307
  private:
2660ccea Poul Sander 2023-09-22 19:25 3308
    /// the iterator
2660ccea Poul Sander 2023-09-22 19:25 3309
    IteratorType anchor;
2660ccea Poul Sander 2023-09-22 19:25 3310
    /// an index for arrays (used to create key names)
2660ccea Poul Sander 2023-09-22 19:25 3311
    std::size_t array_index = 0;
2660ccea Poul Sander 2023-09-22 19:25 3312
    /// last stringified array index
2660ccea Poul Sander 2023-09-22 19:25 3313
    mutable std::size_t array_index_last = 0;
2660ccea Poul Sander 2023-09-22 19:25 3314
    /// a string representation of the array index
2660ccea Poul Sander 2023-09-22 19:25 3315
    mutable string_type array_index_str = "0";
2660ccea Poul Sander 2023-09-22 19:25 3316
    /// an empty string (to return a reference for primitive values)
2660ccea Poul Sander 2023-09-22 19:25 3317
    const string_type empty_str = "";
2660ccea Poul Sander 2023-09-22 19:25 3318
2660ccea Poul Sander 2023-09-22 19:25 3319
  public:
2660ccea Poul Sander 2023-09-22 19:25 3320
    explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
2660ccea Poul Sander 2023-09-22 19:25 3321
2660ccea Poul Sander 2023-09-22 19:25 3322
    /// dereference operator (needed for range-based for)
2660ccea Poul Sander 2023-09-22 19:25 3323
    iteration_proxy_value& operator*()
2660ccea Poul Sander 2023-09-22 19:25 3324
    {
2660ccea Poul Sander 2023-09-22 19:25 3325
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 3326
    }
2660ccea Poul Sander 2023-09-22 19:25 3327
2660ccea Poul Sander 2023-09-22 19:25 3328
    /// increment operator (needed for range-based for)
2660ccea Poul Sander 2023-09-22 19:25 3329
    iteration_proxy_value& operator++()
2660ccea Poul Sander 2023-09-22 19:25 3330
    {
2660ccea Poul Sander 2023-09-22 19:25 3331
        ++anchor;
2660ccea Poul Sander 2023-09-22 19:25 3332
        ++array_index;
2660ccea Poul Sander 2023-09-22 19:25 3333
2660ccea Poul Sander 2023-09-22 19:25 3334
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 3335
    }
2660ccea Poul Sander 2023-09-22 19:25 3336
2660ccea Poul Sander 2023-09-22 19:25 3337
    /// equality operator (needed for InputIterator)
2660ccea Poul Sander 2023-09-22 19:25 3338
    bool operator==(const iteration_proxy_value& o) const
2660ccea Poul Sander 2023-09-22 19:25 3339
    {
2660ccea Poul Sander 2023-09-22 19:25 3340
        return anchor == o.anchor;
2660ccea Poul Sander 2023-09-22 19:25 3341
    }
2660ccea Poul Sander 2023-09-22 19:25 3342
2660ccea Poul Sander 2023-09-22 19:25 3343
    /// inequality operator (needed for range-based for)
2660ccea Poul Sander 2023-09-22 19:25 3344
    bool operator!=(const iteration_proxy_value& o) const
2660ccea Poul Sander 2023-09-22 19:25 3345
    {
2660ccea Poul Sander 2023-09-22 19:25 3346
        return anchor != o.anchor;
2660ccea Poul Sander 2023-09-22 19:25 3347
    }
2660ccea Poul Sander 2023-09-22 19:25 3348
2660ccea Poul Sander 2023-09-22 19:25 3349
    /// return key of the iterator
2660ccea Poul Sander 2023-09-22 19:25 3350
    const string_type& key() const
2660ccea Poul Sander 2023-09-22 19:25 3351
    {
2660ccea Poul Sander 2023-09-22 19:25 3352
        assert(anchor.m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 3353
2660ccea Poul Sander 2023-09-22 19:25 3354
        switch (anchor.m_object->type())
2660ccea Poul Sander 2023-09-22 19:25 3355
        {
2660ccea Poul Sander 2023-09-22 19:25 3356
            // use integer array index as key
2660ccea Poul Sander 2023-09-22 19:25 3357
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 3358
            {
2660ccea Poul Sander 2023-09-22 19:25 3359
                if (array_index != array_index_last)
2660ccea Poul Sander 2023-09-22 19:25 3360
                {
2660ccea Poul Sander 2023-09-22 19:25 3361
                    int_to_string( array_index_str, array_index );
2660ccea Poul Sander 2023-09-22 19:25 3362
                    array_index_last = array_index;
2660ccea Poul Sander 2023-09-22 19:25 3363
                }
2660ccea Poul Sander 2023-09-22 19:25 3364
                return array_index_str;
2660ccea Poul Sander 2023-09-22 19:25 3365
            }
2660ccea Poul Sander 2023-09-22 19:25 3366
2660ccea Poul Sander 2023-09-22 19:25 3367
            // use key from the object
2660ccea Poul Sander 2023-09-22 19:25 3368
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 3369
                return anchor.key();
2660ccea Poul Sander 2023-09-22 19:25 3370
2660ccea Poul Sander 2023-09-22 19:25 3371
            // use an empty key for all primitive types
2660ccea Poul Sander 2023-09-22 19:25 3372
            default:
2660ccea Poul Sander 2023-09-22 19:25 3373
                return empty_str;
2660ccea Poul Sander 2023-09-22 19:25 3374
        }
2660ccea Poul Sander 2023-09-22 19:25 3375
    }
2660ccea Poul Sander 2023-09-22 19:25 3376
2660ccea Poul Sander 2023-09-22 19:25 3377
    /// return value of the iterator
2660ccea Poul Sander 2023-09-22 19:25 3378
    typename IteratorType::reference value() const
2660ccea Poul Sander 2023-09-22 19:25 3379
    {
2660ccea Poul Sander 2023-09-22 19:25 3380
        return anchor.value();
2660ccea Poul Sander 2023-09-22 19:25 3381
    }
2660ccea Poul Sander 2023-09-22 19:25 3382
};
2660ccea Poul Sander 2023-09-22 19:25 3383
2660ccea Poul Sander 2023-09-22 19:25 3384
/// proxy class for the items() function
2660ccea Poul Sander 2023-09-22 19:25 3385
template<typename IteratorType> class iteration_proxy
2660ccea Poul Sander 2023-09-22 19:25 3386
{
2660ccea Poul Sander 2023-09-22 19:25 3387
  private:
2660ccea Poul Sander 2023-09-22 19:25 3388
    /// the container to iterate
2660ccea Poul Sander 2023-09-22 19:25 3389
    typename IteratorType::reference container;
2660ccea Poul Sander 2023-09-22 19:25 3390
2660ccea Poul Sander 2023-09-22 19:25 3391
  public:
2660ccea Poul Sander 2023-09-22 19:25 3392
    /// construct iteration proxy from a container
2660ccea Poul Sander 2023-09-22 19:25 3393
    explicit iteration_proxy(typename IteratorType::reference cont) noexcept
2660ccea Poul Sander 2023-09-22 19:25 3394
        : container(cont) {}
2660ccea Poul Sander 2023-09-22 19:25 3395
2660ccea Poul Sander 2023-09-22 19:25 3396
    /// return iterator begin (needed for range-based for)
2660ccea Poul Sander 2023-09-22 19:25 3397
    iteration_proxy_value<IteratorType> begin() noexcept
2660ccea Poul Sander 2023-09-22 19:25 3398
    {
2660ccea Poul Sander 2023-09-22 19:25 3399
        return iteration_proxy_value<IteratorType>(container.begin());
2660ccea Poul Sander 2023-09-22 19:25 3400
    }
2660ccea Poul Sander 2023-09-22 19:25 3401
2660ccea Poul Sander 2023-09-22 19:25 3402
    /// return iterator end (needed for range-based for)
2660ccea Poul Sander 2023-09-22 19:25 3403
    iteration_proxy_value<IteratorType> end() noexcept
2660ccea Poul Sander 2023-09-22 19:25 3404
    {
2660ccea Poul Sander 2023-09-22 19:25 3405
        return iteration_proxy_value<IteratorType>(container.end());
2660ccea Poul Sander 2023-09-22 19:25 3406
    }
2660ccea Poul Sander 2023-09-22 19:25 3407
};
2660ccea Poul Sander 2023-09-22 19:25 3408
// Structured Bindings Support
2660ccea Poul Sander 2023-09-22 19:25 3409
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
2660ccea Poul Sander 2023-09-22 19:25 3410
// And see https://github.com/nlohmann/json/pull/1391
2660ccea Poul Sander 2023-09-22 19:25 3411
template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3412
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
2660ccea Poul Sander 2023-09-22 19:25 3413
{
2660ccea Poul Sander 2023-09-22 19:25 3414
    return i.key();
2660ccea Poul Sander 2023-09-22 19:25 3415
}
2660ccea Poul Sander 2023-09-22 19:25 3416
// Structured Bindings Support
2660ccea Poul Sander 2023-09-22 19:25 3417
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
2660ccea Poul Sander 2023-09-22 19:25 3418
// And see https://github.com/nlohmann/json/pull/1391
2660ccea Poul Sander 2023-09-22 19:25 3419
template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3420
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
2660ccea Poul Sander 2023-09-22 19:25 3421
{
2660ccea Poul Sander 2023-09-22 19:25 3422
    return i.value();
2660ccea Poul Sander 2023-09-22 19:25 3423
}
2660ccea Poul Sander 2023-09-22 19:25 3424
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 3425
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 3426
2660ccea Poul Sander 2023-09-22 19:25 3427
// The Addition to the STD Namespace is required to add
2660ccea Poul Sander 2023-09-22 19:25 3428
// Structured Bindings Support to the iteration_proxy_value class
2660ccea Poul Sander 2023-09-22 19:25 3429
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
2660ccea Poul Sander 2023-09-22 19:25 3430
// And see https://github.com/nlohmann/json/pull/1391
2660ccea Poul Sander 2023-09-22 19:25 3431
namespace std
2660ccea Poul Sander 2023-09-22 19:25 3432
{
2660ccea Poul Sander 2023-09-22 19:25 3433
#if defined(__clang__)
2660ccea Poul Sander 2023-09-22 19:25 3434
    // Fix: https://github.com/nlohmann/json/issues/1401
2660ccea Poul Sander 2023-09-22 19:25 3435
    #pragma clang diagnostic push
2660ccea Poul Sander 2023-09-22 19:25 3436
    #pragma clang diagnostic ignored "-Wmismatched-tags"
2660ccea Poul Sander 2023-09-22 19:25 3437
#endif
2660ccea Poul Sander 2023-09-22 19:25 3438
template <typename IteratorType>
2660ccea Poul Sander 2023-09-22 19:25 3439
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
2660ccea Poul Sander 2023-09-22 19:25 3440
            : public std::integral_constant<std::size_t, 2> {};
2660ccea Poul Sander 2023-09-22 19:25 3441
2660ccea Poul Sander 2023-09-22 19:25 3442
template <std::size_t N, typename IteratorType>
2660ccea Poul Sander 2023-09-22 19:25 3443
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
2660ccea Poul Sander 2023-09-22 19:25 3444
{
2660ccea Poul Sander 2023-09-22 19:25 3445
  public:
2660ccea Poul Sander 2023-09-22 19:25 3446
    using type = decltype(
2660ccea Poul Sander 2023-09-22 19:25 3447
                     get<N>(std::declval <
2660ccea Poul Sander 2023-09-22 19:25 3448
                            ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
2660ccea Poul Sander 2023-09-22 19:25 3449
};
2660ccea Poul Sander 2023-09-22 19:25 3450
#if defined(__clang__)
2660ccea Poul Sander 2023-09-22 19:25 3451
    #pragma clang diagnostic pop
2660ccea Poul Sander 2023-09-22 19:25 3452
#endif
2660ccea Poul Sander 2023-09-22 19:25 3453
} // namespace std
2660ccea Poul Sander 2023-09-22 19:25 3454
2660ccea Poul Sander 2023-09-22 19:25 3455
// #include <nlohmann/detail/meta/cpp_future.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3456
2660ccea Poul Sander 2023-09-22 19:25 3457
// #include <nlohmann/detail/meta/type_traits.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3458
2660ccea Poul Sander 2023-09-22 19:25 3459
// #include <nlohmann/detail/value_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3460
2660ccea Poul Sander 2023-09-22 19:25 3461
2660ccea Poul Sander 2023-09-22 19:25 3462
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 3463
{
2660ccea Poul Sander 2023-09-22 19:25 3464
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 3465
{
2660ccea Poul Sander 2023-09-22 19:25 3466
//////////////////
2660ccea Poul Sander 2023-09-22 19:25 3467
// constructors //
2660ccea Poul Sander 2023-09-22 19:25 3468
//////////////////
2660ccea Poul Sander 2023-09-22 19:25 3469
2660ccea Poul Sander 2023-09-22 19:25 3470
template<value_t> struct external_constructor;
2660ccea Poul Sander 2023-09-22 19:25 3471
2660ccea Poul Sander 2023-09-22 19:25 3472
template<>
2660ccea Poul Sander 2023-09-22 19:25 3473
struct external_constructor<value_t::boolean>
2660ccea Poul Sander 2023-09-22 19:25 3474
{
2660ccea Poul Sander 2023-09-22 19:25 3475
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3476
    static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
2660ccea Poul Sander 2023-09-22 19:25 3477
    {
2660ccea Poul Sander 2023-09-22 19:25 3478
        j.m_type = value_t::boolean;
2660ccea Poul Sander 2023-09-22 19:25 3479
        j.m_value = b;
2660ccea Poul Sander 2023-09-22 19:25 3480
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3481
    }
2660ccea Poul Sander 2023-09-22 19:25 3482
};
2660ccea Poul Sander 2023-09-22 19:25 3483
2660ccea Poul Sander 2023-09-22 19:25 3484
template<>
2660ccea Poul Sander 2023-09-22 19:25 3485
struct external_constructor<value_t::string>
2660ccea Poul Sander 2023-09-22 19:25 3486
{
2660ccea Poul Sander 2023-09-22 19:25 3487
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3488
    static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
2660ccea Poul Sander 2023-09-22 19:25 3489
    {
2660ccea Poul Sander 2023-09-22 19:25 3490
        j.m_type = value_t::string;
2660ccea Poul Sander 2023-09-22 19:25 3491
        j.m_value = s;
2660ccea Poul Sander 2023-09-22 19:25 3492
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3493
    }
2660ccea Poul Sander 2023-09-22 19:25 3494
2660ccea Poul Sander 2023-09-22 19:25 3495
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3496
    static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
2660ccea Poul Sander 2023-09-22 19:25 3497
    {
2660ccea Poul Sander 2023-09-22 19:25 3498
        j.m_type = value_t::string;
2660ccea Poul Sander 2023-09-22 19:25 3499
        j.m_value = std::move(s);
2660ccea Poul Sander 2023-09-22 19:25 3500
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3501
    }
2660ccea Poul Sander 2023-09-22 19:25 3502
2660ccea Poul Sander 2023-09-22 19:25 3503
    template<typename BasicJsonType, typename CompatibleStringType,
2660ccea Poul Sander 2023-09-22 19:25 3504
             enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 3505
                         int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3506
    static void construct(BasicJsonType& j, const CompatibleStringType& str)
2660ccea Poul Sander 2023-09-22 19:25 3507
    {
2660ccea Poul Sander 2023-09-22 19:25 3508
        j.m_type = value_t::string;
2660ccea Poul Sander 2023-09-22 19:25 3509
        j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
2660ccea Poul Sander 2023-09-22 19:25 3510
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3511
    }
2660ccea Poul Sander 2023-09-22 19:25 3512
};
2660ccea Poul Sander 2023-09-22 19:25 3513
2660ccea Poul Sander 2023-09-22 19:25 3514
template<>
2660ccea Poul Sander 2023-09-22 19:25 3515
struct external_constructor<value_t::number_float>
2660ccea Poul Sander 2023-09-22 19:25 3516
{
2660ccea Poul Sander 2023-09-22 19:25 3517
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3518
    static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
2660ccea Poul Sander 2023-09-22 19:25 3519
    {
2660ccea Poul Sander 2023-09-22 19:25 3520
        j.m_type = value_t::number_float;
2660ccea Poul Sander 2023-09-22 19:25 3521
        j.m_value = val;
2660ccea Poul Sander 2023-09-22 19:25 3522
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3523
    }
2660ccea Poul Sander 2023-09-22 19:25 3524
};
2660ccea Poul Sander 2023-09-22 19:25 3525
2660ccea Poul Sander 2023-09-22 19:25 3526
template<>
2660ccea Poul Sander 2023-09-22 19:25 3527
struct external_constructor<value_t::number_unsigned>
2660ccea Poul Sander 2023-09-22 19:25 3528
{
2660ccea Poul Sander 2023-09-22 19:25 3529
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3530
    static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
2660ccea Poul Sander 2023-09-22 19:25 3531
    {
2660ccea Poul Sander 2023-09-22 19:25 3532
        j.m_type = value_t::number_unsigned;
2660ccea Poul Sander 2023-09-22 19:25 3533
        j.m_value = val;
2660ccea Poul Sander 2023-09-22 19:25 3534
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3535
    }
2660ccea Poul Sander 2023-09-22 19:25 3536
};
2660ccea Poul Sander 2023-09-22 19:25 3537
2660ccea Poul Sander 2023-09-22 19:25 3538
template<>
2660ccea Poul Sander 2023-09-22 19:25 3539
struct external_constructor<value_t::number_integer>
2660ccea Poul Sander 2023-09-22 19:25 3540
{
2660ccea Poul Sander 2023-09-22 19:25 3541
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3542
    static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
2660ccea Poul Sander 2023-09-22 19:25 3543
    {
2660ccea Poul Sander 2023-09-22 19:25 3544
        j.m_type = value_t::number_integer;
2660ccea Poul Sander 2023-09-22 19:25 3545
        j.m_value = val;
2660ccea Poul Sander 2023-09-22 19:25 3546
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3547
    }
2660ccea Poul Sander 2023-09-22 19:25 3548
};
2660ccea Poul Sander 2023-09-22 19:25 3549
2660ccea Poul Sander 2023-09-22 19:25 3550
template<>
2660ccea Poul Sander 2023-09-22 19:25 3551
struct external_constructor<value_t::array>
2660ccea Poul Sander 2023-09-22 19:25 3552
{
2660ccea Poul Sander 2023-09-22 19:25 3553
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3554
    static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
2660ccea Poul Sander 2023-09-22 19:25 3555
    {
2660ccea Poul Sander 2023-09-22 19:25 3556
        j.m_type = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 3557
        j.m_value = arr;
2660ccea Poul Sander 2023-09-22 19:25 3558
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3559
    }
2660ccea Poul Sander 2023-09-22 19:25 3560
2660ccea Poul Sander 2023-09-22 19:25 3561
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3562
    static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
2660ccea Poul Sander 2023-09-22 19:25 3563
    {
2660ccea Poul Sander 2023-09-22 19:25 3564
        j.m_type = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 3565
        j.m_value = std::move(arr);
2660ccea Poul Sander 2023-09-22 19:25 3566
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3567
    }
2660ccea Poul Sander 2023-09-22 19:25 3568
2660ccea Poul Sander 2023-09-22 19:25 3569
    template<typename BasicJsonType, typename CompatibleArrayType,
2660ccea Poul Sander 2023-09-22 19:25 3570
             enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 3571
                         int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3572
    static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
2660ccea Poul Sander 2023-09-22 19:25 3573
    {
2660ccea Poul Sander 2023-09-22 19:25 3574
        using std::begin;
2660ccea Poul Sander 2023-09-22 19:25 3575
        using std::end;
2660ccea Poul Sander 2023-09-22 19:25 3576
        j.m_type = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 3577
        j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
2660ccea Poul Sander 2023-09-22 19:25 3578
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3579
    }
2660ccea Poul Sander 2023-09-22 19:25 3580
2660ccea Poul Sander 2023-09-22 19:25 3581
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3582
    static void construct(BasicJsonType& j, const std::vector<bool>& arr)
2660ccea Poul Sander 2023-09-22 19:25 3583
    {
2660ccea Poul Sander 2023-09-22 19:25 3584
        j.m_type = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 3585
        j.m_value = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 3586
        j.m_value.array->reserve(arr.size());
2660ccea Poul Sander 2023-09-22 19:25 3587
        for (const bool x : arr)
2660ccea Poul Sander 2023-09-22 19:25 3588
        {
2660ccea Poul Sander 2023-09-22 19:25 3589
            j.m_value.array->push_back(x);
2660ccea Poul Sander 2023-09-22 19:25 3590
        }
2660ccea Poul Sander 2023-09-22 19:25 3591
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3592
    }
2660ccea Poul Sander 2023-09-22 19:25 3593
2660ccea Poul Sander 2023-09-22 19:25 3594
    template<typename BasicJsonType, typename T,
2660ccea Poul Sander 2023-09-22 19:25 3595
             enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3596
    static void construct(BasicJsonType& j, const std::valarray<T>& arr)
2660ccea Poul Sander 2023-09-22 19:25 3597
    {
2660ccea Poul Sander 2023-09-22 19:25 3598
        j.m_type = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 3599
        j.m_value = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 3600
        j.m_value.array->resize(arr.size());
2660ccea Poul Sander 2023-09-22 19:25 3601
        if (arr.size() > 0)
2660ccea Poul Sander 2023-09-22 19:25 3602
        {
2660ccea Poul Sander 2023-09-22 19:25 3603
            std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
2660ccea Poul Sander 2023-09-22 19:25 3604
        }
2660ccea Poul Sander 2023-09-22 19:25 3605
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3606
    }
2660ccea Poul Sander 2023-09-22 19:25 3607
};
2660ccea Poul Sander 2023-09-22 19:25 3608
2660ccea Poul Sander 2023-09-22 19:25 3609
template<>
2660ccea Poul Sander 2023-09-22 19:25 3610
struct external_constructor<value_t::object>
2660ccea Poul Sander 2023-09-22 19:25 3611
{
2660ccea Poul Sander 2023-09-22 19:25 3612
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3613
    static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
2660ccea Poul Sander 2023-09-22 19:25 3614
    {
2660ccea Poul Sander 2023-09-22 19:25 3615
        j.m_type = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 3616
        j.m_value = obj;
2660ccea Poul Sander 2023-09-22 19:25 3617
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3618
    }
2660ccea Poul Sander 2023-09-22 19:25 3619
2660ccea Poul Sander 2023-09-22 19:25 3620
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3621
    static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
2660ccea Poul Sander 2023-09-22 19:25 3622
    {
2660ccea Poul Sander 2023-09-22 19:25 3623
        j.m_type = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 3624
        j.m_value = std::move(obj);
2660ccea Poul Sander 2023-09-22 19:25 3625
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3626
    }
2660ccea Poul Sander 2023-09-22 19:25 3627
2660ccea Poul Sander 2023-09-22 19:25 3628
    template<typename BasicJsonType, typename CompatibleObjectType,
2660ccea Poul Sander 2023-09-22 19:25 3629
             enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3630
    static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
2660ccea Poul Sander 2023-09-22 19:25 3631
    {
2660ccea Poul Sander 2023-09-22 19:25 3632
        using std::begin;
2660ccea Poul Sander 2023-09-22 19:25 3633
        using std::end;
2660ccea Poul Sander 2023-09-22 19:25 3634
2660ccea Poul Sander 2023-09-22 19:25 3635
        j.m_type = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 3636
        j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
2660ccea Poul Sander 2023-09-22 19:25 3637
        j.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 3638
    }
2660ccea Poul Sander 2023-09-22 19:25 3639
};
2660ccea Poul Sander 2023-09-22 19:25 3640
2660ccea Poul Sander 2023-09-22 19:25 3641
/////////////
2660ccea Poul Sander 2023-09-22 19:25 3642
// to_json //
2660ccea Poul Sander 2023-09-22 19:25 3643
/////////////
2660ccea Poul Sander 2023-09-22 19:25 3644
2660ccea Poul Sander 2023-09-22 19:25 3645
template<typename BasicJsonType, typename T,
2660ccea Poul Sander 2023-09-22 19:25 3646
         enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3647
void to_json(BasicJsonType& j, T b) noexcept
2660ccea Poul Sander 2023-09-22 19:25 3648
{
2660ccea Poul Sander 2023-09-22 19:25 3649
    external_constructor<value_t::boolean>::construct(j, b);
2660ccea Poul Sander 2023-09-22 19:25 3650
}
2660ccea Poul Sander 2023-09-22 19:25 3651
2660ccea Poul Sander 2023-09-22 19:25 3652
template<typename BasicJsonType, typename CompatibleString,
2660ccea Poul Sander 2023-09-22 19:25 3653
         enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3654
void to_json(BasicJsonType& j, const CompatibleString& s)
2660ccea Poul Sander 2023-09-22 19:25 3655
{
2660ccea Poul Sander 2023-09-22 19:25 3656
    external_constructor<value_t::string>::construct(j, s);
2660ccea Poul Sander 2023-09-22 19:25 3657
}
2660ccea Poul Sander 2023-09-22 19:25 3658
2660ccea Poul Sander 2023-09-22 19:25 3659
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3660
void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
2660ccea Poul Sander 2023-09-22 19:25 3661
{
2660ccea Poul Sander 2023-09-22 19:25 3662
    external_constructor<value_t::string>::construct(j, std::move(s));
2660ccea Poul Sander 2023-09-22 19:25 3663
}
2660ccea Poul Sander 2023-09-22 19:25 3664
2660ccea Poul Sander 2023-09-22 19:25 3665
template<typename BasicJsonType, typename FloatType,
2660ccea Poul Sander 2023-09-22 19:25 3666
         enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3667
void to_json(BasicJsonType& j, FloatType val) noexcept
2660ccea Poul Sander 2023-09-22 19:25 3668
{
2660ccea Poul Sander 2023-09-22 19:25 3669
    external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
2660ccea Poul Sander 2023-09-22 19:25 3670
}
2660ccea Poul Sander 2023-09-22 19:25 3671
2660ccea Poul Sander 2023-09-22 19:25 3672
template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
2660ccea Poul Sander 2023-09-22 19:25 3673
         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3674
void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
2660ccea Poul Sander 2023-09-22 19:25 3675
{
2660ccea Poul Sander 2023-09-22 19:25 3676
    external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
2660ccea Poul Sander 2023-09-22 19:25 3677
}
2660ccea Poul Sander 2023-09-22 19:25 3678
2660ccea Poul Sander 2023-09-22 19:25 3679
template<typename BasicJsonType, typename CompatibleNumberIntegerType,
2660ccea Poul Sander 2023-09-22 19:25 3680
         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3681
void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
2660ccea Poul Sander 2023-09-22 19:25 3682
{
2660ccea Poul Sander 2023-09-22 19:25 3683
    external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
2660ccea Poul Sander 2023-09-22 19:25 3684
}
2660ccea Poul Sander 2023-09-22 19:25 3685
2660ccea Poul Sander 2023-09-22 19:25 3686
template<typename BasicJsonType, typename EnumType,
2660ccea Poul Sander 2023-09-22 19:25 3687
         enable_if_t<std::is_enum<EnumType>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3688
void to_json(BasicJsonType& j, EnumType e) noexcept
2660ccea Poul Sander 2023-09-22 19:25 3689
{
2660ccea Poul Sander 2023-09-22 19:25 3690
    using underlying_type = typename std::underlying_type<EnumType>::type;
2660ccea Poul Sander 2023-09-22 19:25 3691
    external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
2660ccea Poul Sander 2023-09-22 19:25 3692
}
2660ccea Poul Sander 2023-09-22 19:25 3693
2660ccea Poul Sander 2023-09-22 19:25 3694
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3695
void to_json(BasicJsonType& j, const std::vector<bool>& e)
2660ccea Poul Sander 2023-09-22 19:25 3696
{
2660ccea Poul Sander 2023-09-22 19:25 3697
    external_constructor<value_t::array>::construct(j, e);
2660ccea Poul Sander 2023-09-22 19:25 3698
}
2660ccea Poul Sander 2023-09-22 19:25 3699
2660ccea Poul Sander 2023-09-22 19:25 3700
template <typename BasicJsonType, typename CompatibleArrayType,
2660ccea Poul Sander 2023-09-22 19:25 3701
          enable_if_t<is_compatible_array_type<BasicJsonType,
2660ccea Poul Sander 2023-09-22 19:25 3702
                      CompatibleArrayType>::value and
2660ccea Poul Sander 2023-09-22 19:25 3703
                      not is_compatible_object_type<
2660ccea Poul Sander 2023-09-22 19:25 3704
                          BasicJsonType, CompatibleArrayType>::value and
2660ccea Poul Sander 2023-09-22 19:25 3705
                      not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
2660ccea Poul Sander 2023-09-22 19:25 3706
                      not is_basic_json<CompatibleArrayType>::value,
2660ccea Poul Sander 2023-09-22 19:25 3707
                      int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3708
void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
2660ccea Poul Sander 2023-09-22 19:25 3709
{
2660ccea Poul Sander 2023-09-22 19:25 3710
    external_constructor<value_t::array>::construct(j, arr);
2660ccea Poul Sander 2023-09-22 19:25 3711
}
2660ccea Poul Sander 2023-09-22 19:25 3712
2660ccea Poul Sander 2023-09-22 19:25 3713
template<typename BasicJsonType, typename T,
2660ccea Poul Sander 2023-09-22 19:25 3714
         enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3715
void to_json(BasicJsonType& j, const std::valarray<T>& arr)
2660ccea Poul Sander 2023-09-22 19:25 3716
{
2660ccea Poul Sander 2023-09-22 19:25 3717
    external_constructor<value_t::array>::construct(j, std::move(arr));
2660ccea Poul Sander 2023-09-22 19:25 3718
}
2660ccea Poul Sander 2023-09-22 19:25 3719
2660ccea Poul Sander 2023-09-22 19:25 3720
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3721
void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
2660ccea Poul Sander 2023-09-22 19:25 3722
{
2660ccea Poul Sander 2023-09-22 19:25 3723
    external_constructor<value_t::array>::construct(j, std::move(arr));
2660ccea Poul Sander 2023-09-22 19:25 3724
}
2660ccea Poul Sander 2023-09-22 19:25 3725
2660ccea Poul Sander 2023-09-22 19:25 3726
template<typename BasicJsonType, typename CompatibleObjectType,
2660ccea Poul Sander 2023-09-22 19:25 3727
         enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3728
void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
2660ccea Poul Sander 2023-09-22 19:25 3729
{
2660ccea Poul Sander 2023-09-22 19:25 3730
    external_constructor<value_t::object>::construct(j, obj);
2660ccea Poul Sander 2023-09-22 19:25 3731
}
2660ccea Poul Sander 2023-09-22 19:25 3732
2660ccea Poul Sander 2023-09-22 19:25 3733
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 3734
void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
2660ccea Poul Sander 2023-09-22 19:25 3735
{
2660ccea Poul Sander 2023-09-22 19:25 3736
    external_constructor<value_t::object>::construct(j, std::move(obj));
2660ccea Poul Sander 2023-09-22 19:25 3737
}
2660ccea Poul Sander 2023-09-22 19:25 3738
2660ccea Poul Sander 2023-09-22 19:25 3739
template <
2660ccea Poul Sander 2023-09-22 19:25 3740
    typename BasicJsonType, typename T, std::size_t N,
2660ccea Poul Sander 2023-09-22 19:25 3741
    enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
2660ccea Poul Sander 2023-09-22 19:25 3742
                const T(&)[N]>::value,
2660ccea Poul Sander 2023-09-22 19:25 3743
                int> = 0 >
2660ccea Poul Sander 2023-09-22 19:25 3744
void to_json(BasicJsonType& j, const T(&arr)[N])
2660ccea Poul Sander 2023-09-22 19:25 3745
{
2660ccea Poul Sander 2023-09-22 19:25 3746
    external_constructor<value_t::array>::construct(j, arr);
2660ccea Poul Sander 2023-09-22 19:25 3747
}
2660ccea Poul Sander 2023-09-22 19:25 3748
2660ccea Poul Sander 2023-09-22 19:25 3749
template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
2660ccea Poul Sander 2023-09-22 19:25 3750
void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
2660ccea Poul Sander 2023-09-22 19:25 3751
{
2660ccea Poul Sander 2023-09-22 19:25 3752
    j = { p.first, p.second };
2660ccea Poul Sander 2023-09-22 19:25 3753
}
2660ccea Poul Sander 2023-09-22 19:25 3754
2660ccea Poul Sander 2023-09-22 19:25 3755
// for https://github.com/nlohmann/json/pull/1134
2660ccea Poul Sander 2023-09-22 19:25 3756
template < typename BasicJsonType, typename T,
2660ccea Poul Sander 2023-09-22 19:25 3757
           enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 3758
void to_json(BasicJsonType& j, const T& b)
2660ccea Poul Sander 2023-09-22 19:25 3759
{
2660ccea Poul Sander 2023-09-22 19:25 3760
    j = { {b.key(), b.value()} };
2660ccea Poul Sander 2023-09-22 19:25 3761
}
2660ccea Poul Sander 2023-09-22 19:25 3762
2660ccea Poul Sander 2023-09-22 19:25 3763
template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
2660ccea Poul Sander 2023-09-22 19:25 3764
void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 3765
{
2660ccea Poul Sander 2023-09-22 19:25 3766
    j = { std::get<Idx>(t)... };
2660ccea Poul Sander 2023-09-22 19:25 3767
}
2660ccea Poul Sander 2023-09-22 19:25 3768
2660ccea Poul Sander 2023-09-22 19:25 3769
template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
2660ccea Poul Sander 2023-09-22 19:25 3770
void to_json(BasicJsonType& j, const T& t)
2660ccea Poul Sander 2023-09-22 19:25 3771
{
2660ccea Poul Sander 2023-09-22 19:25 3772
    to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
2660ccea Poul Sander 2023-09-22 19:25 3773
}
2660ccea Poul Sander 2023-09-22 19:25 3774
2660ccea Poul Sander 2023-09-22 19:25 3775
struct to_json_fn
2660ccea Poul Sander 2023-09-22 19:25 3776
{
2660ccea Poul Sander 2023-09-22 19:25 3777
    template<typename BasicJsonType, typename T>
2660ccea Poul Sander 2023-09-22 19:25 3778
    auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
2660ccea Poul Sander 2023-09-22 19:25 3779
    -> decltype(to_json(j, std::forward<T>(val)), void())
2660ccea Poul Sander 2023-09-22 19:25 3780
    {
2660ccea Poul Sander 2023-09-22 19:25 3781
        return to_json(j, std::forward<T>(val));
2660ccea Poul Sander 2023-09-22 19:25 3782
    }
2660ccea Poul Sander 2023-09-22 19:25 3783
};
2660ccea Poul Sander 2023-09-22 19:25 3784
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 3785
2660ccea Poul Sander 2023-09-22 19:25 3786
/// namespace to hold default `to_json` function
2660ccea Poul Sander 2023-09-22 19:25 3787
namespace
2660ccea Poul Sander 2023-09-22 19:25 3788
{
2660ccea Poul Sander 2023-09-22 19:25 3789
constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
2660ccea Poul Sander 2023-09-22 19:25 3790
} // namespace
2660ccea Poul Sander 2023-09-22 19:25 3791
} // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 3792
2660ccea Poul Sander 2023-09-22 19:25 3793
2660ccea Poul Sander 2023-09-22 19:25 3794
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 3795
{
2660ccea Poul Sander 2023-09-22 19:25 3796
2660ccea Poul Sander 2023-09-22 19:25 3797
template<typename, typename>
2660ccea Poul Sander 2023-09-22 19:25 3798
struct adl_serializer
2660ccea Poul Sander 2023-09-22 19:25 3799
{
2660ccea Poul Sander 2023-09-22 19:25 3800
    /*!
2660ccea Poul Sander 2023-09-22 19:25 3801
    @brief convert a JSON value to any value type
2660ccea Poul Sander 2023-09-22 19:25 3802
2660ccea Poul Sander 2023-09-22 19:25 3803
    This function is usually called by the `get()` function of the
2660ccea Poul Sander 2023-09-22 19:25 3804
    @ref basic_json class (either explicit or via conversion operators).
2660ccea Poul Sander 2023-09-22 19:25 3805
2660ccea Poul Sander 2023-09-22 19:25 3806
    @param[in] j        JSON value to read from
2660ccea Poul Sander 2023-09-22 19:25 3807
    @param[in,out] val  value to write to
2660ccea Poul Sander 2023-09-22 19:25 3808
    */
2660ccea Poul Sander 2023-09-22 19:25 3809
    template<typename BasicJsonType, typename ValueType>
2660ccea Poul Sander 2023-09-22 19:25 3810
    static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
2660ccea Poul Sander 2023-09-22 19:25 3811
        noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
2660ccea Poul Sander 2023-09-22 19:25 3812
    -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
2660ccea Poul Sander 2023-09-22 19:25 3813
    {
2660ccea Poul Sander 2023-09-22 19:25 3814
        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
2660ccea Poul Sander 2023-09-22 19:25 3815
    }
2660ccea Poul Sander 2023-09-22 19:25 3816
2660ccea Poul Sander 2023-09-22 19:25 3817
    /*!
2660ccea Poul Sander 2023-09-22 19:25 3818
    @brief convert any value type to a JSON value
2660ccea Poul Sander 2023-09-22 19:25 3819
2660ccea Poul Sander 2023-09-22 19:25 3820
    This function is usually called by the constructors of the @ref basic_json
2660ccea Poul Sander 2023-09-22 19:25 3821
    class.
2660ccea Poul Sander 2023-09-22 19:25 3822
2660ccea Poul Sander 2023-09-22 19:25 3823
    @param[in,out] j  JSON value to write to
2660ccea Poul Sander 2023-09-22 19:25 3824
    @param[in] val    value to read from
2660ccea Poul Sander 2023-09-22 19:25 3825
    */
2660ccea Poul Sander 2023-09-22 19:25 3826
    template <typename BasicJsonType, typename ValueType>
2660ccea Poul Sander 2023-09-22 19:25 3827
    static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
2660ccea Poul Sander 2023-09-22 19:25 3828
        noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
2660ccea Poul Sander 2023-09-22 19:25 3829
    -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
2660ccea Poul Sander 2023-09-22 19:25 3830
    {
2660ccea Poul Sander 2023-09-22 19:25 3831
        ::nlohmann::to_json(j, std::forward<ValueType>(val));
2660ccea Poul Sander 2023-09-22 19:25 3832
    }
2660ccea Poul Sander 2023-09-22 19:25 3833
};
2660ccea Poul Sander 2023-09-22 19:25 3834
2660ccea Poul Sander 2023-09-22 19:25 3835
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 3836
2660ccea Poul Sander 2023-09-22 19:25 3837
// #include <nlohmann/detail/conversions/from_json.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3838
2660ccea Poul Sander 2023-09-22 19:25 3839
// #include <nlohmann/detail/conversions/to_json.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3840
2660ccea Poul Sander 2023-09-22 19:25 3841
// #include <nlohmann/detail/exceptions.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3842
2660ccea Poul Sander 2023-09-22 19:25 3843
// #include <nlohmann/detail/input/binary_reader.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3844
2660ccea Poul Sander 2023-09-22 19:25 3845
2660ccea Poul Sander 2023-09-22 19:25 3846
#include <algorithm> // generate_n
2660ccea Poul Sander 2023-09-22 19:25 3847
#include <array> // array
2660ccea Poul Sander 2023-09-22 19:25 3848
#include <cassert> // assert
2660ccea Poul Sander 2023-09-22 19:25 3849
#include <cmath> // ldexp
2660ccea Poul Sander 2023-09-22 19:25 3850
#include <cstddef> // size_t
2660ccea Poul Sander 2023-09-22 19:25 3851
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
2660ccea Poul Sander 2023-09-22 19:25 3852
#include <cstdio> // snprintf
2660ccea Poul Sander 2023-09-22 19:25 3853
#include <cstring> // memcpy
2660ccea Poul Sander 2023-09-22 19:25 3854
#include <iterator> // back_inserter
2660ccea Poul Sander 2023-09-22 19:25 3855
#include <limits> // numeric_limits
2660ccea Poul Sander 2023-09-22 19:25 3856
#include <string> // char_traits, string
2660ccea Poul Sander 2023-09-22 19:25 3857
#include <utility> // make_pair, move
2660ccea Poul Sander 2023-09-22 19:25 3858
2660ccea Poul Sander 2023-09-22 19:25 3859
// #include <nlohmann/detail/exceptions.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3860
2660ccea Poul Sander 2023-09-22 19:25 3861
// #include <nlohmann/detail/input/input_adapters.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3862
2660ccea Poul Sander 2023-09-22 19:25 3863
2660ccea Poul Sander 2023-09-22 19:25 3864
#include <array> // array
2660ccea Poul Sander 2023-09-22 19:25 3865
#include <cassert> // assert
2660ccea Poul Sander 2023-09-22 19:25 3866
#include <cstddef> // size_t
2660ccea Poul Sander 2023-09-22 19:25 3867
#include <cstdio> //FILE *
2660ccea Poul Sander 2023-09-22 19:25 3868
#include <cstring> // strlen
2660ccea Poul Sander 2023-09-22 19:25 3869
#include <istream> // istream
2660ccea Poul Sander 2023-09-22 19:25 3870
#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
2660ccea Poul Sander 2023-09-22 19:25 3871
#include <memory> // shared_ptr, make_shared, addressof
2660ccea Poul Sander 2023-09-22 19:25 3872
#include <numeric> // accumulate
2660ccea Poul Sander 2023-09-22 19:25 3873
#include <string> // string, char_traits
2660ccea Poul Sander 2023-09-22 19:25 3874
#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
2660ccea Poul Sander 2023-09-22 19:25 3875
#include <utility> // pair, declval
2660ccea Poul Sander 2023-09-22 19:25 3876
2660ccea Poul Sander 2023-09-22 19:25 3877
// #include <nlohmann/detail/iterators/iterator_traits.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3878
2660ccea Poul Sander 2023-09-22 19:25 3879
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 3880
2660ccea Poul Sander 2023-09-22 19:25 3881
2660ccea Poul Sander 2023-09-22 19:25 3882
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 3883
{
2660ccea Poul Sander 2023-09-22 19:25 3884
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 3885
{
2660ccea Poul Sander 2023-09-22 19:25 3886
/// the supported input formats
2660ccea Poul Sander 2023-09-22 19:25 3887
enum class input_format_t { json, cbor, msgpack, ubjson, bson };
2660ccea Poul Sander 2023-09-22 19:25 3888
2660ccea Poul Sander 2023-09-22 19:25 3889
////////////////////
2660ccea Poul Sander 2023-09-22 19:25 3890
// input adapters //
2660ccea Poul Sander 2023-09-22 19:25 3891
////////////////////
2660ccea Poul Sander 2023-09-22 19:25 3892
2660ccea Poul Sander 2023-09-22 19:25 3893
/*!
2660ccea Poul Sander 2023-09-22 19:25 3894
@brief abstract input adapter interface
2660ccea Poul Sander 2023-09-22 19:25 3895
2660ccea Poul Sander 2023-09-22 19:25 3896
Produces a stream of std::char_traits<char>::int_type characters from a
2660ccea Poul Sander 2023-09-22 19:25 3897
std::istream, a buffer, or some other input type. Accepts the return of
2660ccea Poul Sander 2023-09-22 19:25 3898
exactly one non-EOF character for future input. The int_type characters
2660ccea Poul Sander 2023-09-22 19:25 3899
returned consist of all valid char values as positive values (typically
2660ccea Poul Sander 2023-09-22 19:25 3900
unsigned char), plus an EOF value outside that range, specified by the value
2660ccea Poul Sander 2023-09-22 19:25 3901
of the function std::char_traits<char>::eof(). This value is typically -1, but
2660ccea Poul Sander 2023-09-22 19:25 3902
could be any arbitrary value which is not a valid char value.
2660ccea Poul Sander 2023-09-22 19:25 3903
*/
2660ccea Poul Sander 2023-09-22 19:25 3904
struct input_adapter_protocol
2660ccea Poul Sander 2023-09-22 19:25 3905
{
2660ccea Poul Sander 2023-09-22 19:25 3906
    /// get a character [0,255] or std::char_traits<char>::eof().
2660ccea Poul Sander 2023-09-22 19:25 3907
    virtual std::char_traits<char>::int_type get_character() = 0;
2660ccea Poul Sander 2023-09-22 19:25 3908
    virtual ~input_adapter_protocol() = default;
2660ccea Poul Sander 2023-09-22 19:25 3909
};
2660ccea Poul Sander 2023-09-22 19:25 3910
2660ccea Poul Sander 2023-09-22 19:25 3911
/// a type to simplify interfaces
2660ccea Poul Sander 2023-09-22 19:25 3912
using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
2660ccea Poul Sander 2023-09-22 19:25 3913
2660ccea Poul Sander 2023-09-22 19:25 3914
/*!
2660ccea Poul Sander 2023-09-22 19:25 3915
Input adapter for stdio file access. This adapter read only 1 byte and do not use any
2660ccea Poul Sander 2023-09-22 19:25 3916
 buffer. This adapter is a very low level adapter.
2660ccea Poul Sander 2023-09-22 19:25 3917
*/
2660ccea Poul Sander 2023-09-22 19:25 3918
class file_input_adapter : public input_adapter_protocol
2660ccea Poul Sander 2023-09-22 19:25 3919
{
2660ccea Poul Sander 2023-09-22 19:25 3920
  public:
2660ccea Poul Sander 2023-09-22 19:25 3921
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 3922
    explicit file_input_adapter(std::FILE* f)  noexcept
2660ccea Poul Sander 2023-09-22 19:25 3923
        : m_file(f)
2660ccea Poul Sander 2023-09-22 19:25 3924
    {}
2660ccea Poul Sander 2023-09-22 19:25 3925
2660ccea Poul Sander 2023-09-22 19:25 3926
    // make class move-only
2660ccea Poul Sander 2023-09-22 19:25 3927
    file_input_adapter(const file_input_adapter&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 3928
    file_input_adapter(file_input_adapter&&) = default;
2660ccea Poul Sander 2023-09-22 19:25 3929
    file_input_adapter& operator=(const file_input_adapter&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 3930
    file_input_adapter& operator=(file_input_adapter&&) = default;
2660ccea Poul Sander 2023-09-22 19:25 3931
    ~file_input_adapter() override = default;
2660ccea Poul Sander 2023-09-22 19:25 3932
2660ccea Poul Sander 2023-09-22 19:25 3933
    std::char_traits<char>::int_type get_character() noexcept override
2660ccea Poul Sander 2023-09-22 19:25 3934
    {
2660ccea Poul Sander 2023-09-22 19:25 3935
        return std::fgetc(m_file);
2660ccea Poul Sander 2023-09-22 19:25 3936
    }
2660ccea Poul Sander 2023-09-22 19:25 3937
2660ccea Poul Sander 2023-09-22 19:25 3938
  private:
2660ccea Poul Sander 2023-09-22 19:25 3939
    /// the file pointer to read from
2660ccea Poul Sander 2023-09-22 19:25 3940
    std::FILE* m_file;
2660ccea Poul Sander 2023-09-22 19:25 3941
};
2660ccea Poul Sander 2023-09-22 19:25 3942
2660ccea Poul Sander 2023-09-22 19:25 3943
2660ccea Poul Sander 2023-09-22 19:25 3944
/*!
2660ccea Poul Sander 2023-09-22 19:25 3945
Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
2660ccea Poul Sander 2023-09-22 19:25 3946
beginning of input. Does not support changing the underlying std::streambuf
2660ccea Poul Sander 2023-09-22 19:25 3947
in mid-input. Maintains underlying std::istream and std::streambuf to support
2660ccea Poul Sander 2023-09-22 19:25 3948
subsequent use of standard std::istream operations to process any input
2660ccea Poul Sander 2023-09-22 19:25 3949
characters following those used in parsing the JSON input.  Clears the
2660ccea Poul Sander 2023-09-22 19:25 3950
std::istream flags; any input errors (e.g., EOF) will be detected by the first
2660ccea Poul Sander 2023-09-22 19:25 3951
subsequent call for input from the std::istream.
2660ccea Poul Sander 2023-09-22 19:25 3952
*/
2660ccea Poul Sander 2023-09-22 19:25 3953
class input_stream_adapter : public input_adapter_protocol
2660ccea Poul Sander 2023-09-22 19:25 3954
{
2660ccea Poul Sander 2023-09-22 19:25 3955
  public:
2660ccea Poul Sander 2023-09-22 19:25 3956
    ~input_stream_adapter() override
2660ccea Poul Sander 2023-09-22 19:25 3957
    {
2660ccea Poul Sander 2023-09-22 19:25 3958
        // clear stream flags; we use underlying streambuf I/O, do not
2660ccea Poul Sander 2023-09-22 19:25 3959
        // maintain ifstream flags, except eof
2660ccea Poul Sander 2023-09-22 19:25 3960
        is.clear(is.rdstate() & std::ios::eofbit);
2660ccea Poul Sander 2023-09-22 19:25 3961
    }
2660ccea Poul Sander 2023-09-22 19:25 3962
2660ccea Poul Sander 2023-09-22 19:25 3963
    explicit input_stream_adapter(std::istream& i)
2660ccea Poul Sander 2023-09-22 19:25 3964
        : is(i), sb(*i.rdbuf())
2660ccea Poul Sander 2023-09-22 19:25 3965
    {}
2660ccea Poul Sander 2023-09-22 19:25 3966
2660ccea Poul Sander 2023-09-22 19:25 3967
    // delete because of pointer members
2660ccea Poul Sander 2023-09-22 19:25 3968
    input_stream_adapter(const input_stream_adapter&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 3969
    input_stream_adapter& operator=(input_stream_adapter&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 3970
    input_stream_adapter(input_stream_adapter&&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 3971
    input_stream_adapter& operator=(input_stream_adapter&&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 3972
2660ccea Poul Sander 2023-09-22 19:25 3973
    // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
2660ccea Poul Sander 2023-09-22 19:25 3974
    // ensure that std::char_traits<char>::eof() and the character 0xFF do not
2660ccea Poul Sander 2023-09-22 19:25 3975
    // end up as the same value, eg. 0xFFFFFFFF.
2660ccea Poul Sander 2023-09-22 19:25 3976
    std::char_traits<char>::int_type get_character() override
2660ccea Poul Sander 2023-09-22 19:25 3977
    {
2660ccea Poul Sander 2023-09-22 19:25 3978
        auto res = sb.sbumpc();
2660ccea Poul Sander 2023-09-22 19:25 3979
        // set eof manually, as we don't use the istream interface.
2660ccea Poul Sander 2023-09-22 19:25 3980
        if (res == EOF)
2660ccea Poul Sander 2023-09-22 19:25 3981
        {
2660ccea Poul Sander 2023-09-22 19:25 3982
            is.clear(is.rdstate() | std::ios::eofbit);
2660ccea Poul Sander 2023-09-22 19:25 3983
        }
2660ccea Poul Sander 2023-09-22 19:25 3984
        return res;
2660ccea Poul Sander 2023-09-22 19:25 3985
    }
2660ccea Poul Sander 2023-09-22 19:25 3986
2660ccea Poul Sander 2023-09-22 19:25 3987
  private:
2660ccea Poul Sander 2023-09-22 19:25 3988
    /// the associated input stream
2660ccea Poul Sander 2023-09-22 19:25 3989
    std::istream& is;
2660ccea Poul Sander 2023-09-22 19:25 3990
    std::streambuf& sb;
2660ccea Poul Sander 2023-09-22 19:25 3991
};
2660ccea Poul Sander 2023-09-22 19:25 3992
2660ccea Poul Sander 2023-09-22 19:25 3993
/// input adapter for buffer input
2660ccea Poul Sander 2023-09-22 19:25 3994
class input_buffer_adapter : public input_adapter_protocol
2660ccea Poul Sander 2023-09-22 19:25 3995
{
2660ccea Poul Sander 2023-09-22 19:25 3996
  public:
2660ccea Poul Sander 2023-09-22 19:25 3997
    input_buffer_adapter(const char* b, const std::size_t l) noexcept
2660ccea Poul Sander 2023-09-22 19:25 3998
        : cursor(b), limit(b == nullptr ? nullptr : (b + l))
2660ccea Poul Sander 2023-09-22 19:25 3999
    {}
2660ccea Poul Sander 2023-09-22 19:25 4000
2660ccea Poul Sander 2023-09-22 19:25 4001
    // delete because of pointer members
2660ccea Poul Sander 2023-09-22 19:25 4002
    input_buffer_adapter(const input_buffer_adapter&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 4003
    input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 4004
    input_buffer_adapter(input_buffer_adapter&&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 4005
    input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 4006
    ~input_buffer_adapter() override = default;
2660ccea Poul Sander 2023-09-22 19:25 4007
2660ccea Poul Sander 2023-09-22 19:25 4008
    std::char_traits<char>::int_type get_character() noexcept override
2660ccea Poul Sander 2023-09-22 19:25 4009
    {
2660ccea Poul Sander 2023-09-22 19:25 4010
        if (JSON_HEDLEY_LIKELY(cursor < limit))
2660ccea Poul Sander 2023-09-22 19:25 4011
        {
2660ccea Poul Sander 2023-09-22 19:25 4012
            assert(cursor != nullptr and limit != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 4013
            return std::char_traits<char>::to_int_type(*(cursor++));
2660ccea Poul Sander 2023-09-22 19:25 4014
        }
2660ccea Poul Sander 2023-09-22 19:25 4015
2660ccea Poul Sander 2023-09-22 19:25 4016
        return std::char_traits<char>::eof();
2660ccea Poul Sander 2023-09-22 19:25 4017
    }
2660ccea Poul Sander 2023-09-22 19:25 4018
2660ccea Poul Sander 2023-09-22 19:25 4019
  private:
2660ccea Poul Sander 2023-09-22 19:25 4020
    /// pointer to the current character
2660ccea Poul Sander 2023-09-22 19:25 4021
    const char* cursor;
2660ccea Poul Sander 2023-09-22 19:25 4022
    /// pointer past the last character
2660ccea Poul Sander 2023-09-22 19:25 4023
    const char* const limit;
2660ccea Poul Sander 2023-09-22 19:25 4024
};
2660ccea Poul Sander 2023-09-22 19:25 4025
2660ccea Poul Sander 2023-09-22 19:25 4026
template<typename WideStringType, size_t T>
2660ccea Poul Sander 2023-09-22 19:25 4027
struct wide_string_input_helper
2660ccea Poul Sander 2023-09-22 19:25 4028
{
2660ccea Poul Sander 2023-09-22 19:25 4029
    // UTF-32
2660ccea Poul Sander 2023-09-22 19:25 4030
    static void fill_buffer(const WideStringType& str,
2660ccea Poul Sander 2023-09-22 19:25 4031
                            size_t& current_wchar,
2660ccea Poul Sander 2023-09-22 19:25 4032
                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
2660ccea Poul Sander 2023-09-22 19:25 4033
                            size_t& utf8_bytes_index,
2660ccea Poul Sander 2023-09-22 19:25 4034
                            size_t& utf8_bytes_filled)
2660ccea Poul Sander 2023-09-22 19:25 4035
    {
2660ccea Poul Sander 2023-09-22 19:25 4036
        utf8_bytes_index = 0;
2660ccea Poul Sander 2023-09-22 19:25 4037
2660ccea Poul Sander 2023-09-22 19:25 4038
        if (current_wchar == str.size())
2660ccea Poul Sander 2023-09-22 19:25 4039
        {
2660ccea Poul Sander 2023-09-22 19:25 4040
            utf8_bytes[0] = std::char_traits<char>::eof();
2660ccea Poul Sander 2023-09-22 19:25 4041
            utf8_bytes_filled = 1;
2660ccea Poul Sander 2023-09-22 19:25 4042
        }
2660ccea Poul Sander 2023-09-22 19:25 4043
        else
2660ccea Poul Sander 2023-09-22 19:25 4044
        {
2660ccea Poul Sander 2023-09-22 19:25 4045
            // get the current character
2660ccea Poul Sander 2023-09-22 19:25 4046
            const auto wc = static_cast<unsigned int>(str[current_wchar++]);
2660ccea Poul Sander 2023-09-22 19:25 4047
2660ccea Poul Sander 2023-09-22 19:25 4048
            // UTF-32 to UTF-8 encoding
2660ccea Poul Sander 2023-09-22 19:25 4049
            if (wc < 0x80)
2660ccea Poul Sander 2023-09-22 19:25 4050
            {
2660ccea Poul Sander 2023-09-22 19:25 4051
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2660ccea Poul Sander 2023-09-22 19:25 4052
                utf8_bytes_filled = 1;
2660ccea Poul Sander 2023-09-22 19:25 4053
            }
2660ccea Poul Sander 2023-09-22 19:25 4054
            else if (wc <= 0x7FF)
2660ccea Poul Sander 2023-09-22 19:25 4055
            {
2660ccea Poul Sander 2023-09-22 19:25 4056
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
2660ccea Poul Sander 2023-09-22 19:25 4057
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4058
                utf8_bytes_filled = 2;
2660ccea Poul Sander 2023-09-22 19:25 4059
            }
2660ccea Poul Sander 2023-09-22 19:25 4060
            else if (wc <= 0xFFFF)
2660ccea Poul Sander 2023-09-22 19:25 4061
            {
2660ccea Poul Sander 2023-09-22 19:25 4062
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
2660ccea Poul Sander 2023-09-22 19:25 4063
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4064
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4065
                utf8_bytes_filled = 3;
2660ccea Poul Sander 2023-09-22 19:25 4066
            }
2660ccea Poul Sander 2023-09-22 19:25 4067
            else if (wc <= 0x10FFFF)
2660ccea Poul Sander 2023-09-22 19:25 4068
            {
2660ccea Poul Sander 2023-09-22 19:25 4069
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
2660ccea Poul Sander 2023-09-22 19:25 4070
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4071
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4072
                utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4073
                utf8_bytes_filled = 4;
2660ccea Poul Sander 2023-09-22 19:25 4074
            }
2660ccea Poul Sander 2023-09-22 19:25 4075
            else
2660ccea Poul Sander 2023-09-22 19:25 4076
            {
2660ccea Poul Sander 2023-09-22 19:25 4077
                // unknown character
2660ccea Poul Sander 2023-09-22 19:25 4078
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2660ccea Poul Sander 2023-09-22 19:25 4079
                utf8_bytes_filled = 1;
2660ccea Poul Sander 2023-09-22 19:25 4080
            }
2660ccea Poul Sander 2023-09-22 19:25 4081
        }
2660ccea Poul Sander 2023-09-22 19:25 4082
    }
2660ccea Poul Sander 2023-09-22 19:25 4083
};
2660ccea Poul Sander 2023-09-22 19:25 4084
2660ccea Poul Sander 2023-09-22 19:25 4085
template<typename WideStringType>
2660ccea Poul Sander 2023-09-22 19:25 4086
struct wide_string_input_helper<WideStringType, 2>
2660ccea Poul Sander 2023-09-22 19:25 4087
{
2660ccea Poul Sander 2023-09-22 19:25 4088
    // UTF-16
2660ccea Poul Sander 2023-09-22 19:25 4089
    static void fill_buffer(const WideStringType& str,
2660ccea Poul Sander 2023-09-22 19:25 4090
                            size_t& current_wchar,
2660ccea Poul Sander 2023-09-22 19:25 4091
                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
2660ccea Poul Sander 2023-09-22 19:25 4092
                            size_t& utf8_bytes_index,
2660ccea Poul Sander 2023-09-22 19:25 4093
                            size_t& utf8_bytes_filled)
2660ccea Poul Sander 2023-09-22 19:25 4094
    {
2660ccea Poul Sander 2023-09-22 19:25 4095
        utf8_bytes_index = 0;
2660ccea Poul Sander 2023-09-22 19:25 4096
2660ccea Poul Sander 2023-09-22 19:25 4097
        if (current_wchar == str.size())
2660ccea Poul Sander 2023-09-22 19:25 4098
        {
2660ccea Poul Sander 2023-09-22 19:25 4099
            utf8_bytes[0] = std::char_traits<char>::eof();
2660ccea Poul Sander 2023-09-22 19:25 4100
            utf8_bytes_filled = 1;
2660ccea Poul Sander 2023-09-22 19:25 4101
        }
2660ccea Poul Sander 2023-09-22 19:25 4102
        else
2660ccea Poul Sander 2023-09-22 19:25 4103
        {
2660ccea Poul Sander 2023-09-22 19:25 4104
            // get the current character
2660ccea Poul Sander 2023-09-22 19:25 4105
            const auto wc = static_cast<unsigned int>(str[current_wchar++]);
2660ccea Poul Sander 2023-09-22 19:25 4106
2660ccea Poul Sander 2023-09-22 19:25 4107
            // UTF-16 to UTF-8 encoding
2660ccea Poul Sander 2023-09-22 19:25 4108
            if (wc < 0x80)
2660ccea Poul Sander 2023-09-22 19:25 4109
            {
2660ccea Poul Sander 2023-09-22 19:25 4110
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2660ccea Poul Sander 2023-09-22 19:25 4111
                utf8_bytes_filled = 1;
2660ccea Poul Sander 2023-09-22 19:25 4112
            }
2660ccea Poul Sander 2023-09-22 19:25 4113
            else if (wc <= 0x7FF)
2660ccea Poul Sander 2023-09-22 19:25 4114
            {
2660ccea Poul Sander 2023-09-22 19:25 4115
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u)));
2660ccea Poul Sander 2023-09-22 19:25 4116
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4117
                utf8_bytes_filled = 2;
2660ccea Poul Sander 2023-09-22 19:25 4118
            }
2660ccea Poul Sander 2023-09-22 19:25 4119
            else if (0xD800 > wc or wc >= 0xE000)
2660ccea Poul Sander 2023-09-22 19:25 4120
            {
2660ccea Poul Sander 2023-09-22 19:25 4121
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u)));
2660ccea Poul Sander 2023-09-22 19:25 4122
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4123
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4124
                utf8_bytes_filled = 3;
2660ccea Poul Sander 2023-09-22 19:25 4125
            }
2660ccea Poul Sander 2023-09-22 19:25 4126
            else
2660ccea Poul Sander 2023-09-22 19:25 4127
            {
2660ccea Poul Sander 2023-09-22 19:25 4128
                if (current_wchar < str.size())
2660ccea Poul Sander 2023-09-22 19:25 4129
                {
2660ccea Poul Sander 2023-09-22 19:25 4130
                    const auto wc2 = static_cast<unsigned int>(str[current_wchar++]);
2660ccea Poul Sander 2023-09-22 19:25 4131
                    const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
2660ccea Poul Sander 2023-09-22 19:25 4132
                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
2660ccea Poul Sander 2023-09-22 19:25 4133
                    utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4134
                    utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4135
                    utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
2660ccea Poul Sander 2023-09-22 19:25 4136
                    utf8_bytes_filled = 4;
2660ccea Poul Sander 2023-09-22 19:25 4137
                }
2660ccea Poul Sander 2023-09-22 19:25 4138
                else
2660ccea Poul Sander 2023-09-22 19:25 4139
                {
2660ccea Poul Sander 2023-09-22 19:25 4140
                    // unknown character
2660ccea Poul Sander 2023-09-22 19:25 4141
                    ++current_wchar;
2660ccea Poul Sander 2023-09-22 19:25 4142
                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2660ccea Poul Sander 2023-09-22 19:25 4143
                    utf8_bytes_filled = 1;
2660ccea Poul Sander 2023-09-22 19:25 4144
                }
2660ccea Poul Sander 2023-09-22 19:25 4145
            }
2660ccea Poul Sander 2023-09-22 19:25 4146
        }
2660ccea Poul Sander 2023-09-22 19:25 4147
    }
2660ccea Poul Sander 2023-09-22 19:25 4148
};
2660ccea Poul Sander 2023-09-22 19:25 4149
2660ccea Poul Sander 2023-09-22 19:25 4150
template<typename WideStringType>
2660ccea Poul Sander 2023-09-22 19:25 4151
class wide_string_input_adapter : public input_adapter_protocol
2660ccea Poul Sander 2023-09-22 19:25 4152
{
2660ccea Poul Sander 2023-09-22 19:25 4153
  public:
2660ccea Poul Sander 2023-09-22 19:25 4154
    explicit wide_string_input_adapter(const WideStringType& w) noexcept
2660ccea Poul Sander 2023-09-22 19:25 4155
        : str(w)
2660ccea Poul Sander 2023-09-22 19:25 4156
    {}
2660ccea Poul Sander 2023-09-22 19:25 4157
2660ccea Poul Sander 2023-09-22 19:25 4158
    std::char_traits<char>::int_type get_character() noexcept override
2660ccea Poul Sander 2023-09-22 19:25 4159
    {
2660ccea Poul Sander 2023-09-22 19:25 4160
        // check if buffer needs to be filled
2660ccea Poul Sander 2023-09-22 19:25 4161
        if (utf8_bytes_index == utf8_bytes_filled)
2660ccea Poul Sander 2023-09-22 19:25 4162
        {
2660ccea Poul Sander 2023-09-22 19:25 4163
            fill_buffer<sizeof(typename WideStringType::value_type)>();
2660ccea Poul Sander 2023-09-22 19:25 4164
2660ccea Poul Sander 2023-09-22 19:25 4165
            assert(utf8_bytes_filled > 0);
2660ccea Poul Sander 2023-09-22 19:25 4166
            assert(utf8_bytes_index == 0);
2660ccea Poul Sander 2023-09-22 19:25 4167
        }
2660ccea Poul Sander 2023-09-22 19:25 4168
2660ccea Poul Sander 2023-09-22 19:25 4169
        // use buffer
2660ccea Poul Sander 2023-09-22 19:25 4170
        assert(utf8_bytes_filled > 0);
2660ccea Poul Sander 2023-09-22 19:25 4171
        assert(utf8_bytes_index < utf8_bytes_filled);
2660ccea Poul Sander 2023-09-22 19:25 4172
        return utf8_bytes[utf8_bytes_index++];
2660ccea Poul Sander 2023-09-22 19:25 4173
    }
2660ccea Poul Sander 2023-09-22 19:25 4174
2660ccea Poul Sander 2023-09-22 19:25 4175
  private:
2660ccea Poul Sander 2023-09-22 19:25 4176
    template<size_t T>
2660ccea Poul Sander 2023-09-22 19:25 4177
    void fill_buffer()
2660ccea Poul Sander 2023-09-22 19:25 4178
    {
2660ccea Poul Sander 2023-09-22 19:25 4179
        wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
2660ccea Poul Sander 2023-09-22 19:25 4180
    }
2660ccea Poul Sander 2023-09-22 19:25 4181
2660ccea Poul Sander 2023-09-22 19:25 4182
    /// the wstring to process
2660ccea Poul Sander 2023-09-22 19:25 4183
    const WideStringType& str;
2660ccea Poul Sander 2023-09-22 19:25 4184
2660ccea Poul Sander 2023-09-22 19:25 4185
    /// index of the current wchar in str
2660ccea Poul Sander 2023-09-22 19:25 4186
    std::size_t current_wchar = 0;
2660ccea Poul Sander 2023-09-22 19:25 4187
2660ccea Poul Sander 2023-09-22 19:25 4188
    /// a buffer for UTF-8 bytes
2660ccea Poul Sander 2023-09-22 19:25 4189
    std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
2660ccea Poul Sander 2023-09-22 19:25 4190
2660ccea Poul Sander 2023-09-22 19:25 4191
    /// index to the utf8_codes array for the next valid byte
2660ccea Poul Sander 2023-09-22 19:25 4192
    std::size_t utf8_bytes_index = 0;
2660ccea Poul Sander 2023-09-22 19:25 4193
    /// number of valid bytes in the utf8_codes array
2660ccea Poul Sander 2023-09-22 19:25 4194
    std::size_t utf8_bytes_filled = 0;
2660ccea Poul Sander 2023-09-22 19:25 4195
};
2660ccea Poul Sander 2023-09-22 19:25 4196
2660ccea Poul Sander 2023-09-22 19:25 4197
class input_adapter
2660ccea Poul Sander 2023-09-22 19:25 4198
{
2660ccea Poul Sander 2023-09-22 19:25 4199
  public:
2660ccea Poul Sander 2023-09-22 19:25 4200
    // native support
2660ccea Poul Sander 2023-09-22 19:25 4201
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 4202
    input_adapter(std::FILE* file)
2660ccea Poul Sander 2023-09-22 19:25 4203
        : ia(std::make_shared<file_input_adapter>(file)) {}
2660ccea Poul Sander 2023-09-22 19:25 4204
    /// input adapter for input stream
2660ccea Poul Sander 2023-09-22 19:25 4205
    input_adapter(std::istream& i)
2660ccea Poul Sander 2023-09-22 19:25 4206
        : ia(std::make_shared<input_stream_adapter>(i)) {}
2660ccea Poul Sander 2023-09-22 19:25 4207
2660ccea Poul Sander 2023-09-22 19:25 4208
    /// input adapter for input stream
2660ccea Poul Sander 2023-09-22 19:25 4209
    input_adapter(std::istream&& i)
2660ccea Poul Sander 2023-09-22 19:25 4210
        : ia(std::make_shared<input_stream_adapter>(i)) {}
2660ccea Poul Sander 2023-09-22 19:25 4211
2660ccea Poul Sander 2023-09-22 19:25 4212
    input_adapter(const std::wstring& ws)
2660ccea Poul Sander 2023-09-22 19:25 4213
        : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
2660ccea Poul Sander 2023-09-22 19:25 4214
2660ccea Poul Sander 2023-09-22 19:25 4215
    input_adapter(const std::u16string& ws)
2660ccea Poul Sander 2023-09-22 19:25 4216
        : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
2660ccea Poul Sander 2023-09-22 19:25 4217
2660ccea Poul Sander 2023-09-22 19:25 4218
    input_adapter(const std::u32string& ws)
2660ccea Poul Sander 2023-09-22 19:25 4219
        : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
2660ccea Poul Sander 2023-09-22 19:25 4220
2660ccea Poul Sander 2023-09-22 19:25 4221
    /// input adapter for buffer
2660ccea Poul Sander 2023-09-22 19:25 4222
    template<typename CharT,
2660ccea Poul Sander 2023-09-22 19:25 4223
             typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 4224
                 std::is_pointer<CharT>::value and
2660ccea Poul Sander 2023-09-22 19:25 4225
                 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2660ccea Poul Sander 2023-09-22 19:25 4226
                 sizeof(typename std::remove_pointer<CharT>::type) == 1,
2660ccea Poul Sander 2023-09-22 19:25 4227
                 int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 4228
    input_adapter(CharT b, std::size_t l)
2660ccea Poul Sander 2023-09-22 19:25 4229
        : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
2660ccea Poul Sander 2023-09-22 19:25 4230
2660ccea Poul Sander 2023-09-22 19:25 4231
    // derived support
2660ccea Poul Sander 2023-09-22 19:25 4232
2660ccea Poul Sander 2023-09-22 19:25 4233
    /// input adapter for string literal
2660ccea Poul Sander 2023-09-22 19:25 4234
    template<typename CharT,
2660ccea Poul Sander 2023-09-22 19:25 4235
             typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 4236
                 std::is_pointer<CharT>::value and
2660ccea Poul Sander 2023-09-22 19:25 4237
                 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2660ccea Poul Sander 2023-09-22 19:25 4238
                 sizeof(typename std::remove_pointer<CharT>::type) == 1,
2660ccea Poul Sander 2023-09-22 19:25 4239
                 int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 4240
    input_adapter(CharT b)
2660ccea Poul Sander 2023-09-22 19:25 4241
        : input_adapter(reinterpret_cast<const char*>(b),
2660ccea Poul Sander 2023-09-22 19:25 4242
                        std::strlen(reinterpret_cast<const char*>(b))) {}
2660ccea Poul Sander 2023-09-22 19:25 4243
2660ccea Poul Sander 2023-09-22 19:25 4244
    /// input adapter for iterator range with contiguous storage
2660ccea Poul Sander 2023-09-22 19:25 4245
    template<class IteratorType,
2660ccea Poul Sander 2023-09-22 19:25 4246
             typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 4247
                 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
2660ccea Poul Sander 2023-09-22 19:25 4248
                 int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 4249
    input_adapter(IteratorType first, IteratorType last)
2660ccea Poul Sander 2023-09-22 19:25 4250
    {
2660ccea Poul Sander 2023-09-22 19:25 4251
#ifndef NDEBUG
2660ccea Poul Sander 2023-09-22 19:25 4252
        // assertion to check that the iterator range is indeed contiguous,
2660ccea Poul Sander 2023-09-22 19:25 4253
        // see http://stackoverflow.com/a/35008842/266378 for more discussion
2660ccea Poul Sander 2023-09-22 19:25 4254
        const auto is_contiguous = std::accumulate(
2660ccea Poul Sander 2023-09-22 19:25 4255
                                       first, last, std::pair<bool, int>(true, 0),
2660ccea Poul Sander 2023-09-22 19:25 4256
                                       [&first](std::pair<bool, int> res, decltype(*first) val)
2660ccea Poul Sander 2023-09-22 19:25 4257
        {
2660ccea Poul Sander 2023-09-22 19:25 4258
            res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2660ccea Poul Sander 2023-09-22 19:25 4259
            return res;
2660ccea Poul Sander 2023-09-22 19:25 4260
        }).first;
2660ccea Poul Sander 2023-09-22 19:25 4261
        assert(is_contiguous);
2660ccea Poul Sander 2023-09-22 19:25 4262
#endif
2660ccea Poul Sander 2023-09-22 19:25 4263
2660ccea Poul Sander 2023-09-22 19:25 4264
        // assertion to check that each element is 1 byte long
2660ccea Poul Sander 2023-09-22 19:25 4265
        static_assert(
2660ccea Poul Sander 2023-09-22 19:25 4266
            sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
2660ccea Poul Sander 2023-09-22 19:25 4267
            "each element in the iterator range must have the size of 1 byte");
2660ccea Poul Sander 2023-09-22 19:25 4268
2660ccea Poul Sander 2023-09-22 19:25 4269
        const auto len = static_cast<size_t>(std::distance(first, last));
2660ccea Poul Sander 2023-09-22 19:25 4270
        if (JSON_HEDLEY_LIKELY(len > 0))
2660ccea Poul Sander 2023-09-22 19:25 4271
        {
2660ccea Poul Sander 2023-09-22 19:25 4272
            // there is at least one element: use the address of first
2660ccea Poul Sander 2023-09-22 19:25 4273
            ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
2660ccea Poul Sander 2023-09-22 19:25 4274
        }
2660ccea Poul Sander 2023-09-22 19:25 4275
        else
2660ccea Poul Sander 2023-09-22 19:25 4276
        {
2660ccea Poul Sander 2023-09-22 19:25 4277
            // the address of first cannot be used: use nullptr
2660ccea Poul Sander 2023-09-22 19:25 4278
            ia = std::make_shared<input_buffer_adapter>(nullptr, len);
2660ccea Poul Sander 2023-09-22 19:25 4279
        }
2660ccea Poul Sander 2023-09-22 19:25 4280
    }
2660ccea Poul Sander 2023-09-22 19:25 4281
2660ccea Poul Sander 2023-09-22 19:25 4282
    /// input adapter for array
2660ccea Poul Sander 2023-09-22 19:25 4283
    template<class T, std::size_t N>
2660ccea Poul Sander 2023-09-22 19:25 4284
    input_adapter(T (&array)[N])
2660ccea Poul Sander 2023-09-22 19:25 4285
        : input_adapter(std::begin(array), std::end(array)) {}
2660ccea Poul Sander 2023-09-22 19:25 4286
2660ccea Poul Sander 2023-09-22 19:25 4287
    /// input adapter for contiguous container
2660ccea Poul Sander 2023-09-22 19:25 4288
    template<class ContiguousContainer, typename
2660ccea Poul Sander 2023-09-22 19:25 4289
             std::enable_if<not std::is_pointer<ContiguousContainer>::value and
2660ccea Poul Sander 2023-09-22 19:25 4290
                            std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
2660ccea Poul Sander 2023-09-22 19:25 4291
                            int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 4292
    input_adapter(const ContiguousContainer& c)
2660ccea Poul Sander 2023-09-22 19:25 4293
        : input_adapter(std::begin(c), std::end(c)) {}
2660ccea Poul Sander 2023-09-22 19:25 4294
2660ccea Poul Sander 2023-09-22 19:25 4295
    operator input_adapter_t()
2660ccea Poul Sander 2023-09-22 19:25 4296
    {
2660ccea Poul Sander 2023-09-22 19:25 4297
        return ia;
2660ccea Poul Sander 2023-09-22 19:25 4298
    }
2660ccea Poul Sander 2023-09-22 19:25 4299
2660ccea Poul Sander 2023-09-22 19:25 4300
  private:
2660ccea Poul Sander 2023-09-22 19:25 4301
    /// the actual adapter
2660ccea Poul Sander 2023-09-22 19:25 4302
    input_adapter_t ia = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 4303
};
2660ccea Poul Sander 2023-09-22 19:25 4304
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 4305
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 4306
2660ccea Poul Sander 2023-09-22 19:25 4307
// #include <nlohmann/detail/input/json_sax.hpp>
2660ccea Poul Sander 2023-09-22 19:25 4308
2660ccea Poul Sander 2023-09-22 19:25 4309
2660ccea Poul Sander 2023-09-22 19:25 4310
#include <cassert> // assert
2660ccea Poul Sander 2023-09-22 19:25 4311
#include <cstddef>
2660ccea Poul Sander 2023-09-22 19:25 4312
#include <string> // string
2660ccea Poul Sander 2023-09-22 19:25 4313
#include <utility> // move
2660ccea Poul Sander 2023-09-22 19:25 4314
#include <vector> // vector
2660ccea Poul Sander 2023-09-22 19:25 4315
2660ccea Poul Sander 2023-09-22 19:25 4316
// #include <nlohmann/detail/exceptions.hpp>
2660ccea Poul Sander 2023-09-22 19:25 4317
2660ccea Poul Sander 2023-09-22 19:25 4318
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 4319
2660ccea Poul Sander 2023-09-22 19:25 4320
2660ccea Poul Sander 2023-09-22 19:25 4321
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 4322
{
2660ccea Poul Sander 2023-09-22 19:25 4323
2660ccea Poul Sander 2023-09-22 19:25 4324
/*!
2660ccea Poul Sander 2023-09-22 19:25 4325
@brief SAX interface
2660ccea Poul Sander 2023-09-22 19:25 4326
2660ccea Poul Sander 2023-09-22 19:25 4327
This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
2660ccea Poul Sander 2023-09-22 19:25 4328
Each function is called in different situations while the input is parsed. The
2660ccea Poul Sander 2023-09-22 19:25 4329
boolean return value informs the parser whether to continue processing the
2660ccea Poul Sander 2023-09-22 19:25 4330
input.
2660ccea Poul Sander 2023-09-22 19:25 4331
*/
2660ccea Poul Sander 2023-09-22 19:25 4332
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 4333
struct json_sax
2660ccea Poul Sander 2023-09-22 19:25 4334
{
2660ccea Poul Sander 2023-09-22 19:25 4335
    /// type for (signed) integers
2660ccea Poul Sander 2023-09-22 19:25 4336
    using number_integer_t = typename BasicJsonType::number_integer_t;
2660ccea Poul Sander 2023-09-22 19:25 4337
    /// type for unsigned integers
2660ccea Poul Sander 2023-09-22 19:25 4338
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2660ccea Poul Sander 2023-09-22 19:25 4339
    /// type for floating-point numbers
2660ccea Poul Sander 2023-09-22 19:25 4340
    using number_float_t = typename BasicJsonType::number_float_t;
2660ccea Poul Sander 2023-09-22 19:25 4341
    /// type for strings
2660ccea Poul Sander 2023-09-22 19:25 4342
    using string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 4343
2660ccea Poul Sander 2023-09-22 19:25 4344
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4345
    @brief a null value was read
2660ccea Poul Sander 2023-09-22 19:25 4346
    @return whether parsing should proceed
2660ccea Poul Sander 2023-09-22 19:25 4347
    */
2660ccea Poul Sander 2023-09-22 19:25 4348
    virtual bool null() = 0;
2660ccea Poul Sander 2023-09-22 19:25 4349
2660ccea Poul Sander 2023-09-22 19:25 4350
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4351
    @brief a boolean value was read
2660ccea Poul Sander 2023-09-22 19:25 4352
    @param[in] val  boolean value
2660ccea Poul Sander 2023-09-22 19:25 4353
    @return whether parsing should proceed
2660ccea Poul Sander 2023-09-22 19:25 4354
    */
2660ccea Poul Sander 2023-09-22 19:25 4355
    virtual bool boolean(bool val) = 0;
2660ccea Poul Sander 2023-09-22 19:25 4356
2660ccea Poul Sander 2023-09-22 19:25 4357
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4358
    @brief an integer number was read
2660ccea Poul Sander 2023-09-22 19:25 4359
    @param[in] val  integer value
2660ccea Poul Sander 2023-09-22 19:25 4360
    @return whether parsing should proceed
2660ccea Poul Sander 2023-09-22 19:25 4361
    */
2660ccea Poul Sander 2023-09-22 19:25 4362
    virtual bool number_integer(number_integer_t val) = 0;
2660ccea Poul Sander 2023-09-22 19:25 4363
2660ccea Poul Sander 2023-09-22 19:25 4364
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4365
    @brief an unsigned integer number was read
2660ccea Poul Sander 2023-09-22 19:25 4366
    @param[in] val  unsigned integer value
2660ccea Poul Sander 2023-09-22 19:25 4367
    @return whether parsing should proceed
2660ccea Poul Sander 2023-09-22 19:25 4368
    */
2660ccea Poul Sander 2023-09-22 19:25 4369
    virtual bool number_unsigned(number_unsigned_t val) = 0;
2660ccea Poul Sander 2023-09-22 19:25 4370
2660ccea Poul Sander 2023-09-22 19:25 4371
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4372
    @brief an floating-point number was read
2660ccea Poul Sander 2023-09-22 19:25 4373
    @param[in] val  floating-point value
2660ccea Poul Sander 2023-09-22 19:25 4374
    @param[in] s    raw token value
2660ccea Poul Sander 2023-09-22 19:25 4375
    @return whether parsing should proceed
2660ccea Poul Sander 2023-09-22 19:25 4376
    */
2660ccea Poul Sander 2023-09-22 19:25 4377
    virtual bool number_float(number_float_t val, const string_t& s) = 0;
2660ccea Poul Sander 2023-09-22 19:25 4378
2660ccea Poul Sander 2023-09-22 19:25 4379
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4380
    @brief a string was read
2660ccea Poul Sander 2023-09-22 19:25 4381
    @param[in] val  string value
2660ccea Poul Sander 2023-09-22 19:25 4382
    @return whether parsing should proceed
2660ccea Poul Sander 2023-09-22 19:25 4383
    @note It is safe to move the passed string.
2660ccea Poul Sander 2023-09-22 19:25 4384
    */
2660ccea Poul Sander 2023-09-22 19:25 4385
    virtual bool string(string_t& val) = 0;
2660ccea Poul Sander 2023-09-22 19:25 4386
2660ccea Poul Sander 2023-09-22 19:25 4387
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4388
    @brief the beginning of an object was read
2660ccea Poul Sander 2023-09-22 19:25 4389
    @param[in] elements  number of object elements or -1 if unknown
2660ccea Poul Sander 2023-09-22 19:25 4390
    @return whether parsing should proceed
2660ccea Poul Sander 2023-09-22 19:25 4391
    @note binary formats may report the number of elements
2660ccea Poul Sander 2023-09-22 19:25 4392
    */
2660ccea Poul Sander 2023-09-22 19:25 4393
    virtual bool start_object(std::size_t elements) = 0;
2660ccea Poul Sander 2023-09-22 19:25 4394
2660ccea Poul Sander 2023-09-22 19:25 4395
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4396
    @brief an object key was read
2660ccea Poul Sander 2023-09-22 19:25 4397
    @param[in] val  object key
2660ccea Poul Sander 2023-09-22 19:25 4398
    @return whether parsing should proceed
2660ccea Poul Sander 2023-09-22 19:25 4399
    @note It is safe to move the passed string.
2660ccea Poul Sander 2023-09-22 19:25 4400
    */
2660ccea Poul Sander 2023-09-22 19:25 4401
    virtual bool key(string_t& val) = 0;
2660ccea Poul Sander 2023-09-22 19:25 4402
2660ccea Poul Sander 2023-09-22 19:25 4403
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4404
    @brief the end of an object was read
2660ccea Poul Sander 2023-09-22 19:25 4405
    @return whether parsing should proceed
2660ccea Poul Sander 2023-09-22 19:25 4406
    */
2660ccea Poul Sander 2023-09-22 19:25 4407
    virtual bool end_object() = 0;
2660ccea Poul Sander 2023-09-22 19:25 4408
2660ccea Poul Sander 2023-09-22 19:25 4409
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4410
    @brief the beginning of an array was read
2660ccea Poul Sander 2023-09-22 19:25 4411
    @param[in] elements  number of array elements or -1 if unknown
2660ccea Poul Sander 2023-09-22 19:25 4412
    @return whether parsing should proceed
2660ccea Poul Sander 2023-09-22 19:25 4413
    @note binary formats may report the number of elements
2660ccea Poul Sander 2023-09-22 19:25 4414
    */
2660ccea Poul Sander 2023-09-22 19:25 4415
    virtual bool start_array(std::size_t elements) = 0;
2660ccea Poul Sander 2023-09-22 19:25 4416
2660ccea Poul Sander 2023-09-22 19:25 4417
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4418
    @brief the end of an array was read
2660ccea Poul Sander 2023-09-22 19:25 4419
    @return whether parsing should proceed
2660ccea Poul Sander 2023-09-22 19:25 4420
    */
2660ccea Poul Sander 2023-09-22 19:25 4421
    virtual bool end_array() = 0;
2660ccea Poul Sander 2023-09-22 19:25 4422
2660ccea Poul Sander 2023-09-22 19:25 4423
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4424
    @brief a parse error occurred
2660ccea Poul Sander 2023-09-22 19:25 4425
    @param[in] position    the position in the input where the error occurs
2660ccea Poul Sander 2023-09-22 19:25 4426
    @param[in] last_token  the last read token
2660ccea Poul Sander 2023-09-22 19:25 4427
    @param[in] ex          an exception object describing the error
2660ccea Poul Sander 2023-09-22 19:25 4428
    @return whether parsing should proceed (must return false)
2660ccea Poul Sander 2023-09-22 19:25 4429
    */
2660ccea Poul Sander 2023-09-22 19:25 4430
    virtual bool parse_error(std::size_t position,
2660ccea Poul Sander 2023-09-22 19:25 4431
                             const std::string& last_token,
2660ccea Poul Sander 2023-09-22 19:25 4432
                             const detail::exception& ex) = 0;
2660ccea Poul Sander 2023-09-22 19:25 4433
2660ccea Poul Sander 2023-09-22 19:25 4434
    virtual ~json_sax() = default;
2660ccea Poul Sander 2023-09-22 19:25 4435
};
2660ccea Poul Sander 2023-09-22 19:25 4436
2660ccea Poul Sander 2023-09-22 19:25 4437
2660ccea Poul Sander 2023-09-22 19:25 4438
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 4439
{
2660ccea Poul Sander 2023-09-22 19:25 4440
/*!
2660ccea Poul Sander 2023-09-22 19:25 4441
@brief SAX implementation to create a JSON value from SAX events
2660ccea Poul Sander 2023-09-22 19:25 4442
2660ccea Poul Sander 2023-09-22 19:25 4443
This class implements the @ref json_sax interface and processes the SAX events
2660ccea Poul Sander 2023-09-22 19:25 4444
to create a JSON value which makes it basically a DOM parser. The structure or
2660ccea Poul Sander 2023-09-22 19:25 4445
hierarchy of the JSON value is managed by the stack `ref_stack` which contains
2660ccea Poul Sander 2023-09-22 19:25 4446
a pointer to the respective array or object for each recursion depth.
2660ccea Poul Sander 2023-09-22 19:25 4447
2660ccea Poul Sander 2023-09-22 19:25 4448
After successful parsing, the value that is passed by reference to the
2660ccea Poul Sander 2023-09-22 19:25 4449
constructor contains the parsed value.
2660ccea Poul Sander 2023-09-22 19:25 4450
2660ccea Poul Sander 2023-09-22 19:25 4451
@tparam BasicJsonType  the JSON type
2660ccea Poul Sander 2023-09-22 19:25 4452
*/
2660ccea Poul Sander 2023-09-22 19:25 4453
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 4454
class json_sax_dom_parser
2660ccea Poul Sander 2023-09-22 19:25 4455
{
2660ccea Poul Sander 2023-09-22 19:25 4456
  public:
2660ccea Poul Sander 2023-09-22 19:25 4457
    using number_integer_t = typename BasicJsonType::number_integer_t;
2660ccea Poul Sander 2023-09-22 19:25 4458
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2660ccea Poul Sander 2023-09-22 19:25 4459
    using number_float_t = typename BasicJsonType::number_float_t;
2660ccea Poul Sander 2023-09-22 19:25 4460
    using string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 4461
2660ccea Poul Sander 2023-09-22 19:25 4462
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4463
    @param[in, out] r  reference to a JSON value that is manipulated while
2660ccea Poul Sander 2023-09-22 19:25 4464
                       parsing
2660ccea Poul Sander 2023-09-22 19:25 4465
    @param[in] allow_exceptions_  whether parse errors yield exceptions
2660ccea Poul Sander 2023-09-22 19:25 4466
    */
2660ccea Poul Sander 2023-09-22 19:25 4467
    explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
2660ccea Poul Sander 2023-09-22 19:25 4468
        : root(r), allow_exceptions(allow_exceptions_)
2660ccea Poul Sander 2023-09-22 19:25 4469
    {}
2660ccea Poul Sander 2023-09-22 19:25 4470
2660ccea Poul Sander 2023-09-22 19:25 4471
    // make class move-only
2660ccea Poul Sander 2023-09-22 19:25 4472
    json_sax_dom_parser(const json_sax_dom_parser&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 4473
    json_sax_dom_parser(json_sax_dom_parser&&) = default;
2660ccea Poul Sander 2023-09-22 19:25 4474
    json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 4475
    json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
2660ccea Poul Sander 2023-09-22 19:25 4476
    ~json_sax_dom_parser() = default;
2660ccea Poul Sander 2023-09-22 19:25 4477
2660ccea Poul Sander 2023-09-22 19:25 4478
    bool null()
2660ccea Poul Sander 2023-09-22 19:25 4479
    {
2660ccea Poul Sander 2023-09-22 19:25 4480
        handle_value(nullptr);
2660ccea Poul Sander 2023-09-22 19:25 4481
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4482
    }
2660ccea Poul Sander 2023-09-22 19:25 4483
2660ccea Poul Sander 2023-09-22 19:25 4484
    bool boolean(bool val)
2660ccea Poul Sander 2023-09-22 19:25 4485
    {
2660ccea Poul Sander 2023-09-22 19:25 4486
        handle_value(val);
2660ccea Poul Sander 2023-09-22 19:25 4487
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4488
    }
2660ccea Poul Sander 2023-09-22 19:25 4489
2660ccea Poul Sander 2023-09-22 19:25 4490
    bool number_integer(number_integer_t val)
2660ccea Poul Sander 2023-09-22 19:25 4491
    {
2660ccea Poul Sander 2023-09-22 19:25 4492
        handle_value(val);
2660ccea Poul Sander 2023-09-22 19:25 4493
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4494
    }
2660ccea Poul Sander 2023-09-22 19:25 4495
2660ccea Poul Sander 2023-09-22 19:25 4496
    bool number_unsigned(number_unsigned_t val)
2660ccea Poul Sander 2023-09-22 19:25 4497
    {
2660ccea Poul Sander 2023-09-22 19:25 4498
        handle_value(val);
2660ccea Poul Sander 2023-09-22 19:25 4499
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4500
    }
2660ccea Poul Sander 2023-09-22 19:25 4501
2660ccea Poul Sander 2023-09-22 19:25 4502
    bool number_float(number_float_t val, const string_t& /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 4503
    {
2660ccea Poul Sander 2023-09-22 19:25 4504
        handle_value(val);
2660ccea Poul Sander 2023-09-22 19:25 4505
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4506
    }
2660ccea Poul Sander 2023-09-22 19:25 4507
2660ccea Poul Sander 2023-09-22 19:25 4508
    bool string(string_t& val)
2660ccea Poul Sander 2023-09-22 19:25 4509
    {
2660ccea Poul Sander 2023-09-22 19:25 4510
        handle_value(val);
2660ccea Poul Sander 2023-09-22 19:25 4511
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4512
    }
2660ccea Poul Sander 2023-09-22 19:25 4513
2660ccea Poul Sander 2023-09-22 19:25 4514
    bool start_object(std::size_t len)
2660ccea Poul Sander 2023-09-22 19:25 4515
    {
2660ccea Poul Sander 2023-09-22 19:25 4516
        ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
2660ccea Poul Sander 2023-09-22 19:25 4517
2660ccea Poul Sander 2023-09-22 19:25 4518
        if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2660ccea Poul Sander 2023-09-22 19:25 4519
        {
2660ccea Poul Sander 2023-09-22 19:25 4520
            JSON_THROW(out_of_range::create(408,
2660ccea Poul Sander 2023-09-22 19:25 4521
                                            "excessive object size: " + std::to_string(len)));
2660ccea Poul Sander 2023-09-22 19:25 4522
        }
2660ccea Poul Sander 2023-09-22 19:25 4523
2660ccea Poul Sander 2023-09-22 19:25 4524
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4525
    }
2660ccea Poul Sander 2023-09-22 19:25 4526
2660ccea Poul Sander 2023-09-22 19:25 4527
    bool key(string_t& val)
2660ccea Poul Sander 2023-09-22 19:25 4528
    {
2660ccea Poul Sander 2023-09-22 19:25 4529
        // add null at given key and store the reference for later
2660ccea Poul Sander 2023-09-22 19:25 4530
        object_element = &(ref_stack.back()->m_value.object->operator[](val));
2660ccea Poul Sander 2023-09-22 19:25 4531
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4532
    }
2660ccea Poul Sander 2023-09-22 19:25 4533
2660ccea Poul Sander 2023-09-22 19:25 4534
    bool end_object()
2660ccea Poul Sander 2023-09-22 19:25 4535
    {
2660ccea Poul Sander 2023-09-22 19:25 4536
        ref_stack.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 4537
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4538
    }
2660ccea Poul Sander 2023-09-22 19:25 4539
2660ccea Poul Sander 2023-09-22 19:25 4540
    bool start_array(std::size_t len)
2660ccea Poul Sander 2023-09-22 19:25 4541
    {
2660ccea Poul Sander 2023-09-22 19:25 4542
        ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
2660ccea Poul Sander 2023-09-22 19:25 4543
2660ccea Poul Sander 2023-09-22 19:25 4544
        if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2660ccea Poul Sander 2023-09-22 19:25 4545
        {
2660ccea Poul Sander 2023-09-22 19:25 4546
            JSON_THROW(out_of_range::create(408,
2660ccea Poul Sander 2023-09-22 19:25 4547
                                            "excessive array size: " + std::to_string(len)));
2660ccea Poul Sander 2023-09-22 19:25 4548
        }
2660ccea Poul Sander 2023-09-22 19:25 4549
2660ccea Poul Sander 2023-09-22 19:25 4550
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4551
    }
2660ccea Poul Sander 2023-09-22 19:25 4552
2660ccea Poul Sander 2023-09-22 19:25 4553
    bool end_array()
2660ccea Poul Sander 2023-09-22 19:25 4554
    {
2660ccea Poul Sander 2023-09-22 19:25 4555
        ref_stack.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 4556
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4557
    }
2660ccea Poul Sander 2023-09-22 19:25 4558
2660ccea Poul Sander 2023-09-22 19:25 4559
    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
2660ccea Poul Sander 2023-09-22 19:25 4560
                     const detail::exception& ex)
2660ccea Poul Sander 2023-09-22 19:25 4561
    {
2660ccea Poul Sander 2023-09-22 19:25 4562
        errored = true;
2660ccea Poul Sander 2023-09-22 19:25 4563
        if (allow_exceptions)
2660ccea Poul Sander 2023-09-22 19:25 4564
        {
2660ccea Poul Sander 2023-09-22 19:25 4565
            // determine the proper exception type from the id
2660ccea Poul Sander 2023-09-22 19:25 4566
            switch ((ex.id / 100) % 100)
2660ccea Poul Sander 2023-09-22 19:25 4567
            {
2660ccea Poul Sander 2023-09-22 19:25 4568
                case 1:
2660ccea Poul Sander 2023-09-22 19:25 4569
                    JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
2660ccea Poul Sander 2023-09-22 19:25 4570
                case 4:
2660ccea Poul Sander 2023-09-22 19:25 4571
                    JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
2660ccea Poul Sander 2023-09-22 19:25 4572
                // LCOV_EXCL_START
2660ccea Poul Sander 2023-09-22 19:25 4573
                case 2:
2660ccea Poul Sander 2023-09-22 19:25 4574
                    JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
2660ccea Poul Sander 2023-09-22 19:25 4575
                case 3:
2660ccea Poul Sander 2023-09-22 19:25 4576
                    JSON_THROW(*static_cast<const detail::type_error*>(&ex));
2660ccea Poul Sander 2023-09-22 19:25 4577
                case 5:
2660ccea Poul Sander 2023-09-22 19:25 4578
                    JSON_THROW(*static_cast<const detail::other_error*>(&ex));
2660ccea Poul Sander 2023-09-22 19:25 4579
                default:
2660ccea Poul Sander 2023-09-22 19:25 4580
                    assert(false);
2660ccea Poul Sander 2023-09-22 19:25 4581
                    // LCOV_EXCL_STOP
2660ccea Poul Sander 2023-09-22 19:25 4582
            }
2660ccea Poul Sander 2023-09-22 19:25 4583
        }
2660ccea Poul Sander 2023-09-22 19:25 4584
        return false;
2660ccea Poul Sander 2023-09-22 19:25 4585
    }
2660ccea Poul Sander 2023-09-22 19:25 4586
2660ccea Poul Sander 2023-09-22 19:25 4587
    constexpr bool is_errored() const
2660ccea Poul Sander 2023-09-22 19:25 4588
    {
2660ccea Poul Sander 2023-09-22 19:25 4589
        return errored;
2660ccea Poul Sander 2023-09-22 19:25 4590
    }
2660ccea Poul Sander 2023-09-22 19:25 4591
2660ccea Poul Sander 2023-09-22 19:25 4592
  private:
2660ccea Poul Sander 2023-09-22 19:25 4593
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4594
    @invariant If the ref stack is empty, then the passed value will be the new
2660ccea Poul Sander 2023-09-22 19:25 4595
               root.
2660ccea Poul Sander 2023-09-22 19:25 4596
    @invariant If the ref stack contains a value, then it is an array or an
2660ccea Poul Sander 2023-09-22 19:25 4597
               object to which we can add elements
2660ccea Poul Sander 2023-09-22 19:25 4598
    */
2660ccea Poul Sander 2023-09-22 19:25 4599
    template<typename Value>
2660ccea Poul Sander 2023-09-22 19:25 4600
    JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 4601
    BasicJsonType* handle_value(Value&& v)
2660ccea Poul Sander 2023-09-22 19:25 4602
    {
2660ccea Poul Sander 2023-09-22 19:25 4603
        if (ref_stack.empty())
2660ccea Poul Sander 2023-09-22 19:25 4604
        {
2660ccea Poul Sander 2023-09-22 19:25 4605
            root = BasicJsonType(std::forward<Value>(v));
2660ccea Poul Sander 2023-09-22 19:25 4606
            return &root;
2660ccea Poul Sander 2023-09-22 19:25 4607
        }
2660ccea Poul Sander 2023-09-22 19:25 4608
2660ccea Poul Sander 2023-09-22 19:25 4609
        assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
2660ccea Poul Sander 2023-09-22 19:25 4610
2660ccea Poul Sander 2023-09-22 19:25 4611
        if (ref_stack.back()->is_array())
2660ccea Poul Sander 2023-09-22 19:25 4612
        {
2660ccea Poul Sander 2023-09-22 19:25 4613
            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
2660ccea Poul Sander 2023-09-22 19:25 4614
            return &(ref_stack.back()->m_value.array->back());
2660ccea Poul Sander 2023-09-22 19:25 4615
        }
2660ccea Poul Sander 2023-09-22 19:25 4616
2660ccea Poul Sander 2023-09-22 19:25 4617
        assert(ref_stack.back()->is_object());
2660ccea Poul Sander 2023-09-22 19:25 4618
        assert(object_element);
2660ccea Poul Sander 2023-09-22 19:25 4619
        *object_element = BasicJsonType(std::forward<Value>(v));
2660ccea Poul Sander 2023-09-22 19:25 4620
        return object_element;
2660ccea Poul Sander 2023-09-22 19:25 4621
    }
2660ccea Poul Sander 2023-09-22 19:25 4622
2660ccea Poul Sander 2023-09-22 19:25 4623
    /// the parsed JSON value
2660ccea Poul Sander 2023-09-22 19:25 4624
    BasicJsonType& root;
2660ccea Poul Sander 2023-09-22 19:25 4625
    /// stack to model hierarchy of values
2660ccea Poul Sander 2023-09-22 19:25 4626
    std::vector<BasicJsonType*> ref_stack {};
2660ccea Poul Sander 2023-09-22 19:25 4627
    /// helper to hold the reference for the next object element
2660ccea Poul Sander 2023-09-22 19:25 4628
    BasicJsonType* object_element = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 4629
    /// whether a syntax error occurred
2660ccea Poul Sander 2023-09-22 19:25 4630
    bool errored = false;
2660ccea Poul Sander 2023-09-22 19:25 4631
    /// whether to throw exceptions in case of errors
2660ccea Poul Sander 2023-09-22 19:25 4632
    const bool allow_exceptions = true;
2660ccea Poul Sander 2023-09-22 19:25 4633
};
2660ccea Poul Sander 2023-09-22 19:25 4634
2660ccea Poul Sander 2023-09-22 19:25 4635
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 4636
class json_sax_dom_callback_parser
2660ccea Poul Sander 2023-09-22 19:25 4637
{
2660ccea Poul Sander 2023-09-22 19:25 4638
  public:
2660ccea Poul Sander 2023-09-22 19:25 4639
    using number_integer_t = typename BasicJsonType::number_integer_t;
2660ccea Poul Sander 2023-09-22 19:25 4640
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2660ccea Poul Sander 2023-09-22 19:25 4641
    using number_float_t = typename BasicJsonType::number_float_t;
2660ccea Poul Sander 2023-09-22 19:25 4642
    using string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 4643
    using parser_callback_t = typename BasicJsonType::parser_callback_t;
2660ccea Poul Sander 2023-09-22 19:25 4644
    using parse_event_t = typename BasicJsonType::parse_event_t;
2660ccea Poul Sander 2023-09-22 19:25 4645
2660ccea Poul Sander 2023-09-22 19:25 4646
    json_sax_dom_callback_parser(BasicJsonType& r,
2660ccea Poul Sander 2023-09-22 19:25 4647
                                 const parser_callback_t cb,
2660ccea Poul Sander 2023-09-22 19:25 4648
                                 const bool allow_exceptions_ = true)
2660ccea Poul Sander 2023-09-22 19:25 4649
        : root(r), callback(cb), allow_exceptions(allow_exceptions_)
2660ccea Poul Sander 2023-09-22 19:25 4650
    {
2660ccea Poul Sander 2023-09-22 19:25 4651
        keep_stack.push_back(true);
2660ccea Poul Sander 2023-09-22 19:25 4652
    }
2660ccea Poul Sander 2023-09-22 19:25 4653
2660ccea Poul Sander 2023-09-22 19:25 4654
    // make class move-only
2660ccea Poul Sander 2023-09-22 19:25 4655
    json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 4656
    json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
2660ccea Poul Sander 2023-09-22 19:25 4657
    json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 4658
    json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
2660ccea Poul Sander 2023-09-22 19:25 4659
    ~json_sax_dom_callback_parser() = default;
2660ccea Poul Sander 2023-09-22 19:25 4660
2660ccea Poul Sander 2023-09-22 19:25 4661
    bool null()
2660ccea Poul Sander 2023-09-22 19:25 4662
    {
2660ccea Poul Sander 2023-09-22 19:25 4663
        handle_value(nullptr);
2660ccea Poul Sander 2023-09-22 19:25 4664
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4665
    }
2660ccea Poul Sander 2023-09-22 19:25 4666
2660ccea Poul Sander 2023-09-22 19:25 4667
    bool boolean(bool val)
2660ccea Poul Sander 2023-09-22 19:25 4668
    {
2660ccea Poul Sander 2023-09-22 19:25 4669
        handle_value(val);
2660ccea Poul Sander 2023-09-22 19:25 4670
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4671
    }
2660ccea Poul Sander 2023-09-22 19:25 4672
2660ccea Poul Sander 2023-09-22 19:25 4673
    bool number_integer(number_integer_t val)
2660ccea Poul Sander 2023-09-22 19:25 4674
    {
2660ccea Poul Sander 2023-09-22 19:25 4675
        handle_value(val);
2660ccea Poul Sander 2023-09-22 19:25 4676
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4677
    }
2660ccea Poul Sander 2023-09-22 19:25 4678
2660ccea Poul Sander 2023-09-22 19:25 4679
    bool number_unsigned(number_unsigned_t val)
2660ccea Poul Sander 2023-09-22 19:25 4680
    {
2660ccea Poul Sander 2023-09-22 19:25 4681
        handle_value(val);
2660ccea Poul Sander 2023-09-22 19:25 4682
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4683
    }
2660ccea Poul Sander 2023-09-22 19:25 4684
2660ccea Poul Sander 2023-09-22 19:25 4685
    bool number_float(number_float_t val, const string_t& /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 4686
    {
2660ccea Poul Sander 2023-09-22 19:25 4687
        handle_value(val);
2660ccea Poul Sander 2023-09-22 19:25 4688
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4689
    }
2660ccea Poul Sander 2023-09-22 19:25 4690
2660ccea Poul Sander 2023-09-22 19:25 4691
    bool string(string_t& val)
2660ccea Poul Sander 2023-09-22 19:25 4692
    {
2660ccea Poul Sander 2023-09-22 19:25 4693
        handle_value(val);
2660ccea Poul Sander 2023-09-22 19:25 4694
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4695
    }
2660ccea Poul Sander 2023-09-22 19:25 4696
2660ccea Poul Sander 2023-09-22 19:25 4697
    bool start_object(std::size_t len)
2660ccea Poul Sander 2023-09-22 19:25 4698
    {
2660ccea Poul Sander 2023-09-22 19:25 4699
        // check callback for object start
2660ccea Poul Sander 2023-09-22 19:25 4700
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
2660ccea Poul Sander 2023-09-22 19:25 4701
        keep_stack.push_back(keep);
2660ccea Poul Sander 2023-09-22 19:25 4702
2660ccea Poul Sander 2023-09-22 19:25 4703
        auto val = handle_value(BasicJsonType::value_t::object, true);
2660ccea Poul Sander 2023-09-22 19:25 4704
        ref_stack.push_back(val.second);
2660ccea Poul Sander 2023-09-22 19:25 4705
2660ccea Poul Sander 2023-09-22 19:25 4706
        // check object limit
2660ccea Poul Sander 2023-09-22 19:25 4707
        if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2660ccea Poul Sander 2023-09-22 19:25 4708
        {
2660ccea Poul Sander 2023-09-22 19:25 4709
            JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
2660ccea Poul Sander 2023-09-22 19:25 4710
        }
2660ccea Poul Sander 2023-09-22 19:25 4711
2660ccea Poul Sander 2023-09-22 19:25 4712
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4713
    }
2660ccea Poul Sander 2023-09-22 19:25 4714
2660ccea Poul Sander 2023-09-22 19:25 4715
    bool key(string_t& val)
2660ccea Poul Sander 2023-09-22 19:25 4716
    {
2660ccea Poul Sander 2023-09-22 19:25 4717
        BasicJsonType k = BasicJsonType(val);
2660ccea Poul Sander 2023-09-22 19:25 4718
2660ccea Poul Sander 2023-09-22 19:25 4719
        // check callback for key
2660ccea Poul Sander 2023-09-22 19:25 4720
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
2660ccea Poul Sander 2023-09-22 19:25 4721
        key_keep_stack.push_back(keep);
2660ccea Poul Sander 2023-09-22 19:25 4722
2660ccea Poul Sander 2023-09-22 19:25 4723
        // add discarded value at given key and store the reference for later
2660ccea Poul Sander 2023-09-22 19:25 4724
        if (keep and ref_stack.back())
2660ccea Poul Sander 2023-09-22 19:25 4725
        {
2660ccea Poul Sander 2023-09-22 19:25 4726
            object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
2660ccea Poul Sander 2023-09-22 19:25 4727
        }
2660ccea Poul Sander 2023-09-22 19:25 4728
2660ccea Poul Sander 2023-09-22 19:25 4729
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4730
    }
2660ccea Poul Sander 2023-09-22 19:25 4731
2660ccea Poul Sander 2023-09-22 19:25 4732
    bool end_object()
2660ccea Poul Sander 2023-09-22 19:25 4733
    {
2660ccea Poul Sander 2023-09-22 19:25 4734
        if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
2660ccea Poul Sander 2023-09-22 19:25 4735
        {
2660ccea Poul Sander 2023-09-22 19:25 4736
            // discard object
2660ccea Poul Sander 2023-09-22 19:25 4737
            *ref_stack.back() = discarded;
2660ccea Poul Sander 2023-09-22 19:25 4738
        }
2660ccea Poul Sander 2023-09-22 19:25 4739
2660ccea Poul Sander 2023-09-22 19:25 4740
        assert(not ref_stack.empty());
2660ccea Poul Sander 2023-09-22 19:25 4741
        assert(not keep_stack.empty());
2660ccea Poul Sander 2023-09-22 19:25 4742
        ref_stack.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 4743
        keep_stack.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 4744
2660ccea Poul Sander 2023-09-22 19:25 4745
        if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
2660ccea Poul Sander 2023-09-22 19:25 4746
        {
2660ccea Poul Sander 2023-09-22 19:25 4747
            // remove discarded value
2660ccea Poul Sander 2023-09-22 19:25 4748
            for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
2660ccea Poul Sander 2023-09-22 19:25 4749
            {
2660ccea Poul Sander 2023-09-22 19:25 4750
                if (it->is_discarded())
2660ccea Poul Sander 2023-09-22 19:25 4751
                {
2660ccea Poul Sander 2023-09-22 19:25 4752
                    ref_stack.back()->erase(it);
2660ccea Poul Sander 2023-09-22 19:25 4753
                    break;
2660ccea Poul Sander 2023-09-22 19:25 4754
                }
2660ccea Poul Sander 2023-09-22 19:25 4755
            }
2660ccea Poul Sander 2023-09-22 19:25 4756
        }
2660ccea Poul Sander 2023-09-22 19:25 4757
2660ccea Poul Sander 2023-09-22 19:25 4758
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4759
    }
2660ccea Poul Sander 2023-09-22 19:25 4760
2660ccea Poul Sander 2023-09-22 19:25 4761
    bool start_array(std::size_t len)
2660ccea Poul Sander 2023-09-22 19:25 4762
    {
2660ccea Poul Sander 2023-09-22 19:25 4763
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
2660ccea Poul Sander 2023-09-22 19:25 4764
        keep_stack.push_back(keep);
2660ccea Poul Sander 2023-09-22 19:25 4765
2660ccea Poul Sander 2023-09-22 19:25 4766
        auto val = handle_value(BasicJsonType::value_t::array, true);
2660ccea Poul Sander 2023-09-22 19:25 4767
        ref_stack.push_back(val.second);
2660ccea Poul Sander 2023-09-22 19:25 4768
2660ccea Poul Sander 2023-09-22 19:25 4769
        // check array limit
2660ccea Poul Sander 2023-09-22 19:25 4770
        if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2660ccea Poul Sander 2023-09-22 19:25 4771
        {
2660ccea Poul Sander 2023-09-22 19:25 4772
            JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
2660ccea Poul Sander 2023-09-22 19:25 4773
        }
2660ccea Poul Sander 2023-09-22 19:25 4774
2660ccea Poul Sander 2023-09-22 19:25 4775
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4776
    }
2660ccea Poul Sander 2023-09-22 19:25 4777
2660ccea Poul Sander 2023-09-22 19:25 4778
    bool end_array()
2660ccea Poul Sander 2023-09-22 19:25 4779
    {
2660ccea Poul Sander 2023-09-22 19:25 4780
        bool keep = true;
2660ccea Poul Sander 2023-09-22 19:25 4781
2660ccea Poul Sander 2023-09-22 19:25 4782
        if (ref_stack.back())
2660ccea Poul Sander 2023-09-22 19:25 4783
        {
2660ccea Poul Sander 2023-09-22 19:25 4784
            keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
2660ccea Poul Sander 2023-09-22 19:25 4785
            if (not keep)
2660ccea Poul Sander 2023-09-22 19:25 4786
            {
2660ccea Poul Sander 2023-09-22 19:25 4787
                // discard array
2660ccea Poul Sander 2023-09-22 19:25 4788
                *ref_stack.back() = discarded;
2660ccea Poul Sander 2023-09-22 19:25 4789
            }
2660ccea Poul Sander 2023-09-22 19:25 4790
        }
2660ccea Poul Sander 2023-09-22 19:25 4791
2660ccea Poul Sander 2023-09-22 19:25 4792
        assert(not ref_stack.empty());
2660ccea Poul Sander 2023-09-22 19:25 4793
        assert(not keep_stack.empty());
2660ccea Poul Sander 2023-09-22 19:25 4794
        ref_stack.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 4795
        keep_stack.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 4796
2660ccea Poul Sander 2023-09-22 19:25 4797
        // remove discarded value
2660ccea Poul Sander 2023-09-22 19:25 4798
        if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
2660ccea Poul Sander 2023-09-22 19:25 4799
        {
2660ccea Poul Sander 2023-09-22 19:25 4800
            ref_stack.back()->m_value.array->pop_back();
2660ccea Poul Sander 2023-09-22 19:25 4801
        }
2660ccea Poul Sander 2023-09-22 19:25 4802
2660ccea Poul Sander 2023-09-22 19:25 4803
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4804
    }
2660ccea Poul Sander 2023-09-22 19:25 4805
2660ccea Poul Sander 2023-09-22 19:25 4806
    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
2660ccea Poul Sander 2023-09-22 19:25 4807
                     const detail::exception& ex)
2660ccea Poul Sander 2023-09-22 19:25 4808
    {
2660ccea Poul Sander 2023-09-22 19:25 4809
        errored = true;
2660ccea Poul Sander 2023-09-22 19:25 4810
        if (allow_exceptions)
2660ccea Poul Sander 2023-09-22 19:25 4811
        {
2660ccea Poul Sander 2023-09-22 19:25 4812
            // determine the proper exception type from the id
2660ccea Poul Sander 2023-09-22 19:25 4813
            switch ((ex.id / 100) % 100)
2660ccea Poul Sander 2023-09-22 19:25 4814
            {
2660ccea Poul Sander 2023-09-22 19:25 4815
                case 1:
2660ccea Poul Sander 2023-09-22 19:25 4816
                    JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
2660ccea Poul Sander 2023-09-22 19:25 4817
                case 4:
2660ccea Poul Sander 2023-09-22 19:25 4818
                    JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
2660ccea Poul Sander 2023-09-22 19:25 4819
                // LCOV_EXCL_START
2660ccea Poul Sander 2023-09-22 19:25 4820
                case 2:
2660ccea Poul Sander 2023-09-22 19:25 4821
                    JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
2660ccea Poul Sander 2023-09-22 19:25 4822
                case 3:
2660ccea Poul Sander 2023-09-22 19:25 4823
                    JSON_THROW(*static_cast<const detail::type_error*>(&ex));
2660ccea Poul Sander 2023-09-22 19:25 4824
                case 5:
2660ccea Poul Sander 2023-09-22 19:25 4825
                    JSON_THROW(*static_cast<const detail::other_error*>(&ex));
2660ccea Poul Sander 2023-09-22 19:25 4826
                default:
2660ccea Poul Sander 2023-09-22 19:25 4827
                    assert(false);
2660ccea Poul Sander 2023-09-22 19:25 4828
                    // LCOV_EXCL_STOP
2660ccea Poul Sander 2023-09-22 19:25 4829
            }
2660ccea Poul Sander 2023-09-22 19:25 4830
        }
2660ccea Poul Sander 2023-09-22 19:25 4831
        return false;
2660ccea Poul Sander 2023-09-22 19:25 4832
    }
2660ccea Poul Sander 2023-09-22 19:25 4833
2660ccea Poul Sander 2023-09-22 19:25 4834
    constexpr bool is_errored() const
2660ccea Poul Sander 2023-09-22 19:25 4835
    {
2660ccea Poul Sander 2023-09-22 19:25 4836
        return errored;
2660ccea Poul Sander 2023-09-22 19:25 4837
    }
2660ccea Poul Sander 2023-09-22 19:25 4838
2660ccea Poul Sander 2023-09-22 19:25 4839
  private:
2660ccea Poul Sander 2023-09-22 19:25 4840
    /*!
2660ccea Poul Sander 2023-09-22 19:25 4841
    @param[in] v  value to add to the JSON value we build during parsing
2660ccea Poul Sander 2023-09-22 19:25 4842
    @param[in] skip_callback  whether we should skip calling the callback
2660ccea Poul Sander 2023-09-22 19:25 4843
               function; this is required after start_array() and
2660ccea Poul Sander 2023-09-22 19:25 4844
               start_object() SAX events, because otherwise we would call the
2660ccea Poul Sander 2023-09-22 19:25 4845
               callback function with an empty array or object, respectively.
2660ccea Poul Sander 2023-09-22 19:25 4846
2660ccea Poul Sander 2023-09-22 19:25 4847
    @invariant If the ref stack is empty, then the passed value will be the new
2660ccea Poul Sander 2023-09-22 19:25 4848
               root.
2660ccea Poul Sander 2023-09-22 19:25 4849
    @invariant If the ref stack contains a value, then it is an array or an
2660ccea Poul Sander 2023-09-22 19:25 4850
               object to which we can add elements
2660ccea Poul Sander 2023-09-22 19:25 4851
2660ccea Poul Sander 2023-09-22 19:25 4852
    @return pair of boolean (whether value should be kept) and pointer (to the
2660ccea Poul Sander 2023-09-22 19:25 4853
            passed value in the ref_stack hierarchy; nullptr if not kept)
2660ccea Poul Sander 2023-09-22 19:25 4854
    */
2660ccea Poul Sander 2023-09-22 19:25 4855
    template<typename Value>
2660ccea Poul Sander 2023-09-22 19:25 4856
    std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
2660ccea Poul Sander 2023-09-22 19:25 4857
    {
2660ccea Poul Sander 2023-09-22 19:25 4858
        assert(not keep_stack.empty());
2660ccea Poul Sander 2023-09-22 19:25 4859
2660ccea Poul Sander 2023-09-22 19:25 4860
        // do not handle this value if we know it would be added to a discarded
2660ccea Poul Sander 2023-09-22 19:25 4861
        // container
2660ccea Poul Sander 2023-09-22 19:25 4862
        if (not keep_stack.back())
2660ccea Poul Sander 2023-09-22 19:25 4863
        {
2660ccea Poul Sander 2023-09-22 19:25 4864
            return {false, nullptr};
2660ccea Poul Sander 2023-09-22 19:25 4865
        }
2660ccea Poul Sander 2023-09-22 19:25 4866
2660ccea Poul Sander 2023-09-22 19:25 4867
        // create value
2660ccea Poul Sander 2023-09-22 19:25 4868
        auto value = BasicJsonType(std::forward<Value>(v));
2660ccea Poul Sander 2023-09-22 19:25 4869
2660ccea Poul Sander 2023-09-22 19:25 4870
        // check callback
2660ccea Poul Sander 2023-09-22 19:25 4871
        const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
2660ccea Poul Sander 2023-09-22 19:25 4872
2660ccea Poul Sander 2023-09-22 19:25 4873
        // do not handle this value if we just learnt it shall be discarded
2660ccea Poul Sander 2023-09-22 19:25 4874
        if (not keep)
2660ccea Poul Sander 2023-09-22 19:25 4875
        {
2660ccea Poul Sander 2023-09-22 19:25 4876
            return {false, nullptr};
2660ccea Poul Sander 2023-09-22 19:25 4877
        }
2660ccea Poul Sander 2023-09-22 19:25 4878
2660ccea Poul Sander 2023-09-22 19:25 4879
        if (ref_stack.empty())
2660ccea Poul Sander 2023-09-22 19:25 4880
        {
2660ccea Poul Sander 2023-09-22 19:25 4881
            root = std::move(value);
2660ccea Poul Sander 2023-09-22 19:25 4882
            return {true, &root};
2660ccea Poul Sander 2023-09-22 19:25 4883
        }
2660ccea Poul Sander 2023-09-22 19:25 4884
2660ccea Poul Sander 2023-09-22 19:25 4885
        // skip this value if we already decided to skip the parent
2660ccea Poul Sander 2023-09-22 19:25 4886
        // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
2660ccea Poul Sander 2023-09-22 19:25 4887
        if (not ref_stack.back())
2660ccea Poul Sander 2023-09-22 19:25 4888
        {
2660ccea Poul Sander 2023-09-22 19:25 4889
            return {false, nullptr};
2660ccea Poul Sander 2023-09-22 19:25 4890
        }
2660ccea Poul Sander 2023-09-22 19:25 4891
2660ccea Poul Sander 2023-09-22 19:25 4892
        // we now only expect arrays and objects
2660ccea Poul Sander 2023-09-22 19:25 4893
        assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
2660ccea Poul Sander 2023-09-22 19:25 4894
2660ccea Poul Sander 2023-09-22 19:25 4895
        // array
2660ccea Poul Sander 2023-09-22 19:25 4896
        if (ref_stack.back()->is_array())
2660ccea Poul Sander 2023-09-22 19:25 4897
        {
2660ccea Poul Sander 2023-09-22 19:25 4898
            ref_stack.back()->m_value.array->push_back(std::move(value));
2660ccea Poul Sander 2023-09-22 19:25 4899
            return {true, &(ref_stack.back()->m_value.array->back())};
2660ccea Poul Sander 2023-09-22 19:25 4900
        }
2660ccea Poul Sander 2023-09-22 19:25 4901
2660ccea Poul Sander 2023-09-22 19:25 4902
        // object
2660ccea Poul Sander 2023-09-22 19:25 4903
        assert(ref_stack.back()->is_object());
2660ccea Poul Sander 2023-09-22 19:25 4904
        // check if we should store an element for the current key
2660ccea Poul Sander 2023-09-22 19:25 4905
        assert(not key_keep_stack.empty());
2660ccea Poul Sander 2023-09-22 19:25 4906
        const bool store_element = key_keep_stack.back();
2660ccea Poul Sander 2023-09-22 19:25 4907
        key_keep_stack.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 4908
2660ccea Poul Sander 2023-09-22 19:25 4909
        if (not store_element)
2660ccea Poul Sander 2023-09-22 19:25 4910
        {
2660ccea Poul Sander 2023-09-22 19:25 4911
            return {false, nullptr};
2660ccea Poul Sander 2023-09-22 19:25 4912
        }
2660ccea Poul Sander 2023-09-22 19:25 4913
2660ccea Poul Sander 2023-09-22 19:25 4914
        assert(object_element);
2660ccea Poul Sander 2023-09-22 19:25 4915
        *object_element = std::move(value);
2660ccea Poul Sander 2023-09-22 19:25 4916
        return {true, object_element};
2660ccea Poul Sander 2023-09-22 19:25 4917
    }
2660ccea Poul Sander 2023-09-22 19:25 4918
2660ccea Poul Sander 2023-09-22 19:25 4919
    /// the parsed JSON value
2660ccea Poul Sander 2023-09-22 19:25 4920
    BasicJsonType& root;
2660ccea Poul Sander 2023-09-22 19:25 4921
    /// stack to model hierarchy of values
2660ccea Poul Sander 2023-09-22 19:25 4922
    std::vector<BasicJsonType*> ref_stack {};
2660ccea Poul Sander 2023-09-22 19:25 4923
    /// stack to manage which values to keep
2660ccea Poul Sander 2023-09-22 19:25 4924
    std::vector<bool> keep_stack {};
2660ccea Poul Sander 2023-09-22 19:25 4925
    /// stack to manage which object keys to keep
2660ccea Poul Sander 2023-09-22 19:25 4926
    std::vector<bool> key_keep_stack {};
2660ccea Poul Sander 2023-09-22 19:25 4927
    /// helper to hold the reference for the next object element
2660ccea Poul Sander 2023-09-22 19:25 4928
    BasicJsonType* object_element = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 4929
    /// whether a syntax error occurred
2660ccea Poul Sander 2023-09-22 19:25 4930
    bool errored = false;
2660ccea Poul Sander 2023-09-22 19:25 4931
    /// callback function
2660ccea Poul Sander 2023-09-22 19:25 4932
    const parser_callback_t callback = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 4933
    /// whether to throw exceptions in case of errors
2660ccea Poul Sander 2023-09-22 19:25 4934
    const bool allow_exceptions = true;
2660ccea Poul Sander 2023-09-22 19:25 4935
    /// a discarded value for the callback
2660ccea Poul Sander 2023-09-22 19:25 4936
    BasicJsonType discarded = BasicJsonType::value_t::discarded;
2660ccea Poul Sander 2023-09-22 19:25 4937
};
2660ccea Poul Sander 2023-09-22 19:25 4938
2660ccea Poul Sander 2023-09-22 19:25 4939
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 4940
class json_sax_acceptor
2660ccea Poul Sander 2023-09-22 19:25 4941
{
2660ccea Poul Sander 2023-09-22 19:25 4942
  public:
2660ccea Poul Sander 2023-09-22 19:25 4943
    using number_integer_t = typename BasicJsonType::number_integer_t;
2660ccea Poul Sander 2023-09-22 19:25 4944
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2660ccea Poul Sander 2023-09-22 19:25 4945
    using number_float_t = typename BasicJsonType::number_float_t;
2660ccea Poul Sander 2023-09-22 19:25 4946
    using string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 4947
2660ccea Poul Sander 2023-09-22 19:25 4948
    bool null()
2660ccea Poul Sander 2023-09-22 19:25 4949
    {
2660ccea Poul Sander 2023-09-22 19:25 4950
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4951
    }
2660ccea Poul Sander 2023-09-22 19:25 4952
2660ccea Poul Sander 2023-09-22 19:25 4953
    bool boolean(bool /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 4954
    {
2660ccea Poul Sander 2023-09-22 19:25 4955
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4956
    }
2660ccea Poul Sander 2023-09-22 19:25 4957
2660ccea Poul Sander 2023-09-22 19:25 4958
    bool number_integer(number_integer_t /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 4959
    {
2660ccea Poul Sander 2023-09-22 19:25 4960
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4961
    }
2660ccea Poul Sander 2023-09-22 19:25 4962
2660ccea Poul Sander 2023-09-22 19:25 4963
    bool number_unsigned(number_unsigned_t /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 4964
    {
2660ccea Poul Sander 2023-09-22 19:25 4965
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4966
    }
2660ccea Poul Sander 2023-09-22 19:25 4967
2660ccea Poul Sander 2023-09-22 19:25 4968
    bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 4969
    {
2660ccea Poul Sander 2023-09-22 19:25 4970
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4971
    }
2660ccea Poul Sander 2023-09-22 19:25 4972
2660ccea Poul Sander 2023-09-22 19:25 4973
    bool string(string_t& /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 4974
    {
2660ccea Poul Sander 2023-09-22 19:25 4975
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4976
    }
2660ccea Poul Sander 2023-09-22 19:25 4977
2660ccea Poul Sander 2023-09-22 19:25 4978
    bool start_object(std::size_t  /*unused*/ = std::size_t(-1))
2660ccea Poul Sander 2023-09-22 19:25 4979
    {
2660ccea Poul Sander 2023-09-22 19:25 4980
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4981
    }
2660ccea Poul Sander 2023-09-22 19:25 4982
2660ccea Poul Sander 2023-09-22 19:25 4983
    bool key(string_t& /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 4984
    {
2660ccea Poul Sander 2023-09-22 19:25 4985
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4986
    }
2660ccea Poul Sander 2023-09-22 19:25 4987
2660ccea Poul Sander 2023-09-22 19:25 4988
    bool end_object()
2660ccea Poul Sander 2023-09-22 19:25 4989
    {
2660ccea Poul Sander 2023-09-22 19:25 4990
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4991
    }
2660ccea Poul Sander 2023-09-22 19:25 4992
2660ccea Poul Sander 2023-09-22 19:25 4993
    bool start_array(std::size_t  /*unused*/ = std::size_t(-1))
2660ccea Poul Sander 2023-09-22 19:25 4994
    {
2660ccea Poul Sander 2023-09-22 19:25 4995
        return true;
2660ccea Poul Sander 2023-09-22 19:25 4996
    }
2660ccea Poul Sander 2023-09-22 19:25 4997
2660ccea Poul Sander 2023-09-22 19:25 4998
    bool end_array()
2660ccea Poul Sander 2023-09-22 19:25 4999
    {
2660ccea Poul Sander 2023-09-22 19:25 5000
        return true;
2660ccea Poul Sander 2023-09-22 19:25 5001
    }
2660ccea Poul Sander 2023-09-22 19:25 5002
2660ccea Poul Sander 2023-09-22 19:25 5003
    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 5004
    {
2660ccea Poul Sander 2023-09-22 19:25 5005
        return false;
2660ccea Poul Sander 2023-09-22 19:25 5006
    }
2660ccea Poul Sander 2023-09-22 19:25 5007
};
2660ccea Poul Sander 2023-09-22 19:25 5008
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 5009
2660ccea Poul Sander 2023-09-22 19:25 5010
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 5011
2660ccea Poul Sander 2023-09-22 19:25 5012
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 5013
2660ccea Poul Sander 2023-09-22 19:25 5014
// #include <nlohmann/detail/meta/is_sax.hpp>
2660ccea Poul Sander 2023-09-22 19:25 5015
2660ccea Poul Sander 2023-09-22 19:25 5016
2660ccea Poul Sander 2023-09-22 19:25 5017
#include <cstdint> // size_t
2660ccea Poul Sander 2023-09-22 19:25 5018
#include <utility> // declval
2660ccea Poul Sander 2023-09-22 19:25 5019
#include <string> // string
2660ccea Poul Sander 2023-09-22 19:25 5020
2660ccea Poul Sander 2023-09-22 19:25 5021
// #include <nlohmann/detail/meta/detected.hpp>
2660ccea Poul Sander 2023-09-22 19:25 5022
2660ccea Poul Sander 2023-09-22 19:25 5023
// #include <nlohmann/detail/meta/type_traits.hpp>
2660ccea Poul Sander 2023-09-22 19:25 5024
2660ccea Poul Sander 2023-09-22 19:25 5025
2660ccea Poul Sander 2023-09-22 19:25 5026
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 5027
{
2660ccea Poul Sander 2023-09-22 19:25 5028
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 5029
{
2660ccea Poul Sander 2023-09-22 19:25 5030
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 5031
using null_function_t = decltype(std::declval<T&>().null());
2660ccea Poul Sander 2023-09-22 19:25 5032
2660ccea Poul Sander 2023-09-22 19:25 5033
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 5034
using boolean_function_t =
2660ccea Poul Sander 2023-09-22 19:25 5035
    decltype(std::declval<T&>().boolean(std::declval<bool>()));
2660ccea Poul Sander 2023-09-22 19:25 5036
2660ccea Poul Sander 2023-09-22 19:25 5037
template <typename T, typename Integer>
2660ccea Poul Sander 2023-09-22 19:25 5038
using number_integer_function_t =
2660ccea Poul Sander 2023-09-22 19:25 5039
    decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
2660ccea Poul Sander 2023-09-22 19:25 5040
2660ccea Poul Sander 2023-09-22 19:25 5041
template <typename T, typename Unsigned>
2660ccea Poul Sander 2023-09-22 19:25 5042
using number_unsigned_function_t =
2660ccea Poul Sander 2023-09-22 19:25 5043
    decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
2660ccea Poul Sander 2023-09-22 19:25 5044
2660ccea Poul Sander 2023-09-22 19:25 5045
template <typename T, typename Float, typename String>
2660ccea Poul Sander 2023-09-22 19:25 5046
using number_float_function_t = decltype(std::declval<T&>().number_float(
2660ccea Poul Sander 2023-09-22 19:25 5047
                                    std::declval<Float>(), std::declval<const String&>()));
2660ccea Poul Sander 2023-09-22 19:25 5048
2660ccea Poul Sander 2023-09-22 19:25 5049
template <typename T, typename String>
2660ccea Poul Sander 2023-09-22 19:25 5050
using string_function_t =
2660ccea Poul Sander 2023-09-22 19:25 5051
    decltype(std::declval<T&>().string(std::declval<String&>()));
2660ccea Poul Sander 2023-09-22 19:25 5052
2660ccea Poul Sander 2023-09-22 19:25 5053
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 5054
using start_object_function_t =
2660ccea Poul Sander 2023-09-22 19:25 5055
    decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
2660ccea Poul Sander 2023-09-22 19:25 5056
2660ccea Poul Sander 2023-09-22 19:25 5057
template <typename T, typename String>
2660ccea Poul Sander 2023-09-22 19:25 5058
using key_function_t =
2660ccea Poul Sander 2023-09-22 19:25 5059
    decltype(std::declval<T&>().key(std::declval<String&>()));
2660ccea Poul Sander 2023-09-22 19:25 5060
2660ccea Poul Sander 2023-09-22 19:25 5061
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 5062
using end_object_function_t = decltype(std::declval<T&>().end_object());
2660ccea Poul Sander 2023-09-22 19:25 5063
2660ccea Poul Sander 2023-09-22 19:25 5064
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 5065
using start_array_function_t =
2660ccea Poul Sander 2023-09-22 19:25 5066
    decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
2660ccea Poul Sander 2023-09-22 19:25 5067
2660ccea Poul Sander 2023-09-22 19:25 5068
template <typename T>
2660ccea Poul Sander 2023-09-22 19:25 5069
using end_array_function_t = decltype(std::declval<T&>().end_array());
2660ccea Poul Sander 2023-09-22 19:25 5070
2660ccea Poul Sander 2023-09-22 19:25 5071
template <typename T, typename Exception>
2660ccea Poul Sander 2023-09-22 19:25 5072
using parse_error_function_t = decltype(std::declval<T&>().parse_error(
2660ccea Poul Sander 2023-09-22 19:25 5073
        std::declval<std::size_t>(), std::declval<const std::string&>(),
2660ccea Poul Sander 2023-09-22 19:25 5074
        std::declval<const Exception&>()));
2660ccea Poul Sander 2023-09-22 19:25 5075
2660ccea Poul Sander 2023-09-22 19:25 5076
template <typename SAX, typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 5077
struct is_sax
2660ccea Poul Sander 2023-09-22 19:25 5078
{
2660ccea Poul Sander 2023-09-22 19:25 5079
  private:
2660ccea Poul Sander 2023-09-22 19:25 5080
    static_assert(is_basic_json<BasicJsonType>::value,
2660ccea Poul Sander 2023-09-22 19:25 5081
                  "BasicJsonType must be of type basic_json<...>");
2660ccea Poul Sander 2023-09-22 19:25 5082
2660ccea Poul Sander 2023-09-22 19:25 5083
    using number_integer_t = typename BasicJsonType::number_integer_t;
2660ccea Poul Sander 2023-09-22 19:25 5084
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2660ccea Poul Sander 2023-09-22 19:25 5085
    using number_float_t = typename BasicJsonType::number_float_t;
2660ccea Poul Sander 2023-09-22 19:25 5086
    using string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 5087
    using exception_t = typename BasicJsonType::exception;
2660ccea Poul Sander 2023-09-22 19:25 5088
2660ccea Poul Sander 2023-09-22 19:25 5089
  public:
2660ccea Poul Sander 2023-09-22 19:25 5090
    static constexpr bool value =
2660ccea Poul Sander 2023-09-22 19:25 5091
        is_detected_exact<bool, null_function_t, SAX>::value &&
2660ccea Poul Sander 2023-09-22 19:25 5092
        is_detected_exact<bool, boolean_function_t, SAX>::value &&
2660ccea Poul Sander 2023-09-22 19:25 5093
        is_detected_exact<bool, number_integer_function_t, SAX,
2660ccea Poul Sander 2023-09-22 19:25 5094
        number_integer_t>::value &&
2660ccea Poul Sander 2023-09-22 19:25 5095
        is_detected_exact<bool, number_unsigned_function_t, SAX,
2660ccea Poul Sander 2023-09-22 19:25 5096
        number_unsigned_t>::value &&
2660ccea Poul Sander 2023-09-22 19:25 5097
        is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
2660ccea Poul Sander 2023-09-22 19:25 5098
        string_t>::value &&
2660ccea Poul Sander 2023-09-22 19:25 5099
        is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
2660ccea Poul Sander 2023-09-22 19:25 5100
        is_detected_exact<bool, start_object_function_t, SAX>::value &&
2660ccea Poul Sander 2023-09-22 19:25 5101
        is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
2660ccea Poul Sander 2023-09-22 19:25 5102
        is_detected_exact<bool, end_object_function_t, SAX>::value &&
2660ccea Poul Sander 2023-09-22 19:25 5103
        is_detected_exact<bool, start_array_function_t, SAX>::value &&
2660ccea Poul Sander 2023-09-22 19:25 5104
        is_detected_exact<bool, end_array_function_t, SAX>::value &&
2660ccea Poul Sander 2023-09-22 19:25 5105
        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
2660ccea Poul Sander 2023-09-22 19:25 5106
};
2660ccea Poul Sander 2023-09-22 19:25 5107
2660ccea Poul Sander 2023-09-22 19:25 5108
template <typename SAX, typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 5109
struct is_sax_static_asserts
2660ccea Poul Sander 2023-09-22 19:25 5110
{
2660ccea Poul Sander 2023-09-22 19:25 5111
  private:
2660ccea Poul Sander 2023-09-22 19:25 5112
    static_assert(is_basic_json<BasicJsonType>::value,
2660ccea Poul Sander 2023-09-22 19:25 5113
                  "BasicJsonType must be of type basic_json<...>");
2660ccea Poul Sander 2023-09-22 19:25 5114
2660ccea Poul Sander 2023-09-22 19:25 5115
    using number_integer_t = typename BasicJsonType::number_integer_t;
2660ccea Poul Sander 2023-09-22 19:25 5116
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2660ccea Poul Sander 2023-09-22 19:25 5117
    using number_float_t = typename BasicJsonType::number_float_t;
2660ccea Poul Sander 2023-09-22 19:25 5118
    using string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 5119
    using exception_t = typename BasicJsonType::exception;
2660ccea Poul Sander 2023-09-22 19:25 5120
2660ccea Poul Sander 2023-09-22 19:25 5121
  public:
2660ccea Poul Sander 2023-09-22 19:25 5122
    static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
2660ccea Poul Sander 2023-09-22 19:25 5123
                  "Missing/invalid function: bool null()");
2660ccea Poul Sander 2023-09-22 19:25 5124
    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
2660ccea Poul Sander 2023-09-22 19:25 5125
                  "Missing/invalid function: bool boolean(bool)");
2660ccea Poul Sander 2023-09-22 19:25 5126
    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
2660ccea Poul Sander 2023-09-22 19:25 5127
                  "Missing/invalid function: bool boolean(bool)");
2660ccea Poul Sander 2023-09-22 19:25 5128
    static_assert(
2660ccea Poul Sander 2023-09-22 19:25 5129
        is_detected_exact<bool, number_integer_function_t, SAX,
2660ccea Poul Sander 2023-09-22 19:25 5130
        number_integer_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 5131
        "Missing/invalid function: bool number_integer(number_integer_t)");
2660ccea Poul Sander 2023-09-22 19:25 5132
    static_assert(
2660ccea Poul Sander 2023-09-22 19:25 5133
        is_detected_exact<bool, number_unsigned_function_t, SAX,
2660ccea Poul Sander 2023-09-22 19:25 5134
        number_unsigned_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 5135
        "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
2660ccea Poul Sander 2023-09-22 19:25 5136
    static_assert(is_detected_exact<bool, number_float_function_t, SAX,
2660ccea Poul Sander 2023-09-22 19:25 5137
                  number_float_t, string_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 5138
                  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
2660ccea Poul Sander 2023-09-22 19:25 5139
    static_assert(
2660ccea Poul Sander 2023-09-22 19:25 5140
        is_detected_exact<bool, string_function_t, SAX, string_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 5141
        "Missing/invalid function: bool string(string_t&)");
2660ccea Poul Sander 2023-09-22 19:25 5142
    static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
2660ccea Poul Sander 2023-09-22 19:25 5143
                  "Missing/invalid function: bool start_object(std::size_t)");
2660ccea Poul Sander 2023-09-22 19:25 5144
    static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 5145
                  "Missing/invalid function: bool key(string_t&)");
2660ccea Poul Sander 2023-09-22 19:25 5146
    static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
2660ccea Poul Sander 2023-09-22 19:25 5147
                  "Missing/invalid function: bool end_object()");
2660ccea Poul Sander 2023-09-22 19:25 5148
    static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
2660ccea Poul Sander 2023-09-22 19:25 5149
                  "Missing/invalid function: bool start_array(std::size_t)");
2660ccea Poul Sander 2023-09-22 19:25 5150
    static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
2660ccea Poul Sander 2023-09-22 19:25 5151
                  "Missing/invalid function: bool end_array()");
2660ccea Poul Sander 2023-09-22 19:25 5152
    static_assert(
2660ccea Poul Sander 2023-09-22 19:25 5153
        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 5154
        "Missing/invalid function: bool parse_error(std::size_t, const "
2660ccea Poul Sander 2023-09-22 19:25 5155
        "std::string&, const exception&)");
2660ccea Poul Sander 2023-09-22 19:25 5156
};
2660ccea Poul Sander 2023-09-22 19:25 5157
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 5158
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 5159
2660ccea Poul Sander 2023-09-22 19:25 5160
// #include <nlohmann/detail/value_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 5161
2660ccea Poul Sander 2023-09-22 19:25 5162
2660ccea Poul Sander 2023-09-22 19:25 5163
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 5164
{
2660ccea Poul Sander 2023-09-22 19:25 5165
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 5166
{
2660ccea Poul Sander 2023-09-22 19:25 5167
///////////////////
2660ccea Poul Sander 2023-09-22 19:25 5168
// binary reader //
2660ccea Poul Sander 2023-09-22 19:25 5169
///////////////////
2660ccea Poul Sander 2023-09-22 19:25 5170
2660ccea Poul Sander 2023-09-22 19:25 5171
/*!
2660ccea Poul Sander 2023-09-22 19:25 5172
@brief deserialization of CBOR, MessagePack, and UBJSON values
2660ccea Poul Sander 2023-09-22 19:25 5173
*/
2660ccea Poul Sander 2023-09-22 19:25 5174
template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
2660ccea Poul Sander 2023-09-22 19:25 5175
class binary_reader
2660ccea Poul Sander 2023-09-22 19:25 5176
{
2660ccea Poul Sander 2023-09-22 19:25 5177
    using number_integer_t = typename BasicJsonType::number_integer_t;
2660ccea Poul Sander 2023-09-22 19:25 5178
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2660ccea Poul Sander 2023-09-22 19:25 5179
    using number_float_t = typename BasicJsonType::number_float_t;
2660ccea Poul Sander 2023-09-22 19:25 5180
    using string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 5181
    using json_sax_t = SAX;
2660ccea Poul Sander 2023-09-22 19:25 5182
2660ccea Poul Sander 2023-09-22 19:25 5183
  public:
2660ccea Poul Sander 2023-09-22 19:25 5184
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5185
    @brief create a binary reader
2660ccea Poul Sander 2023-09-22 19:25 5186
2660ccea Poul Sander 2023-09-22 19:25 5187
    @param[in] adapter  input adapter to read from
2660ccea Poul Sander 2023-09-22 19:25 5188
    */
2660ccea Poul Sander 2023-09-22 19:25 5189
    explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
2660ccea Poul Sander 2023-09-22 19:25 5190
    {
2660ccea Poul Sander 2023-09-22 19:25 5191
        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
2660ccea Poul Sander 2023-09-22 19:25 5192
        assert(ia);
2660ccea Poul Sander 2023-09-22 19:25 5193
    }
2660ccea Poul Sander 2023-09-22 19:25 5194
2660ccea Poul Sander 2023-09-22 19:25 5195
    // make class move-only
2660ccea Poul Sander 2023-09-22 19:25 5196
    binary_reader(const binary_reader&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 5197
    binary_reader(binary_reader&&) = default;
2660ccea Poul Sander 2023-09-22 19:25 5198
    binary_reader& operator=(const binary_reader&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 5199
    binary_reader& operator=(binary_reader&&) = default;
2660ccea Poul Sander 2023-09-22 19:25 5200
    ~binary_reader() = default;
2660ccea Poul Sander 2023-09-22 19:25 5201
2660ccea Poul Sander 2023-09-22 19:25 5202
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5203
    @param[in] format  the binary format to parse
2660ccea Poul Sander 2023-09-22 19:25 5204
    @param[in] sax_    a SAX event processor
2660ccea Poul Sander 2023-09-22 19:25 5205
    @param[in] strict  whether to expect the input to be consumed completed
2660ccea Poul Sander 2023-09-22 19:25 5206
2660ccea Poul Sander 2023-09-22 19:25 5207
    @return
2660ccea Poul Sander 2023-09-22 19:25 5208
    */
2660ccea Poul Sander 2023-09-22 19:25 5209
    JSON_HEDLEY_NON_NULL(3)
2660ccea Poul Sander 2023-09-22 19:25 5210
    bool sax_parse(const input_format_t format,
2660ccea Poul Sander 2023-09-22 19:25 5211
                   json_sax_t* sax_,
2660ccea Poul Sander 2023-09-22 19:25 5212
                   const bool strict = true)
2660ccea Poul Sander 2023-09-22 19:25 5213
    {
2660ccea Poul Sander 2023-09-22 19:25 5214
        sax = sax_;
2660ccea Poul Sander 2023-09-22 19:25 5215
        bool result = false;
2660ccea Poul Sander 2023-09-22 19:25 5216
2660ccea Poul Sander 2023-09-22 19:25 5217
        switch (format)
2660ccea Poul Sander 2023-09-22 19:25 5218
        {
2660ccea Poul Sander 2023-09-22 19:25 5219
            case input_format_t::bson:
2660ccea Poul Sander 2023-09-22 19:25 5220
                result = parse_bson_internal();
2660ccea Poul Sander 2023-09-22 19:25 5221
                break;
2660ccea Poul Sander 2023-09-22 19:25 5222
2660ccea Poul Sander 2023-09-22 19:25 5223
            case input_format_t::cbor:
2660ccea Poul Sander 2023-09-22 19:25 5224
                result = parse_cbor_internal();
2660ccea Poul Sander 2023-09-22 19:25 5225
                break;
2660ccea Poul Sander 2023-09-22 19:25 5226
2660ccea Poul Sander 2023-09-22 19:25 5227
            case input_format_t::msgpack:
2660ccea Poul Sander 2023-09-22 19:25 5228
                result = parse_msgpack_internal();
2660ccea Poul Sander 2023-09-22 19:25 5229
                break;
2660ccea Poul Sander 2023-09-22 19:25 5230
2660ccea Poul Sander 2023-09-22 19:25 5231
            case input_format_t::ubjson:
2660ccea Poul Sander 2023-09-22 19:25 5232
                result = parse_ubjson_internal();
2660ccea Poul Sander 2023-09-22 19:25 5233
                break;
2660ccea Poul Sander 2023-09-22 19:25 5234
2660ccea Poul Sander 2023-09-22 19:25 5235
            default:            // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 5236
                assert(false);  // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 5237
        }
2660ccea Poul Sander 2023-09-22 19:25 5238
2660ccea Poul Sander 2023-09-22 19:25 5239
        // strict mode: next byte must be EOF
2660ccea Poul Sander 2023-09-22 19:25 5240
        if (result and strict)
2660ccea Poul Sander 2023-09-22 19:25 5241
        {
2660ccea Poul Sander 2023-09-22 19:25 5242
            if (format == input_format_t::ubjson)
2660ccea Poul Sander 2023-09-22 19:25 5243
            {
2660ccea Poul Sander 2023-09-22 19:25 5244
                get_ignore_noop();
2660ccea Poul Sander 2023-09-22 19:25 5245
            }
2660ccea Poul Sander 2023-09-22 19:25 5246
            else
2660ccea Poul Sander 2023-09-22 19:25 5247
            {
2660ccea Poul Sander 2023-09-22 19:25 5248
                get();
2660ccea Poul Sander 2023-09-22 19:25 5249
            }
2660ccea Poul Sander 2023-09-22 19:25 5250
2660ccea Poul Sander 2023-09-22 19:25 5251
            if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char>::eof()))
2660ccea Poul Sander 2023-09-22 19:25 5252
            {
2660ccea Poul Sander 2023-09-22 19:25 5253
                return sax->parse_error(chars_read, get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 5254
                                        parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
2660ccea Poul Sander 2023-09-22 19:25 5255
            }
2660ccea Poul Sander 2023-09-22 19:25 5256
        }
2660ccea Poul Sander 2023-09-22 19:25 5257
2660ccea Poul Sander 2023-09-22 19:25 5258
        return result;
2660ccea Poul Sander 2023-09-22 19:25 5259
    }
2660ccea Poul Sander 2023-09-22 19:25 5260
2660ccea Poul Sander 2023-09-22 19:25 5261
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5262
    @brief determine system byte order
2660ccea Poul Sander 2023-09-22 19:25 5263
2660ccea Poul Sander 2023-09-22 19:25 5264
    @return true if and only if system's byte order is little endian
2660ccea Poul Sander 2023-09-22 19:25 5265
2660ccea Poul Sander 2023-09-22 19:25 5266
    @note from http://stackoverflow.com/a/1001328/266378
2660ccea Poul Sander 2023-09-22 19:25 5267
    */
2660ccea Poul Sander 2023-09-22 19:25 5268
    static constexpr bool little_endianess(int num = 1) noexcept
2660ccea Poul Sander 2023-09-22 19:25 5269
    {
2660ccea Poul Sander 2023-09-22 19:25 5270
        return *reinterpret_cast<char*>(&num) == 1;
2660ccea Poul Sander 2023-09-22 19:25 5271
    }
2660ccea Poul Sander 2023-09-22 19:25 5272
2660ccea Poul Sander 2023-09-22 19:25 5273
  private:
2660ccea Poul Sander 2023-09-22 19:25 5274
    //////////
2660ccea Poul Sander 2023-09-22 19:25 5275
    // BSON //
2660ccea Poul Sander 2023-09-22 19:25 5276
    //////////
2660ccea Poul Sander 2023-09-22 19:25 5277
2660ccea Poul Sander 2023-09-22 19:25 5278
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5279
    @brief Reads in a BSON-object and passes it to the SAX-parser.
2660ccea Poul Sander 2023-09-22 19:25 5280
    @return whether a valid BSON-value was passed to the SAX parser
2660ccea Poul Sander 2023-09-22 19:25 5281
    */
2660ccea Poul Sander 2023-09-22 19:25 5282
    bool parse_bson_internal()
2660ccea Poul Sander 2023-09-22 19:25 5283
    {
2660ccea Poul Sander 2023-09-22 19:25 5284
        std::int32_t document_size;
2660ccea Poul Sander 2023-09-22 19:25 5285
        get_number<std::int32_t, true>(input_format_t::bson, document_size);
2660ccea Poul Sander 2023-09-22 19:25 5286
2660ccea Poul Sander 2023-09-22 19:25 5287
        if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
2660ccea Poul Sander 2023-09-22 19:25 5288
        {
2660ccea Poul Sander 2023-09-22 19:25 5289
            return false;
2660ccea Poul Sander 2023-09-22 19:25 5290
        }
2660ccea Poul Sander 2023-09-22 19:25 5291
2660ccea Poul Sander 2023-09-22 19:25 5292
        if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
2660ccea Poul Sander 2023-09-22 19:25 5293
        {
2660ccea Poul Sander 2023-09-22 19:25 5294
            return false;
2660ccea Poul Sander 2023-09-22 19:25 5295
        }
2660ccea Poul Sander 2023-09-22 19:25 5296
2660ccea Poul Sander 2023-09-22 19:25 5297
        return sax->end_object();
2660ccea Poul Sander 2023-09-22 19:25 5298
    }
2660ccea Poul Sander 2023-09-22 19:25 5299
2660ccea Poul Sander 2023-09-22 19:25 5300
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5301
    @brief Parses a C-style string from the BSON input.
2660ccea Poul Sander 2023-09-22 19:25 5302
    @param[in, out] result  A reference to the string variable where the read
2660ccea Poul Sander 2023-09-22 19:25 5303
                            string is to be stored.
2660ccea Poul Sander 2023-09-22 19:25 5304
    @return `true` if the \x00-byte indicating the end of the string was
2660ccea Poul Sander 2023-09-22 19:25 5305
             encountered before the EOF; false` indicates an unexpected EOF.
2660ccea Poul Sander 2023-09-22 19:25 5306
    */
2660ccea Poul Sander 2023-09-22 19:25 5307
    bool get_bson_cstr(string_t& result)
2660ccea Poul Sander 2023-09-22 19:25 5308
    {
2660ccea Poul Sander 2023-09-22 19:25 5309
        auto out = std::back_inserter(result);
2660ccea Poul Sander 2023-09-22 19:25 5310
        while (true)
2660ccea Poul Sander 2023-09-22 19:25 5311
        {
2660ccea Poul Sander 2023-09-22 19:25 5312
            get();
2660ccea Poul Sander 2023-09-22 19:25 5313
            if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
2660ccea Poul Sander 2023-09-22 19:25 5314
            {
2660ccea Poul Sander 2023-09-22 19:25 5315
                return false;
2660ccea Poul Sander 2023-09-22 19:25 5316
            }
2660ccea Poul Sander 2023-09-22 19:25 5317
            if (current == 0x00)
2660ccea Poul Sander 2023-09-22 19:25 5318
            {
2660ccea Poul Sander 2023-09-22 19:25 5319
                return true;
2660ccea Poul Sander 2023-09-22 19:25 5320
            }
2660ccea Poul Sander 2023-09-22 19:25 5321
            *out++ = static_cast<char>(current);
2660ccea Poul Sander 2023-09-22 19:25 5322
        }
2660ccea Poul Sander 2023-09-22 19:25 5323
2660ccea Poul Sander 2023-09-22 19:25 5324
        return true;
2660ccea Poul Sander 2023-09-22 19:25 5325
    }
2660ccea Poul Sander 2023-09-22 19:25 5326
2660ccea Poul Sander 2023-09-22 19:25 5327
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5328
    @brief Parses a zero-terminated string of length @a len from the BSON
2660ccea Poul Sander 2023-09-22 19:25 5329
           input.
2660ccea Poul Sander 2023-09-22 19:25 5330
    @param[in] len  The length (including the zero-byte at the end) of the
2660ccea Poul Sander 2023-09-22 19:25 5331
                    string to be read.
2660ccea Poul Sander 2023-09-22 19:25 5332
    @param[in, out] result  A reference to the string variable where the read
2660ccea Poul Sander 2023-09-22 19:25 5333
                            string is to be stored.
2660ccea Poul Sander 2023-09-22 19:25 5334
    @tparam NumberType The type of the length @a len
2660ccea Poul Sander 2023-09-22 19:25 5335
    @pre len >= 1
2660ccea Poul Sander 2023-09-22 19:25 5336
    @return `true` if the string was successfully parsed
2660ccea Poul Sander 2023-09-22 19:25 5337
    */
2660ccea Poul Sander 2023-09-22 19:25 5338
    template<typename NumberType>
2660ccea Poul Sander 2023-09-22 19:25 5339
    bool get_bson_string(const NumberType len, string_t& result)
2660ccea Poul Sander 2023-09-22 19:25 5340
    {
2660ccea Poul Sander 2023-09-22 19:25 5341
        if (JSON_HEDLEY_UNLIKELY(len < 1))
2660ccea Poul Sander 2023-09-22 19:25 5342
        {
2660ccea Poul Sander 2023-09-22 19:25 5343
            auto last_token = get_token_string();
2660ccea Poul Sander 2023-09-22 19:25 5344
            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")));
2660ccea Poul Sander 2023-09-22 19:25 5345
        }
2660ccea Poul Sander 2023-09-22 19:25 5346
2660ccea Poul Sander 2023-09-22 19:25 5347
        return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof();
2660ccea Poul Sander 2023-09-22 19:25 5348
    }
2660ccea Poul Sander 2023-09-22 19:25 5349
2660ccea Poul Sander 2023-09-22 19:25 5350
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5351
    @brief Read a BSON document element of the given @a element_type.
2660ccea Poul Sander 2023-09-22 19:25 5352
    @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
2660ccea Poul Sander 2023-09-22 19:25 5353
    @param[in] element_type_parse_position The position in the input stream,
2660ccea Poul Sander 2023-09-22 19:25 5354
               where the `element_type` was read.
2660ccea Poul Sander 2023-09-22 19:25 5355
    @warning Not all BSON element types are supported yet. An unsupported
2660ccea Poul Sander 2023-09-22 19:25 5356
             @a element_type will give rise to a parse_error.114:
2660ccea Poul Sander 2023-09-22 19:25 5357
             Unsupported BSON record type 0x...
2660ccea Poul Sander 2023-09-22 19:25 5358
    @return whether a valid BSON-object/array was passed to the SAX parser
2660ccea Poul Sander 2023-09-22 19:25 5359
    */
2660ccea Poul Sander 2023-09-22 19:25 5360
    bool parse_bson_element_internal(const int element_type,
2660ccea Poul Sander 2023-09-22 19:25 5361
                                     const std::size_t element_type_parse_position)
2660ccea Poul Sander 2023-09-22 19:25 5362
    {
2660ccea Poul Sander 2023-09-22 19:25 5363
        switch (element_type)
2660ccea Poul Sander 2023-09-22 19:25 5364
        {
2660ccea Poul Sander 2023-09-22 19:25 5365
            case 0x01: // double
2660ccea Poul Sander 2023-09-22 19:25 5366
            {
2660ccea Poul Sander 2023-09-22 19:25 5367
                double number;
2660ccea Poul Sander 2023-09-22 19:25 5368
                return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
2660ccea Poul Sander 2023-09-22 19:25 5369
            }
2660ccea Poul Sander 2023-09-22 19:25 5370
2660ccea Poul Sander 2023-09-22 19:25 5371
            case 0x02: // string
2660ccea Poul Sander 2023-09-22 19:25 5372
            {
2660ccea Poul Sander 2023-09-22 19:25 5373
                std::int32_t len;
2660ccea Poul Sander 2023-09-22 19:25 5374
                string_t value;
2660ccea Poul Sander 2023-09-22 19:25 5375
                return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
2660ccea Poul Sander 2023-09-22 19:25 5376
            }
2660ccea Poul Sander 2023-09-22 19:25 5377
2660ccea Poul Sander 2023-09-22 19:25 5378
            case 0x03: // object
2660ccea Poul Sander 2023-09-22 19:25 5379
            {
2660ccea Poul Sander 2023-09-22 19:25 5380
                return parse_bson_internal();
2660ccea Poul Sander 2023-09-22 19:25 5381
            }
2660ccea Poul Sander 2023-09-22 19:25 5382
2660ccea Poul Sander 2023-09-22 19:25 5383
            case 0x04: // array
2660ccea Poul Sander 2023-09-22 19:25 5384
            {
2660ccea Poul Sander 2023-09-22 19:25 5385
                return parse_bson_array();
2660ccea Poul Sander 2023-09-22 19:25 5386
            }
2660ccea Poul Sander 2023-09-22 19:25 5387
2660ccea Poul Sander 2023-09-22 19:25 5388
            case 0x08: // boolean
2660ccea Poul Sander 2023-09-22 19:25 5389
            {
2660ccea Poul Sander 2023-09-22 19:25 5390
                return sax->boolean(get() != 0);
2660ccea Poul Sander 2023-09-22 19:25 5391
            }
2660ccea Poul Sander 2023-09-22 19:25 5392
2660ccea Poul Sander 2023-09-22 19:25 5393
            case 0x0A: // null
2660ccea Poul Sander 2023-09-22 19:25 5394
            {
2660ccea Poul Sander 2023-09-22 19:25 5395
                return sax->null();
2660ccea Poul Sander 2023-09-22 19:25 5396
            }
2660ccea Poul Sander 2023-09-22 19:25 5397
2660ccea Poul Sander 2023-09-22 19:25 5398
            case 0x10: // int32
2660ccea Poul Sander 2023-09-22 19:25 5399
            {
2660ccea Poul Sander 2023-09-22 19:25 5400
                std::int32_t value;
2660ccea Poul Sander 2023-09-22 19:25 5401
                return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
2660ccea Poul Sander 2023-09-22 19:25 5402
            }
2660ccea Poul Sander 2023-09-22 19:25 5403
2660ccea Poul Sander 2023-09-22 19:25 5404
            case 0x12: // int64
2660ccea Poul Sander 2023-09-22 19:25 5405
            {
2660ccea Poul Sander 2023-09-22 19:25 5406
                std::int64_t value;
2660ccea Poul Sander 2023-09-22 19:25 5407
                return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
2660ccea Poul Sander 2023-09-22 19:25 5408
            }
2660ccea Poul Sander 2023-09-22 19:25 5409
2660ccea Poul Sander 2023-09-22 19:25 5410
            default: // anything else not supported (yet)
2660ccea Poul Sander 2023-09-22 19:25 5411
            {
2660ccea Poul Sander 2023-09-22 19:25 5412
                std::array<char, 3> cr{{}};
2660ccea Poul Sander 2023-09-22 19:25 5413
                (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
2660ccea Poul Sander 2023-09-22 19:25 5414
                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())));
2660ccea Poul Sander 2023-09-22 19:25 5415
            }
2660ccea Poul Sander 2023-09-22 19:25 5416
        }
2660ccea Poul Sander 2023-09-22 19:25 5417
    }
2660ccea Poul Sander 2023-09-22 19:25 5418
2660ccea Poul Sander 2023-09-22 19:25 5419
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5420
    @brief Read a BSON element list (as specified in the BSON-spec)
2660ccea Poul Sander 2023-09-22 19:25 5421
2660ccea Poul Sander 2023-09-22 19:25 5422
    The same binary layout is used for objects and arrays, hence it must be
2660ccea Poul Sander 2023-09-22 19:25 5423
    indicated with the argument @a is_array which one is expected
2660ccea Poul Sander 2023-09-22 19:25 5424
    (true --> array, false --> object).
2660ccea Poul Sander 2023-09-22 19:25 5425
2660ccea Poul Sander 2023-09-22 19:25 5426
    @param[in] is_array Determines if the element list being read is to be
2660ccea Poul Sander 2023-09-22 19:25 5427
                        treated as an object (@a is_array == false), or as an
2660ccea Poul Sander 2023-09-22 19:25 5428
                        array (@a is_array == true).
2660ccea Poul Sander 2023-09-22 19:25 5429
    @return whether a valid BSON-object/array was passed to the SAX parser
2660ccea Poul Sander 2023-09-22 19:25 5430
    */
2660ccea Poul Sander 2023-09-22 19:25 5431
    bool parse_bson_element_list(const bool is_array)
2660ccea Poul Sander 2023-09-22 19:25 5432
    {
2660ccea Poul Sander 2023-09-22 19:25 5433
        string_t key;
2660ccea Poul Sander 2023-09-22 19:25 5434
        while (int element_type = get())
2660ccea Poul Sander 2023-09-22 19:25 5435
        {
2660ccea Poul Sander 2023-09-22 19:25 5436
            if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
2660ccea Poul Sander 2023-09-22 19:25 5437
            {
2660ccea Poul Sander 2023-09-22 19:25 5438
                return false;
2660ccea Poul Sander 2023-09-22 19:25 5439
            }
2660ccea Poul Sander 2023-09-22 19:25 5440
2660ccea Poul Sander 2023-09-22 19:25 5441
            const std::size_t element_type_parse_position = chars_read;
2660ccea Poul Sander 2023-09-22 19:25 5442
            if (JSON_HEDLEY_UNLIKELY(not get_bson_cstr(key)))
2660ccea Poul Sander 2023-09-22 19:25 5443
            {
2660ccea Poul Sander 2023-09-22 19:25 5444
                return false;
2660ccea Poul Sander 2023-09-22 19:25 5445
            }
2660ccea Poul Sander 2023-09-22 19:25 5446
2660ccea Poul Sander 2023-09-22 19:25 5447
            if (not is_array and not sax->key(key))
2660ccea Poul Sander 2023-09-22 19:25 5448
            {
2660ccea Poul Sander 2023-09-22 19:25 5449
                return false;
2660ccea Poul Sander 2023-09-22 19:25 5450
            }
2660ccea Poul Sander 2023-09-22 19:25 5451
2660ccea Poul Sander 2023-09-22 19:25 5452
            if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
2660ccea Poul Sander 2023-09-22 19:25 5453
            {
2660ccea Poul Sander 2023-09-22 19:25 5454
                return false;
2660ccea Poul Sander 2023-09-22 19:25 5455
            }
2660ccea Poul Sander 2023-09-22 19:25 5456
2660ccea Poul Sander 2023-09-22 19:25 5457
            // get_bson_cstr only appends
2660ccea Poul Sander 2023-09-22 19:25 5458
            key.clear();
2660ccea Poul Sander 2023-09-22 19:25 5459
        }
2660ccea Poul Sander 2023-09-22 19:25 5460
2660ccea Poul Sander 2023-09-22 19:25 5461
        return true;
2660ccea Poul Sander 2023-09-22 19:25 5462
    }
2660ccea Poul Sander 2023-09-22 19:25 5463
2660ccea Poul Sander 2023-09-22 19:25 5464
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5465
    @brief Reads an array from the BSON input and passes it to the SAX-parser.
2660ccea Poul Sander 2023-09-22 19:25 5466
    @return whether a valid BSON-array was passed to the SAX parser
2660ccea Poul Sander 2023-09-22 19:25 5467
    */
2660ccea Poul Sander 2023-09-22 19:25 5468
    bool parse_bson_array()
2660ccea Poul Sander 2023-09-22 19:25 5469
    {
2660ccea Poul Sander 2023-09-22 19:25 5470
        std::int32_t document_size;
2660ccea Poul Sander 2023-09-22 19:25 5471
        get_number<std::int32_t, true>(input_format_t::bson, document_size);
2660ccea Poul Sander 2023-09-22 19:25 5472
2660ccea Poul Sander 2023-09-22 19:25 5473
        if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
2660ccea Poul Sander 2023-09-22 19:25 5474
        {
2660ccea Poul Sander 2023-09-22 19:25 5475
            return false;
2660ccea Poul Sander 2023-09-22 19:25 5476
        }
2660ccea Poul Sander 2023-09-22 19:25 5477
2660ccea Poul Sander 2023-09-22 19:25 5478
        if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
2660ccea Poul Sander 2023-09-22 19:25 5479
        {
2660ccea Poul Sander 2023-09-22 19:25 5480
            return false;
2660ccea Poul Sander 2023-09-22 19:25 5481
        }
2660ccea Poul Sander 2023-09-22 19:25 5482
2660ccea Poul Sander 2023-09-22 19:25 5483
        return sax->end_array();
2660ccea Poul Sander 2023-09-22 19:25 5484
    }
2660ccea Poul Sander 2023-09-22 19:25 5485
2660ccea Poul Sander 2023-09-22 19:25 5486
    //////////
2660ccea Poul Sander 2023-09-22 19:25 5487
    // CBOR //
2660ccea Poul Sander 2023-09-22 19:25 5488
    //////////
2660ccea Poul Sander 2023-09-22 19:25 5489
2660ccea Poul Sander 2023-09-22 19:25 5490
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5491
    @param[in] get_char  whether a new character should be retrieved from the
2660ccea Poul Sander 2023-09-22 19:25 5492
                         input (true, default) or whether the last read
2660ccea Poul Sander 2023-09-22 19:25 5493
                         character should be considered instead
2660ccea Poul Sander 2023-09-22 19:25 5494
2660ccea Poul Sander 2023-09-22 19:25 5495
    @return whether a valid CBOR value was passed to the SAX parser
2660ccea Poul Sander 2023-09-22 19:25 5496
    */
2660ccea Poul Sander 2023-09-22 19:25 5497
    bool parse_cbor_internal(const bool get_char = true)
2660ccea Poul Sander 2023-09-22 19:25 5498
    {
2660ccea Poul Sander 2023-09-22 19:25 5499
        switch (get_char ? get() : current)
2660ccea Poul Sander 2023-09-22 19:25 5500
        {
2660ccea Poul Sander 2023-09-22 19:25 5501
            // EOF
2660ccea Poul Sander 2023-09-22 19:25 5502
            case std::char_traits<char>::eof():
2660ccea Poul Sander 2023-09-22 19:25 5503
                return unexpect_eof(input_format_t::cbor, "value");
2660ccea Poul Sander 2023-09-22 19:25 5504
2660ccea Poul Sander 2023-09-22 19:25 5505
            // Integer 0x00..0x17 (0..23)
2660ccea Poul Sander 2023-09-22 19:25 5506
            case 0x00:
2660ccea Poul Sander 2023-09-22 19:25 5507
            case 0x01:
2660ccea Poul Sander 2023-09-22 19:25 5508
            case 0x02:
2660ccea Poul Sander 2023-09-22 19:25 5509
            case 0x03:
2660ccea Poul Sander 2023-09-22 19:25 5510
            case 0x04:
2660ccea Poul Sander 2023-09-22 19:25 5511
            case 0x05:
2660ccea Poul Sander 2023-09-22 19:25 5512
            case 0x06:
2660ccea Poul Sander 2023-09-22 19:25 5513
            case 0x07:
2660ccea Poul Sander 2023-09-22 19:25 5514
            case 0x08:
2660ccea Poul Sander 2023-09-22 19:25 5515
            case 0x09:
2660ccea Poul Sander 2023-09-22 19:25 5516
            case 0x0A:
2660ccea Poul Sander 2023-09-22 19:25 5517
            case 0x0B:
2660ccea Poul Sander 2023-09-22 19:25 5518
            case 0x0C:
2660ccea Poul Sander 2023-09-22 19:25 5519
            case 0x0D:
2660ccea Poul Sander 2023-09-22 19:25 5520
            case 0x0E:
2660ccea Poul Sander 2023-09-22 19:25 5521
            case 0x0F:
2660ccea Poul Sander 2023-09-22 19:25 5522
            case 0x10:
2660ccea Poul Sander 2023-09-22 19:25 5523
            case 0x11:
2660ccea Poul Sander 2023-09-22 19:25 5524
            case 0x12:
2660ccea Poul Sander 2023-09-22 19:25 5525
            case 0x13:
2660ccea Poul Sander 2023-09-22 19:25 5526
            case 0x14:
2660ccea Poul Sander 2023-09-22 19:25 5527
            case 0x15:
2660ccea Poul Sander 2023-09-22 19:25 5528
            case 0x16:
2660ccea Poul Sander 2023-09-22 19:25 5529
            case 0x17:
2660ccea Poul Sander 2023-09-22 19:25 5530
                return sax->number_unsigned(static_cast<number_unsigned_t>(current));
2660ccea Poul Sander 2023-09-22 19:25 5531
2660ccea Poul Sander 2023-09-22 19:25 5532
            case 0x18: // Unsigned integer (one-byte uint8_t follows)
2660ccea Poul Sander 2023-09-22 19:25 5533
            {
2660ccea Poul Sander 2023-09-22 19:25 5534
                std::uint8_t number;
2660ccea Poul Sander 2023-09-22 19:25 5535
                return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
2660ccea Poul Sander 2023-09-22 19:25 5536
            }
2660ccea Poul Sander 2023-09-22 19:25 5537
2660ccea Poul Sander 2023-09-22 19:25 5538
            case 0x19: // Unsigned integer (two-byte uint16_t follows)
2660ccea Poul Sander 2023-09-22 19:25 5539
            {
2660ccea Poul Sander 2023-09-22 19:25 5540
                std::uint16_t number;
2660ccea Poul Sander 2023-09-22 19:25 5541
                return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
2660ccea Poul Sander 2023-09-22 19:25 5542
            }
2660ccea Poul Sander 2023-09-22 19:25 5543
2660ccea Poul Sander 2023-09-22 19:25 5544
            case 0x1A: // Unsigned integer (four-byte uint32_t follows)
2660ccea Poul Sander 2023-09-22 19:25 5545
            {
2660ccea Poul Sander 2023-09-22 19:25 5546
                std::uint32_t number;
2660ccea Poul Sander 2023-09-22 19:25 5547
                return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
2660ccea Poul Sander 2023-09-22 19:25 5548
            }
2660ccea Poul Sander 2023-09-22 19:25 5549
2660ccea Poul Sander 2023-09-22 19:25 5550
            case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
2660ccea Poul Sander 2023-09-22 19:25 5551
            {
2660ccea Poul Sander 2023-09-22 19:25 5552
                std::uint64_t number;
2660ccea Poul Sander 2023-09-22 19:25 5553
                return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
2660ccea Poul Sander 2023-09-22 19:25 5554
            }
2660ccea Poul Sander 2023-09-22 19:25 5555
2660ccea Poul Sander 2023-09-22 19:25 5556
            // Negative integer -1-0x00..-1-0x17 (-1..-24)
2660ccea Poul Sander 2023-09-22 19:25 5557
            case 0x20:
2660ccea Poul Sander 2023-09-22 19:25 5558
            case 0x21:
2660ccea Poul Sander 2023-09-22 19:25 5559
            case 0x22:
2660ccea Poul Sander 2023-09-22 19:25 5560
            case 0x23:
2660ccea Poul Sander 2023-09-22 19:25 5561
            case 0x24:
2660ccea Poul Sander 2023-09-22 19:25 5562
            case 0x25:
2660ccea Poul Sander 2023-09-22 19:25 5563
            case 0x26:
2660ccea Poul Sander 2023-09-22 19:25 5564
            case 0x27:
2660ccea Poul Sander 2023-09-22 19:25 5565
            case 0x28:
2660ccea Poul Sander 2023-09-22 19:25 5566
            case 0x29:
2660ccea Poul Sander 2023-09-22 19:25 5567
            case 0x2A:
2660ccea Poul Sander 2023-09-22 19:25 5568
            case 0x2B:
2660ccea Poul Sander 2023-09-22 19:25 5569
            case 0x2C:
2660ccea Poul Sander 2023-09-22 19:25 5570
            case 0x2D:
2660ccea Poul Sander 2023-09-22 19:25 5571
            case 0x2E:
2660ccea Poul Sander 2023-09-22 19:25 5572
            case 0x2F:
2660ccea Poul Sander 2023-09-22 19:25 5573
            case 0x30:
2660ccea Poul Sander 2023-09-22 19:25 5574
            case 0x31:
2660ccea Poul Sander 2023-09-22 19:25 5575
            case 0x32:
2660ccea Poul Sander 2023-09-22 19:25 5576
            case 0x33:
2660ccea Poul Sander 2023-09-22 19:25 5577
            case 0x34:
2660ccea Poul Sander 2023-09-22 19:25 5578
            case 0x35:
2660ccea Poul Sander 2023-09-22 19:25 5579
            case 0x36:
2660ccea Poul Sander 2023-09-22 19:25 5580
            case 0x37:
2660ccea Poul Sander 2023-09-22 19:25 5581
                return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
2660ccea Poul Sander 2023-09-22 19:25 5582
2660ccea Poul Sander 2023-09-22 19:25 5583
            case 0x38: // Negative integer (one-byte uint8_t follows)
2660ccea Poul Sander 2023-09-22 19:25 5584
            {
2660ccea Poul Sander 2023-09-22 19:25 5585
                std::uint8_t number;
2660ccea Poul Sander 2023-09-22 19:25 5586
                return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
2660ccea Poul Sander 2023-09-22 19:25 5587
            }
2660ccea Poul Sander 2023-09-22 19:25 5588
2660ccea Poul Sander 2023-09-22 19:25 5589
            case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
2660ccea Poul Sander 2023-09-22 19:25 5590
            {
2660ccea Poul Sander 2023-09-22 19:25 5591
                std::uint16_t number;
2660ccea Poul Sander 2023-09-22 19:25 5592
                return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
2660ccea Poul Sander 2023-09-22 19:25 5593
            }
2660ccea Poul Sander 2023-09-22 19:25 5594
2660ccea Poul Sander 2023-09-22 19:25 5595
            case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
2660ccea Poul Sander 2023-09-22 19:25 5596
            {
2660ccea Poul Sander 2023-09-22 19:25 5597
                std::uint32_t number;
2660ccea Poul Sander 2023-09-22 19:25 5598
                return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
2660ccea Poul Sander 2023-09-22 19:25 5599
            }
2660ccea Poul Sander 2023-09-22 19:25 5600
2660ccea Poul Sander 2023-09-22 19:25 5601
            case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
2660ccea Poul Sander 2023-09-22 19:25 5602
            {
2660ccea Poul Sander 2023-09-22 19:25 5603
                std::uint64_t number;
2660ccea Poul Sander 2023-09-22 19:25 5604
                return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
2660ccea Poul Sander 2023-09-22 19:25 5605
                        - static_cast<number_integer_t>(number));
2660ccea Poul Sander 2023-09-22 19:25 5606
            }
2660ccea Poul Sander 2023-09-22 19:25 5607
2660ccea Poul Sander 2023-09-22 19:25 5608
            // UTF-8 string (0x00..0x17 bytes follow)
2660ccea Poul Sander 2023-09-22 19:25 5609
            case 0x60:
2660ccea Poul Sander 2023-09-22 19:25 5610
            case 0x61:
2660ccea Poul Sander 2023-09-22 19:25 5611
            case 0x62:
2660ccea Poul Sander 2023-09-22 19:25 5612
            case 0x63:
2660ccea Poul Sander 2023-09-22 19:25 5613
            case 0x64:
2660ccea Poul Sander 2023-09-22 19:25 5614
            case 0x65:
2660ccea Poul Sander 2023-09-22 19:25 5615
            case 0x66:
2660ccea Poul Sander 2023-09-22 19:25 5616
            case 0x67:
2660ccea Poul Sander 2023-09-22 19:25 5617
            case 0x68:
2660ccea Poul Sander 2023-09-22 19:25 5618
            case 0x69:
2660ccea Poul Sander 2023-09-22 19:25 5619
            case 0x6A:
2660ccea Poul Sander 2023-09-22 19:25 5620
            case 0x6B:
2660ccea Poul Sander 2023-09-22 19:25 5621
            case 0x6C:
2660ccea Poul Sander 2023-09-22 19:25 5622
            case 0x6D:
2660ccea Poul Sander 2023-09-22 19:25 5623
            case 0x6E:
2660ccea Poul Sander 2023-09-22 19:25 5624
            case 0x6F:
2660ccea Poul Sander 2023-09-22 19:25 5625
            case 0x70:
2660ccea Poul Sander 2023-09-22 19:25 5626
            case 0x71:
2660ccea Poul Sander 2023-09-22 19:25 5627
            case 0x72:
2660ccea Poul Sander 2023-09-22 19:25 5628
            case 0x73:
2660ccea Poul Sander 2023-09-22 19:25 5629
            case 0x74:
2660ccea Poul Sander 2023-09-22 19:25 5630
            case 0x75:
2660ccea Poul Sander 2023-09-22 19:25 5631
            case 0x76:
2660ccea Poul Sander 2023-09-22 19:25 5632
            case 0x77:
2660ccea Poul Sander 2023-09-22 19:25 5633
            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
2660ccea Poul Sander 2023-09-22 19:25 5634
            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5635
            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5636
            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5637
            case 0x7F: // UTF-8 string (indefinite length)
2660ccea Poul Sander 2023-09-22 19:25 5638
            {
2660ccea Poul Sander 2023-09-22 19:25 5639
                string_t s;
2660ccea Poul Sander 2023-09-22 19:25 5640
                return get_cbor_string(s) and sax->string(s);
2660ccea Poul Sander 2023-09-22 19:25 5641
            }
2660ccea Poul Sander 2023-09-22 19:25 5642
2660ccea Poul Sander 2023-09-22 19:25 5643
            // array (0x00..0x17 data items follow)
2660ccea Poul Sander 2023-09-22 19:25 5644
            case 0x80:
2660ccea Poul Sander 2023-09-22 19:25 5645
            case 0x81:
2660ccea Poul Sander 2023-09-22 19:25 5646
            case 0x82:
2660ccea Poul Sander 2023-09-22 19:25 5647
            case 0x83:
2660ccea Poul Sander 2023-09-22 19:25 5648
            case 0x84:
2660ccea Poul Sander 2023-09-22 19:25 5649
            case 0x85:
2660ccea Poul Sander 2023-09-22 19:25 5650
            case 0x86:
2660ccea Poul Sander 2023-09-22 19:25 5651
            case 0x87:
2660ccea Poul Sander 2023-09-22 19:25 5652
            case 0x88:
2660ccea Poul Sander 2023-09-22 19:25 5653
            case 0x89:
2660ccea Poul Sander 2023-09-22 19:25 5654
            case 0x8A:
2660ccea Poul Sander 2023-09-22 19:25 5655
            case 0x8B:
2660ccea Poul Sander 2023-09-22 19:25 5656
            case 0x8C:
2660ccea Poul Sander 2023-09-22 19:25 5657
            case 0x8D:
2660ccea Poul Sander 2023-09-22 19:25 5658
            case 0x8E:
2660ccea Poul Sander 2023-09-22 19:25 5659
            case 0x8F:
2660ccea Poul Sander 2023-09-22 19:25 5660
            case 0x90:
2660ccea Poul Sander 2023-09-22 19:25 5661
            case 0x91:
2660ccea Poul Sander 2023-09-22 19:25 5662
            case 0x92:
2660ccea Poul Sander 2023-09-22 19:25 5663
            case 0x93:
2660ccea Poul Sander 2023-09-22 19:25 5664
            case 0x94:
2660ccea Poul Sander 2023-09-22 19:25 5665
            case 0x95:
2660ccea Poul Sander 2023-09-22 19:25 5666
            case 0x96:
2660ccea Poul Sander 2023-09-22 19:25 5667
            case 0x97:
2660ccea Poul Sander 2023-09-22 19:25 5668
                return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
2660ccea Poul Sander 2023-09-22 19:25 5669
2660ccea Poul Sander 2023-09-22 19:25 5670
            case 0x98: // array (one-byte uint8_t for n follows)
2660ccea Poul Sander 2023-09-22 19:25 5671
            {
2660ccea Poul Sander 2023-09-22 19:25 5672
                std::uint8_t len;
2660ccea Poul Sander 2023-09-22 19:25 5673
                return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 5674
            }
2660ccea Poul Sander 2023-09-22 19:25 5675
2660ccea Poul Sander 2023-09-22 19:25 5676
            case 0x99: // array (two-byte uint16_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5677
            {
2660ccea Poul Sander 2023-09-22 19:25 5678
                std::uint16_t len;
2660ccea Poul Sander 2023-09-22 19:25 5679
                return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 5680
            }
2660ccea Poul Sander 2023-09-22 19:25 5681
2660ccea Poul Sander 2023-09-22 19:25 5682
            case 0x9A: // array (four-byte uint32_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5683
            {
2660ccea Poul Sander 2023-09-22 19:25 5684
                std::uint32_t len;
2660ccea Poul Sander 2023-09-22 19:25 5685
                return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 5686
            }
2660ccea Poul Sander 2023-09-22 19:25 5687
2660ccea Poul Sander 2023-09-22 19:25 5688
            case 0x9B: // array (eight-byte uint64_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5689
            {
2660ccea Poul Sander 2023-09-22 19:25 5690
                std::uint64_t len;
2660ccea Poul Sander 2023-09-22 19:25 5691
                return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 5692
            }
2660ccea Poul Sander 2023-09-22 19:25 5693
2660ccea Poul Sander 2023-09-22 19:25 5694
            case 0x9F: // array (indefinite length)
2660ccea Poul Sander 2023-09-22 19:25 5695
                return get_cbor_array(std::size_t(-1));
2660ccea Poul Sander 2023-09-22 19:25 5696
2660ccea Poul Sander 2023-09-22 19:25 5697
            // map (0x00..0x17 pairs of data items follow)
2660ccea Poul Sander 2023-09-22 19:25 5698
            case 0xA0:
2660ccea Poul Sander 2023-09-22 19:25 5699
            case 0xA1:
2660ccea Poul Sander 2023-09-22 19:25 5700
            case 0xA2:
2660ccea Poul Sander 2023-09-22 19:25 5701
            case 0xA3:
2660ccea Poul Sander 2023-09-22 19:25 5702
            case 0xA4:
2660ccea Poul Sander 2023-09-22 19:25 5703
            case 0xA5:
2660ccea Poul Sander 2023-09-22 19:25 5704
            case 0xA6:
2660ccea Poul Sander 2023-09-22 19:25 5705
            case 0xA7:
2660ccea Poul Sander 2023-09-22 19:25 5706
            case 0xA8:
2660ccea Poul Sander 2023-09-22 19:25 5707
            case 0xA9:
2660ccea Poul Sander 2023-09-22 19:25 5708
            case 0xAA:
2660ccea Poul Sander 2023-09-22 19:25 5709
            case 0xAB:
2660ccea Poul Sander 2023-09-22 19:25 5710
            case 0xAC:
2660ccea Poul Sander 2023-09-22 19:25 5711
            case 0xAD:
2660ccea Poul Sander 2023-09-22 19:25 5712
            case 0xAE:
2660ccea Poul Sander 2023-09-22 19:25 5713
            case 0xAF:
2660ccea Poul Sander 2023-09-22 19:25 5714
            case 0xB0:
2660ccea Poul Sander 2023-09-22 19:25 5715
            case 0xB1:
2660ccea Poul Sander 2023-09-22 19:25 5716
            case 0xB2:
2660ccea Poul Sander 2023-09-22 19:25 5717
            case 0xB3:
2660ccea Poul Sander 2023-09-22 19:25 5718
            case 0xB4:
2660ccea Poul Sander 2023-09-22 19:25 5719
            case 0xB5:
2660ccea Poul Sander 2023-09-22 19:25 5720
            case 0xB6:
2660ccea Poul Sander 2023-09-22 19:25 5721
            case 0xB7:
2660ccea Poul Sander 2023-09-22 19:25 5722
                return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
2660ccea Poul Sander 2023-09-22 19:25 5723
2660ccea Poul Sander 2023-09-22 19:25 5724
            case 0xB8: // map (one-byte uint8_t for n follows)
2660ccea Poul Sander 2023-09-22 19:25 5725
            {
2660ccea Poul Sander 2023-09-22 19:25 5726
                std::uint8_t len;
2660ccea Poul Sander 2023-09-22 19:25 5727
                return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 5728
            }
2660ccea Poul Sander 2023-09-22 19:25 5729
2660ccea Poul Sander 2023-09-22 19:25 5730
            case 0xB9: // map (two-byte uint16_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5731
            {
2660ccea Poul Sander 2023-09-22 19:25 5732
                std::uint16_t len;
2660ccea Poul Sander 2023-09-22 19:25 5733
                return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 5734
            }
2660ccea Poul Sander 2023-09-22 19:25 5735
2660ccea Poul Sander 2023-09-22 19:25 5736
            case 0xBA: // map (four-byte uint32_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5737
            {
2660ccea Poul Sander 2023-09-22 19:25 5738
                std::uint32_t len;
2660ccea Poul Sander 2023-09-22 19:25 5739
                return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 5740
            }
2660ccea Poul Sander 2023-09-22 19:25 5741
2660ccea Poul Sander 2023-09-22 19:25 5742
            case 0xBB: // map (eight-byte uint64_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5743
            {
2660ccea Poul Sander 2023-09-22 19:25 5744
                std::uint64_t len;
2660ccea Poul Sander 2023-09-22 19:25 5745
                return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 5746
            }
2660ccea Poul Sander 2023-09-22 19:25 5747
2660ccea Poul Sander 2023-09-22 19:25 5748
            case 0xBF: // map (indefinite length)
2660ccea Poul Sander 2023-09-22 19:25 5749
                return get_cbor_object(std::size_t(-1));
2660ccea Poul Sander 2023-09-22 19:25 5750
2660ccea Poul Sander 2023-09-22 19:25 5751
            case 0xF4: // false
2660ccea Poul Sander 2023-09-22 19:25 5752
                return sax->boolean(false);
2660ccea Poul Sander 2023-09-22 19:25 5753
2660ccea Poul Sander 2023-09-22 19:25 5754
            case 0xF5: // true
2660ccea Poul Sander 2023-09-22 19:25 5755
                return sax->boolean(true);
2660ccea Poul Sander 2023-09-22 19:25 5756
2660ccea Poul Sander 2023-09-22 19:25 5757
            case 0xF6: // null
2660ccea Poul Sander 2023-09-22 19:25 5758
                return sax->null();
2660ccea Poul Sander 2023-09-22 19:25 5759
2660ccea Poul Sander 2023-09-22 19:25 5760
            case 0xF9: // Half-Precision Float (two-byte IEEE 754)
2660ccea Poul Sander 2023-09-22 19:25 5761
            {
2660ccea Poul Sander 2023-09-22 19:25 5762
                const int byte1_raw = get();
2660ccea Poul Sander 2023-09-22 19:25 5763
                if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
2660ccea Poul Sander 2023-09-22 19:25 5764
                {
2660ccea Poul Sander 2023-09-22 19:25 5765
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 5766
                }
2660ccea Poul Sander 2023-09-22 19:25 5767
                const int byte2_raw = get();
2660ccea Poul Sander 2023-09-22 19:25 5768
                if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
2660ccea Poul Sander 2023-09-22 19:25 5769
                {
2660ccea Poul Sander 2023-09-22 19:25 5770
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 5771
                }
2660ccea Poul Sander 2023-09-22 19:25 5772
2660ccea Poul Sander 2023-09-22 19:25 5773
                const auto byte1 = static_cast<unsigned char>(byte1_raw);
2660ccea Poul Sander 2023-09-22 19:25 5774
                const auto byte2 = static_cast<unsigned char>(byte2_raw);
2660ccea Poul Sander 2023-09-22 19:25 5775
2660ccea Poul Sander 2023-09-22 19:25 5776
                // code from RFC 7049, Appendix D, Figure 3:
2660ccea Poul Sander 2023-09-22 19:25 5777
                // As half-precision floating-point numbers were only added
2660ccea Poul Sander 2023-09-22 19:25 5778
                // to IEEE 754 in 2008, today's programming platforms often
2660ccea Poul Sander 2023-09-22 19:25 5779
                // still only have limited support for them. It is very
2660ccea Poul Sander 2023-09-22 19:25 5780
                // easy to include at least decoding support for them even
2660ccea Poul Sander 2023-09-22 19:25 5781
                // without such support. An example of a small decoder for
2660ccea Poul Sander 2023-09-22 19:25 5782
                // half-precision floating-point numbers in the C language
2660ccea Poul Sander 2023-09-22 19:25 5783
                // is shown in Fig. 3.
2660ccea Poul Sander 2023-09-22 19:25 5784
                const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
2660ccea Poul Sander 2023-09-22 19:25 5785
                const double val = [&half]
2660ccea Poul Sander 2023-09-22 19:25 5786
                {
2660ccea Poul Sander 2023-09-22 19:25 5787
                    const int exp = (half >> 10u) & 0x1Fu;
2660ccea Poul Sander 2023-09-22 19:25 5788
                    const unsigned int mant = half & 0x3FFu;
2660ccea Poul Sander 2023-09-22 19:25 5789
                    assert(0 <= exp and exp <= 32);
2660ccea Poul Sander 2023-09-22 19:25 5790
                    assert(mant <= 1024);
2660ccea Poul Sander 2023-09-22 19:25 5791
                    switch (exp)
2660ccea Poul Sander 2023-09-22 19:25 5792
                    {
2660ccea Poul Sander 2023-09-22 19:25 5793
                        case 0:
2660ccea Poul Sander 2023-09-22 19:25 5794
                            return std::ldexp(mant, -24);
2660ccea Poul Sander 2023-09-22 19:25 5795
                        case 31:
2660ccea Poul Sander 2023-09-22 19:25 5796
                            return (mant == 0)
2660ccea Poul Sander 2023-09-22 19:25 5797
                            ? std::numeric_limits<double>::infinity()
2660ccea Poul Sander 2023-09-22 19:25 5798
                            : std::numeric_limits<double>::quiet_NaN();
2660ccea Poul Sander 2023-09-22 19:25 5799
                        default:
2660ccea Poul Sander 2023-09-22 19:25 5800
                            return std::ldexp(mant + 1024, exp - 25);
2660ccea Poul Sander 2023-09-22 19:25 5801
                    }
2660ccea Poul Sander 2023-09-22 19:25 5802
                }();
2660ccea Poul Sander 2023-09-22 19:25 5803
                return sax->number_float((half & 0x8000u) != 0
2660ccea Poul Sander 2023-09-22 19:25 5804
                                         ? static_cast<number_float_t>(-val)
2660ccea Poul Sander 2023-09-22 19:25 5805
                                         : static_cast<number_float_t>(val), "");
2660ccea Poul Sander 2023-09-22 19:25 5806
            }
2660ccea Poul Sander 2023-09-22 19:25 5807
2660ccea Poul Sander 2023-09-22 19:25 5808
            case 0xFA: // Single-Precision Float (four-byte IEEE 754)
2660ccea Poul Sander 2023-09-22 19:25 5809
            {
2660ccea Poul Sander 2023-09-22 19:25 5810
                float number;
2660ccea Poul Sander 2023-09-22 19:25 5811
                return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
2660ccea Poul Sander 2023-09-22 19:25 5812
            }
2660ccea Poul Sander 2023-09-22 19:25 5813
2660ccea Poul Sander 2023-09-22 19:25 5814
            case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
2660ccea Poul Sander 2023-09-22 19:25 5815
            {
2660ccea Poul Sander 2023-09-22 19:25 5816
                double number;
2660ccea Poul Sander 2023-09-22 19:25 5817
                return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
2660ccea Poul Sander 2023-09-22 19:25 5818
            }
2660ccea Poul Sander 2023-09-22 19:25 5819
2660ccea Poul Sander 2023-09-22 19:25 5820
            default: // anything else (0xFF is handled inside the other types)
2660ccea Poul Sander 2023-09-22 19:25 5821
            {
2660ccea Poul Sander 2023-09-22 19:25 5822
                auto last_token = get_token_string();
2660ccea Poul Sander 2023-09-22 19:25 5823
                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")));
2660ccea Poul Sander 2023-09-22 19:25 5824
            }
2660ccea Poul Sander 2023-09-22 19:25 5825
        }
2660ccea Poul Sander 2023-09-22 19:25 5826
    }
2660ccea Poul Sander 2023-09-22 19:25 5827
2660ccea Poul Sander 2023-09-22 19:25 5828
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5829
    @brief reads a CBOR string
2660ccea Poul Sander 2023-09-22 19:25 5830
2660ccea Poul Sander 2023-09-22 19:25 5831
    This function first reads starting bytes to determine the expected
2660ccea Poul Sander 2023-09-22 19:25 5832
    string length and then copies this number of bytes into a string.
2660ccea Poul Sander 2023-09-22 19:25 5833
    Additionally, CBOR's strings with indefinite lengths are supported.
2660ccea Poul Sander 2023-09-22 19:25 5834
2660ccea Poul Sander 2023-09-22 19:25 5835
    @param[out] result  created string
2660ccea Poul Sander 2023-09-22 19:25 5836
2660ccea Poul Sander 2023-09-22 19:25 5837
    @return whether string creation completed
2660ccea Poul Sander 2023-09-22 19:25 5838
    */
2660ccea Poul Sander 2023-09-22 19:25 5839
    bool get_cbor_string(string_t& result)
2660ccea Poul Sander 2023-09-22 19:25 5840
    {
2660ccea Poul Sander 2023-09-22 19:25 5841
        if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
2660ccea Poul Sander 2023-09-22 19:25 5842
        {
2660ccea Poul Sander 2023-09-22 19:25 5843
            return false;
2660ccea Poul Sander 2023-09-22 19:25 5844
        }
2660ccea Poul Sander 2023-09-22 19:25 5845
2660ccea Poul Sander 2023-09-22 19:25 5846
        switch (current)
2660ccea Poul Sander 2023-09-22 19:25 5847
        {
2660ccea Poul Sander 2023-09-22 19:25 5848
            // UTF-8 string (0x00..0x17 bytes follow)
2660ccea Poul Sander 2023-09-22 19:25 5849
            case 0x60:
2660ccea Poul Sander 2023-09-22 19:25 5850
            case 0x61:
2660ccea Poul Sander 2023-09-22 19:25 5851
            case 0x62:
2660ccea Poul Sander 2023-09-22 19:25 5852
            case 0x63:
2660ccea Poul Sander 2023-09-22 19:25 5853
            case 0x64:
2660ccea Poul Sander 2023-09-22 19:25 5854
            case 0x65:
2660ccea Poul Sander 2023-09-22 19:25 5855
            case 0x66:
2660ccea Poul Sander 2023-09-22 19:25 5856
            case 0x67:
2660ccea Poul Sander 2023-09-22 19:25 5857
            case 0x68:
2660ccea Poul Sander 2023-09-22 19:25 5858
            case 0x69:
2660ccea Poul Sander 2023-09-22 19:25 5859
            case 0x6A:
2660ccea Poul Sander 2023-09-22 19:25 5860
            case 0x6B:
2660ccea Poul Sander 2023-09-22 19:25 5861
            case 0x6C:
2660ccea Poul Sander 2023-09-22 19:25 5862
            case 0x6D:
2660ccea Poul Sander 2023-09-22 19:25 5863
            case 0x6E:
2660ccea Poul Sander 2023-09-22 19:25 5864
            case 0x6F:
2660ccea Poul Sander 2023-09-22 19:25 5865
            case 0x70:
2660ccea Poul Sander 2023-09-22 19:25 5866
            case 0x71:
2660ccea Poul Sander 2023-09-22 19:25 5867
            case 0x72:
2660ccea Poul Sander 2023-09-22 19:25 5868
            case 0x73:
2660ccea Poul Sander 2023-09-22 19:25 5869
            case 0x74:
2660ccea Poul Sander 2023-09-22 19:25 5870
            case 0x75:
2660ccea Poul Sander 2023-09-22 19:25 5871
            case 0x76:
2660ccea Poul Sander 2023-09-22 19:25 5872
            case 0x77:
2660ccea Poul Sander 2023-09-22 19:25 5873
            {
2660ccea Poul Sander 2023-09-22 19:25 5874
                return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
2660ccea Poul Sander 2023-09-22 19:25 5875
            }
2660ccea Poul Sander 2023-09-22 19:25 5876
2660ccea Poul Sander 2023-09-22 19:25 5877
            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
2660ccea Poul Sander 2023-09-22 19:25 5878
            {
2660ccea Poul Sander 2023-09-22 19:25 5879
                std::uint8_t len;
2660ccea Poul Sander 2023-09-22 19:25 5880
                return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
2660ccea Poul Sander 2023-09-22 19:25 5881
            }
2660ccea Poul Sander 2023-09-22 19:25 5882
2660ccea Poul Sander 2023-09-22 19:25 5883
            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5884
            {
2660ccea Poul Sander 2023-09-22 19:25 5885
                std::uint16_t len;
2660ccea Poul Sander 2023-09-22 19:25 5886
                return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
2660ccea Poul Sander 2023-09-22 19:25 5887
            }
2660ccea Poul Sander 2023-09-22 19:25 5888
2660ccea Poul Sander 2023-09-22 19:25 5889
            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5890
            {
2660ccea Poul Sander 2023-09-22 19:25 5891
                std::uint32_t len;
2660ccea Poul Sander 2023-09-22 19:25 5892
                return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
2660ccea Poul Sander 2023-09-22 19:25 5893
            }
2660ccea Poul Sander 2023-09-22 19:25 5894
2660ccea Poul Sander 2023-09-22 19:25 5895
            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
2660ccea Poul Sander 2023-09-22 19:25 5896
            {
2660ccea Poul Sander 2023-09-22 19:25 5897
                std::uint64_t len;
2660ccea Poul Sander 2023-09-22 19:25 5898
                return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
2660ccea Poul Sander 2023-09-22 19:25 5899
            }
2660ccea Poul Sander 2023-09-22 19:25 5900
2660ccea Poul Sander 2023-09-22 19:25 5901
            case 0x7F: // UTF-8 string (indefinite length)
2660ccea Poul Sander 2023-09-22 19:25 5902
            {
2660ccea Poul Sander 2023-09-22 19:25 5903
                while (get() != 0xFF)
2660ccea Poul Sander 2023-09-22 19:25 5904
                {
2660ccea Poul Sander 2023-09-22 19:25 5905
                    string_t chunk;
2660ccea Poul Sander 2023-09-22 19:25 5906
                    if (not get_cbor_string(chunk))
2660ccea Poul Sander 2023-09-22 19:25 5907
                    {
2660ccea Poul Sander 2023-09-22 19:25 5908
                        return false;
2660ccea Poul Sander 2023-09-22 19:25 5909
                    }
2660ccea Poul Sander 2023-09-22 19:25 5910
                    result.append(chunk);
2660ccea Poul Sander 2023-09-22 19:25 5911
                }
2660ccea Poul Sander 2023-09-22 19:25 5912
                return true;
2660ccea Poul Sander 2023-09-22 19:25 5913
            }
2660ccea Poul Sander 2023-09-22 19:25 5914
2660ccea Poul Sander 2023-09-22 19:25 5915
            default:
2660ccea Poul Sander 2023-09-22 19:25 5916
            {
2660ccea Poul Sander 2023-09-22 19:25 5917
                auto last_token = get_token_string();
2660ccea Poul Sander 2023-09-22 19:25 5918
                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")));
2660ccea Poul Sander 2023-09-22 19:25 5919
            }
2660ccea Poul Sander 2023-09-22 19:25 5920
        }
2660ccea Poul Sander 2023-09-22 19:25 5921
    }
2660ccea Poul Sander 2023-09-22 19:25 5922
2660ccea Poul Sander 2023-09-22 19:25 5923
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5924
    @param[in] len  the length of the array or std::size_t(-1) for an
2660ccea Poul Sander 2023-09-22 19:25 5925
                    array of indefinite size
2660ccea Poul Sander 2023-09-22 19:25 5926
    @return whether array creation completed
2660ccea Poul Sander 2023-09-22 19:25 5927
    */
2660ccea Poul Sander 2023-09-22 19:25 5928
    bool get_cbor_array(const std::size_t len)
2660ccea Poul Sander 2023-09-22 19:25 5929
    {
2660ccea Poul Sander 2023-09-22 19:25 5930
        if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
2660ccea Poul Sander 2023-09-22 19:25 5931
        {
2660ccea Poul Sander 2023-09-22 19:25 5932
            return false;
2660ccea Poul Sander 2023-09-22 19:25 5933
        }
2660ccea Poul Sander 2023-09-22 19:25 5934
2660ccea Poul Sander 2023-09-22 19:25 5935
        if (len != std::size_t(-1))
2660ccea Poul Sander 2023-09-22 19:25 5936
        {
2660ccea Poul Sander 2023-09-22 19:25 5937
            for (std::size_t i = 0; i < len; ++i)
2660ccea Poul Sander 2023-09-22 19:25 5938
            {
2660ccea Poul Sander 2023-09-22 19:25 5939
                if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
2660ccea Poul Sander 2023-09-22 19:25 5940
                {
2660ccea Poul Sander 2023-09-22 19:25 5941
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 5942
                }
2660ccea Poul Sander 2023-09-22 19:25 5943
            }
2660ccea Poul Sander 2023-09-22 19:25 5944
        }
2660ccea Poul Sander 2023-09-22 19:25 5945
        else
2660ccea Poul Sander 2023-09-22 19:25 5946
        {
2660ccea Poul Sander 2023-09-22 19:25 5947
            while (get() != 0xFF)
2660ccea Poul Sander 2023-09-22 19:25 5948
            {
2660ccea Poul Sander 2023-09-22 19:25 5949
                if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal(false)))
2660ccea Poul Sander 2023-09-22 19:25 5950
                {
2660ccea Poul Sander 2023-09-22 19:25 5951
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 5952
                }
2660ccea Poul Sander 2023-09-22 19:25 5953
            }
2660ccea Poul Sander 2023-09-22 19:25 5954
        }
2660ccea Poul Sander 2023-09-22 19:25 5955
2660ccea Poul Sander 2023-09-22 19:25 5956
        return sax->end_array();
2660ccea Poul Sander 2023-09-22 19:25 5957
    }
2660ccea Poul Sander 2023-09-22 19:25 5958
2660ccea Poul Sander 2023-09-22 19:25 5959
    /*!
2660ccea Poul Sander 2023-09-22 19:25 5960
    @param[in] len  the length of the object or std::size_t(-1) for an
2660ccea Poul Sander 2023-09-22 19:25 5961
                    object of indefinite size
2660ccea Poul Sander 2023-09-22 19:25 5962
    @return whether object creation completed
2660ccea Poul Sander 2023-09-22 19:25 5963
    */
2660ccea Poul Sander 2023-09-22 19:25 5964
    bool get_cbor_object(const std::size_t len)
2660ccea Poul Sander 2023-09-22 19:25 5965
    {
2660ccea Poul Sander 2023-09-22 19:25 5966
        if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
2660ccea Poul Sander 2023-09-22 19:25 5967
        {
2660ccea Poul Sander 2023-09-22 19:25 5968
            return false;
2660ccea Poul Sander 2023-09-22 19:25 5969
        }
2660ccea Poul Sander 2023-09-22 19:25 5970
2660ccea Poul Sander 2023-09-22 19:25 5971
        string_t key;
2660ccea Poul Sander 2023-09-22 19:25 5972
        if (len != std::size_t(-1))
2660ccea Poul Sander 2023-09-22 19:25 5973
        {
2660ccea Poul Sander 2023-09-22 19:25 5974
            for (std::size_t i = 0; i < len; ++i)
2660ccea Poul Sander 2023-09-22 19:25 5975
            {
2660ccea Poul Sander 2023-09-22 19:25 5976
                get();
2660ccea Poul Sander 2023-09-22 19:25 5977
                if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
2660ccea Poul Sander 2023-09-22 19:25 5978
                {
2660ccea Poul Sander 2023-09-22 19:25 5979
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 5980
                }
2660ccea Poul Sander 2023-09-22 19:25 5981
2660ccea Poul Sander 2023-09-22 19:25 5982
                if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
2660ccea Poul Sander 2023-09-22 19:25 5983
                {
2660ccea Poul Sander 2023-09-22 19:25 5984
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 5985
                }
2660ccea Poul Sander 2023-09-22 19:25 5986
                key.clear();
2660ccea Poul Sander 2023-09-22 19:25 5987
            }
2660ccea Poul Sander 2023-09-22 19:25 5988
        }
2660ccea Poul Sander 2023-09-22 19:25 5989
        else
2660ccea Poul Sander 2023-09-22 19:25 5990
        {
2660ccea Poul Sander 2023-09-22 19:25 5991
            while (get() != 0xFF)
2660ccea Poul Sander 2023-09-22 19:25 5992
            {
2660ccea Poul Sander 2023-09-22 19:25 5993
                if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
2660ccea Poul Sander 2023-09-22 19:25 5994
                {
2660ccea Poul Sander 2023-09-22 19:25 5995
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 5996
                }
2660ccea Poul Sander 2023-09-22 19:25 5997
2660ccea Poul Sander 2023-09-22 19:25 5998
                if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
2660ccea Poul Sander 2023-09-22 19:25 5999
                {
2660ccea Poul Sander 2023-09-22 19:25 6000
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 6001
                }
2660ccea Poul Sander 2023-09-22 19:25 6002
                key.clear();
2660ccea Poul Sander 2023-09-22 19:25 6003
            }
2660ccea Poul Sander 2023-09-22 19:25 6004
        }
2660ccea Poul Sander 2023-09-22 19:25 6005
2660ccea Poul Sander 2023-09-22 19:25 6006
        return sax->end_object();
2660ccea Poul Sander 2023-09-22 19:25 6007
    }
2660ccea Poul Sander 2023-09-22 19:25 6008
2660ccea Poul Sander 2023-09-22 19:25 6009
    /////////////
2660ccea Poul Sander 2023-09-22 19:25 6010
    // MsgPack //
2660ccea Poul Sander 2023-09-22 19:25 6011
    /////////////
2660ccea Poul Sander 2023-09-22 19:25 6012
2660ccea Poul Sander 2023-09-22 19:25 6013
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6014
    @return whether a valid MessagePack value was passed to the SAX parser
2660ccea Poul Sander 2023-09-22 19:25 6015
    */
2660ccea Poul Sander 2023-09-22 19:25 6016
    bool parse_msgpack_internal()
2660ccea Poul Sander 2023-09-22 19:25 6017
    {
2660ccea Poul Sander 2023-09-22 19:25 6018
        switch (get())
2660ccea Poul Sander 2023-09-22 19:25 6019
        {
2660ccea Poul Sander 2023-09-22 19:25 6020
            // EOF
2660ccea Poul Sander 2023-09-22 19:25 6021
            case std::char_traits<char>::eof():
2660ccea Poul Sander 2023-09-22 19:25 6022
                return unexpect_eof(input_format_t::msgpack, "value");
2660ccea Poul Sander 2023-09-22 19:25 6023
2660ccea Poul Sander 2023-09-22 19:25 6024
            // positive fixint
2660ccea Poul Sander 2023-09-22 19:25 6025
            case 0x00:
2660ccea Poul Sander 2023-09-22 19:25 6026
            case 0x01:
2660ccea Poul Sander 2023-09-22 19:25 6027
            case 0x02:
2660ccea Poul Sander 2023-09-22 19:25 6028
            case 0x03:
2660ccea Poul Sander 2023-09-22 19:25 6029
            case 0x04:
2660ccea Poul Sander 2023-09-22 19:25 6030
            case 0x05:
2660ccea Poul Sander 2023-09-22 19:25 6031
            case 0x06:
2660ccea Poul Sander 2023-09-22 19:25 6032
            case 0x07:
2660ccea Poul Sander 2023-09-22 19:25 6033
            case 0x08:
2660ccea Poul Sander 2023-09-22 19:25 6034
            case 0x09:
2660ccea Poul Sander 2023-09-22 19:25 6035
            case 0x0A:
2660ccea Poul Sander 2023-09-22 19:25 6036
            case 0x0B:
2660ccea Poul Sander 2023-09-22 19:25 6037
            case 0x0C:
2660ccea Poul Sander 2023-09-22 19:25 6038
            case 0x0D:
2660ccea Poul Sander 2023-09-22 19:25 6039
            case 0x0E:
2660ccea Poul Sander 2023-09-22 19:25 6040
            case 0x0F:
2660ccea Poul Sander 2023-09-22 19:25 6041
            case 0x10:
2660ccea Poul Sander 2023-09-22 19:25 6042
            case 0x11:
2660ccea Poul Sander 2023-09-22 19:25 6043
            case 0x12:
2660ccea Poul Sander 2023-09-22 19:25 6044
            case 0x13:
2660ccea Poul Sander 2023-09-22 19:25 6045
            case 0x14:
2660ccea Poul Sander 2023-09-22 19:25 6046
            case 0x15:
2660ccea Poul Sander 2023-09-22 19:25 6047
            case 0x16:
2660ccea Poul Sander 2023-09-22 19:25 6048
            case 0x17:
2660ccea Poul Sander 2023-09-22 19:25 6049
            case 0x18:
2660ccea Poul Sander 2023-09-22 19:25 6050
            case 0x19:
2660ccea Poul Sander 2023-09-22 19:25 6051
            case 0x1A:
2660ccea Poul Sander 2023-09-22 19:25 6052
            case 0x1B:
2660ccea Poul Sander 2023-09-22 19:25 6053
            case 0x1C:
2660ccea Poul Sander 2023-09-22 19:25 6054
            case 0x1D:
2660ccea Poul Sander 2023-09-22 19:25 6055
            case 0x1E:
2660ccea Poul Sander 2023-09-22 19:25 6056
            case 0x1F:
2660ccea Poul Sander 2023-09-22 19:25 6057
            case 0x20:
2660ccea Poul Sander 2023-09-22 19:25 6058
            case 0x21:
2660ccea Poul Sander 2023-09-22 19:25 6059
            case 0x22:
2660ccea Poul Sander 2023-09-22 19:25 6060
            case 0x23:
2660ccea Poul Sander 2023-09-22 19:25 6061
            case 0x24:
2660ccea Poul Sander 2023-09-22 19:25 6062
            case 0x25:
2660ccea Poul Sander 2023-09-22 19:25 6063
            case 0x26:
2660ccea Poul Sander 2023-09-22 19:25 6064
            case 0x27:
2660ccea Poul Sander 2023-09-22 19:25 6065
            case 0x28:
2660ccea Poul Sander 2023-09-22 19:25 6066
            case 0x29:
2660ccea Poul Sander 2023-09-22 19:25 6067
            case 0x2A:
2660ccea Poul Sander 2023-09-22 19:25 6068
            case 0x2B:
2660ccea Poul Sander 2023-09-22 19:25 6069
            case 0x2C:
2660ccea Poul Sander 2023-09-22 19:25 6070
            case 0x2D:
2660ccea Poul Sander 2023-09-22 19:25 6071
            case 0x2E:
2660ccea Poul Sander 2023-09-22 19:25 6072
            case 0x2F:
2660ccea Poul Sander 2023-09-22 19:25 6073
            case 0x30:
2660ccea Poul Sander 2023-09-22 19:25 6074
            case 0x31:
2660ccea Poul Sander 2023-09-22 19:25 6075
            case 0x32:
2660ccea Poul Sander 2023-09-22 19:25 6076
            case 0x33:
2660ccea Poul Sander 2023-09-22 19:25 6077
            case 0x34:
2660ccea Poul Sander 2023-09-22 19:25 6078
            case 0x35:
2660ccea Poul Sander 2023-09-22 19:25 6079
            case 0x36:
2660ccea Poul Sander 2023-09-22 19:25 6080
            case 0x37:
2660ccea Poul Sander 2023-09-22 19:25 6081
            case 0x38:
2660ccea Poul Sander 2023-09-22 19:25 6082
            case 0x39:
2660ccea Poul Sander 2023-09-22 19:25 6083
            case 0x3A:
2660ccea Poul Sander 2023-09-22 19:25 6084
            case 0x3B:
2660ccea Poul Sander 2023-09-22 19:25 6085
            case 0x3C:
2660ccea Poul Sander 2023-09-22 19:25 6086
            case 0x3D:
2660ccea Poul Sander 2023-09-22 19:25 6087
            case 0x3E:
2660ccea Poul Sander 2023-09-22 19:25 6088
            case 0x3F:
2660ccea Poul Sander 2023-09-22 19:25 6089
            case 0x40:
2660ccea Poul Sander 2023-09-22 19:25 6090
            case 0x41:
2660ccea Poul Sander 2023-09-22 19:25 6091
            case 0x42:
2660ccea Poul Sander 2023-09-22 19:25 6092
            case 0x43:
2660ccea Poul Sander 2023-09-22 19:25 6093
            case 0x44:
2660ccea Poul Sander 2023-09-22 19:25 6094
            case 0x45:
2660ccea Poul Sander 2023-09-22 19:25 6095
            case 0x46:
2660ccea Poul Sander 2023-09-22 19:25 6096
            case 0x47:
2660ccea Poul Sander 2023-09-22 19:25 6097
            case 0x48:
2660ccea Poul Sander 2023-09-22 19:25 6098
            case 0x49:
2660ccea Poul Sander 2023-09-22 19:25 6099
            case 0x4A:
2660ccea Poul Sander 2023-09-22 19:25 6100
            case 0x4B:
2660ccea Poul Sander 2023-09-22 19:25 6101
            case 0x4C:
2660ccea Poul Sander 2023-09-22 19:25 6102
            case 0x4D:
2660ccea Poul Sander 2023-09-22 19:25 6103
            case 0x4E:
2660ccea Poul Sander 2023-09-22 19:25 6104
            case 0x4F:
2660ccea Poul Sander 2023-09-22 19:25 6105
            case 0x50:
2660ccea Poul Sander 2023-09-22 19:25 6106
            case 0x51:
2660ccea Poul Sander 2023-09-22 19:25 6107
            case 0x52:
2660ccea Poul Sander 2023-09-22 19:25 6108
            case 0x53:
2660ccea Poul Sander 2023-09-22 19:25 6109
            case 0x54:
2660ccea Poul Sander 2023-09-22 19:25 6110
            case 0x55:
2660ccea Poul Sander 2023-09-22 19:25 6111
            case 0x56:
2660ccea Poul Sander 2023-09-22 19:25 6112
            case 0x57:
2660ccea Poul Sander 2023-09-22 19:25 6113
            case 0x58:
2660ccea Poul Sander 2023-09-22 19:25 6114
            case 0x59:
2660ccea Poul Sander 2023-09-22 19:25 6115
            case 0x5A:
2660ccea Poul Sander 2023-09-22 19:25 6116
            case 0x5B:
2660ccea Poul Sander 2023-09-22 19:25 6117
            case 0x5C:
2660ccea Poul Sander 2023-09-22 19:25 6118
            case 0x5D:
2660ccea Poul Sander 2023-09-22 19:25 6119
            case 0x5E:
2660ccea Poul Sander 2023-09-22 19:25 6120
            case 0x5F:
2660ccea Poul Sander 2023-09-22 19:25 6121
            case 0x60:
2660ccea Poul Sander 2023-09-22 19:25 6122
            case 0x61:
2660ccea Poul Sander 2023-09-22 19:25 6123
            case 0x62:
2660ccea Poul Sander 2023-09-22 19:25 6124
            case 0x63:
2660ccea Poul Sander 2023-09-22 19:25 6125
            case 0x64:
2660ccea Poul Sander 2023-09-22 19:25 6126
            case 0x65:
2660ccea Poul Sander 2023-09-22 19:25 6127
            case 0x66:
2660ccea Poul Sander 2023-09-22 19:25 6128
            case 0x67:
2660ccea Poul Sander 2023-09-22 19:25 6129
            case 0x68:
2660ccea Poul Sander 2023-09-22 19:25 6130
            case 0x69:
2660ccea Poul Sander 2023-09-22 19:25 6131
            case 0x6A:
2660ccea Poul Sander 2023-09-22 19:25 6132
            case 0x6B:
2660ccea Poul Sander 2023-09-22 19:25 6133
            case 0x6C:
2660ccea Poul Sander 2023-09-22 19:25 6134
            case 0x6D:
2660ccea Poul Sander 2023-09-22 19:25 6135
            case 0x6E:
2660ccea Poul Sander 2023-09-22 19:25 6136
            case 0x6F:
2660ccea Poul Sander 2023-09-22 19:25 6137
            case 0x70:
2660ccea Poul Sander 2023-09-22 19:25 6138
            case 0x71:
2660ccea Poul Sander 2023-09-22 19:25 6139
            case 0x72:
2660ccea Poul Sander 2023-09-22 19:25 6140
            case 0x73:
2660ccea Poul Sander 2023-09-22 19:25 6141
            case 0x74:
2660ccea Poul Sander 2023-09-22 19:25 6142
            case 0x75:
2660ccea Poul Sander 2023-09-22 19:25 6143
            case 0x76:
2660ccea Poul Sander 2023-09-22 19:25 6144
            case 0x77:
2660ccea Poul Sander 2023-09-22 19:25 6145
            case 0x78:
2660ccea Poul Sander 2023-09-22 19:25 6146
            case 0x79:
2660ccea Poul Sander 2023-09-22 19:25 6147
            case 0x7A:
2660ccea Poul Sander 2023-09-22 19:25 6148
            case 0x7B:
2660ccea Poul Sander 2023-09-22 19:25 6149
            case 0x7C:
2660ccea Poul Sander 2023-09-22 19:25 6150
            case 0x7D:
2660ccea Poul Sander 2023-09-22 19:25 6151
            case 0x7E:
2660ccea Poul Sander 2023-09-22 19:25 6152
            case 0x7F:
2660ccea Poul Sander 2023-09-22 19:25 6153
                return sax->number_unsigned(static_cast<number_unsigned_t>(current));
2660ccea Poul Sander 2023-09-22 19:25 6154
2660ccea Poul Sander 2023-09-22 19:25 6155
            // fixmap
2660ccea Poul Sander 2023-09-22 19:25 6156
            case 0x80:
2660ccea Poul Sander 2023-09-22 19:25 6157
            case 0x81:
2660ccea Poul Sander 2023-09-22 19:25 6158
            case 0x82:
2660ccea Poul Sander 2023-09-22 19:25 6159
            case 0x83:
2660ccea Poul Sander 2023-09-22 19:25 6160
            case 0x84:
2660ccea Poul Sander 2023-09-22 19:25 6161
            case 0x85:
2660ccea Poul Sander 2023-09-22 19:25 6162
            case 0x86:
2660ccea Poul Sander 2023-09-22 19:25 6163
            case 0x87:
2660ccea Poul Sander 2023-09-22 19:25 6164
            case 0x88:
2660ccea Poul Sander 2023-09-22 19:25 6165
            case 0x89:
2660ccea Poul Sander 2023-09-22 19:25 6166
            case 0x8A:
2660ccea Poul Sander 2023-09-22 19:25 6167
            case 0x8B:
2660ccea Poul Sander 2023-09-22 19:25 6168
            case 0x8C:
2660ccea Poul Sander 2023-09-22 19:25 6169
            case 0x8D:
2660ccea Poul Sander 2023-09-22 19:25 6170
            case 0x8E:
2660ccea Poul Sander 2023-09-22 19:25 6171
            case 0x8F:
2660ccea Poul Sander 2023-09-22 19:25 6172
                return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
2660ccea Poul Sander 2023-09-22 19:25 6173
2660ccea Poul Sander 2023-09-22 19:25 6174
            // fixarray
2660ccea Poul Sander 2023-09-22 19:25 6175
            case 0x90:
2660ccea Poul Sander 2023-09-22 19:25 6176
            case 0x91:
2660ccea Poul Sander 2023-09-22 19:25 6177
            case 0x92:
2660ccea Poul Sander 2023-09-22 19:25 6178
            case 0x93:
2660ccea Poul Sander 2023-09-22 19:25 6179
            case 0x94:
2660ccea Poul Sander 2023-09-22 19:25 6180
            case 0x95:
2660ccea Poul Sander 2023-09-22 19:25 6181
            case 0x96:
2660ccea Poul Sander 2023-09-22 19:25 6182
            case 0x97:
2660ccea Poul Sander 2023-09-22 19:25 6183
            case 0x98:
2660ccea Poul Sander 2023-09-22 19:25 6184
            case 0x99:
2660ccea Poul Sander 2023-09-22 19:25 6185
            case 0x9A:
2660ccea Poul Sander 2023-09-22 19:25 6186
            case 0x9B:
2660ccea Poul Sander 2023-09-22 19:25 6187
            case 0x9C:
2660ccea Poul Sander 2023-09-22 19:25 6188
            case 0x9D:
2660ccea Poul Sander 2023-09-22 19:25 6189
            case 0x9E:
2660ccea Poul Sander 2023-09-22 19:25 6190
            case 0x9F:
2660ccea Poul Sander 2023-09-22 19:25 6191
                return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
2660ccea Poul Sander 2023-09-22 19:25 6192
2660ccea Poul Sander 2023-09-22 19:25 6193
            // fixstr
2660ccea Poul Sander 2023-09-22 19:25 6194
            case 0xA0:
2660ccea Poul Sander 2023-09-22 19:25 6195
            case 0xA1:
2660ccea Poul Sander 2023-09-22 19:25 6196
            case 0xA2:
2660ccea Poul Sander 2023-09-22 19:25 6197
            case 0xA3:
2660ccea Poul Sander 2023-09-22 19:25 6198
            case 0xA4:
2660ccea Poul Sander 2023-09-22 19:25 6199
            case 0xA5:
2660ccea Poul Sander 2023-09-22 19:25 6200
            case 0xA6:
2660ccea Poul Sander 2023-09-22 19:25 6201
            case 0xA7:
2660ccea Poul Sander 2023-09-22 19:25 6202
            case 0xA8:
2660ccea Poul Sander 2023-09-22 19:25 6203
            case 0xA9:
2660ccea Poul Sander 2023-09-22 19:25 6204
            case 0xAA:
2660ccea Poul Sander 2023-09-22 19:25 6205
            case 0xAB:
2660ccea Poul Sander 2023-09-22 19:25 6206
            case 0xAC:
2660ccea Poul Sander 2023-09-22 19:25 6207
            case 0xAD:
2660ccea Poul Sander 2023-09-22 19:25 6208
            case 0xAE:
2660ccea Poul Sander 2023-09-22 19:25 6209
            case 0xAF:
2660ccea Poul Sander 2023-09-22 19:25 6210
            case 0xB0:
2660ccea Poul Sander 2023-09-22 19:25 6211
            case 0xB1:
2660ccea Poul Sander 2023-09-22 19:25 6212
            case 0xB2:
2660ccea Poul Sander 2023-09-22 19:25 6213
            case 0xB3:
2660ccea Poul Sander 2023-09-22 19:25 6214
            case 0xB4:
2660ccea Poul Sander 2023-09-22 19:25 6215
            case 0xB5:
2660ccea Poul Sander 2023-09-22 19:25 6216
            case 0xB6:
2660ccea Poul Sander 2023-09-22 19:25 6217
            case 0xB7:
2660ccea Poul Sander 2023-09-22 19:25 6218
            case 0xB8:
2660ccea Poul Sander 2023-09-22 19:25 6219
            case 0xB9:
2660ccea Poul Sander 2023-09-22 19:25 6220
            case 0xBA:
2660ccea Poul Sander 2023-09-22 19:25 6221
            case 0xBB:
2660ccea Poul Sander 2023-09-22 19:25 6222
            case 0xBC:
2660ccea Poul Sander 2023-09-22 19:25 6223
            case 0xBD:
2660ccea Poul Sander 2023-09-22 19:25 6224
            case 0xBE:
2660ccea Poul Sander 2023-09-22 19:25 6225
            case 0xBF:
2660ccea Poul Sander 2023-09-22 19:25 6226
            case 0xD9: // str 8
2660ccea Poul Sander 2023-09-22 19:25 6227
            case 0xDA: // str 16
2660ccea Poul Sander 2023-09-22 19:25 6228
            case 0xDB: // str 32
2660ccea Poul Sander 2023-09-22 19:25 6229
            {
2660ccea Poul Sander 2023-09-22 19:25 6230
                string_t s;
2660ccea Poul Sander 2023-09-22 19:25 6231
                return get_msgpack_string(s) and sax->string(s);
2660ccea Poul Sander 2023-09-22 19:25 6232
            }
2660ccea Poul Sander 2023-09-22 19:25 6233
2660ccea Poul Sander 2023-09-22 19:25 6234
            case 0xC0: // nil
2660ccea Poul Sander 2023-09-22 19:25 6235
                return sax->null();
2660ccea Poul Sander 2023-09-22 19:25 6236
2660ccea Poul Sander 2023-09-22 19:25 6237
            case 0xC2: // false
2660ccea Poul Sander 2023-09-22 19:25 6238
                return sax->boolean(false);
2660ccea Poul Sander 2023-09-22 19:25 6239
2660ccea Poul Sander 2023-09-22 19:25 6240
            case 0xC3: // true
2660ccea Poul Sander 2023-09-22 19:25 6241
                return sax->boolean(true);
2660ccea Poul Sander 2023-09-22 19:25 6242
2660ccea Poul Sander 2023-09-22 19:25 6243
            case 0xCA: // float 32
2660ccea Poul Sander 2023-09-22 19:25 6244
            {
2660ccea Poul Sander 2023-09-22 19:25 6245
                float number;
2660ccea Poul Sander 2023-09-22 19:25 6246
                return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
2660ccea Poul Sander 2023-09-22 19:25 6247
            }
2660ccea Poul Sander 2023-09-22 19:25 6248
2660ccea Poul Sander 2023-09-22 19:25 6249
            case 0xCB: // float 64
2660ccea Poul Sander 2023-09-22 19:25 6250
            {
2660ccea Poul Sander 2023-09-22 19:25 6251
                double number;
2660ccea Poul Sander 2023-09-22 19:25 6252
                return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
2660ccea Poul Sander 2023-09-22 19:25 6253
            }
2660ccea Poul Sander 2023-09-22 19:25 6254
2660ccea Poul Sander 2023-09-22 19:25 6255
            case 0xCC: // uint 8
2660ccea Poul Sander 2023-09-22 19:25 6256
            {
2660ccea Poul Sander 2023-09-22 19:25 6257
                std::uint8_t number;
2660ccea Poul Sander 2023-09-22 19:25 6258
                return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
2660ccea Poul Sander 2023-09-22 19:25 6259
            }
2660ccea Poul Sander 2023-09-22 19:25 6260
2660ccea Poul Sander 2023-09-22 19:25 6261
            case 0xCD: // uint 16
2660ccea Poul Sander 2023-09-22 19:25 6262
            {
2660ccea Poul Sander 2023-09-22 19:25 6263
                std::uint16_t number;
2660ccea Poul Sander 2023-09-22 19:25 6264
                return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
2660ccea Poul Sander 2023-09-22 19:25 6265
            }
2660ccea Poul Sander 2023-09-22 19:25 6266
2660ccea Poul Sander 2023-09-22 19:25 6267
            case 0xCE: // uint 32
2660ccea Poul Sander 2023-09-22 19:25 6268
            {
2660ccea Poul Sander 2023-09-22 19:25 6269
                std::uint32_t number;
2660ccea Poul Sander 2023-09-22 19:25 6270
                return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
2660ccea Poul Sander 2023-09-22 19:25 6271
            }
2660ccea Poul Sander 2023-09-22 19:25 6272
2660ccea Poul Sander 2023-09-22 19:25 6273
            case 0xCF: // uint 64
2660ccea Poul Sander 2023-09-22 19:25 6274
            {
2660ccea Poul Sander 2023-09-22 19:25 6275
                std::uint64_t number;
2660ccea Poul Sander 2023-09-22 19:25 6276
                return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
2660ccea Poul Sander 2023-09-22 19:25 6277
            }
2660ccea Poul Sander 2023-09-22 19:25 6278
2660ccea Poul Sander 2023-09-22 19:25 6279
            case 0xD0: // int 8
2660ccea Poul Sander 2023-09-22 19:25 6280
            {
2660ccea Poul Sander 2023-09-22 19:25 6281
                std::int8_t number;
2660ccea Poul Sander 2023-09-22 19:25 6282
                return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
2660ccea Poul Sander 2023-09-22 19:25 6283
            }
2660ccea Poul Sander 2023-09-22 19:25 6284
2660ccea Poul Sander 2023-09-22 19:25 6285
            case 0xD1: // int 16
2660ccea Poul Sander 2023-09-22 19:25 6286
            {
2660ccea Poul Sander 2023-09-22 19:25 6287
                std::int16_t number;
2660ccea Poul Sander 2023-09-22 19:25 6288
                return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
2660ccea Poul Sander 2023-09-22 19:25 6289
            }
2660ccea Poul Sander 2023-09-22 19:25 6290
2660ccea Poul Sander 2023-09-22 19:25 6291
            case 0xD2: // int 32
2660ccea Poul Sander 2023-09-22 19:25 6292
            {
2660ccea Poul Sander 2023-09-22 19:25 6293
                std::int32_t number;
2660ccea Poul Sander 2023-09-22 19:25 6294
                return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
2660ccea Poul Sander 2023-09-22 19:25 6295
            }
2660ccea Poul Sander 2023-09-22 19:25 6296
2660ccea Poul Sander 2023-09-22 19:25 6297
            case 0xD3: // int 64
2660ccea Poul Sander 2023-09-22 19:25 6298
            {
2660ccea Poul Sander 2023-09-22 19:25 6299
                std::int64_t number;
2660ccea Poul Sander 2023-09-22 19:25 6300
                return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
2660ccea Poul Sander 2023-09-22 19:25 6301
            }
2660ccea Poul Sander 2023-09-22 19:25 6302
2660ccea Poul Sander 2023-09-22 19:25 6303
            case 0xDC: // array 16
2660ccea Poul Sander 2023-09-22 19:25 6304
            {
2660ccea Poul Sander 2023-09-22 19:25 6305
                std::uint16_t len;
2660ccea Poul Sander 2023-09-22 19:25 6306
                return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 6307
            }
2660ccea Poul Sander 2023-09-22 19:25 6308
2660ccea Poul Sander 2023-09-22 19:25 6309
            case 0xDD: // array 32
2660ccea Poul Sander 2023-09-22 19:25 6310
            {
2660ccea Poul Sander 2023-09-22 19:25 6311
                std::uint32_t len;
2660ccea Poul Sander 2023-09-22 19:25 6312
                return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 6313
            }
2660ccea Poul Sander 2023-09-22 19:25 6314
2660ccea Poul Sander 2023-09-22 19:25 6315
            case 0xDE: // map 16
2660ccea Poul Sander 2023-09-22 19:25 6316
            {
2660ccea Poul Sander 2023-09-22 19:25 6317
                std::uint16_t len;
2660ccea Poul Sander 2023-09-22 19:25 6318
                return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 6319
            }
2660ccea Poul Sander 2023-09-22 19:25 6320
2660ccea Poul Sander 2023-09-22 19:25 6321
            case 0xDF: // map 32
2660ccea Poul Sander 2023-09-22 19:25 6322
            {
2660ccea Poul Sander 2023-09-22 19:25 6323
                std::uint32_t len;
2660ccea Poul Sander 2023-09-22 19:25 6324
                return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 6325
            }
2660ccea Poul Sander 2023-09-22 19:25 6326
2660ccea Poul Sander 2023-09-22 19:25 6327
            // negative fixint
2660ccea Poul Sander 2023-09-22 19:25 6328
            case 0xE0:
2660ccea Poul Sander 2023-09-22 19:25 6329
            case 0xE1:
2660ccea Poul Sander 2023-09-22 19:25 6330
            case 0xE2:
2660ccea Poul Sander 2023-09-22 19:25 6331
            case 0xE3:
2660ccea Poul Sander 2023-09-22 19:25 6332
            case 0xE4:
2660ccea Poul Sander 2023-09-22 19:25 6333
            case 0xE5:
2660ccea Poul Sander 2023-09-22 19:25 6334
            case 0xE6:
2660ccea Poul Sander 2023-09-22 19:25 6335
            case 0xE7:
2660ccea Poul Sander 2023-09-22 19:25 6336
            case 0xE8:
2660ccea Poul Sander 2023-09-22 19:25 6337
            case 0xE9:
2660ccea Poul Sander 2023-09-22 19:25 6338
            case 0xEA:
2660ccea Poul Sander 2023-09-22 19:25 6339
            case 0xEB:
2660ccea Poul Sander 2023-09-22 19:25 6340
            case 0xEC:
2660ccea Poul Sander 2023-09-22 19:25 6341
            case 0xED:
2660ccea Poul Sander 2023-09-22 19:25 6342
            case 0xEE:
2660ccea Poul Sander 2023-09-22 19:25 6343
            case 0xEF:
2660ccea Poul Sander 2023-09-22 19:25 6344
            case 0xF0:
2660ccea Poul Sander 2023-09-22 19:25 6345
            case 0xF1:
2660ccea Poul Sander 2023-09-22 19:25 6346
            case 0xF2:
2660ccea Poul Sander 2023-09-22 19:25 6347
            case 0xF3:
2660ccea Poul Sander 2023-09-22 19:25 6348
            case 0xF4:
2660ccea Poul Sander 2023-09-22 19:25 6349
            case 0xF5:
2660ccea Poul Sander 2023-09-22 19:25 6350
            case 0xF6:
2660ccea Poul Sander 2023-09-22 19:25 6351
            case 0xF7:
2660ccea Poul Sander 2023-09-22 19:25 6352
            case 0xF8:
2660ccea Poul Sander 2023-09-22 19:25 6353
            case 0xF9:
2660ccea Poul Sander 2023-09-22 19:25 6354
            case 0xFA:
2660ccea Poul Sander 2023-09-22 19:25 6355
            case 0xFB:
2660ccea Poul Sander 2023-09-22 19:25 6356
            case 0xFC:
2660ccea Poul Sander 2023-09-22 19:25 6357
            case 0xFD:
2660ccea Poul Sander 2023-09-22 19:25 6358
            case 0xFE:
2660ccea Poul Sander 2023-09-22 19:25 6359
            case 0xFF:
2660ccea Poul Sander 2023-09-22 19:25 6360
                return sax->number_integer(static_cast<std::int8_t>(current));
2660ccea Poul Sander 2023-09-22 19:25 6361
2660ccea Poul Sander 2023-09-22 19:25 6362
            default: // anything else
2660ccea Poul Sander 2023-09-22 19:25 6363
            {
2660ccea Poul Sander 2023-09-22 19:25 6364
                auto last_token = get_token_string();
2660ccea Poul Sander 2023-09-22 19:25 6365
                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")));
2660ccea Poul Sander 2023-09-22 19:25 6366
            }
2660ccea Poul Sander 2023-09-22 19:25 6367
        }
2660ccea Poul Sander 2023-09-22 19:25 6368
    }
2660ccea Poul Sander 2023-09-22 19:25 6369
2660ccea Poul Sander 2023-09-22 19:25 6370
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6371
    @brief reads a MessagePack string
2660ccea Poul Sander 2023-09-22 19:25 6372
2660ccea Poul Sander 2023-09-22 19:25 6373
    This function first reads starting bytes to determine the expected
2660ccea Poul Sander 2023-09-22 19:25 6374
    string length and then copies this number of bytes into a string.
2660ccea Poul Sander 2023-09-22 19:25 6375
2660ccea Poul Sander 2023-09-22 19:25 6376
    @param[out] result  created string
2660ccea Poul Sander 2023-09-22 19:25 6377
2660ccea Poul Sander 2023-09-22 19:25 6378
    @return whether string creation completed
2660ccea Poul Sander 2023-09-22 19:25 6379
    */
2660ccea Poul Sander 2023-09-22 19:25 6380
    bool get_msgpack_string(string_t& result)
2660ccea Poul Sander 2023-09-22 19:25 6381
    {
2660ccea Poul Sander 2023-09-22 19:25 6382
        if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
2660ccea Poul Sander 2023-09-22 19:25 6383
        {
2660ccea Poul Sander 2023-09-22 19:25 6384
            return false;
2660ccea Poul Sander 2023-09-22 19:25 6385
        }
2660ccea Poul Sander 2023-09-22 19:25 6386
2660ccea Poul Sander 2023-09-22 19:25 6387
        switch (current)
2660ccea Poul Sander 2023-09-22 19:25 6388
        {
2660ccea Poul Sander 2023-09-22 19:25 6389
            // fixstr
2660ccea Poul Sander 2023-09-22 19:25 6390
            case 0xA0:
2660ccea Poul Sander 2023-09-22 19:25 6391
            case 0xA1:
2660ccea Poul Sander 2023-09-22 19:25 6392
            case 0xA2:
2660ccea Poul Sander 2023-09-22 19:25 6393
            case 0xA3:
2660ccea Poul Sander 2023-09-22 19:25 6394
            case 0xA4:
2660ccea Poul Sander 2023-09-22 19:25 6395
            case 0xA5:
2660ccea Poul Sander 2023-09-22 19:25 6396
            case 0xA6:
2660ccea Poul Sander 2023-09-22 19:25 6397
            case 0xA7:
2660ccea Poul Sander 2023-09-22 19:25 6398
            case 0xA8:
2660ccea Poul Sander 2023-09-22 19:25 6399
            case 0xA9:
2660ccea Poul Sander 2023-09-22 19:25 6400
            case 0xAA:
2660ccea Poul Sander 2023-09-22 19:25 6401
            case 0xAB:
2660ccea Poul Sander 2023-09-22 19:25 6402
            case 0xAC:
2660ccea Poul Sander 2023-09-22 19:25 6403
            case 0xAD:
2660ccea Poul Sander 2023-09-22 19:25 6404
            case 0xAE:
2660ccea Poul Sander 2023-09-22 19:25 6405
            case 0xAF:
2660ccea Poul Sander 2023-09-22 19:25 6406
            case 0xB0:
2660ccea Poul Sander 2023-09-22 19:25 6407
            case 0xB1:
2660ccea Poul Sander 2023-09-22 19:25 6408
            case 0xB2:
2660ccea Poul Sander 2023-09-22 19:25 6409
            case 0xB3:
2660ccea Poul Sander 2023-09-22 19:25 6410
            case 0xB4:
2660ccea Poul Sander 2023-09-22 19:25 6411
            case 0xB5:
2660ccea Poul Sander 2023-09-22 19:25 6412
            case 0xB6:
2660ccea Poul Sander 2023-09-22 19:25 6413
            case 0xB7:
2660ccea Poul Sander 2023-09-22 19:25 6414
            case 0xB8:
2660ccea Poul Sander 2023-09-22 19:25 6415
            case 0xB9:
2660ccea Poul Sander 2023-09-22 19:25 6416
            case 0xBA:
2660ccea Poul Sander 2023-09-22 19:25 6417
            case 0xBB:
2660ccea Poul Sander 2023-09-22 19:25 6418
            case 0xBC:
2660ccea Poul Sander 2023-09-22 19:25 6419
            case 0xBD:
2660ccea Poul Sander 2023-09-22 19:25 6420
            case 0xBE:
2660ccea Poul Sander 2023-09-22 19:25 6421
            case 0xBF:
2660ccea Poul Sander 2023-09-22 19:25 6422
            {
2660ccea Poul Sander 2023-09-22 19:25 6423
                return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
2660ccea Poul Sander 2023-09-22 19:25 6424
            }
2660ccea Poul Sander 2023-09-22 19:25 6425
2660ccea Poul Sander 2023-09-22 19:25 6426
            case 0xD9: // str 8
2660ccea Poul Sander 2023-09-22 19:25 6427
            {
2660ccea Poul Sander 2023-09-22 19:25 6428
                std::uint8_t len;
2660ccea Poul Sander 2023-09-22 19:25 6429
                return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
2660ccea Poul Sander 2023-09-22 19:25 6430
            }
2660ccea Poul Sander 2023-09-22 19:25 6431
2660ccea Poul Sander 2023-09-22 19:25 6432
            case 0xDA: // str 16
2660ccea Poul Sander 2023-09-22 19:25 6433
            {
2660ccea Poul Sander 2023-09-22 19:25 6434
                std::uint16_t len;
2660ccea Poul Sander 2023-09-22 19:25 6435
                return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
2660ccea Poul Sander 2023-09-22 19:25 6436
            }
2660ccea Poul Sander 2023-09-22 19:25 6437
2660ccea Poul Sander 2023-09-22 19:25 6438
            case 0xDB: // str 32
2660ccea Poul Sander 2023-09-22 19:25 6439
            {
2660ccea Poul Sander 2023-09-22 19:25 6440
                std::uint32_t len;
2660ccea Poul Sander 2023-09-22 19:25 6441
                return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
2660ccea Poul Sander 2023-09-22 19:25 6442
            }
2660ccea Poul Sander 2023-09-22 19:25 6443
2660ccea Poul Sander 2023-09-22 19:25 6444
            default:
2660ccea Poul Sander 2023-09-22 19:25 6445
            {
2660ccea Poul Sander 2023-09-22 19:25 6446
                auto last_token = get_token_string();
2660ccea Poul Sander 2023-09-22 19:25 6447
                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")));
2660ccea Poul Sander 2023-09-22 19:25 6448
            }
2660ccea Poul Sander 2023-09-22 19:25 6449
        }
2660ccea Poul Sander 2023-09-22 19:25 6450
    }
2660ccea Poul Sander 2023-09-22 19:25 6451
2660ccea Poul Sander 2023-09-22 19:25 6452
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6453
    @param[in] len  the length of the array
2660ccea Poul Sander 2023-09-22 19:25 6454
    @return whether array creation completed
2660ccea Poul Sander 2023-09-22 19:25 6455
    */
2660ccea Poul Sander 2023-09-22 19:25 6456
    bool get_msgpack_array(const std::size_t len)
2660ccea Poul Sander 2023-09-22 19:25 6457
    {
2660ccea Poul Sander 2023-09-22 19:25 6458
        if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
2660ccea Poul Sander 2023-09-22 19:25 6459
        {
2660ccea Poul Sander 2023-09-22 19:25 6460
            return false;
2660ccea Poul Sander 2023-09-22 19:25 6461
        }
2660ccea Poul Sander 2023-09-22 19:25 6462
2660ccea Poul Sander 2023-09-22 19:25 6463
        for (std::size_t i = 0; i < len; ++i)
2660ccea Poul Sander 2023-09-22 19:25 6464
        {
2660ccea Poul Sander 2023-09-22 19:25 6465
            if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
2660ccea Poul Sander 2023-09-22 19:25 6466
            {
2660ccea Poul Sander 2023-09-22 19:25 6467
                return false;
2660ccea Poul Sander 2023-09-22 19:25 6468
            }
2660ccea Poul Sander 2023-09-22 19:25 6469
        }
2660ccea Poul Sander 2023-09-22 19:25 6470
2660ccea Poul Sander 2023-09-22 19:25 6471
        return sax->end_array();
2660ccea Poul Sander 2023-09-22 19:25 6472
    }
2660ccea Poul Sander 2023-09-22 19:25 6473
2660ccea Poul Sander 2023-09-22 19:25 6474
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6475
    @param[in] len  the length of the object
2660ccea Poul Sander 2023-09-22 19:25 6476
    @return whether object creation completed
2660ccea Poul Sander 2023-09-22 19:25 6477
    */
2660ccea Poul Sander 2023-09-22 19:25 6478
    bool get_msgpack_object(const std::size_t len)
2660ccea Poul Sander 2023-09-22 19:25 6479
    {
2660ccea Poul Sander 2023-09-22 19:25 6480
        if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
2660ccea Poul Sander 2023-09-22 19:25 6481
        {
2660ccea Poul Sander 2023-09-22 19:25 6482
            return false;
2660ccea Poul Sander 2023-09-22 19:25 6483
        }
2660ccea Poul Sander 2023-09-22 19:25 6484
2660ccea Poul Sander 2023-09-22 19:25 6485
        string_t key;
2660ccea Poul Sander 2023-09-22 19:25 6486
        for (std::size_t i = 0; i < len; ++i)
2660ccea Poul Sander 2023-09-22 19:25 6487
        {
2660ccea Poul Sander 2023-09-22 19:25 6488
            get();
2660ccea Poul Sander 2023-09-22 19:25 6489
            if (JSON_HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
2660ccea Poul Sander 2023-09-22 19:25 6490
            {
2660ccea Poul Sander 2023-09-22 19:25 6491
                return false;
2660ccea Poul Sander 2023-09-22 19:25 6492
            }
2660ccea Poul Sander 2023-09-22 19:25 6493
2660ccea Poul Sander 2023-09-22 19:25 6494
            if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
2660ccea Poul Sander 2023-09-22 19:25 6495
            {
2660ccea Poul Sander 2023-09-22 19:25 6496
                return false;
2660ccea Poul Sander 2023-09-22 19:25 6497
            }
2660ccea Poul Sander 2023-09-22 19:25 6498
            key.clear();
2660ccea Poul Sander 2023-09-22 19:25 6499
        }
2660ccea Poul Sander 2023-09-22 19:25 6500
2660ccea Poul Sander 2023-09-22 19:25 6501
        return sax->end_object();
2660ccea Poul Sander 2023-09-22 19:25 6502
    }
2660ccea Poul Sander 2023-09-22 19:25 6503
2660ccea Poul Sander 2023-09-22 19:25 6504
    ////////////
2660ccea Poul Sander 2023-09-22 19:25 6505
    // UBJSON //
2660ccea Poul Sander 2023-09-22 19:25 6506
    ////////////
2660ccea Poul Sander 2023-09-22 19:25 6507
2660ccea Poul Sander 2023-09-22 19:25 6508
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6509
    @param[in] get_char  whether a new character should be retrieved from the
2660ccea Poul Sander 2023-09-22 19:25 6510
                         input (true, default) or whether the last read
2660ccea Poul Sander 2023-09-22 19:25 6511
                         character should be considered instead
2660ccea Poul Sander 2023-09-22 19:25 6512
2660ccea Poul Sander 2023-09-22 19:25 6513
    @return whether a valid UBJSON value was passed to the SAX parser
2660ccea Poul Sander 2023-09-22 19:25 6514
    */
2660ccea Poul Sander 2023-09-22 19:25 6515
    bool parse_ubjson_internal(const bool get_char = true)
2660ccea Poul Sander 2023-09-22 19:25 6516
    {
2660ccea Poul Sander 2023-09-22 19:25 6517
        return get_ubjson_value(get_char ? get_ignore_noop() : current);
2660ccea Poul Sander 2023-09-22 19:25 6518
    }
2660ccea Poul Sander 2023-09-22 19:25 6519
2660ccea Poul Sander 2023-09-22 19:25 6520
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6521
    @brief reads a UBJSON string
2660ccea Poul Sander 2023-09-22 19:25 6522
2660ccea Poul Sander 2023-09-22 19:25 6523
    This function is either called after reading the 'S' byte explicitly
2660ccea Poul Sander 2023-09-22 19:25 6524
    indicating a string, or in case of an object key where the 'S' byte can be
2660ccea Poul Sander 2023-09-22 19:25 6525
    left out.
2660ccea Poul Sander 2023-09-22 19:25 6526
2660ccea Poul Sander 2023-09-22 19:25 6527
    @param[out] result   created string
2660ccea Poul Sander 2023-09-22 19:25 6528
    @param[in] get_char  whether a new character should be retrieved from the
2660ccea Poul Sander 2023-09-22 19:25 6529
                         input (true, default) or whether the last read
2660ccea Poul Sander 2023-09-22 19:25 6530
                         character should be considered instead
2660ccea Poul Sander 2023-09-22 19:25 6531
2660ccea Poul Sander 2023-09-22 19:25 6532
    @return whether string creation completed
2660ccea Poul Sander 2023-09-22 19:25 6533
    */
2660ccea Poul Sander 2023-09-22 19:25 6534
    bool get_ubjson_string(string_t& result, const bool get_char = true)
2660ccea Poul Sander 2023-09-22 19:25 6535
    {
2660ccea Poul Sander 2023-09-22 19:25 6536
        if (get_char)
2660ccea Poul Sander 2023-09-22 19:25 6537
        {
2660ccea Poul Sander 2023-09-22 19:25 6538
            get();  // TODO(niels): may we ignore N here?
2660ccea Poul Sander 2023-09-22 19:25 6539
        }
2660ccea Poul Sander 2023-09-22 19:25 6540
2660ccea Poul Sander 2023-09-22 19:25 6541
        if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
2660ccea Poul Sander 2023-09-22 19:25 6542
        {
2660ccea Poul Sander 2023-09-22 19:25 6543
            return false;
2660ccea Poul Sander 2023-09-22 19:25 6544
        }
2660ccea Poul Sander 2023-09-22 19:25 6545
2660ccea Poul Sander 2023-09-22 19:25 6546
        switch (current)
2660ccea Poul Sander 2023-09-22 19:25 6547
        {
2660ccea Poul Sander 2023-09-22 19:25 6548
            case 'U':
2660ccea Poul Sander 2023-09-22 19:25 6549
            {
2660ccea Poul Sander 2023-09-22 19:25 6550
                std::uint8_t len;
2660ccea Poul Sander 2023-09-22 19:25 6551
                return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
2660ccea Poul Sander 2023-09-22 19:25 6552
            }
2660ccea Poul Sander 2023-09-22 19:25 6553
2660ccea Poul Sander 2023-09-22 19:25 6554
            case 'i':
2660ccea Poul Sander 2023-09-22 19:25 6555
            {
2660ccea Poul Sander 2023-09-22 19:25 6556
                std::int8_t len;
2660ccea Poul Sander 2023-09-22 19:25 6557
                return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
2660ccea Poul Sander 2023-09-22 19:25 6558
            }
2660ccea Poul Sander 2023-09-22 19:25 6559
2660ccea Poul Sander 2023-09-22 19:25 6560
            case 'I':
2660ccea Poul Sander 2023-09-22 19:25 6561
            {
2660ccea Poul Sander 2023-09-22 19:25 6562
                std::int16_t len;
2660ccea Poul Sander 2023-09-22 19:25 6563
                return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
2660ccea Poul Sander 2023-09-22 19:25 6564
            }
2660ccea Poul Sander 2023-09-22 19:25 6565
2660ccea Poul Sander 2023-09-22 19:25 6566
            case 'l':
2660ccea Poul Sander 2023-09-22 19:25 6567
            {
2660ccea Poul Sander 2023-09-22 19:25 6568
                std::int32_t len;
2660ccea Poul Sander 2023-09-22 19:25 6569
                return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
2660ccea Poul Sander 2023-09-22 19:25 6570
            }
2660ccea Poul Sander 2023-09-22 19:25 6571
2660ccea Poul Sander 2023-09-22 19:25 6572
            case 'L':
2660ccea Poul Sander 2023-09-22 19:25 6573
            {
2660ccea Poul Sander 2023-09-22 19:25 6574
                std::int64_t len;
2660ccea Poul Sander 2023-09-22 19:25 6575
                return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
2660ccea Poul Sander 2023-09-22 19:25 6576
            }
2660ccea Poul Sander 2023-09-22 19:25 6577
2660ccea Poul Sander 2023-09-22 19:25 6578
            default:
2660ccea Poul Sander 2023-09-22 19:25 6579
                auto last_token = get_token_string();
2660ccea Poul Sander 2023-09-22 19:25 6580
                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")));
2660ccea Poul Sander 2023-09-22 19:25 6581
        }
2660ccea Poul Sander 2023-09-22 19:25 6582
    }
2660ccea Poul Sander 2023-09-22 19:25 6583
2660ccea Poul Sander 2023-09-22 19:25 6584
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6585
    @param[out] result  determined size
2660ccea Poul Sander 2023-09-22 19:25 6586
    @return whether size determination completed
2660ccea Poul Sander 2023-09-22 19:25 6587
    */
2660ccea Poul Sander 2023-09-22 19:25 6588
    bool get_ubjson_size_value(std::size_t& result)
2660ccea Poul Sander 2023-09-22 19:25 6589
    {
2660ccea Poul Sander 2023-09-22 19:25 6590
        switch (get_ignore_noop())
2660ccea Poul Sander 2023-09-22 19:25 6591
        {
2660ccea Poul Sander 2023-09-22 19:25 6592
            case 'U':
2660ccea Poul Sander 2023-09-22 19:25 6593
            {
2660ccea Poul Sander 2023-09-22 19:25 6594
                std::uint8_t number;
2660ccea Poul Sander 2023-09-22 19:25 6595
                if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
2660ccea Poul Sander 2023-09-22 19:25 6596
                {
2660ccea Poul Sander 2023-09-22 19:25 6597
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 6598
                }
2660ccea Poul Sander 2023-09-22 19:25 6599
                result = static_cast<std::size_t>(number);
2660ccea Poul Sander 2023-09-22 19:25 6600
                return true;
2660ccea Poul Sander 2023-09-22 19:25 6601
            }
2660ccea Poul Sander 2023-09-22 19:25 6602
2660ccea Poul Sander 2023-09-22 19:25 6603
            case 'i':
2660ccea Poul Sander 2023-09-22 19:25 6604
            {
2660ccea Poul Sander 2023-09-22 19:25 6605
                std::int8_t number;
2660ccea Poul Sander 2023-09-22 19:25 6606
                if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
2660ccea Poul Sander 2023-09-22 19:25 6607
                {
2660ccea Poul Sander 2023-09-22 19:25 6608
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 6609
                }
2660ccea Poul Sander 2023-09-22 19:25 6610
                result = static_cast<std::size_t>(number);
2660ccea Poul Sander 2023-09-22 19:25 6611
                return true;
2660ccea Poul Sander 2023-09-22 19:25 6612
            }
2660ccea Poul Sander 2023-09-22 19:25 6613
2660ccea Poul Sander 2023-09-22 19:25 6614
            case 'I':
2660ccea Poul Sander 2023-09-22 19:25 6615
            {
2660ccea Poul Sander 2023-09-22 19:25 6616
                std::int16_t number;
2660ccea Poul Sander 2023-09-22 19:25 6617
                if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
2660ccea Poul Sander 2023-09-22 19:25 6618
                {
2660ccea Poul Sander 2023-09-22 19:25 6619
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 6620
                }
2660ccea Poul Sander 2023-09-22 19:25 6621
                result = static_cast<std::size_t>(number);
2660ccea Poul Sander 2023-09-22 19:25 6622
                return true;
2660ccea Poul Sander 2023-09-22 19:25 6623
            }
2660ccea Poul Sander 2023-09-22 19:25 6624
2660ccea Poul Sander 2023-09-22 19:25 6625
            case 'l':
2660ccea Poul Sander 2023-09-22 19:25 6626
            {
2660ccea Poul Sander 2023-09-22 19:25 6627
                std::int32_t number;
2660ccea Poul Sander 2023-09-22 19:25 6628
                if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
2660ccea Poul Sander 2023-09-22 19:25 6629
                {
2660ccea Poul Sander 2023-09-22 19:25 6630
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 6631
                }
2660ccea Poul Sander 2023-09-22 19:25 6632
                result = static_cast<std::size_t>(number);
2660ccea Poul Sander 2023-09-22 19:25 6633
                return true;
2660ccea Poul Sander 2023-09-22 19:25 6634
            }
2660ccea Poul Sander 2023-09-22 19:25 6635
2660ccea Poul Sander 2023-09-22 19:25 6636
            case 'L':
2660ccea Poul Sander 2023-09-22 19:25 6637
            {
2660ccea Poul Sander 2023-09-22 19:25 6638
                std::int64_t number;
2660ccea Poul Sander 2023-09-22 19:25 6639
                if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
2660ccea Poul Sander 2023-09-22 19:25 6640
                {
2660ccea Poul Sander 2023-09-22 19:25 6641
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 6642
                }
2660ccea Poul Sander 2023-09-22 19:25 6643
                result = static_cast<std::size_t>(number);
2660ccea Poul Sander 2023-09-22 19:25 6644
                return true;
2660ccea Poul Sander 2023-09-22 19:25 6645
            }
2660ccea Poul Sander 2023-09-22 19:25 6646
2660ccea Poul Sander 2023-09-22 19:25 6647
            default:
2660ccea Poul Sander 2023-09-22 19:25 6648
            {
2660ccea Poul Sander 2023-09-22 19:25 6649
                auto last_token = get_token_string();
2660ccea Poul Sander 2023-09-22 19:25 6650
                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")));
2660ccea Poul Sander 2023-09-22 19:25 6651
            }
2660ccea Poul Sander 2023-09-22 19:25 6652
        }
2660ccea Poul Sander 2023-09-22 19:25 6653
    }
2660ccea Poul Sander 2023-09-22 19:25 6654
2660ccea Poul Sander 2023-09-22 19:25 6655
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6656
    @brief determine the type and size for a container
2660ccea Poul Sander 2023-09-22 19:25 6657
2660ccea Poul Sander 2023-09-22 19:25 6658
    In the optimized UBJSON format, a type and a size can be provided to allow
2660ccea Poul Sander 2023-09-22 19:25 6659
    for a more compact representation.
2660ccea Poul Sander 2023-09-22 19:25 6660
2660ccea Poul Sander 2023-09-22 19:25 6661
    @param[out] result  pair of the size and the type
2660ccea Poul Sander 2023-09-22 19:25 6662
2660ccea Poul Sander 2023-09-22 19:25 6663
    @return whether pair creation completed
2660ccea Poul Sander 2023-09-22 19:25 6664
    */
2660ccea Poul Sander 2023-09-22 19:25 6665
    bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
2660ccea Poul Sander 2023-09-22 19:25 6666
    {
2660ccea Poul Sander 2023-09-22 19:25 6667
        result.first = string_t::npos; // size
2660ccea Poul Sander 2023-09-22 19:25 6668
        result.second = 0; // type
2660ccea Poul Sander 2023-09-22 19:25 6669
2660ccea Poul Sander 2023-09-22 19:25 6670
        get_ignore_noop();
2660ccea Poul Sander 2023-09-22 19:25 6671
2660ccea Poul Sander 2023-09-22 19:25 6672
        if (current == '$')
2660ccea Poul Sander 2023-09-22 19:25 6673
        {
2660ccea Poul Sander 2023-09-22 19:25 6674
            result.second = get();  // must not ignore 'N', because 'N' maybe the type
2660ccea Poul Sander 2023-09-22 19:25 6675
            if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
2660ccea Poul Sander 2023-09-22 19:25 6676
            {
2660ccea Poul Sander 2023-09-22 19:25 6677
                return false;
2660ccea Poul Sander 2023-09-22 19:25 6678
            }
2660ccea Poul Sander 2023-09-22 19:25 6679
2660ccea Poul Sander 2023-09-22 19:25 6680
            get_ignore_noop();
2660ccea Poul Sander 2023-09-22 19:25 6681
            if (JSON_HEDLEY_UNLIKELY(current != '#'))
2660ccea Poul Sander 2023-09-22 19:25 6682
            {
2660ccea Poul Sander 2023-09-22 19:25 6683
                if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
2660ccea Poul Sander 2023-09-22 19:25 6684
                {
2660ccea Poul Sander 2023-09-22 19:25 6685
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 6686
                }
2660ccea Poul Sander 2023-09-22 19:25 6687
                auto last_token = get_token_string();
2660ccea Poul Sander 2023-09-22 19:25 6688
                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")));
2660ccea Poul Sander 2023-09-22 19:25 6689
            }
2660ccea Poul Sander 2023-09-22 19:25 6690
2660ccea Poul Sander 2023-09-22 19:25 6691
            return get_ubjson_size_value(result.first);
2660ccea Poul Sander 2023-09-22 19:25 6692
        }
2660ccea Poul Sander 2023-09-22 19:25 6693
2660ccea Poul Sander 2023-09-22 19:25 6694
        if (current == '#')
2660ccea Poul Sander 2023-09-22 19:25 6695
        {
2660ccea Poul Sander 2023-09-22 19:25 6696
            return get_ubjson_size_value(result.first);
2660ccea Poul Sander 2023-09-22 19:25 6697
        }
2660ccea Poul Sander 2023-09-22 19:25 6698
2660ccea Poul Sander 2023-09-22 19:25 6699
        return true;
2660ccea Poul Sander 2023-09-22 19:25 6700
    }
2660ccea Poul Sander 2023-09-22 19:25 6701
2660ccea Poul Sander 2023-09-22 19:25 6702
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6703
    @param prefix  the previously read or set type prefix
2660ccea Poul Sander 2023-09-22 19:25 6704
    @return whether value creation completed
2660ccea Poul Sander 2023-09-22 19:25 6705
    */
2660ccea Poul Sander 2023-09-22 19:25 6706
    bool get_ubjson_value(const int prefix)
2660ccea Poul Sander 2023-09-22 19:25 6707
    {
2660ccea Poul Sander 2023-09-22 19:25 6708
        switch (prefix)
2660ccea Poul Sander 2023-09-22 19:25 6709
        {
2660ccea Poul Sander 2023-09-22 19:25 6710
            case std::char_traits<char>::eof():  // EOF
2660ccea Poul Sander 2023-09-22 19:25 6711
                return unexpect_eof(input_format_t::ubjson, "value");
2660ccea Poul Sander 2023-09-22 19:25 6712
2660ccea Poul Sander 2023-09-22 19:25 6713
            case 'T':  // true
2660ccea Poul Sander 2023-09-22 19:25 6714
                return sax->boolean(true);
2660ccea Poul Sander 2023-09-22 19:25 6715
            case 'F':  // false
2660ccea Poul Sander 2023-09-22 19:25 6716
                return sax->boolean(false);
2660ccea Poul Sander 2023-09-22 19:25 6717
2660ccea Poul Sander 2023-09-22 19:25 6718
            case 'Z':  // null
2660ccea Poul Sander 2023-09-22 19:25 6719
                return sax->null();
2660ccea Poul Sander 2023-09-22 19:25 6720
2660ccea Poul Sander 2023-09-22 19:25 6721
            case 'U':
2660ccea Poul Sander 2023-09-22 19:25 6722
            {
2660ccea Poul Sander 2023-09-22 19:25 6723
                std::uint8_t number;
2660ccea Poul Sander 2023-09-22 19:25 6724
                return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
2660ccea Poul Sander 2023-09-22 19:25 6725
            }
2660ccea Poul Sander 2023-09-22 19:25 6726
2660ccea Poul Sander 2023-09-22 19:25 6727
            case 'i':
2660ccea Poul Sander 2023-09-22 19:25 6728
            {
2660ccea Poul Sander 2023-09-22 19:25 6729
                std::int8_t number;
2660ccea Poul Sander 2023-09-22 19:25 6730
                return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
2660ccea Poul Sander 2023-09-22 19:25 6731
            }
2660ccea Poul Sander 2023-09-22 19:25 6732
2660ccea Poul Sander 2023-09-22 19:25 6733
            case 'I':
2660ccea Poul Sander 2023-09-22 19:25 6734
            {
2660ccea Poul Sander 2023-09-22 19:25 6735
                std::int16_t number;
2660ccea Poul Sander 2023-09-22 19:25 6736
                return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
2660ccea Poul Sander 2023-09-22 19:25 6737
            }
2660ccea Poul Sander 2023-09-22 19:25 6738
2660ccea Poul Sander 2023-09-22 19:25 6739
            case 'l':
2660ccea Poul Sander 2023-09-22 19:25 6740
            {
2660ccea Poul Sander 2023-09-22 19:25 6741
                std::int32_t number;
2660ccea Poul Sander 2023-09-22 19:25 6742
                return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
2660ccea Poul Sander 2023-09-22 19:25 6743
            }
2660ccea Poul Sander 2023-09-22 19:25 6744
2660ccea Poul Sander 2023-09-22 19:25 6745
            case 'L':
2660ccea Poul Sander 2023-09-22 19:25 6746
            {
2660ccea Poul Sander 2023-09-22 19:25 6747
                std::int64_t number;
2660ccea Poul Sander 2023-09-22 19:25 6748
                return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
2660ccea Poul Sander 2023-09-22 19:25 6749
            }
2660ccea Poul Sander 2023-09-22 19:25 6750
2660ccea Poul Sander 2023-09-22 19:25 6751
            case 'd':
2660ccea Poul Sander 2023-09-22 19:25 6752
            {
2660ccea Poul Sander 2023-09-22 19:25 6753
                float number;
2660ccea Poul Sander 2023-09-22 19:25 6754
                return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
2660ccea Poul Sander 2023-09-22 19:25 6755
            }
2660ccea Poul Sander 2023-09-22 19:25 6756
2660ccea Poul Sander 2023-09-22 19:25 6757
            case 'D':
2660ccea Poul Sander 2023-09-22 19:25 6758
            {
2660ccea Poul Sander 2023-09-22 19:25 6759
                double number;
2660ccea Poul Sander 2023-09-22 19:25 6760
                return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
2660ccea Poul Sander 2023-09-22 19:25 6761
            }
2660ccea Poul Sander 2023-09-22 19:25 6762
2660ccea Poul Sander 2023-09-22 19:25 6763
            case 'C':  // char
2660ccea Poul Sander 2023-09-22 19:25 6764
            {
2660ccea Poul Sander 2023-09-22 19:25 6765
                get();
2660ccea Poul Sander 2023-09-22 19:25 6766
                if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
2660ccea Poul Sander 2023-09-22 19:25 6767
                {
2660ccea Poul Sander 2023-09-22 19:25 6768
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 6769
                }
2660ccea Poul Sander 2023-09-22 19:25 6770
                if (JSON_HEDLEY_UNLIKELY(current > 127))
2660ccea Poul Sander 2023-09-22 19:25 6771
                {
2660ccea Poul Sander 2023-09-22 19:25 6772
                    auto last_token = get_token_string();
2660ccea Poul Sander 2023-09-22 19:25 6773
                    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")));
2660ccea Poul Sander 2023-09-22 19:25 6774
                }
2660ccea Poul Sander 2023-09-22 19:25 6775
                string_t s(1, static_cast<char>(current));
2660ccea Poul Sander 2023-09-22 19:25 6776
                return sax->string(s);
2660ccea Poul Sander 2023-09-22 19:25 6777
            }
2660ccea Poul Sander 2023-09-22 19:25 6778
2660ccea Poul Sander 2023-09-22 19:25 6779
            case 'S':  // string
2660ccea Poul Sander 2023-09-22 19:25 6780
            {
2660ccea Poul Sander 2023-09-22 19:25 6781
                string_t s;
2660ccea Poul Sander 2023-09-22 19:25 6782
                return get_ubjson_string(s) and sax->string(s);
2660ccea Poul Sander 2023-09-22 19:25 6783
            }
2660ccea Poul Sander 2023-09-22 19:25 6784
2660ccea Poul Sander 2023-09-22 19:25 6785
            case '[':  // array
2660ccea Poul Sander 2023-09-22 19:25 6786
                return get_ubjson_array();
2660ccea Poul Sander 2023-09-22 19:25 6787
2660ccea Poul Sander 2023-09-22 19:25 6788
            case '{':  // object
2660ccea Poul Sander 2023-09-22 19:25 6789
                return get_ubjson_object();
2660ccea Poul Sander 2023-09-22 19:25 6790
2660ccea Poul Sander 2023-09-22 19:25 6791
            default: // anything else
2660ccea Poul Sander 2023-09-22 19:25 6792
            {
2660ccea Poul Sander 2023-09-22 19:25 6793
                auto last_token = get_token_string();
2660ccea Poul Sander 2023-09-22 19:25 6794
                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")));
2660ccea Poul Sander 2023-09-22 19:25 6795
            }
2660ccea Poul Sander 2023-09-22 19:25 6796
        }
2660ccea Poul Sander 2023-09-22 19:25 6797
    }
2660ccea Poul Sander 2023-09-22 19:25 6798
2660ccea Poul Sander 2023-09-22 19:25 6799
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6800
    @return whether array creation completed
2660ccea Poul Sander 2023-09-22 19:25 6801
    */
2660ccea Poul Sander 2023-09-22 19:25 6802
    bool get_ubjson_array()
2660ccea Poul Sander 2023-09-22 19:25 6803
    {
2660ccea Poul Sander 2023-09-22 19:25 6804
        std::pair<std::size_t, int> size_and_type;
2660ccea Poul Sander 2023-09-22 19:25 6805
        if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
2660ccea Poul Sander 2023-09-22 19:25 6806
        {
2660ccea Poul Sander 2023-09-22 19:25 6807
            return false;
2660ccea Poul Sander 2023-09-22 19:25 6808
        }
2660ccea Poul Sander 2023-09-22 19:25 6809
2660ccea Poul Sander 2023-09-22 19:25 6810
        if (size_and_type.first != string_t::npos)
2660ccea Poul Sander 2023-09-22 19:25 6811
        {
2660ccea Poul Sander 2023-09-22 19:25 6812
            if (JSON_HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first)))
2660ccea Poul Sander 2023-09-22 19:25 6813
            {
2660ccea Poul Sander 2023-09-22 19:25 6814
                return false;
2660ccea Poul Sander 2023-09-22 19:25 6815
            }
2660ccea Poul Sander 2023-09-22 19:25 6816
2660ccea Poul Sander 2023-09-22 19:25 6817
            if (size_and_type.second != 0)
2660ccea Poul Sander 2023-09-22 19:25 6818
            {
2660ccea Poul Sander 2023-09-22 19:25 6819
                if (size_and_type.second != 'N')
2660ccea Poul Sander 2023-09-22 19:25 6820
                {
2660ccea Poul Sander 2023-09-22 19:25 6821
                    for (std::size_t i = 0; i < size_and_type.first; ++i)
2660ccea Poul Sander 2023-09-22 19:25 6822
                    {
2660ccea Poul Sander 2023-09-22 19:25 6823
                        if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
2660ccea Poul Sander 2023-09-22 19:25 6824
                        {
2660ccea Poul Sander 2023-09-22 19:25 6825
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 6826
                        }
2660ccea Poul Sander 2023-09-22 19:25 6827
                    }
2660ccea Poul Sander 2023-09-22 19:25 6828
                }
2660ccea Poul Sander 2023-09-22 19:25 6829
            }
2660ccea Poul Sander 2023-09-22 19:25 6830
            else
2660ccea Poul Sander 2023-09-22 19:25 6831
            {
2660ccea Poul Sander 2023-09-22 19:25 6832
                for (std::size_t i = 0; i < size_and_type.first; ++i)
2660ccea Poul Sander 2023-09-22 19:25 6833
                {
2660ccea Poul Sander 2023-09-22 19:25 6834
                    if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
2660ccea Poul Sander 2023-09-22 19:25 6835
                    {
2660ccea Poul Sander 2023-09-22 19:25 6836
                        return false;
2660ccea Poul Sander 2023-09-22 19:25 6837
                    }
2660ccea Poul Sander 2023-09-22 19:25 6838
                }
2660ccea Poul Sander 2023-09-22 19:25 6839
            }
2660ccea Poul Sander 2023-09-22 19:25 6840
        }
2660ccea Poul Sander 2023-09-22 19:25 6841
        else
2660ccea Poul Sander 2023-09-22 19:25 6842
        {
2660ccea Poul Sander 2023-09-22 19:25 6843
            if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
2660ccea Poul Sander 2023-09-22 19:25 6844
            {
2660ccea Poul Sander 2023-09-22 19:25 6845
                return false;
2660ccea Poul Sander 2023-09-22 19:25 6846
            }
2660ccea Poul Sander 2023-09-22 19:25 6847
2660ccea Poul Sander 2023-09-22 19:25 6848
            while (current != ']')
2660ccea Poul Sander 2023-09-22 19:25 6849
            {
2660ccea Poul Sander 2023-09-22 19:25 6850
                if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal(false)))
2660ccea Poul Sander 2023-09-22 19:25 6851
                {
2660ccea Poul Sander 2023-09-22 19:25 6852
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 6853
                }
2660ccea Poul Sander 2023-09-22 19:25 6854
                get_ignore_noop();
2660ccea Poul Sander 2023-09-22 19:25 6855
            }
2660ccea Poul Sander 2023-09-22 19:25 6856
        }
2660ccea Poul Sander 2023-09-22 19:25 6857
2660ccea Poul Sander 2023-09-22 19:25 6858
        return sax->end_array();
2660ccea Poul Sander 2023-09-22 19:25 6859
    }
2660ccea Poul Sander 2023-09-22 19:25 6860
2660ccea Poul Sander 2023-09-22 19:25 6861
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6862
    @return whether object creation completed
2660ccea Poul Sander 2023-09-22 19:25 6863
    */
2660ccea Poul Sander 2023-09-22 19:25 6864
    bool get_ubjson_object()
2660ccea Poul Sander 2023-09-22 19:25 6865
    {
2660ccea Poul Sander 2023-09-22 19:25 6866
        std::pair<std::size_t, int> size_and_type;
2660ccea Poul Sander 2023-09-22 19:25 6867
        if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
2660ccea Poul Sander 2023-09-22 19:25 6868
        {
2660ccea Poul Sander 2023-09-22 19:25 6869
            return false;
2660ccea Poul Sander 2023-09-22 19:25 6870
        }
2660ccea Poul Sander 2023-09-22 19:25 6871
2660ccea Poul Sander 2023-09-22 19:25 6872
        string_t key;
2660ccea Poul Sander 2023-09-22 19:25 6873
        if (size_and_type.first != string_t::npos)
2660ccea Poul Sander 2023-09-22 19:25 6874
        {
2660ccea Poul Sander 2023-09-22 19:25 6875
            if (JSON_HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first)))
2660ccea Poul Sander 2023-09-22 19:25 6876
            {
2660ccea Poul Sander 2023-09-22 19:25 6877
                return false;
2660ccea Poul Sander 2023-09-22 19:25 6878
            }
2660ccea Poul Sander 2023-09-22 19:25 6879
2660ccea Poul Sander 2023-09-22 19:25 6880
            if (size_and_type.second != 0)
2660ccea Poul Sander 2023-09-22 19:25 6881
            {
2660ccea Poul Sander 2023-09-22 19:25 6882
                for (std::size_t i = 0; i < size_and_type.first; ++i)
2660ccea Poul Sander 2023-09-22 19:25 6883
                {
2660ccea Poul Sander 2023-09-22 19:25 6884
                    if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
2660ccea Poul Sander 2023-09-22 19:25 6885
                    {
2660ccea Poul Sander 2023-09-22 19:25 6886
                        return false;
2660ccea Poul Sander 2023-09-22 19:25 6887
                    }
2660ccea Poul Sander 2023-09-22 19:25 6888
                    if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
2660ccea Poul Sander 2023-09-22 19:25 6889
                    {
2660ccea Poul Sander 2023-09-22 19:25 6890
                        return false;
2660ccea Poul Sander 2023-09-22 19:25 6891
                    }
2660ccea Poul Sander 2023-09-22 19:25 6892
                    key.clear();
2660ccea Poul Sander 2023-09-22 19:25 6893
                }
2660ccea Poul Sander 2023-09-22 19:25 6894
            }
2660ccea Poul Sander 2023-09-22 19:25 6895
            else
2660ccea Poul Sander 2023-09-22 19:25 6896
            {
2660ccea Poul Sander 2023-09-22 19:25 6897
                for (std::size_t i = 0; i < size_and_type.first; ++i)
2660ccea Poul Sander 2023-09-22 19:25 6898
                {
2660ccea Poul Sander 2023-09-22 19:25 6899
                    if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
2660ccea Poul Sander 2023-09-22 19:25 6900
                    {
2660ccea Poul Sander 2023-09-22 19:25 6901
                        return false;
2660ccea Poul Sander 2023-09-22 19:25 6902
                    }
2660ccea Poul Sander 2023-09-22 19:25 6903
                    if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
2660ccea Poul Sander 2023-09-22 19:25 6904
                    {
2660ccea Poul Sander 2023-09-22 19:25 6905
                        return false;
2660ccea Poul Sander 2023-09-22 19:25 6906
                    }
2660ccea Poul Sander 2023-09-22 19:25 6907
                    key.clear();
2660ccea Poul Sander 2023-09-22 19:25 6908
                }
2660ccea Poul Sander 2023-09-22 19:25 6909
            }
2660ccea Poul Sander 2023-09-22 19:25 6910
        }
2660ccea Poul Sander 2023-09-22 19:25 6911
        else
2660ccea Poul Sander 2023-09-22 19:25 6912
        {
2660ccea Poul Sander 2023-09-22 19:25 6913
            if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
2660ccea Poul Sander 2023-09-22 19:25 6914
            {
2660ccea Poul Sander 2023-09-22 19:25 6915
                return false;
2660ccea Poul Sander 2023-09-22 19:25 6916
            }
2660ccea Poul Sander 2023-09-22 19:25 6917
2660ccea Poul Sander 2023-09-22 19:25 6918
            while (current != '}')
2660ccea Poul Sander 2023-09-22 19:25 6919
            {
2660ccea Poul Sander 2023-09-22 19:25 6920
                if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
2660ccea Poul Sander 2023-09-22 19:25 6921
                {
2660ccea Poul Sander 2023-09-22 19:25 6922
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 6923
                }
2660ccea Poul Sander 2023-09-22 19:25 6924
                if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
2660ccea Poul Sander 2023-09-22 19:25 6925
                {
2660ccea Poul Sander 2023-09-22 19:25 6926
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 6927
                }
2660ccea Poul Sander 2023-09-22 19:25 6928
                get_ignore_noop();
2660ccea Poul Sander 2023-09-22 19:25 6929
                key.clear();
2660ccea Poul Sander 2023-09-22 19:25 6930
            }
2660ccea Poul Sander 2023-09-22 19:25 6931
        }
2660ccea Poul Sander 2023-09-22 19:25 6932
2660ccea Poul Sander 2023-09-22 19:25 6933
        return sax->end_object();
2660ccea Poul Sander 2023-09-22 19:25 6934
    }
2660ccea Poul Sander 2023-09-22 19:25 6935
2660ccea Poul Sander 2023-09-22 19:25 6936
    ///////////////////////
2660ccea Poul Sander 2023-09-22 19:25 6937
    // Utility functions //
2660ccea Poul Sander 2023-09-22 19:25 6938
    ///////////////////////
2660ccea Poul Sander 2023-09-22 19:25 6939
2660ccea Poul Sander 2023-09-22 19:25 6940
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6941
    @brief get next character from the input
2660ccea Poul Sander 2023-09-22 19:25 6942
2660ccea Poul Sander 2023-09-22 19:25 6943
    This function provides the interface to the used input adapter. It does
2660ccea Poul Sander 2023-09-22 19:25 6944
    not throw in case the input reached EOF, but returns a -'ve valued
2660ccea Poul Sander 2023-09-22 19:25 6945
    `std::char_traits<char>::eof()` in that case.
2660ccea Poul Sander 2023-09-22 19:25 6946
2660ccea Poul Sander 2023-09-22 19:25 6947
    @return character read from the input
2660ccea Poul Sander 2023-09-22 19:25 6948
    */
2660ccea Poul Sander 2023-09-22 19:25 6949
    int get()
2660ccea Poul Sander 2023-09-22 19:25 6950
    {
2660ccea Poul Sander 2023-09-22 19:25 6951
        ++chars_read;
2660ccea Poul Sander 2023-09-22 19:25 6952
        return current = ia->get_character();
2660ccea Poul Sander 2023-09-22 19:25 6953
    }
2660ccea Poul Sander 2023-09-22 19:25 6954
2660ccea Poul Sander 2023-09-22 19:25 6955
    /*!
2660ccea Poul Sander 2023-09-22 19:25 6956
    @return character read from the input after ignoring all 'N' entries
2660ccea Poul Sander 2023-09-22 19:25 6957
    */
2660ccea Poul Sander 2023-09-22 19:25 6958
    int get_ignore_noop()
2660ccea Poul Sander 2023-09-22 19:25 6959
    {
2660ccea Poul Sander 2023-09-22 19:25 6960
        do
2660ccea Poul Sander 2023-09-22 19:25 6961
        {
2660ccea Poul Sander 2023-09-22 19:25 6962
            get();
2660ccea Poul Sander 2023-09-22 19:25 6963
        }
2660ccea Poul Sander 2023-09-22 19:25 6964
        while (current == 'N');
2660ccea Poul Sander 2023-09-22 19:25 6965
2660ccea Poul Sander 2023-09-22 19:25 6966
        return current;
2660ccea Poul Sander 2023-09-22 19:25 6967
    }
2660ccea Poul Sander 2023-09-22 19:25 6968
2660ccea Poul Sander 2023-09-22 19:25 6969
    /*
2660ccea Poul Sander 2023-09-22 19:25 6970
    @brief read a number from the input
2660ccea Poul Sander 2023-09-22 19:25 6971
2660ccea Poul Sander 2023-09-22 19:25 6972
    @tparam NumberType the type of the number
2660ccea Poul Sander 2023-09-22 19:25 6973
    @param[in] format   the current format (for diagnostics)
2660ccea Poul Sander 2023-09-22 19:25 6974
    @param[out] result  number of type @a NumberType
2660ccea Poul Sander 2023-09-22 19:25 6975
2660ccea Poul Sander 2023-09-22 19:25 6976
    @return whether conversion completed
2660ccea Poul Sander 2023-09-22 19:25 6977
2660ccea Poul Sander 2023-09-22 19:25 6978
    @note This function needs to respect the system's endianess, because
2660ccea Poul Sander 2023-09-22 19:25 6979
          bytes in CBOR, MessagePack, and UBJSON are stored in network order
2660ccea Poul Sander 2023-09-22 19:25 6980
          (big endian) and therefore need reordering on little endian systems.
2660ccea Poul Sander 2023-09-22 19:25 6981
    */
2660ccea Poul Sander 2023-09-22 19:25 6982
    template<typename NumberType, bool InputIsLittleEndian = false>
2660ccea Poul Sander 2023-09-22 19:25 6983
    bool get_number(const input_format_t format, NumberType& result)
2660ccea Poul Sander 2023-09-22 19:25 6984
    {
2660ccea Poul Sander 2023-09-22 19:25 6985
        // step 1: read input into array with system's byte order
2660ccea Poul Sander 2023-09-22 19:25 6986
        std::array<std::uint8_t, sizeof(NumberType)> vec;
2660ccea Poul Sander 2023-09-22 19:25 6987
        for (std::size_t i = 0; i < sizeof(NumberType); ++i)
2660ccea Poul Sander 2023-09-22 19:25 6988
        {
2660ccea Poul Sander 2023-09-22 19:25 6989
            get();
2660ccea Poul Sander 2023-09-22 19:25 6990
            if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "number")))
2660ccea Poul Sander 2023-09-22 19:25 6991
            {
2660ccea Poul Sander 2023-09-22 19:25 6992
                return false;
2660ccea Poul Sander 2023-09-22 19:25 6993
            }
2660ccea Poul Sander 2023-09-22 19:25 6994
2660ccea Poul Sander 2023-09-22 19:25 6995
            // reverse byte order prior to conversion if necessary
2660ccea Poul Sander 2023-09-22 19:25 6996
            if (is_little_endian != InputIsLittleEndian)
2660ccea Poul Sander 2023-09-22 19:25 6997
            {
2660ccea Poul Sander 2023-09-22 19:25 6998
                vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
2660ccea Poul Sander 2023-09-22 19:25 6999
            }
2660ccea Poul Sander 2023-09-22 19:25 7000
            else
2660ccea Poul Sander 2023-09-22 19:25 7001
            {
2660ccea Poul Sander 2023-09-22 19:25 7002
                vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 7003
            }
2660ccea Poul Sander 2023-09-22 19:25 7004
        }
2660ccea Poul Sander 2023-09-22 19:25 7005
2660ccea Poul Sander 2023-09-22 19:25 7006
        // step 2: convert array into number of type T and return
2660ccea Poul Sander 2023-09-22 19:25 7007
        std::memcpy(&result, vec.data(), sizeof(NumberType));
2660ccea Poul Sander 2023-09-22 19:25 7008
        return true;
2660ccea Poul Sander 2023-09-22 19:25 7009
    }
2660ccea Poul Sander 2023-09-22 19:25 7010
2660ccea Poul Sander 2023-09-22 19:25 7011
    /*!
2660ccea Poul Sander 2023-09-22 19:25 7012
    @brief create a string by reading characters from the input
2660ccea Poul Sander 2023-09-22 19:25 7013
2660ccea Poul Sander 2023-09-22 19:25 7014
    @tparam NumberType the type of the number
2660ccea Poul Sander 2023-09-22 19:25 7015
    @param[in] format the current format (for diagnostics)
2660ccea Poul Sander 2023-09-22 19:25 7016
    @param[in] len number of characters to read
2660ccea Poul Sander 2023-09-22 19:25 7017
    @param[out] result string created by reading @a len bytes
2660ccea Poul Sander 2023-09-22 19:25 7018
2660ccea Poul Sander 2023-09-22 19:25 7019
    @return whether string creation completed
2660ccea Poul Sander 2023-09-22 19:25 7020
2660ccea Poul Sander 2023-09-22 19:25 7021
    @note We can not reserve @a len bytes for the result, because @a len
2660ccea Poul Sander 2023-09-22 19:25 7022
          may be too large. Usually, @ref unexpect_eof() detects the end of
2660ccea Poul Sander 2023-09-22 19:25 7023
          the input before we run out of string memory.
2660ccea Poul Sander 2023-09-22 19:25 7024
    */
2660ccea Poul Sander 2023-09-22 19:25 7025
    template<typename NumberType>
2660ccea Poul Sander 2023-09-22 19:25 7026
    bool get_string(const input_format_t format,
2660ccea Poul Sander 2023-09-22 19:25 7027
                    const NumberType len,
2660ccea Poul Sander 2023-09-22 19:25 7028
                    string_t& result)
2660ccea Poul Sander 2023-09-22 19:25 7029
    {
2660ccea Poul Sander 2023-09-22 19:25 7030
        bool success = true;
2660ccea Poul Sander 2023-09-22 19:25 7031
        std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
2660ccea Poul Sander 2023-09-22 19:25 7032
        {
2660ccea Poul Sander 2023-09-22 19:25 7033
            get();
2660ccea Poul Sander 2023-09-22 19:25 7034
            if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "string")))
2660ccea Poul Sander 2023-09-22 19:25 7035
            {
2660ccea Poul Sander 2023-09-22 19:25 7036
                success = false;
2660ccea Poul Sander 2023-09-22 19:25 7037
            }
2660ccea Poul Sander 2023-09-22 19:25 7038
            return static_cast<char>(current);
2660ccea Poul Sander 2023-09-22 19:25 7039
        });
2660ccea Poul Sander 2023-09-22 19:25 7040
        return success;
2660ccea Poul Sander 2023-09-22 19:25 7041
    }
2660ccea Poul Sander 2023-09-22 19:25 7042
2660ccea Poul Sander 2023-09-22 19:25 7043
    /*!
2660ccea Poul Sander 2023-09-22 19:25 7044
    @param[in] format   the current format (for diagnostics)
2660ccea Poul Sander 2023-09-22 19:25 7045
    @param[in] context  further context information (for diagnostics)
2660ccea Poul Sander 2023-09-22 19:25 7046
    @return whether the last read character is not EOF
2660ccea Poul Sander 2023-09-22 19:25 7047
    */
2660ccea Poul Sander 2023-09-22 19:25 7048
    JSON_HEDLEY_NON_NULL(3)
2660ccea Poul Sander 2023-09-22 19:25 7049
    bool unexpect_eof(const input_format_t format, const char* context) const
2660ccea Poul Sander 2023-09-22 19:25 7050
    {
2660ccea Poul Sander 2023-09-22 19:25 7051
        if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char>::eof()))
2660ccea Poul Sander 2023-09-22 19:25 7052
        {
2660ccea Poul Sander 2023-09-22 19:25 7053
            return sax->parse_error(chars_read, "<end of file>",
2660ccea Poul Sander 2023-09-22 19:25 7054
                                    parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
2660ccea Poul Sander 2023-09-22 19:25 7055
        }
2660ccea Poul Sander 2023-09-22 19:25 7056
        return true;
2660ccea Poul Sander 2023-09-22 19:25 7057
    }
2660ccea Poul Sander 2023-09-22 19:25 7058
2660ccea Poul Sander 2023-09-22 19:25 7059
    /*!
2660ccea Poul Sander 2023-09-22 19:25 7060
    @return a string representation of the last read byte
2660ccea Poul Sander 2023-09-22 19:25 7061
    */
2660ccea Poul Sander 2023-09-22 19:25 7062
    std::string get_token_string() const
2660ccea Poul Sander 2023-09-22 19:25 7063
    {
2660ccea Poul Sander 2023-09-22 19:25 7064
        std::array<char, 3> cr{{}};
2660ccea Poul Sander 2023-09-22 19:25 7065
        (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
2660ccea Poul Sander 2023-09-22 19:25 7066
        return std::string{cr.data()};
2660ccea Poul Sander 2023-09-22 19:25 7067
    }
2660ccea Poul Sander 2023-09-22 19:25 7068
2660ccea Poul Sander 2023-09-22 19:25 7069
    /*!
2660ccea Poul Sander 2023-09-22 19:25 7070
    @param[in] format   the current format
2660ccea Poul Sander 2023-09-22 19:25 7071
    @param[in] detail   a detailed error message
2660ccea Poul Sander 2023-09-22 19:25 7072
    @param[in] context  further context information
2660ccea Poul Sander 2023-09-22 19:25 7073
    @return a message string to use in the parse_error exceptions
2660ccea Poul Sander 2023-09-22 19:25 7074
    */
2660ccea Poul Sander 2023-09-22 19:25 7075
    std::string exception_message(const input_format_t format,
2660ccea Poul Sander 2023-09-22 19:25 7076
                                  const std::string& detail,
2660ccea Poul Sander 2023-09-22 19:25 7077
                                  const std::string& context) const
2660ccea Poul Sander 2023-09-22 19:25 7078
    {
2660ccea Poul Sander 2023-09-22 19:25 7079
        std::string error_msg = "syntax error while parsing ";
2660ccea Poul Sander 2023-09-22 19:25 7080
2660ccea Poul Sander 2023-09-22 19:25 7081
        switch (format)
2660ccea Poul Sander 2023-09-22 19:25 7082
        {
2660ccea Poul Sander 2023-09-22 19:25 7083
            case input_format_t::cbor:
2660ccea Poul Sander 2023-09-22 19:25 7084
                error_msg += "CBOR";
2660ccea Poul Sander 2023-09-22 19:25 7085
                break;
2660ccea Poul Sander 2023-09-22 19:25 7086
2660ccea Poul Sander 2023-09-22 19:25 7087
            case input_format_t::msgpack:
2660ccea Poul Sander 2023-09-22 19:25 7088
                error_msg += "MessagePack";
2660ccea Poul Sander 2023-09-22 19:25 7089
                break;
2660ccea Poul Sander 2023-09-22 19:25 7090
2660ccea Poul Sander 2023-09-22 19:25 7091
            case input_format_t::ubjson:
2660ccea Poul Sander 2023-09-22 19:25 7092
                error_msg += "UBJSON";
2660ccea Poul Sander 2023-09-22 19:25 7093
                break;
2660ccea Poul Sander 2023-09-22 19:25 7094
2660ccea Poul Sander 2023-09-22 19:25 7095
            case input_format_t::bson:
2660ccea Poul Sander 2023-09-22 19:25 7096
                error_msg += "BSON";
2660ccea Poul Sander 2023-09-22 19:25 7097
                break;
2660ccea Poul Sander 2023-09-22 19:25 7098
2660ccea Poul Sander 2023-09-22 19:25 7099
            default:            // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 7100
                assert(false);  // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 7101
        }
2660ccea Poul Sander 2023-09-22 19:25 7102
2660ccea Poul Sander 2023-09-22 19:25 7103
        return error_msg + " " + context + ": " + detail;
2660ccea Poul Sander 2023-09-22 19:25 7104
    }
2660ccea Poul Sander 2023-09-22 19:25 7105
2660ccea Poul Sander 2023-09-22 19:25 7106
  private:
2660ccea Poul Sander 2023-09-22 19:25 7107
    /// input adapter
2660ccea Poul Sander 2023-09-22 19:25 7108
    input_adapter_t ia = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 7109
2660ccea Poul Sander 2023-09-22 19:25 7110
    /// the current character
2660ccea Poul Sander 2023-09-22 19:25 7111
    int current = std::char_traits<char>::eof();
2660ccea Poul Sander 2023-09-22 19:25 7112
2660ccea Poul Sander 2023-09-22 19:25 7113
    /// the number of characters read
2660ccea Poul Sander 2023-09-22 19:25 7114
    std::size_t chars_read = 0;
2660ccea Poul Sander 2023-09-22 19:25 7115
2660ccea Poul Sander 2023-09-22 19:25 7116
    /// whether we can assume little endianess
2660ccea Poul Sander 2023-09-22 19:25 7117
    const bool is_little_endian = little_endianess();
2660ccea Poul Sander 2023-09-22 19:25 7118
2660ccea Poul Sander 2023-09-22 19:25 7119
    /// the SAX parser
2660ccea Poul Sander 2023-09-22 19:25 7120
    json_sax_t* sax = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 7121
};
2660ccea Poul Sander 2023-09-22 19:25 7122
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 7123
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 7124
2660ccea Poul Sander 2023-09-22 19:25 7125
// #include <nlohmann/detail/input/input_adapters.hpp>
2660ccea Poul Sander 2023-09-22 19:25 7126
2660ccea Poul Sander 2023-09-22 19:25 7127
// #include <nlohmann/detail/input/lexer.hpp>
2660ccea Poul Sander 2023-09-22 19:25 7128
2660ccea Poul Sander 2023-09-22 19:25 7129
2660ccea Poul Sander 2023-09-22 19:25 7130
#include <array> // array
2660ccea Poul Sander 2023-09-22 19:25 7131
#include <clocale> // localeconv
2660ccea Poul Sander 2023-09-22 19:25 7132
#include <cstddef> // size_t
2660ccea Poul Sander 2023-09-22 19:25 7133
#include <cstdio> // snprintf
2660ccea Poul Sander 2023-09-22 19:25 7134
#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
2660ccea Poul Sander 2023-09-22 19:25 7135
#include <initializer_list> // initializer_list
2660ccea Poul Sander 2023-09-22 19:25 7136
#include <string> // char_traits, string
2660ccea Poul Sander 2023-09-22 19:25 7137
#include <utility> // move
2660ccea Poul Sander 2023-09-22 19:25 7138
#include <vector> // vector
2660ccea Poul Sander 2023-09-22 19:25 7139
2660ccea Poul Sander 2023-09-22 19:25 7140
// #include <nlohmann/detail/input/input_adapters.hpp>
2660ccea Poul Sander 2023-09-22 19:25 7141
2660ccea Poul Sander 2023-09-22 19:25 7142
// #include <nlohmann/detail/input/position_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 7143
2660ccea Poul Sander 2023-09-22 19:25 7144
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 7145
2660ccea Poul Sander 2023-09-22 19:25 7146
2660ccea Poul Sander 2023-09-22 19:25 7147
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 7148
{
2660ccea Poul Sander 2023-09-22 19:25 7149
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 7150
{
2660ccea Poul Sander 2023-09-22 19:25 7151
///////////
2660ccea Poul Sander 2023-09-22 19:25 7152
// lexer //
2660ccea Poul Sander 2023-09-22 19:25 7153
///////////
2660ccea Poul Sander 2023-09-22 19:25 7154
2660ccea Poul Sander 2023-09-22 19:25 7155
/*!
2660ccea Poul Sander 2023-09-22 19:25 7156
@brief lexical analysis
2660ccea Poul Sander 2023-09-22 19:25 7157
2660ccea Poul Sander 2023-09-22 19:25 7158
This class organizes the lexical analysis during JSON deserialization.
2660ccea Poul Sander 2023-09-22 19:25 7159
*/
2660ccea Poul Sander 2023-09-22 19:25 7160
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 7161
class lexer
2660ccea Poul Sander 2023-09-22 19:25 7162
{
2660ccea Poul Sander 2023-09-22 19:25 7163
    using number_integer_t = typename BasicJsonType::number_integer_t;
2660ccea Poul Sander 2023-09-22 19:25 7164
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2660ccea Poul Sander 2023-09-22 19:25 7165
    using number_float_t = typename BasicJsonType::number_float_t;
2660ccea Poul Sander 2023-09-22 19:25 7166
    using string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 7167
2660ccea Poul Sander 2023-09-22 19:25 7168
  public:
2660ccea Poul Sander 2023-09-22 19:25 7169
    /// token types for the parser
2660ccea Poul Sander 2023-09-22 19:25 7170
    enum class token_type
2660ccea Poul Sander 2023-09-22 19:25 7171
    {
2660ccea Poul Sander 2023-09-22 19:25 7172
        uninitialized,    ///< indicating the scanner is uninitialized
2660ccea Poul Sander 2023-09-22 19:25 7173
        literal_true,     ///< the `true` literal
2660ccea Poul Sander 2023-09-22 19:25 7174
        literal_false,    ///< the `false` literal
2660ccea Poul Sander 2023-09-22 19:25 7175
        literal_null,     ///< the `null` literal
2660ccea Poul Sander 2023-09-22 19:25 7176
        value_string,     ///< a string -- use get_string() for actual value
2660ccea Poul Sander 2023-09-22 19:25 7177
        value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
2660ccea Poul Sander 2023-09-22 19:25 7178
        value_integer,    ///< a signed integer -- use get_number_integer() for actual value
2660ccea Poul Sander 2023-09-22 19:25 7179
        value_float,      ///< an floating point number -- use get_number_float() for actual value
2660ccea Poul Sander 2023-09-22 19:25 7180
        begin_array,      ///< the character for array begin `[`
2660ccea Poul Sander 2023-09-22 19:25 7181
        begin_object,     ///< the character for object begin `{`
2660ccea Poul Sander 2023-09-22 19:25 7182
        end_array,        ///< the character for array end `]`
2660ccea Poul Sander 2023-09-22 19:25 7183
        end_object,       ///< the character for object end `}`
2660ccea Poul Sander 2023-09-22 19:25 7184
        name_separator,   ///< the name separator `:`
2660ccea Poul Sander 2023-09-22 19:25 7185
        value_separator,  ///< the value separator `,`
2660ccea Poul Sander 2023-09-22 19:25 7186
        parse_error,      ///< indicating a parse error
2660ccea Poul Sander 2023-09-22 19:25 7187
        end_of_input,     ///< indicating the end of the input buffer
2660ccea Poul Sander 2023-09-22 19:25 7188
        literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
2660ccea Poul Sander 2023-09-22 19:25 7189
    };
2660ccea Poul Sander 2023-09-22 19:25 7190
2660ccea Poul Sander 2023-09-22 19:25 7191
    /// return name of values of type token_type (only used for errors)
2660ccea Poul Sander 2023-09-22 19:25 7192
    JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 7193
    JSON_HEDLEY_CONST
2660ccea Poul Sander 2023-09-22 19:25 7194
    static const char* token_type_name(const token_type t) noexcept
2660ccea Poul Sander 2023-09-22 19:25 7195
    {
2660ccea Poul Sander 2023-09-22 19:25 7196
        switch (t)
2660ccea Poul Sander 2023-09-22 19:25 7197
        {
2660ccea Poul Sander 2023-09-22 19:25 7198
            case token_type::uninitialized:
2660ccea Poul Sander 2023-09-22 19:25 7199
                return "<uninitialized>";
2660ccea Poul Sander 2023-09-22 19:25 7200
            case token_type::literal_true:
2660ccea Poul Sander 2023-09-22 19:25 7201
                return "true literal";
2660ccea Poul Sander 2023-09-22 19:25 7202
            case token_type::literal_false:
2660ccea Poul Sander 2023-09-22 19:25 7203
                return "false literal";
2660ccea Poul Sander 2023-09-22 19:25 7204
            case token_type::literal_null:
2660ccea Poul Sander 2023-09-22 19:25 7205
                return "null literal";
2660ccea Poul Sander 2023-09-22 19:25 7206
            case token_type::value_string:
2660ccea Poul Sander 2023-09-22 19:25 7207
                return "string literal";
2660ccea Poul Sander 2023-09-22 19:25 7208
            case lexer::token_type::value_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 7209
            case lexer::token_type::value_integer:
2660ccea Poul Sander 2023-09-22 19:25 7210
            case lexer::token_type::value_float:
2660ccea Poul Sander 2023-09-22 19:25 7211
                return "number literal";
2660ccea Poul Sander 2023-09-22 19:25 7212
            case token_type::begin_array:
2660ccea Poul Sander 2023-09-22 19:25 7213
                return "'['";
2660ccea Poul Sander 2023-09-22 19:25 7214
            case token_type::begin_object:
2660ccea Poul Sander 2023-09-22 19:25 7215
                return "'{'";
2660ccea Poul Sander 2023-09-22 19:25 7216
            case token_type::end_array:
2660ccea Poul Sander 2023-09-22 19:25 7217
                return "']'";
2660ccea Poul Sander 2023-09-22 19:25 7218
            case token_type::end_object:
2660ccea Poul Sander 2023-09-22 19:25 7219
                return "'}'";
2660ccea Poul Sander 2023-09-22 19:25 7220
            case token_type::name_separator:
2660ccea Poul Sander 2023-09-22 19:25 7221
                return "':'";
2660ccea Poul Sander 2023-09-22 19:25 7222
            case token_type::value_separator:
2660ccea Poul Sander 2023-09-22 19:25 7223
                return "','";
2660ccea Poul Sander 2023-09-22 19:25 7224
            case token_type::parse_error:
2660ccea Poul Sander 2023-09-22 19:25 7225
                return "<parse error>";
2660ccea Poul Sander 2023-09-22 19:25 7226
            case token_type::end_of_input:
2660ccea Poul Sander 2023-09-22 19:25 7227
                return "end of input";
2660ccea Poul Sander 2023-09-22 19:25 7228
            case token_type::literal_or_value:
2660ccea Poul Sander 2023-09-22 19:25 7229
                return "'[', '{', or a literal";
2660ccea Poul Sander 2023-09-22 19:25 7230
            // LCOV_EXCL_START
2660ccea Poul Sander 2023-09-22 19:25 7231
            default: // catch non-enum values
2660ccea Poul Sander 2023-09-22 19:25 7232
                return "unknown token";
2660ccea Poul Sander 2023-09-22 19:25 7233
                // LCOV_EXCL_STOP
2660ccea Poul Sander 2023-09-22 19:25 7234
        }
2660ccea Poul Sander 2023-09-22 19:25 7235
    }
2660ccea Poul Sander 2023-09-22 19:25 7236
2660ccea Poul Sander 2023-09-22 19:25 7237
    explicit lexer(detail::input_adapter_t&& adapter)
2660ccea Poul Sander 2023-09-22 19:25 7238
        : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
2660ccea Poul Sander 2023-09-22 19:25 7239
2660ccea Poul Sander 2023-09-22 19:25 7240
    // delete because of pointer members
2660ccea Poul Sander 2023-09-22 19:25 7241
    lexer(const lexer&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 7242
    lexer(lexer&&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 7243
    lexer& operator=(lexer&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 7244
    lexer& operator=(lexer&&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 7245
    ~lexer() = default;
2660ccea Poul Sander 2023-09-22 19:25 7246
2660ccea Poul Sander 2023-09-22 19:25 7247
  private:
2660ccea Poul Sander 2023-09-22 19:25 7248
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 7249
    // locales
2660ccea Poul Sander 2023-09-22 19:25 7250
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 7251
2660ccea Poul Sander 2023-09-22 19:25 7252
    /// return the locale-dependent decimal point
2660ccea Poul Sander 2023-09-22 19:25 7253
    JSON_HEDLEY_PURE
2660ccea Poul Sander 2023-09-22 19:25 7254
    static char get_decimal_point() noexcept
2660ccea Poul Sander 2023-09-22 19:25 7255
    {
2660ccea Poul Sander 2023-09-22 19:25 7256
        const auto loc = localeconv();
2660ccea Poul Sander 2023-09-22 19:25 7257
        assert(loc != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 7258
        return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
2660ccea Poul Sander 2023-09-22 19:25 7259
    }
2660ccea Poul Sander 2023-09-22 19:25 7260
2660ccea Poul Sander 2023-09-22 19:25 7261
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 7262
    // scan functions
2660ccea Poul Sander 2023-09-22 19:25 7263
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 7264
2660ccea Poul Sander 2023-09-22 19:25 7265
    /*!
2660ccea Poul Sander 2023-09-22 19:25 7266
    @brief get codepoint from 4 hex characters following `\u`
2660ccea Poul Sander 2023-09-22 19:25 7267
2660ccea Poul Sander 2023-09-22 19:25 7268
    For input "\u c1 c2 c3 c4" the codepoint is:
2660ccea Poul Sander 2023-09-22 19:25 7269
      (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
2660ccea Poul Sander 2023-09-22 19:25 7270
    = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
2660ccea Poul Sander 2023-09-22 19:25 7271
2660ccea Poul Sander 2023-09-22 19:25 7272
    Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
2660ccea Poul Sander 2023-09-22 19:25 7273
    must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
2660ccea Poul Sander 2023-09-22 19:25 7274
    conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
2660ccea Poul Sander 2023-09-22 19:25 7275
    between the ASCII value of the character and the desired integer value.
2660ccea Poul Sander 2023-09-22 19:25 7276
2660ccea Poul Sander 2023-09-22 19:25 7277
    @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
2660ccea Poul Sander 2023-09-22 19:25 7278
            non-hex character)
2660ccea Poul Sander 2023-09-22 19:25 7279
    */
2660ccea Poul Sander 2023-09-22 19:25 7280
    int get_codepoint()
2660ccea Poul Sander 2023-09-22 19:25 7281
    {
2660ccea Poul Sander 2023-09-22 19:25 7282
        // this function only makes sense after reading `\u`
2660ccea Poul Sander 2023-09-22 19:25 7283
        assert(current == 'u');
2660ccea Poul Sander 2023-09-22 19:25 7284
        int codepoint = 0;
2660ccea Poul Sander 2023-09-22 19:25 7285
2660ccea Poul Sander 2023-09-22 19:25 7286
        const auto factors = { 12u, 8u, 4u, 0u };
2660ccea Poul Sander 2023-09-22 19:25 7287
        for (const auto factor : factors)
2660ccea Poul Sander 2023-09-22 19:25 7288
        {
2660ccea Poul Sander 2023-09-22 19:25 7289
            get();
2660ccea Poul Sander 2023-09-22 19:25 7290
2660ccea Poul Sander 2023-09-22 19:25 7291
            if (current >= '0' and current <= '9')
2660ccea Poul Sander 2023-09-22 19:25 7292
            {
2660ccea Poul Sander 2023-09-22 19:25 7293
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
2660ccea Poul Sander 2023-09-22 19:25 7294
            }
2660ccea Poul Sander 2023-09-22 19:25 7295
            else if (current >= 'A' and current <= 'F')
2660ccea Poul Sander 2023-09-22 19:25 7296
            {
2660ccea Poul Sander 2023-09-22 19:25 7297
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
2660ccea Poul Sander 2023-09-22 19:25 7298
            }
2660ccea Poul Sander 2023-09-22 19:25 7299
            else if (current >= 'a' and current <= 'f')
2660ccea Poul Sander 2023-09-22 19:25 7300
            {
2660ccea Poul Sander 2023-09-22 19:25 7301
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
2660ccea Poul Sander 2023-09-22 19:25 7302
            }
2660ccea Poul Sander 2023-09-22 19:25 7303
            else
2660ccea Poul Sander 2023-09-22 19:25 7304
            {
2660ccea Poul Sander 2023-09-22 19:25 7305
                return -1;
2660ccea Poul Sander 2023-09-22 19:25 7306
            }
2660ccea Poul Sander 2023-09-22 19:25 7307
        }
2660ccea Poul Sander 2023-09-22 19:25 7308
2660ccea Poul Sander 2023-09-22 19:25 7309
        assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2660ccea Poul Sander 2023-09-22 19:25 7310
        return codepoint;
2660ccea Poul Sander 2023-09-22 19:25 7311
    }
2660ccea Poul Sander 2023-09-22 19:25 7312
2660ccea Poul Sander 2023-09-22 19:25 7313
    /*!
2660ccea Poul Sander 2023-09-22 19:25 7314
    @brief check if the next byte(s) are inside a given range
2660ccea Poul Sander 2023-09-22 19:25 7315
2660ccea Poul Sander 2023-09-22 19:25 7316
    Adds the current byte and, for each passed range, reads a new byte and
2660ccea Poul Sander 2023-09-22 19:25 7317
    checks if it is inside the range. If a violation was detected, set up an
2660ccea Poul Sander 2023-09-22 19:25 7318
    error message and return false. Otherwise, return true.
2660ccea Poul Sander 2023-09-22 19:25 7319
2660ccea Poul Sander 2023-09-22 19:25 7320
    @param[in] ranges  list of integers; interpreted as list of pairs of
2660ccea Poul Sander 2023-09-22 19:25 7321
                       inclusive lower and upper bound, respectively
2660ccea Poul Sander 2023-09-22 19:25 7322
2660ccea Poul Sander 2023-09-22 19:25 7323
    @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
2660ccea Poul Sander 2023-09-22 19:25 7324
         1, 2, or 3 pairs. This precondition is enforced by an assertion.
2660ccea Poul Sander 2023-09-22 19:25 7325
2660ccea Poul Sander 2023-09-22 19:25 7326
    @return true if and only if no range violation was detected
2660ccea Poul Sander 2023-09-22 19:25 7327
    */
2660ccea Poul Sander 2023-09-22 19:25 7328
    bool next_byte_in_range(std::initializer_list<int> ranges)
2660ccea Poul Sander 2023-09-22 19:25 7329
    {
2660ccea Poul Sander 2023-09-22 19:25 7330
        assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2660ccea Poul Sander 2023-09-22 19:25 7331
        add(current);
2660ccea Poul Sander 2023-09-22 19:25 7332
2660ccea Poul Sander 2023-09-22 19:25 7333
        for (auto range = ranges.begin(); range != ranges.end(); ++range)
2660ccea Poul Sander 2023-09-22 19:25 7334
        {
2660ccea Poul Sander 2023-09-22 19:25 7335
            get();
2660ccea Poul Sander 2023-09-22 19:25 7336
            if (JSON_HEDLEY_LIKELY(*range <= current and current <= *(++range)))
2660ccea Poul Sander 2023-09-22 19:25 7337
            {
2660ccea Poul Sander 2023-09-22 19:25 7338
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 7339
            }
2660ccea Poul Sander 2023-09-22 19:25 7340
            else
2660ccea Poul Sander 2023-09-22 19:25 7341
            {
2660ccea Poul Sander 2023-09-22 19:25 7342
                error_message = "invalid string: ill-formed UTF-8 byte";
2660ccea Poul Sander 2023-09-22 19:25 7343
                return false;
2660ccea Poul Sander 2023-09-22 19:25 7344
            }
2660ccea Poul Sander 2023-09-22 19:25 7345
        }
2660ccea Poul Sander 2023-09-22 19:25 7346
2660ccea Poul Sander 2023-09-22 19:25 7347
        return true;
2660ccea Poul Sander 2023-09-22 19:25 7348
    }
2660ccea Poul Sander 2023-09-22 19:25 7349
2660ccea Poul Sander 2023-09-22 19:25 7350
    /*!
2660ccea Poul Sander 2023-09-22 19:25 7351
    @brief scan a string literal
2660ccea Poul Sander 2023-09-22 19:25 7352
2660ccea Poul Sander 2023-09-22 19:25 7353
    This function scans a string according to Sect. 7 of RFC 7159. While
2660ccea Poul Sander 2023-09-22 19:25 7354
    scanning, bytes are escaped and copied into buffer token_buffer. Then the
2660ccea Poul Sander 2023-09-22 19:25 7355
    function returns successfully, token_buffer is *not* null-terminated (as it
2660ccea Poul Sander 2023-09-22 19:25 7356
    may contain \0 bytes), and token_buffer.size() is the number of bytes in the
2660ccea Poul Sander 2023-09-22 19:25 7357
    string.
2660ccea Poul Sander 2023-09-22 19:25 7358
2660ccea Poul Sander 2023-09-22 19:25 7359
    @return token_type::value_string if string could be successfully scanned,
2660ccea Poul Sander 2023-09-22 19:25 7360
            token_type::parse_error otherwise
2660ccea Poul Sander 2023-09-22 19:25 7361
2660ccea Poul Sander 2023-09-22 19:25 7362
    @note In case of errors, variable error_message contains a textual
2660ccea Poul Sander 2023-09-22 19:25 7363
          description.
2660ccea Poul Sander 2023-09-22 19:25 7364
    */
2660ccea Poul Sander 2023-09-22 19:25 7365
    token_type scan_string()
2660ccea Poul Sander 2023-09-22 19:25 7366
    {
2660ccea Poul Sander 2023-09-22 19:25 7367
        // reset token_buffer (ignore opening quote)
2660ccea Poul Sander 2023-09-22 19:25 7368
        reset();
2660ccea Poul Sander 2023-09-22 19:25 7369
2660ccea Poul Sander 2023-09-22 19:25 7370
        // we entered the function by reading an open quote
2660ccea Poul Sander 2023-09-22 19:25 7371
        assert(current == '\"');
2660ccea Poul Sander 2023-09-22 19:25 7372
2660ccea Poul Sander 2023-09-22 19:25 7373
        while (true)
2660ccea Poul Sander 2023-09-22 19:25 7374
        {
2660ccea Poul Sander 2023-09-22 19:25 7375
            // get next character
2660ccea Poul Sander 2023-09-22 19:25 7376
            switch (get())
2660ccea Poul Sander 2023-09-22 19:25 7377
            {
2660ccea Poul Sander 2023-09-22 19:25 7378
                // end of file while parsing string
2660ccea Poul Sander 2023-09-22 19:25 7379
                case std::char_traits<char>::eof():
2660ccea Poul Sander 2023-09-22 19:25 7380
                {
2660ccea Poul Sander 2023-09-22 19:25 7381
                    error_message = "invalid string: missing closing quote";
2660ccea Poul Sander 2023-09-22 19:25 7382
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7383
                }
2660ccea Poul Sander 2023-09-22 19:25 7384
2660ccea Poul Sander 2023-09-22 19:25 7385
                // closing quote
2660ccea Poul Sander 2023-09-22 19:25 7386
                case '\"':
2660ccea Poul Sander 2023-09-22 19:25 7387
                {
2660ccea Poul Sander 2023-09-22 19:25 7388
                    return token_type::value_string;
2660ccea Poul Sander 2023-09-22 19:25 7389
                }
2660ccea Poul Sander 2023-09-22 19:25 7390
2660ccea Poul Sander 2023-09-22 19:25 7391
                // escapes
2660ccea Poul Sander 2023-09-22 19:25 7392
                case '\\':
2660ccea Poul Sander 2023-09-22 19:25 7393
                {
2660ccea Poul Sander 2023-09-22 19:25 7394
                    switch (get())
2660ccea Poul Sander 2023-09-22 19:25 7395
                    {
2660ccea Poul Sander 2023-09-22 19:25 7396
                        // quotation mark
2660ccea Poul Sander 2023-09-22 19:25 7397
                        case '\"':
2660ccea Poul Sander 2023-09-22 19:25 7398
                            add('\"');
2660ccea Poul Sander 2023-09-22 19:25 7399
                            break;
2660ccea Poul Sander 2023-09-22 19:25 7400
                        // reverse solidus
2660ccea Poul Sander 2023-09-22 19:25 7401
                        case '\\':
2660ccea Poul Sander 2023-09-22 19:25 7402
                            add('\\');
2660ccea Poul Sander 2023-09-22 19:25 7403
                            break;
2660ccea Poul Sander 2023-09-22 19:25 7404
                        // solidus
2660ccea Poul Sander 2023-09-22 19:25 7405
                        case '/':
2660ccea Poul Sander 2023-09-22 19:25 7406
                            add('/');
2660ccea Poul Sander 2023-09-22 19:25 7407
                            break;
2660ccea Poul Sander 2023-09-22 19:25 7408
                        // backspace
2660ccea Poul Sander 2023-09-22 19:25 7409
                        case 'b':
2660ccea Poul Sander 2023-09-22 19:25 7410
                            add('\b');
2660ccea Poul Sander 2023-09-22 19:25 7411
                            break;
2660ccea Poul Sander 2023-09-22 19:25 7412
                        // form feed
2660ccea Poul Sander 2023-09-22 19:25 7413
                        case 'f':
2660ccea Poul Sander 2023-09-22 19:25 7414
                            add('\f');
2660ccea Poul Sander 2023-09-22 19:25 7415
                            break;
2660ccea Poul Sander 2023-09-22 19:25 7416
                        // line feed
2660ccea Poul Sander 2023-09-22 19:25 7417
                        case 'n':
2660ccea Poul Sander 2023-09-22 19:25 7418
                            add('\n');
2660ccea Poul Sander 2023-09-22 19:25 7419
                            break;
2660ccea Poul Sander 2023-09-22 19:25 7420
                        // carriage return
2660ccea Poul Sander 2023-09-22 19:25 7421
                        case 'r':
2660ccea Poul Sander 2023-09-22 19:25 7422
                            add('\r');
2660ccea Poul Sander 2023-09-22 19:25 7423
                            break;
2660ccea Poul Sander 2023-09-22 19:25 7424
                        // tab
2660ccea Poul Sander 2023-09-22 19:25 7425
                        case 't':
2660ccea Poul Sander 2023-09-22 19:25 7426
                            add('\t');
2660ccea Poul Sander 2023-09-22 19:25 7427
                            break;
2660ccea Poul Sander 2023-09-22 19:25 7428
2660ccea Poul Sander 2023-09-22 19:25 7429
                        // unicode escapes
2660ccea Poul Sander 2023-09-22 19:25 7430
                        case 'u':
2660ccea Poul Sander 2023-09-22 19:25 7431
                        {
2660ccea Poul Sander 2023-09-22 19:25 7432
                            const int codepoint1 = get_codepoint();
2660ccea Poul Sander 2023-09-22 19:25 7433
                            int codepoint = codepoint1; // start with codepoint1
2660ccea Poul Sander 2023-09-22 19:25 7434
2660ccea Poul Sander 2023-09-22 19:25 7435
                            if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
2660ccea Poul Sander 2023-09-22 19:25 7436
                            {
2660ccea Poul Sander 2023-09-22 19:25 7437
                                error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2660ccea Poul Sander 2023-09-22 19:25 7438
                                return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7439
                            }
2660ccea Poul Sander 2023-09-22 19:25 7440
2660ccea Poul Sander 2023-09-22 19:25 7441
                            // check if code point is a high surrogate
2660ccea Poul Sander 2023-09-22 19:25 7442
                            if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
2660ccea Poul Sander 2023-09-22 19:25 7443
                            {
2660ccea Poul Sander 2023-09-22 19:25 7444
                                // expect next \uxxxx entry
2660ccea Poul Sander 2023-09-22 19:25 7445
                                if (JSON_HEDLEY_LIKELY(get() == '\\' and get() == 'u'))
2660ccea Poul Sander 2023-09-22 19:25 7446
                                {
2660ccea Poul Sander 2023-09-22 19:25 7447
                                    const int codepoint2 = get_codepoint();
2660ccea Poul Sander 2023-09-22 19:25 7448
2660ccea Poul Sander 2023-09-22 19:25 7449
                                    if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
2660ccea Poul Sander 2023-09-22 19:25 7450
                                    {
2660ccea Poul Sander 2023-09-22 19:25 7451
                                        error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2660ccea Poul Sander 2023-09-22 19:25 7452
                                        return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7453
                                    }
2660ccea Poul Sander 2023-09-22 19:25 7454
2660ccea Poul Sander 2023-09-22 19:25 7455
                                    // check if codepoint2 is a low surrogate
2660ccea Poul Sander 2023-09-22 19:25 7456
                                    if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
2660ccea Poul Sander 2023-09-22 19:25 7457
                                    {
2660ccea Poul Sander 2023-09-22 19:25 7458
                                        // overwrite codepoint
2660ccea Poul Sander 2023-09-22 19:25 7459
                                        codepoint = static_cast<int>(
2660ccea Poul Sander 2023-09-22 19:25 7460
                                                        // high surrogate occupies the most significant 22 bits
2660ccea Poul Sander 2023-09-22 19:25 7461
                                                        (static_cast<unsigned int>(codepoint1) << 10u)
2660ccea Poul Sander 2023-09-22 19:25 7462
                                                        // low surrogate occupies the least significant 15 bits
2660ccea Poul Sander 2023-09-22 19:25 7463
                                                        + static_cast<unsigned int>(codepoint2)
2660ccea Poul Sander 2023-09-22 19:25 7464
                                                        // there is still the 0xD800, 0xDC00 and 0x10000 noise
2660ccea Poul Sander 2023-09-22 19:25 7465
                                                        // in the result so we have to subtract with:
2660ccea Poul Sander 2023-09-22 19:25 7466
                                                        // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
2660ccea Poul Sander 2023-09-22 19:25 7467
                                                        - 0x35FDC00u);
2660ccea Poul Sander 2023-09-22 19:25 7468
                                    }
2660ccea Poul Sander 2023-09-22 19:25 7469
                                    else
2660ccea Poul Sander 2023-09-22 19:25 7470
                                    {
2660ccea Poul Sander 2023-09-22 19:25 7471
                                        error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2660ccea Poul Sander 2023-09-22 19:25 7472
                                        return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7473
                                    }
2660ccea Poul Sander 2023-09-22 19:25 7474
                                }
2660ccea Poul Sander 2023-09-22 19:25 7475
                                else
2660ccea Poul Sander 2023-09-22 19:25 7476
                                {
2660ccea Poul Sander 2023-09-22 19:25 7477
                                    error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2660ccea Poul Sander 2023-09-22 19:25 7478
                                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7479
                                }
2660ccea Poul Sander 2023-09-22 19:25 7480
                            }
2660ccea Poul Sander 2023-09-22 19:25 7481
                            else
2660ccea Poul Sander 2023-09-22 19:25 7482
                            {
2660ccea Poul Sander 2023-09-22 19:25 7483
                                if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
2660ccea Poul Sander 2023-09-22 19:25 7484
                                {
2660ccea Poul Sander 2023-09-22 19:25 7485
                                    error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2660ccea Poul Sander 2023-09-22 19:25 7486
                                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7487
                                }
2660ccea Poul Sander 2023-09-22 19:25 7488
                            }
2660ccea Poul Sander 2023-09-22 19:25 7489
2660ccea Poul Sander 2023-09-22 19:25 7490
                            // result of the above calculation yields a proper codepoint
2660ccea Poul Sander 2023-09-22 19:25 7491
                            assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2660ccea Poul Sander 2023-09-22 19:25 7492
2660ccea Poul Sander 2023-09-22 19:25 7493
                            // translate codepoint into bytes
2660ccea Poul Sander 2023-09-22 19:25 7494
                            if (codepoint < 0x80)
2660ccea Poul Sander 2023-09-22 19:25 7495
                            {
2660ccea Poul Sander 2023-09-22 19:25 7496
                                // 1-byte characters: 0xxxxxxx (ASCII)
2660ccea Poul Sander 2023-09-22 19:25 7497
                                add(codepoint);
2660ccea Poul Sander 2023-09-22 19:25 7498
                            }
2660ccea Poul Sander 2023-09-22 19:25 7499
                            else if (codepoint <= 0x7FF)
2660ccea Poul Sander 2023-09-22 19:25 7500
                            {
2660ccea Poul Sander 2023-09-22 19:25 7501
                                // 2-byte characters: 110xxxxx 10xxxxxx
2660ccea Poul Sander 2023-09-22 19:25 7502
                                add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
2660ccea Poul Sander 2023-09-22 19:25 7503
                                add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
2660ccea Poul Sander 2023-09-22 19:25 7504
                            }
2660ccea Poul Sander 2023-09-22 19:25 7505
                            else if (codepoint <= 0xFFFF)
2660ccea Poul Sander 2023-09-22 19:25 7506
                            {
2660ccea Poul Sander 2023-09-22 19:25 7507
                                // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
2660ccea Poul Sander 2023-09-22 19:25 7508
                                add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
2660ccea Poul Sander 2023-09-22 19:25 7509
                                add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
2660ccea Poul Sander 2023-09-22 19:25 7510
                                add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
2660ccea Poul Sander 2023-09-22 19:25 7511
                            }
2660ccea Poul Sander 2023-09-22 19:25 7512
                            else
2660ccea Poul Sander 2023-09-22 19:25 7513
                            {
2660ccea Poul Sander 2023-09-22 19:25 7514
                                // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
2660ccea Poul Sander 2023-09-22 19:25 7515
                                add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
2660ccea Poul Sander 2023-09-22 19:25 7516
                                add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
2660ccea Poul Sander 2023-09-22 19:25 7517
                                add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
2660ccea Poul Sander 2023-09-22 19:25 7518
                                add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
2660ccea Poul Sander 2023-09-22 19:25 7519
                            }
2660ccea Poul Sander 2023-09-22 19:25 7520
2660ccea Poul Sander 2023-09-22 19:25 7521
                            break;
2660ccea Poul Sander 2023-09-22 19:25 7522
                        }
2660ccea Poul Sander 2023-09-22 19:25 7523
2660ccea Poul Sander 2023-09-22 19:25 7524
                        // other characters after escape
2660ccea Poul Sander 2023-09-22 19:25 7525
                        default:
2660ccea Poul Sander 2023-09-22 19:25 7526
                            error_message = "invalid string: forbidden character after backslash";
2660ccea Poul Sander 2023-09-22 19:25 7527
                            return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7528
                    }
2660ccea Poul Sander 2023-09-22 19:25 7529
2660ccea Poul Sander 2023-09-22 19:25 7530
                    break;
2660ccea Poul Sander 2023-09-22 19:25 7531
                }
2660ccea Poul Sander 2023-09-22 19:25 7532
2660ccea Poul Sander 2023-09-22 19:25 7533
                // invalid control characters
2660ccea Poul Sander 2023-09-22 19:25 7534
                case 0x00:
2660ccea Poul Sander 2023-09-22 19:25 7535
                {
2660ccea Poul Sander 2023-09-22 19:25 7536
                    error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
2660ccea Poul Sander 2023-09-22 19:25 7537
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7538
                }
2660ccea Poul Sander 2023-09-22 19:25 7539
2660ccea Poul Sander 2023-09-22 19:25 7540
                case 0x01:
2660ccea Poul Sander 2023-09-22 19:25 7541
                {
2660ccea Poul Sander 2023-09-22 19:25 7542
                    error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
2660ccea Poul Sander 2023-09-22 19:25 7543
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7544
                }
2660ccea Poul Sander 2023-09-22 19:25 7545
2660ccea Poul Sander 2023-09-22 19:25 7546
                case 0x02:
2660ccea Poul Sander 2023-09-22 19:25 7547
                {
2660ccea Poul Sander 2023-09-22 19:25 7548
                    error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
2660ccea Poul Sander 2023-09-22 19:25 7549
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7550
                }
2660ccea Poul Sander 2023-09-22 19:25 7551
2660ccea Poul Sander 2023-09-22 19:25 7552
                case 0x03:
2660ccea Poul Sander 2023-09-22 19:25 7553
                {
2660ccea Poul Sander 2023-09-22 19:25 7554
                    error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
2660ccea Poul Sander 2023-09-22 19:25 7555
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7556
                }
2660ccea Poul Sander 2023-09-22 19:25 7557
2660ccea Poul Sander 2023-09-22 19:25 7558
                case 0x04:
2660ccea Poul Sander 2023-09-22 19:25 7559
                {
2660ccea Poul Sander 2023-09-22 19:25 7560
                    error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
2660ccea Poul Sander 2023-09-22 19:25 7561
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7562
                }
2660ccea Poul Sander 2023-09-22 19:25 7563
2660ccea Poul Sander 2023-09-22 19:25 7564
                case 0x05:
2660ccea Poul Sander 2023-09-22 19:25 7565
                {
2660ccea Poul Sander 2023-09-22 19:25 7566
                    error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
2660ccea Poul Sander 2023-09-22 19:25 7567
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7568
                }
2660ccea Poul Sander 2023-09-22 19:25 7569
2660ccea Poul Sander 2023-09-22 19:25 7570
                case 0x06:
2660ccea Poul Sander 2023-09-22 19:25 7571
                {
2660ccea Poul Sander 2023-09-22 19:25 7572
                    error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
2660ccea Poul Sander 2023-09-22 19:25 7573
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7574
                }
2660ccea Poul Sander 2023-09-22 19:25 7575
2660ccea Poul Sander 2023-09-22 19:25 7576
                case 0x07:
2660ccea Poul Sander 2023-09-22 19:25 7577
                {
2660ccea Poul Sander 2023-09-22 19:25 7578
                    error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
2660ccea Poul Sander 2023-09-22 19:25 7579
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7580
                }
2660ccea Poul Sander 2023-09-22 19:25 7581
2660ccea Poul Sander 2023-09-22 19:25 7582
                case 0x08:
2660ccea Poul Sander 2023-09-22 19:25 7583
                {
2660ccea Poul Sander 2023-09-22 19:25 7584
                    error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
2660ccea Poul Sander 2023-09-22 19:25 7585
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7586
                }
2660ccea Poul Sander 2023-09-22 19:25 7587
2660ccea Poul Sander 2023-09-22 19:25 7588
                case 0x09:
2660ccea Poul Sander 2023-09-22 19:25 7589
                {
2660ccea Poul Sander 2023-09-22 19:25 7590
                    error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
2660ccea Poul Sander 2023-09-22 19:25 7591
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7592
                }
2660ccea Poul Sander 2023-09-22 19:25 7593
2660ccea Poul Sander 2023-09-22 19:25 7594
                case 0x0A:
2660ccea Poul Sander 2023-09-22 19:25 7595
                {
2660ccea Poul Sander 2023-09-22 19:25 7596
                    error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
2660ccea Poul Sander 2023-09-22 19:25 7597
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7598
                }
2660ccea Poul Sander 2023-09-22 19:25 7599
2660ccea Poul Sander 2023-09-22 19:25 7600
                case 0x0B:
2660ccea Poul Sander 2023-09-22 19:25 7601
                {
2660ccea Poul Sander 2023-09-22 19:25 7602
                    error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
2660ccea Poul Sander 2023-09-22 19:25 7603
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7604
                }
2660ccea Poul Sander 2023-09-22 19:25 7605
2660ccea Poul Sander 2023-09-22 19:25 7606
                case 0x0C:
2660ccea Poul Sander 2023-09-22 19:25 7607
                {
2660ccea Poul Sander 2023-09-22 19:25 7608
                    error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
2660ccea Poul Sander 2023-09-22 19:25 7609
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7610
                }
2660ccea Poul Sander 2023-09-22 19:25 7611
2660ccea Poul Sander 2023-09-22 19:25 7612
                case 0x0D:
2660ccea Poul Sander 2023-09-22 19:25 7613
                {
2660ccea Poul Sander 2023-09-22 19:25 7614
                    error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
2660ccea Poul Sander 2023-09-22 19:25 7615
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7616
                }
2660ccea Poul Sander 2023-09-22 19:25 7617
2660ccea Poul Sander 2023-09-22 19:25 7618
                case 0x0E:
2660ccea Poul Sander 2023-09-22 19:25 7619
                {
2660ccea Poul Sander 2023-09-22 19:25 7620
                    error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
2660ccea Poul Sander 2023-09-22 19:25 7621
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7622
                }
2660ccea Poul Sander 2023-09-22 19:25 7623
2660ccea Poul Sander 2023-09-22 19:25 7624
                case 0x0F:
2660ccea Poul Sander 2023-09-22 19:25 7625
                {
2660ccea Poul Sander 2023-09-22 19:25 7626
                    error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
2660ccea Poul Sander 2023-09-22 19:25 7627
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7628
                }
2660ccea Poul Sander 2023-09-22 19:25 7629
2660ccea Poul Sander 2023-09-22 19:25 7630
                case 0x10:
2660ccea Poul Sander 2023-09-22 19:25 7631
                {
2660ccea Poul Sander 2023-09-22 19:25 7632
                    error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
2660ccea Poul Sander 2023-09-22 19:25 7633
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7634
                }
2660ccea Poul Sander 2023-09-22 19:25 7635
2660ccea Poul Sander 2023-09-22 19:25 7636
                case 0x11:
2660ccea Poul Sander 2023-09-22 19:25 7637
                {
2660ccea Poul Sander 2023-09-22 19:25 7638
                    error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
2660ccea Poul Sander 2023-09-22 19:25 7639
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7640
                }
2660ccea Poul Sander 2023-09-22 19:25 7641
2660ccea Poul Sander 2023-09-22 19:25 7642
                case 0x12:
2660ccea Poul Sander 2023-09-22 19:25 7643
                {
2660ccea Poul Sander 2023-09-22 19:25 7644
                    error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
2660ccea Poul Sander 2023-09-22 19:25 7645
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7646
                }
2660ccea Poul Sander 2023-09-22 19:25 7647
2660ccea Poul Sander 2023-09-22 19:25 7648
                case 0x13:
2660ccea Poul Sander 2023-09-22 19:25 7649
                {
2660ccea Poul Sander 2023-09-22 19:25 7650
                    error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
2660ccea Poul Sander 2023-09-22 19:25 7651
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7652
                }
2660ccea Poul Sander 2023-09-22 19:25 7653
2660ccea Poul Sander 2023-09-22 19:25 7654
                case 0x14:
2660ccea Poul Sander 2023-09-22 19:25 7655
                {
2660ccea Poul Sander 2023-09-22 19:25 7656
                    error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
2660ccea Poul Sander 2023-09-22 19:25 7657
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7658
                }
2660ccea Poul Sander 2023-09-22 19:25 7659
2660ccea Poul Sander 2023-09-22 19:25 7660
                case 0x15:
2660ccea Poul Sander 2023-09-22 19:25 7661
                {
2660ccea Poul Sander 2023-09-22 19:25 7662
                    error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
2660ccea Poul Sander 2023-09-22 19:25 7663
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7664
                }
2660ccea Poul Sander 2023-09-22 19:25 7665
2660ccea Poul Sander 2023-09-22 19:25 7666
                case 0x16:
2660ccea Poul Sander 2023-09-22 19:25 7667
                {
2660ccea Poul Sander 2023-09-22 19:25 7668
                    error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
2660ccea Poul Sander 2023-09-22 19:25 7669
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7670
                }
2660ccea Poul Sander 2023-09-22 19:25 7671
2660ccea Poul Sander 2023-09-22 19:25 7672
                case 0x17:
2660ccea Poul Sander 2023-09-22 19:25 7673
                {
2660ccea Poul Sander 2023-09-22 19:25 7674
                    error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
2660ccea Poul Sander 2023-09-22 19:25 7675
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7676
                }
2660ccea Poul Sander 2023-09-22 19:25 7677
2660ccea Poul Sander 2023-09-22 19:25 7678
                case 0x18:
2660ccea Poul Sander 2023-09-22 19:25 7679
                {
2660ccea Poul Sander 2023-09-22 19:25 7680
                    error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
2660ccea Poul Sander 2023-09-22 19:25 7681
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7682
                }
2660ccea Poul Sander 2023-09-22 19:25 7683
2660ccea Poul Sander 2023-09-22 19:25 7684
                case 0x19:
2660ccea Poul Sander 2023-09-22 19:25 7685
                {
2660ccea Poul Sander 2023-09-22 19:25 7686
                    error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
2660ccea Poul Sander 2023-09-22 19:25 7687
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7688
                }
2660ccea Poul Sander 2023-09-22 19:25 7689
2660ccea Poul Sander 2023-09-22 19:25 7690
                case 0x1A:
2660ccea Poul Sander 2023-09-22 19:25 7691
                {
2660ccea Poul Sander 2023-09-22 19:25 7692
                    error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
2660ccea Poul Sander 2023-09-22 19:25 7693
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7694
                }
2660ccea Poul Sander 2023-09-22 19:25 7695
2660ccea Poul Sander 2023-09-22 19:25 7696
                case 0x1B:
2660ccea Poul Sander 2023-09-22 19:25 7697
                {
2660ccea Poul Sander 2023-09-22 19:25 7698
                    error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
2660ccea Poul Sander 2023-09-22 19:25 7699
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7700
                }
2660ccea Poul Sander 2023-09-22 19:25 7701
2660ccea Poul Sander 2023-09-22 19:25 7702
                case 0x1C:
2660ccea Poul Sander 2023-09-22 19:25 7703
                {
2660ccea Poul Sander 2023-09-22 19:25 7704
                    error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
2660ccea Poul Sander 2023-09-22 19:25 7705
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7706
                }
2660ccea Poul Sander 2023-09-22 19:25 7707
2660ccea Poul Sander 2023-09-22 19:25 7708
                case 0x1D:
2660ccea Poul Sander 2023-09-22 19:25 7709
                {
2660ccea Poul Sander 2023-09-22 19:25 7710
                    error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
2660ccea Poul Sander 2023-09-22 19:25 7711
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7712
                }
2660ccea Poul Sander 2023-09-22 19:25 7713
2660ccea Poul Sander 2023-09-22 19:25 7714
                case 0x1E:
2660ccea Poul Sander 2023-09-22 19:25 7715
                {
2660ccea Poul Sander 2023-09-22 19:25 7716
                    error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
2660ccea Poul Sander 2023-09-22 19:25 7717
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7718
                }
2660ccea Poul Sander 2023-09-22 19:25 7719
2660ccea Poul Sander 2023-09-22 19:25 7720
                case 0x1F:
2660ccea Poul Sander 2023-09-22 19:25 7721
                {
2660ccea Poul Sander 2023-09-22 19:25 7722
                    error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
2660ccea Poul Sander 2023-09-22 19:25 7723
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7724
                }
2660ccea Poul Sander 2023-09-22 19:25 7725
2660ccea Poul Sander 2023-09-22 19:25 7726
                // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
2660ccea Poul Sander 2023-09-22 19:25 7727
                case 0x20:
2660ccea Poul Sander 2023-09-22 19:25 7728
                case 0x21:
2660ccea Poul Sander 2023-09-22 19:25 7729
                case 0x23:
2660ccea Poul Sander 2023-09-22 19:25 7730
                case 0x24:
2660ccea Poul Sander 2023-09-22 19:25 7731
                case 0x25:
2660ccea Poul Sander 2023-09-22 19:25 7732
                case 0x26:
2660ccea Poul Sander 2023-09-22 19:25 7733
                case 0x27:
2660ccea Poul Sander 2023-09-22 19:25 7734
                case 0x28:
2660ccea Poul Sander 2023-09-22 19:25 7735
                case 0x29:
2660ccea Poul Sander 2023-09-22 19:25 7736
                case 0x2A:
2660ccea Poul Sander 2023-09-22 19:25 7737
                case 0x2B:
2660ccea Poul Sander 2023-09-22 19:25 7738
                case 0x2C:
2660ccea Poul Sander 2023-09-22 19:25 7739
                case 0x2D:
2660ccea Poul Sander 2023-09-22 19:25 7740
                case 0x2E:
2660ccea Poul Sander 2023-09-22 19:25 7741
                case 0x2F:
2660ccea Poul Sander 2023-09-22 19:25 7742
                case 0x30:
2660ccea Poul Sander 2023-09-22 19:25 7743
                case 0x31:
2660ccea Poul Sander 2023-09-22 19:25 7744
                case 0x32:
2660ccea Poul Sander 2023-09-22 19:25 7745
                case 0x33:
2660ccea Poul Sander 2023-09-22 19:25 7746
                case 0x34:
2660ccea Poul Sander 2023-09-22 19:25 7747
                case 0x35:
2660ccea Poul Sander 2023-09-22 19:25 7748
                case 0x36:
2660ccea Poul Sander 2023-09-22 19:25 7749
                case 0x37:
2660ccea Poul Sander 2023-09-22 19:25 7750
                case 0x38:
2660ccea Poul Sander 2023-09-22 19:25 7751
                case 0x39:
2660ccea Poul Sander 2023-09-22 19:25 7752
                case 0x3A:
2660ccea Poul Sander 2023-09-22 19:25 7753
                case 0x3B:
2660ccea Poul Sander 2023-09-22 19:25 7754
                case 0x3C:
2660ccea Poul Sander 2023-09-22 19:25 7755
                case 0x3D:
2660ccea Poul Sander 2023-09-22 19:25 7756
                case 0x3E:
2660ccea Poul Sander 2023-09-22 19:25 7757
                case 0x3F:
2660ccea Poul Sander 2023-09-22 19:25 7758
                case 0x40:
2660ccea Poul Sander 2023-09-22 19:25 7759
                case 0x41:
2660ccea Poul Sander 2023-09-22 19:25 7760
                case 0x42:
2660ccea Poul Sander 2023-09-22 19:25 7761
                case 0x43:
2660ccea Poul Sander 2023-09-22 19:25 7762
                case 0x44:
2660ccea Poul Sander 2023-09-22 19:25 7763
                case 0x45:
2660ccea Poul Sander 2023-09-22 19:25 7764
                case 0x46:
2660ccea Poul Sander 2023-09-22 19:25 7765
                case 0x47:
2660ccea Poul Sander 2023-09-22 19:25 7766
                case 0x48:
2660ccea Poul Sander 2023-09-22 19:25 7767
                case 0x49:
2660ccea Poul Sander 2023-09-22 19:25 7768
                case 0x4A:
2660ccea Poul Sander 2023-09-22 19:25 7769
                case 0x4B:
2660ccea Poul Sander 2023-09-22 19:25 7770
                case 0x4C:
2660ccea Poul Sander 2023-09-22 19:25 7771
                case 0x4D:
2660ccea Poul Sander 2023-09-22 19:25 7772
                case 0x4E:
2660ccea Poul Sander 2023-09-22 19:25 7773
                case 0x4F:
2660ccea Poul Sander 2023-09-22 19:25 7774
                case 0x50:
2660ccea Poul Sander 2023-09-22 19:25 7775
                case 0x51:
2660ccea Poul Sander 2023-09-22 19:25 7776
                case 0x52:
2660ccea Poul Sander 2023-09-22 19:25 7777
                case 0x53:
2660ccea Poul Sander 2023-09-22 19:25 7778
                case 0x54:
2660ccea Poul Sander 2023-09-22 19:25 7779
                case 0x55:
2660ccea Poul Sander 2023-09-22 19:25 7780
                case 0x56:
2660ccea Poul Sander 2023-09-22 19:25 7781
                case 0x57:
2660ccea Poul Sander 2023-09-22 19:25 7782
                case 0x58:
2660ccea Poul Sander 2023-09-22 19:25 7783
                case 0x59:
2660ccea Poul Sander 2023-09-22 19:25 7784
                case 0x5A:
2660ccea Poul Sander 2023-09-22 19:25 7785
                case 0x5B:
2660ccea Poul Sander 2023-09-22 19:25 7786
                case 0x5D:
2660ccea Poul Sander 2023-09-22 19:25 7787
                case 0x5E:
2660ccea Poul Sander 2023-09-22 19:25 7788
                case 0x5F:
2660ccea Poul Sander 2023-09-22 19:25 7789
                case 0x60:
2660ccea Poul Sander 2023-09-22 19:25 7790
                case 0x61:
2660ccea Poul Sander 2023-09-22 19:25 7791
                case 0x62:
2660ccea Poul Sander 2023-09-22 19:25 7792
                case 0x63:
2660ccea Poul Sander 2023-09-22 19:25 7793
                case 0x64:
2660ccea Poul Sander 2023-09-22 19:25 7794
                case 0x65:
2660ccea Poul Sander 2023-09-22 19:25 7795
                case 0x66:
2660ccea Poul Sander 2023-09-22 19:25 7796
                case 0x67:
2660ccea Poul Sander 2023-09-22 19:25 7797
                case 0x68:
2660ccea Poul Sander 2023-09-22 19:25 7798
                case 0x69:
2660ccea Poul Sander 2023-09-22 19:25 7799
                case 0x6A:
2660ccea Poul Sander 2023-09-22 19:25 7800
                case 0x6B:
2660ccea Poul Sander 2023-09-22 19:25 7801
                case 0x6C:
2660ccea Poul Sander 2023-09-22 19:25 7802
                case 0x6D:
2660ccea Poul Sander 2023-09-22 19:25 7803
                case 0x6E:
2660ccea Poul Sander 2023-09-22 19:25 7804
                case 0x6F:
2660ccea Poul Sander 2023-09-22 19:25 7805
                case 0x70:
2660ccea Poul Sander 2023-09-22 19:25 7806
                case 0x71:
2660ccea Poul Sander 2023-09-22 19:25 7807
                case 0x72:
2660ccea Poul Sander 2023-09-22 19:25 7808
                case 0x73:
2660ccea Poul Sander 2023-09-22 19:25 7809
                case 0x74:
2660ccea Poul Sander 2023-09-22 19:25 7810
                case 0x75:
2660ccea Poul Sander 2023-09-22 19:25 7811
                case 0x76:
2660ccea Poul Sander 2023-09-22 19:25 7812
                case 0x77:
2660ccea Poul Sander 2023-09-22 19:25 7813
                case 0x78:
2660ccea Poul Sander 2023-09-22 19:25 7814
                case 0x79:
2660ccea Poul Sander 2023-09-22 19:25 7815
                case 0x7A:
2660ccea Poul Sander 2023-09-22 19:25 7816
                case 0x7B:
2660ccea Poul Sander 2023-09-22 19:25 7817
                case 0x7C:
2660ccea Poul Sander 2023-09-22 19:25 7818
                case 0x7D:
2660ccea Poul Sander 2023-09-22 19:25 7819
                case 0x7E:
2660ccea Poul Sander 2023-09-22 19:25 7820
                case 0x7F:
2660ccea Poul Sander 2023-09-22 19:25 7821
                {
2660ccea Poul Sander 2023-09-22 19:25 7822
                    add(current);
2660ccea Poul Sander 2023-09-22 19:25 7823
                    break;
2660ccea Poul Sander 2023-09-22 19:25 7824
                }
2660ccea Poul Sander 2023-09-22 19:25 7825
2660ccea Poul Sander 2023-09-22 19:25 7826
                // U+0080..U+07FF: bytes C2..DF 80..BF
2660ccea Poul Sander 2023-09-22 19:25 7827
                case 0xC2:
2660ccea Poul Sander 2023-09-22 19:25 7828
                case 0xC3:
2660ccea Poul Sander 2023-09-22 19:25 7829
                case 0xC4:
2660ccea Poul Sander 2023-09-22 19:25 7830
                case 0xC5:
2660ccea Poul Sander 2023-09-22 19:25 7831
                case 0xC6:
2660ccea Poul Sander 2023-09-22 19:25 7832
                case 0xC7:
2660ccea Poul Sander 2023-09-22 19:25 7833
                case 0xC8:
2660ccea Poul Sander 2023-09-22 19:25 7834
                case 0xC9:
2660ccea Poul Sander 2023-09-22 19:25 7835
                case 0xCA:
2660ccea Poul Sander 2023-09-22 19:25 7836
                case 0xCB:
2660ccea Poul Sander 2023-09-22 19:25 7837
                case 0xCC:
2660ccea Poul Sander 2023-09-22 19:25 7838
                case 0xCD:
2660ccea Poul Sander 2023-09-22 19:25 7839
                case 0xCE:
2660ccea Poul Sander 2023-09-22 19:25 7840
                case 0xCF:
2660ccea Poul Sander 2023-09-22 19:25 7841
                case 0xD0:
2660ccea Poul Sander 2023-09-22 19:25 7842
                case 0xD1:
2660ccea Poul Sander 2023-09-22 19:25 7843
                case 0xD2:
2660ccea Poul Sander 2023-09-22 19:25 7844
                case 0xD3:
2660ccea Poul Sander 2023-09-22 19:25 7845
                case 0xD4:
2660ccea Poul Sander 2023-09-22 19:25 7846
                case 0xD5:
2660ccea Poul Sander 2023-09-22 19:25 7847
                case 0xD6:
2660ccea Poul Sander 2023-09-22 19:25 7848
                case 0xD7:
2660ccea Poul Sander 2023-09-22 19:25 7849
                case 0xD8:
2660ccea Poul Sander 2023-09-22 19:25 7850
                case 0xD9:
2660ccea Poul Sander 2023-09-22 19:25 7851
                case 0xDA:
2660ccea Poul Sander 2023-09-22 19:25 7852
                case 0xDB:
2660ccea Poul Sander 2023-09-22 19:25 7853
                case 0xDC:
2660ccea Poul Sander 2023-09-22 19:25 7854
                case 0xDD:
2660ccea Poul Sander 2023-09-22 19:25 7855
                case 0xDE:
2660ccea Poul Sander 2023-09-22 19:25 7856
                case 0xDF:
2660ccea Poul Sander 2023-09-22 19:25 7857
                {
2660ccea Poul Sander 2023-09-22 19:25 7858
                    if (JSON_HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
2660ccea Poul Sander 2023-09-22 19:25 7859
                    {
2660ccea Poul Sander 2023-09-22 19:25 7860
                        return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7861
                    }
2660ccea Poul Sander 2023-09-22 19:25 7862
                    break;
2660ccea Poul Sander 2023-09-22 19:25 7863
                }
2660ccea Poul Sander 2023-09-22 19:25 7864
2660ccea Poul Sander 2023-09-22 19:25 7865
                // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
2660ccea Poul Sander 2023-09-22 19:25 7866
                case 0xE0:
2660ccea Poul Sander 2023-09-22 19:25 7867
                {
2660ccea Poul Sander 2023-09-22 19:25 7868
                    if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2660ccea Poul Sander 2023-09-22 19:25 7869
                    {
2660ccea Poul Sander 2023-09-22 19:25 7870
                        return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7871
                    }
2660ccea Poul Sander 2023-09-22 19:25 7872
                    break;
2660ccea Poul Sander 2023-09-22 19:25 7873
                }
2660ccea Poul Sander 2023-09-22 19:25 7874
2660ccea Poul Sander 2023-09-22 19:25 7875
                // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
2660ccea Poul Sander 2023-09-22 19:25 7876
                // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
2660ccea Poul Sander 2023-09-22 19:25 7877
                case 0xE1:
2660ccea Poul Sander 2023-09-22 19:25 7878
                case 0xE2:
2660ccea Poul Sander 2023-09-22 19:25 7879
                case 0xE3:
2660ccea Poul Sander 2023-09-22 19:25 7880
                case 0xE4:
2660ccea Poul Sander 2023-09-22 19:25 7881
                case 0xE5:
2660ccea Poul Sander 2023-09-22 19:25 7882
                case 0xE6:
2660ccea Poul Sander 2023-09-22 19:25 7883
                case 0xE7:
2660ccea Poul Sander 2023-09-22 19:25 7884
                case 0xE8:
2660ccea Poul Sander 2023-09-22 19:25 7885
                case 0xE9:
2660ccea Poul Sander 2023-09-22 19:25 7886
                case 0xEA:
2660ccea Poul Sander 2023-09-22 19:25 7887
                case 0xEB:
2660ccea Poul Sander 2023-09-22 19:25 7888
                case 0xEC:
2660ccea Poul Sander 2023-09-22 19:25 7889
                case 0xEE:
2660ccea Poul Sander 2023-09-22 19:25 7890
                case 0xEF:
2660ccea Poul Sander 2023-09-22 19:25 7891
                {
2660ccea Poul Sander 2023-09-22 19:25 7892
                    if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2660ccea Poul Sander 2023-09-22 19:25 7893
                    {
2660ccea Poul Sander 2023-09-22 19:25 7894
                        return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7895
                    }
2660ccea Poul Sander 2023-09-22 19:25 7896
                    break;
2660ccea Poul Sander 2023-09-22 19:25 7897
                }
2660ccea Poul Sander 2023-09-22 19:25 7898
2660ccea Poul Sander 2023-09-22 19:25 7899
                // U+D000..U+D7FF: bytes ED 80..9F 80..BF
2660ccea Poul Sander 2023-09-22 19:25 7900
                case 0xED:
2660ccea Poul Sander 2023-09-22 19:25 7901
                {
2660ccea Poul Sander 2023-09-22 19:25 7902
                    if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2660ccea Poul Sander 2023-09-22 19:25 7903
                    {
2660ccea Poul Sander 2023-09-22 19:25 7904
                        return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7905
                    }
2660ccea Poul Sander 2023-09-22 19:25 7906
                    break;
2660ccea Poul Sander 2023-09-22 19:25 7907
                }
2660ccea Poul Sander 2023-09-22 19:25 7908
2660ccea Poul Sander 2023-09-22 19:25 7909
                // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
2660ccea Poul Sander 2023-09-22 19:25 7910
                case 0xF0:
2660ccea Poul Sander 2023-09-22 19:25 7911
                {
2660ccea Poul Sander 2023-09-22 19:25 7912
                    if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2660ccea Poul Sander 2023-09-22 19:25 7913
                    {
2660ccea Poul Sander 2023-09-22 19:25 7914
                        return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7915
                    }
2660ccea Poul Sander 2023-09-22 19:25 7916
                    break;
2660ccea Poul Sander 2023-09-22 19:25 7917
                }
2660ccea Poul Sander 2023-09-22 19:25 7918
2660ccea Poul Sander 2023-09-22 19:25 7919
                // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
2660ccea Poul Sander 2023-09-22 19:25 7920
                case 0xF1:
2660ccea Poul Sander 2023-09-22 19:25 7921
                case 0xF2:
2660ccea Poul Sander 2023-09-22 19:25 7922
                case 0xF3:
2660ccea Poul Sander 2023-09-22 19:25 7923
                {
2660ccea Poul Sander 2023-09-22 19:25 7924
                    if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2660ccea Poul Sander 2023-09-22 19:25 7925
                    {
2660ccea Poul Sander 2023-09-22 19:25 7926
                        return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7927
                    }
2660ccea Poul Sander 2023-09-22 19:25 7928
                    break;
2660ccea Poul Sander 2023-09-22 19:25 7929
                }
2660ccea Poul Sander 2023-09-22 19:25 7930
2660ccea Poul Sander 2023-09-22 19:25 7931
                // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
2660ccea Poul Sander 2023-09-22 19:25 7932
                case 0xF4:
2660ccea Poul Sander 2023-09-22 19:25 7933
                {
2660ccea Poul Sander 2023-09-22 19:25 7934
                    if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2660ccea Poul Sander 2023-09-22 19:25 7935
                    {
2660ccea Poul Sander 2023-09-22 19:25 7936
                        return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7937
                    }
2660ccea Poul Sander 2023-09-22 19:25 7938
                    break;
2660ccea Poul Sander 2023-09-22 19:25 7939
                }
2660ccea Poul Sander 2023-09-22 19:25 7940
2660ccea Poul Sander 2023-09-22 19:25 7941
                // remaining bytes (80..C1 and F5..FF) are ill-formed
2660ccea Poul Sander 2023-09-22 19:25 7942
                default:
2660ccea Poul Sander 2023-09-22 19:25 7943
                {
2660ccea Poul Sander 2023-09-22 19:25 7944
                    error_message = "invalid string: ill-formed UTF-8 byte";
2660ccea Poul Sander 2023-09-22 19:25 7945
                    return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 7946
                }
2660ccea Poul Sander 2023-09-22 19:25 7947
            }
2660ccea Poul Sander 2023-09-22 19:25 7948
        }
2660ccea Poul Sander 2023-09-22 19:25 7949
    }
2660ccea Poul Sander 2023-09-22 19:25 7950
2660ccea Poul Sander 2023-09-22 19:25 7951
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 7952
    static void strtof(float& f, const char* str, char** endptr) noexcept
2660ccea Poul Sander 2023-09-22 19:25 7953
    {
2660ccea Poul Sander 2023-09-22 19:25 7954
        f = std::strtof(str, endptr);
2660ccea Poul Sander 2023-09-22 19:25 7955
    }
2660ccea Poul Sander 2023-09-22 19:25 7956
2660ccea Poul Sander 2023-09-22 19:25 7957
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 7958
    static void strtof(double& f, const char* str, char** endptr) noexcept
2660ccea Poul Sander 2023-09-22 19:25 7959
    {
2660ccea Poul Sander 2023-09-22 19:25 7960
        f = std::strtod(str, endptr);
2660ccea Poul Sander 2023-09-22 19:25 7961
    }
2660ccea Poul Sander 2023-09-22 19:25 7962
2660ccea Poul Sander 2023-09-22 19:25 7963
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 7964
    static void strtof(long double& f, const char* str, char** endptr) noexcept
2660ccea Poul Sander 2023-09-22 19:25 7965
    {
2660ccea Poul Sander 2023-09-22 19:25 7966
        f = std::strtold(str, endptr);
2660ccea Poul Sander 2023-09-22 19:25 7967
    }
2660ccea Poul Sander 2023-09-22 19:25 7968
2660ccea Poul Sander 2023-09-22 19:25 7969
    /*!
2660ccea Poul Sander 2023-09-22 19:25 7970
    @brief scan a number literal
2660ccea Poul Sander 2023-09-22 19:25 7971
2660ccea Poul Sander 2023-09-22 19:25 7972
    This function scans a string according to Sect. 6 of RFC 7159.
2660ccea Poul Sander 2023-09-22 19:25 7973
2660ccea Poul Sander 2023-09-22 19:25 7974
    The function is realized with a deterministic finite state machine derived
2660ccea Poul Sander 2023-09-22 19:25 7975
    from the grammar described in RFC 7159. Starting in state "init", the
2660ccea Poul Sander 2023-09-22 19:25 7976
    input is read and used to determined the next state. Only state "done"
2660ccea Poul Sander 2023-09-22 19:25 7977
    accepts the number. State "error" is a trap state to model errors. In the
2660ccea Poul Sander 2023-09-22 19:25 7978
    table below, "anything" means any character but the ones listed before.
2660ccea Poul Sander 2023-09-22 19:25 7979
2660ccea Poul Sander 2023-09-22 19:25 7980
    state    | 0        | 1-9      | e E      | +       | -       | .        | anything
2660ccea Poul Sander 2023-09-22 19:25 7981
    ---------|----------|----------|----------|---------|---------|----------|-----------
2660ccea Poul Sander 2023-09-22 19:25 7982
    init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
2660ccea Poul Sander 2023-09-22 19:25 7983
    minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
2660ccea Poul Sander 2023-09-22 19:25 7984
    zero     | done     | done     | exponent | done    | done    | decimal1 | done
2660ccea Poul Sander 2023-09-22 19:25 7985
    any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
2660ccea Poul Sander 2023-09-22 19:25 7986
    decimal1 | decimal2 | [error]  | [error]  | [error] | [error] | [error]  | [error]
2660ccea Poul Sander 2023-09-22 19:25 7987
    decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
2660ccea Poul Sander 2023-09-22 19:25 7988
    exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
2660ccea Poul Sander 2023-09-22 19:25 7989
    sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
2660ccea Poul Sander 2023-09-22 19:25 7990
    any2     | any2     | any2     | done     | done    | done    | done     | done
2660ccea Poul Sander 2023-09-22 19:25 7991
2660ccea Poul Sander 2023-09-22 19:25 7992
    The state machine is realized with one label per state (prefixed with
2660ccea Poul Sander 2023-09-22 19:25 7993
    "scan_number_") and `goto` statements between them. The state machine
2660ccea Poul Sander 2023-09-22 19:25 7994
    contains cycles, but any cycle can be left when EOF is read. Therefore,
2660ccea Poul Sander 2023-09-22 19:25 7995
    the function is guaranteed to terminate.
2660ccea Poul Sander 2023-09-22 19:25 7996
2660ccea Poul Sander 2023-09-22 19:25 7997
    During scanning, the read bytes are stored in token_buffer. This string is
2660ccea Poul Sander 2023-09-22 19:25 7998
    then converted to a signed integer, an unsigned integer, or a
2660ccea Poul Sander 2023-09-22 19:25 7999
    floating-point number.
2660ccea Poul Sander 2023-09-22 19:25 8000
2660ccea Poul Sander 2023-09-22 19:25 8001
    @return token_type::value_unsigned, token_type::value_integer, or
2660ccea Poul Sander 2023-09-22 19:25 8002
            token_type::value_float if number could be successfully scanned,
2660ccea Poul Sander 2023-09-22 19:25 8003
            token_type::parse_error otherwise
2660ccea Poul Sander 2023-09-22 19:25 8004
2660ccea Poul Sander 2023-09-22 19:25 8005
    @note The scanner is independent of the current locale. Internally, the
2660ccea Poul Sander 2023-09-22 19:25 8006
          locale's decimal point is used instead of `.` to work with the
2660ccea Poul Sander 2023-09-22 19:25 8007
          locale-dependent converters.
2660ccea Poul Sander 2023-09-22 19:25 8008
    */
2660ccea Poul Sander 2023-09-22 19:25 8009
    token_type scan_number()  // lgtm [cpp/use-of-goto]
2660ccea Poul Sander 2023-09-22 19:25 8010
    {
2660ccea Poul Sander 2023-09-22 19:25 8011
        // reset token_buffer to store the number's bytes
2660ccea Poul Sander 2023-09-22 19:25 8012
        reset();
2660ccea Poul Sander 2023-09-22 19:25 8013
2660ccea Poul Sander 2023-09-22 19:25 8014
        // the type of the parsed number; initially set to unsigned; will be
2660ccea Poul Sander 2023-09-22 19:25 8015
        // changed if minus sign, decimal point or exponent is read
2660ccea Poul Sander 2023-09-22 19:25 8016
        token_type number_type = token_type::value_unsigned;
2660ccea Poul Sander 2023-09-22 19:25 8017
2660ccea Poul Sander 2023-09-22 19:25 8018
        // state (init): we just found out we need to scan a number
2660ccea Poul Sander 2023-09-22 19:25 8019
        switch (current)
2660ccea Poul Sander 2023-09-22 19:25 8020
        {
2660ccea Poul Sander 2023-09-22 19:25 8021
            case '-':
2660ccea Poul Sander 2023-09-22 19:25 8022
            {
2660ccea Poul Sander 2023-09-22 19:25 8023
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8024
                goto scan_number_minus;
2660ccea Poul Sander 2023-09-22 19:25 8025
            }
2660ccea Poul Sander 2023-09-22 19:25 8026
2660ccea Poul Sander 2023-09-22 19:25 8027
            case '0':
2660ccea Poul Sander 2023-09-22 19:25 8028
            {
2660ccea Poul Sander 2023-09-22 19:25 8029
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8030
                goto scan_number_zero;
2660ccea Poul Sander 2023-09-22 19:25 8031
            }
2660ccea Poul Sander 2023-09-22 19:25 8032
2660ccea Poul Sander 2023-09-22 19:25 8033
            case '1':
2660ccea Poul Sander 2023-09-22 19:25 8034
            case '2':
2660ccea Poul Sander 2023-09-22 19:25 8035
            case '3':
2660ccea Poul Sander 2023-09-22 19:25 8036
            case '4':
2660ccea Poul Sander 2023-09-22 19:25 8037
            case '5':
2660ccea Poul Sander 2023-09-22 19:25 8038
            case '6':
2660ccea Poul Sander 2023-09-22 19:25 8039
            case '7':
2660ccea Poul Sander 2023-09-22 19:25 8040
            case '8':
2660ccea Poul Sander 2023-09-22 19:25 8041
            case '9':
2660ccea Poul Sander 2023-09-22 19:25 8042
            {
2660ccea Poul Sander 2023-09-22 19:25 8043
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8044
                goto scan_number_any1;
2660ccea Poul Sander 2023-09-22 19:25 8045
            }
2660ccea Poul Sander 2023-09-22 19:25 8046
2660ccea Poul Sander 2023-09-22 19:25 8047
            // all other characters are rejected outside scan_number()
2660ccea Poul Sander 2023-09-22 19:25 8048
            default:            // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 8049
                assert(false);  // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 8050
        }
2660ccea Poul Sander 2023-09-22 19:25 8051
2660ccea Poul Sander 2023-09-22 19:25 8052
scan_number_minus:
2660ccea Poul Sander 2023-09-22 19:25 8053
        // state: we just parsed a leading minus sign
2660ccea Poul Sander 2023-09-22 19:25 8054
        number_type = token_type::value_integer;
2660ccea Poul Sander 2023-09-22 19:25 8055
        switch (get())
2660ccea Poul Sander 2023-09-22 19:25 8056
        {
2660ccea Poul Sander 2023-09-22 19:25 8057
            case '0':
2660ccea Poul Sander 2023-09-22 19:25 8058
            {
2660ccea Poul Sander 2023-09-22 19:25 8059
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8060
                goto scan_number_zero;
2660ccea Poul Sander 2023-09-22 19:25 8061
            }
2660ccea Poul Sander 2023-09-22 19:25 8062
2660ccea Poul Sander 2023-09-22 19:25 8063
            case '1':
2660ccea Poul Sander 2023-09-22 19:25 8064
            case '2':
2660ccea Poul Sander 2023-09-22 19:25 8065
            case '3':
2660ccea Poul Sander 2023-09-22 19:25 8066
            case '4':
2660ccea Poul Sander 2023-09-22 19:25 8067
            case '5':
2660ccea Poul Sander 2023-09-22 19:25 8068
            case '6':
2660ccea Poul Sander 2023-09-22 19:25 8069
            case '7':
2660ccea Poul Sander 2023-09-22 19:25 8070
            case '8':
2660ccea Poul Sander 2023-09-22 19:25 8071
            case '9':
2660ccea Poul Sander 2023-09-22 19:25 8072
            {
2660ccea Poul Sander 2023-09-22 19:25 8073
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8074
                goto scan_number_any1;
2660ccea Poul Sander 2023-09-22 19:25 8075
            }
2660ccea Poul Sander 2023-09-22 19:25 8076
2660ccea Poul Sander 2023-09-22 19:25 8077
            default:
2660ccea Poul Sander 2023-09-22 19:25 8078
            {
2660ccea Poul Sander 2023-09-22 19:25 8079
                error_message = "invalid number; expected digit after '-'";
2660ccea Poul Sander 2023-09-22 19:25 8080
                return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 8081
            }
2660ccea Poul Sander 2023-09-22 19:25 8082
        }
2660ccea Poul Sander 2023-09-22 19:25 8083
2660ccea Poul Sander 2023-09-22 19:25 8084
scan_number_zero:
2660ccea Poul Sander 2023-09-22 19:25 8085
        // state: we just parse a zero (maybe with a leading minus sign)
2660ccea Poul Sander 2023-09-22 19:25 8086
        switch (get())
2660ccea Poul Sander 2023-09-22 19:25 8087
        {
2660ccea Poul Sander 2023-09-22 19:25 8088
            case '.':
2660ccea Poul Sander 2023-09-22 19:25 8089
            {
2660ccea Poul Sander 2023-09-22 19:25 8090
                add(decimal_point_char);
2660ccea Poul Sander 2023-09-22 19:25 8091
                goto scan_number_decimal1;
2660ccea Poul Sander 2023-09-22 19:25 8092
            }
2660ccea Poul Sander 2023-09-22 19:25 8093
2660ccea Poul Sander 2023-09-22 19:25 8094
            case 'e':
2660ccea Poul Sander 2023-09-22 19:25 8095
            case 'E':
2660ccea Poul Sander 2023-09-22 19:25 8096
            {
2660ccea Poul Sander 2023-09-22 19:25 8097
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8098
                goto scan_number_exponent;
2660ccea Poul Sander 2023-09-22 19:25 8099
            }
2660ccea Poul Sander 2023-09-22 19:25 8100
2660ccea Poul Sander 2023-09-22 19:25 8101
            default:
2660ccea Poul Sander 2023-09-22 19:25 8102
                goto scan_number_done;
2660ccea Poul Sander 2023-09-22 19:25 8103
        }
2660ccea Poul Sander 2023-09-22 19:25 8104
2660ccea Poul Sander 2023-09-22 19:25 8105
scan_number_any1:
2660ccea Poul Sander 2023-09-22 19:25 8106
        // state: we just parsed a number 0-9 (maybe with a leading minus sign)
2660ccea Poul Sander 2023-09-22 19:25 8107
        switch (get())
2660ccea Poul Sander 2023-09-22 19:25 8108
        {
2660ccea Poul Sander 2023-09-22 19:25 8109
            case '0':
2660ccea Poul Sander 2023-09-22 19:25 8110
            case '1':
2660ccea Poul Sander 2023-09-22 19:25 8111
            case '2':
2660ccea Poul Sander 2023-09-22 19:25 8112
            case '3':
2660ccea Poul Sander 2023-09-22 19:25 8113
            case '4':
2660ccea Poul Sander 2023-09-22 19:25 8114
            case '5':
2660ccea Poul Sander 2023-09-22 19:25 8115
            case '6':
2660ccea Poul Sander 2023-09-22 19:25 8116
            case '7':
2660ccea Poul Sander 2023-09-22 19:25 8117
            case '8':
2660ccea Poul Sander 2023-09-22 19:25 8118
            case '9':
2660ccea Poul Sander 2023-09-22 19:25 8119
            {
2660ccea Poul Sander 2023-09-22 19:25 8120
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8121
                goto scan_number_any1;
2660ccea Poul Sander 2023-09-22 19:25 8122
            }
2660ccea Poul Sander 2023-09-22 19:25 8123
2660ccea Poul Sander 2023-09-22 19:25 8124
            case '.':
2660ccea Poul Sander 2023-09-22 19:25 8125
            {
2660ccea Poul Sander 2023-09-22 19:25 8126
                add(decimal_point_char);
2660ccea Poul Sander 2023-09-22 19:25 8127
                goto scan_number_decimal1;
2660ccea Poul Sander 2023-09-22 19:25 8128
            }
2660ccea Poul Sander 2023-09-22 19:25 8129
2660ccea Poul Sander 2023-09-22 19:25 8130
            case 'e':
2660ccea Poul Sander 2023-09-22 19:25 8131
            case 'E':
2660ccea Poul Sander 2023-09-22 19:25 8132
            {
2660ccea Poul Sander 2023-09-22 19:25 8133
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8134
                goto scan_number_exponent;
2660ccea Poul Sander 2023-09-22 19:25 8135
            }
2660ccea Poul Sander 2023-09-22 19:25 8136
2660ccea Poul Sander 2023-09-22 19:25 8137
            default:
2660ccea Poul Sander 2023-09-22 19:25 8138
                goto scan_number_done;
2660ccea Poul Sander 2023-09-22 19:25 8139
        }
2660ccea Poul Sander 2023-09-22 19:25 8140
2660ccea Poul Sander 2023-09-22 19:25 8141
scan_number_decimal1:
2660ccea Poul Sander 2023-09-22 19:25 8142
        // state: we just parsed a decimal point
2660ccea Poul Sander 2023-09-22 19:25 8143
        number_type = token_type::value_float;
2660ccea Poul Sander 2023-09-22 19:25 8144
        switch (get())
2660ccea Poul Sander 2023-09-22 19:25 8145
        {
2660ccea Poul Sander 2023-09-22 19:25 8146
            case '0':
2660ccea Poul Sander 2023-09-22 19:25 8147
            case '1':
2660ccea Poul Sander 2023-09-22 19:25 8148
            case '2':
2660ccea Poul Sander 2023-09-22 19:25 8149
            case '3':
2660ccea Poul Sander 2023-09-22 19:25 8150
            case '4':
2660ccea Poul Sander 2023-09-22 19:25 8151
            case '5':
2660ccea Poul Sander 2023-09-22 19:25 8152
            case '6':
2660ccea Poul Sander 2023-09-22 19:25 8153
            case '7':
2660ccea Poul Sander 2023-09-22 19:25 8154
            case '8':
2660ccea Poul Sander 2023-09-22 19:25 8155
            case '9':
2660ccea Poul Sander 2023-09-22 19:25 8156
            {
2660ccea Poul Sander 2023-09-22 19:25 8157
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8158
                goto scan_number_decimal2;
2660ccea Poul Sander 2023-09-22 19:25 8159
            }
2660ccea Poul Sander 2023-09-22 19:25 8160
2660ccea Poul Sander 2023-09-22 19:25 8161
            default:
2660ccea Poul Sander 2023-09-22 19:25 8162
            {
2660ccea Poul Sander 2023-09-22 19:25 8163
                error_message = "invalid number; expected digit after '.'";
2660ccea Poul Sander 2023-09-22 19:25 8164
                return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 8165
            }
2660ccea Poul Sander 2023-09-22 19:25 8166
        }
2660ccea Poul Sander 2023-09-22 19:25 8167
2660ccea Poul Sander 2023-09-22 19:25 8168
scan_number_decimal2:
2660ccea Poul Sander 2023-09-22 19:25 8169
        // we just parsed at least one number after a decimal point
2660ccea Poul Sander 2023-09-22 19:25 8170
        switch (get())
2660ccea Poul Sander 2023-09-22 19:25 8171
        {
2660ccea Poul Sander 2023-09-22 19:25 8172
            case '0':
2660ccea Poul Sander 2023-09-22 19:25 8173
            case '1':
2660ccea Poul Sander 2023-09-22 19:25 8174
            case '2':
2660ccea Poul Sander 2023-09-22 19:25 8175
            case '3':
2660ccea Poul Sander 2023-09-22 19:25 8176
            case '4':
2660ccea Poul Sander 2023-09-22 19:25 8177
            case '5':
2660ccea Poul Sander 2023-09-22 19:25 8178
            case '6':
2660ccea Poul Sander 2023-09-22 19:25 8179
            case '7':
2660ccea Poul Sander 2023-09-22 19:25 8180
            case '8':
2660ccea Poul Sander 2023-09-22 19:25 8181
            case '9':
2660ccea Poul Sander 2023-09-22 19:25 8182
            {
2660ccea Poul Sander 2023-09-22 19:25 8183
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8184
                goto scan_number_decimal2;
2660ccea Poul Sander 2023-09-22 19:25 8185
            }
2660ccea Poul Sander 2023-09-22 19:25 8186
2660ccea Poul Sander 2023-09-22 19:25 8187
            case 'e':
2660ccea Poul Sander 2023-09-22 19:25 8188
            case 'E':
2660ccea Poul Sander 2023-09-22 19:25 8189
            {
2660ccea Poul Sander 2023-09-22 19:25 8190
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8191
                goto scan_number_exponent;
2660ccea Poul Sander 2023-09-22 19:25 8192
            }
2660ccea Poul Sander 2023-09-22 19:25 8193
2660ccea Poul Sander 2023-09-22 19:25 8194
            default:
2660ccea Poul Sander 2023-09-22 19:25 8195
                goto scan_number_done;
2660ccea Poul Sander 2023-09-22 19:25 8196
        }
2660ccea Poul Sander 2023-09-22 19:25 8197
2660ccea Poul Sander 2023-09-22 19:25 8198
scan_number_exponent:
2660ccea Poul Sander 2023-09-22 19:25 8199
        // we just parsed an exponent
2660ccea Poul Sander 2023-09-22 19:25 8200
        number_type = token_type::value_float;
2660ccea Poul Sander 2023-09-22 19:25 8201
        switch (get())
2660ccea Poul Sander 2023-09-22 19:25 8202
        {
2660ccea Poul Sander 2023-09-22 19:25 8203
            case '+':
2660ccea Poul Sander 2023-09-22 19:25 8204
            case '-':
2660ccea Poul Sander 2023-09-22 19:25 8205
            {
2660ccea Poul Sander 2023-09-22 19:25 8206
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8207
                goto scan_number_sign;
2660ccea Poul Sander 2023-09-22 19:25 8208
            }
2660ccea Poul Sander 2023-09-22 19:25 8209
2660ccea Poul Sander 2023-09-22 19:25 8210
            case '0':
2660ccea Poul Sander 2023-09-22 19:25 8211
            case '1':
2660ccea Poul Sander 2023-09-22 19:25 8212
            case '2':
2660ccea Poul Sander 2023-09-22 19:25 8213
            case '3':
2660ccea Poul Sander 2023-09-22 19:25 8214
            case '4':
2660ccea Poul Sander 2023-09-22 19:25 8215
            case '5':
2660ccea Poul Sander 2023-09-22 19:25 8216
            case '6':
2660ccea Poul Sander 2023-09-22 19:25 8217
            case '7':
2660ccea Poul Sander 2023-09-22 19:25 8218
            case '8':
2660ccea Poul Sander 2023-09-22 19:25 8219
            case '9':
2660ccea Poul Sander 2023-09-22 19:25 8220
            {
2660ccea Poul Sander 2023-09-22 19:25 8221
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8222
                goto scan_number_any2;
2660ccea Poul Sander 2023-09-22 19:25 8223
            }
2660ccea Poul Sander 2023-09-22 19:25 8224
2660ccea Poul Sander 2023-09-22 19:25 8225
            default:
2660ccea Poul Sander 2023-09-22 19:25 8226
            {
2660ccea Poul Sander 2023-09-22 19:25 8227
                error_message =
2660ccea Poul Sander 2023-09-22 19:25 8228
                    "invalid number; expected '+', '-', or digit after exponent";
2660ccea Poul Sander 2023-09-22 19:25 8229
                return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 8230
            }
2660ccea Poul Sander 2023-09-22 19:25 8231
        }
2660ccea Poul Sander 2023-09-22 19:25 8232
2660ccea Poul Sander 2023-09-22 19:25 8233
scan_number_sign:
2660ccea Poul Sander 2023-09-22 19:25 8234
        // we just parsed an exponent sign
2660ccea Poul Sander 2023-09-22 19:25 8235
        switch (get())
2660ccea Poul Sander 2023-09-22 19:25 8236
        {
2660ccea Poul Sander 2023-09-22 19:25 8237
            case '0':
2660ccea Poul Sander 2023-09-22 19:25 8238
            case '1':
2660ccea Poul Sander 2023-09-22 19:25 8239
            case '2':
2660ccea Poul Sander 2023-09-22 19:25 8240
            case '3':
2660ccea Poul Sander 2023-09-22 19:25 8241
            case '4':
2660ccea Poul Sander 2023-09-22 19:25 8242
            case '5':
2660ccea Poul Sander 2023-09-22 19:25 8243
            case '6':
2660ccea Poul Sander 2023-09-22 19:25 8244
            case '7':
2660ccea Poul Sander 2023-09-22 19:25 8245
            case '8':
2660ccea Poul Sander 2023-09-22 19:25 8246
            case '9':
2660ccea Poul Sander 2023-09-22 19:25 8247
            {
2660ccea Poul Sander 2023-09-22 19:25 8248
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8249
                goto scan_number_any2;
2660ccea Poul Sander 2023-09-22 19:25 8250
            }
2660ccea Poul Sander 2023-09-22 19:25 8251
2660ccea Poul Sander 2023-09-22 19:25 8252
            default:
2660ccea Poul Sander 2023-09-22 19:25 8253
            {
2660ccea Poul Sander 2023-09-22 19:25 8254
                error_message = "invalid number; expected digit after exponent sign";
2660ccea Poul Sander 2023-09-22 19:25 8255
                return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 8256
            }
2660ccea Poul Sander 2023-09-22 19:25 8257
        }
2660ccea Poul Sander 2023-09-22 19:25 8258
2660ccea Poul Sander 2023-09-22 19:25 8259
scan_number_any2:
2660ccea Poul Sander 2023-09-22 19:25 8260
        // we just parsed a number after the exponent or exponent sign
2660ccea Poul Sander 2023-09-22 19:25 8261
        switch (get())
2660ccea Poul Sander 2023-09-22 19:25 8262
        {
2660ccea Poul Sander 2023-09-22 19:25 8263
            case '0':
2660ccea Poul Sander 2023-09-22 19:25 8264
            case '1':
2660ccea Poul Sander 2023-09-22 19:25 8265
            case '2':
2660ccea Poul Sander 2023-09-22 19:25 8266
            case '3':
2660ccea Poul Sander 2023-09-22 19:25 8267
            case '4':
2660ccea Poul Sander 2023-09-22 19:25 8268
            case '5':
2660ccea Poul Sander 2023-09-22 19:25 8269
            case '6':
2660ccea Poul Sander 2023-09-22 19:25 8270
            case '7':
2660ccea Poul Sander 2023-09-22 19:25 8271
            case '8':
2660ccea Poul Sander 2023-09-22 19:25 8272
            case '9':
2660ccea Poul Sander 2023-09-22 19:25 8273
            {
2660ccea Poul Sander 2023-09-22 19:25 8274
                add(current);
2660ccea Poul Sander 2023-09-22 19:25 8275
                goto scan_number_any2;
2660ccea Poul Sander 2023-09-22 19:25 8276
            }
2660ccea Poul Sander 2023-09-22 19:25 8277
2660ccea Poul Sander 2023-09-22 19:25 8278
            default:
2660ccea Poul Sander 2023-09-22 19:25 8279
                goto scan_number_done;
2660ccea Poul Sander 2023-09-22 19:25 8280
        }
2660ccea Poul Sander 2023-09-22 19:25 8281
2660ccea Poul Sander 2023-09-22 19:25 8282
scan_number_done:
2660ccea Poul Sander 2023-09-22 19:25 8283
        // unget the character after the number (we only read it to know that
2660ccea Poul Sander 2023-09-22 19:25 8284
        // we are done scanning a number)
2660ccea Poul Sander 2023-09-22 19:25 8285
        unget();
2660ccea Poul Sander 2023-09-22 19:25 8286
2660ccea Poul Sander 2023-09-22 19:25 8287
        char* endptr = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 8288
        errno = 0;
2660ccea Poul Sander 2023-09-22 19:25 8289
2660ccea Poul Sander 2023-09-22 19:25 8290
        // try to parse integers first and fall back to floats
2660ccea Poul Sander 2023-09-22 19:25 8291
        if (number_type == token_type::value_unsigned)
2660ccea Poul Sander 2023-09-22 19:25 8292
        {
2660ccea Poul Sander 2023-09-22 19:25 8293
            const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
2660ccea Poul Sander 2023-09-22 19:25 8294
2660ccea Poul Sander 2023-09-22 19:25 8295
            // we checked the number format before
2660ccea Poul Sander 2023-09-22 19:25 8296
            assert(endptr == token_buffer.data() + token_buffer.size());
2660ccea Poul Sander 2023-09-22 19:25 8297
2660ccea Poul Sander 2023-09-22 19:25 8298
            if (errno == 0)
2660ccea Poul Sander 2023-09-22 19:25 8299
            {
2660ccea Poul Sander 2023-09-22 19:25 8300
                value_unsigned = static_cast<number_unsigned_t>(x);
2660ccea Poul Sander 2023-09-22 19:25 8301
                if (value_unsigned == x)
2660ccea Poul Sander 2023-09-22 19:25 8302
                {
2660ccea Poul Sander 2023-09-22 19:25 8303
                    return token_type::value_unsigned;
2660ccea Poul Sander 2023-09-22 19:25 8304
                }
2660ccea Poul Sander 2023-09-22 19:25 8305
            }
2660ccea Poul Sander 2023-09-22 19:25 8306
        }
2660ccea Poul Sander 2023-09-22 19:25 8307
        else if (number_type == token_type::value_integer)
2660ccea Poul Sander 2023-09-22 19:25 8308
        {
2660ccea Poul Sander 2023-09-22 19:25 8309
            const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
2660ccea Poul Sander 2023-09-22 19:25 8310
2660ccea Poul Sander 2023-09-22 19:25 8311
            // we checked the number format before
2660ccea Poul Sander 2023-09-22 19:25 8312
            assert(endptr == token_buffer.data() + token_buffer.size());
2660ccea Poul Sander 2023-09-22 19:25 8313
2660ccea Poul Sander 2023-09-22 19:25 8314
            if (errno == 0)
2660ccea Poul Sander 2023-09-22 19:25 8315
            {
2660ccea Poul Sander 2023-09-22 19:25 8316
                value_integer = static_cast<number_integer_t>(x);
2660ccea Poul Sander 2023-09-22 19:25 8317
                if (value_integer == x)
2660ccea Poul Sander 2023-09-22 19:25 8318
                {
2660ccea Poul Sander 2023-09-22 19:25 8319
                    return token_type::value_integer;
2660ccea Poul Sander 2023-09-22 19:25 8320
                }
2660ccea Poul Sander 2023-09-22 19:25 8321
            }
2660ccea Poul Sander 2023-09-22 19:25 8322
        }
2660ccea Poul Sander 2023-09-22 19:25 8323
2660ccea Poul Sander 2023-09-22 19:25 8324
        // this code is reached if we parse a floating-point number or if an
2660ccea Poul Sander 2023-09-22 19:25 8325
        // integer conversion above failed
2660ccea Poul Sander 2023-09-22 19:25 8326
        strtof(value_float, token_buffer.data(), &endptr);
2660ccea Poul Sander 2023-09-22 19:25 8327
2660ccea Poul Sander 2023-09-22 19:25 8328
        // we checked the number format before
2660ccea Poul Sander 2023-09-22 19:25 8329
        assert(endptr == token_buffer.data() + token_buffer.size());
2660ccea Poul Sander 2023-09-22 19:25 8330
2660ccea Poul Sander 2023-09-22 19:25 8331
        return token_type::value_float;
2660ccea Poul Sander 2023-09-22 19:25 8332
    }
2660ccea Poul Sander 2023-09-22 19:25 8333
2660ccea Poul Sander 2023-09-22 19:25 8334
    /*!
2660ccea Poul Sander 2023-09-22 19:25 8335
    @param[in] literal_text  the literal text to expect
2660ccea Poul Sander 2023-09-22 19:25 8336
    @param[in] length        the length of the passed literal text
2660ccea Poul Sander 2023-09-22 19:25 8337
    @param[in] return_type   the token type to return on success
2660ccea Poul Sander 2023-09-22 19:25 8338
    */
2660ccea Poul Sander 2023-09-22 19:25 8339
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 8340
    token_type scan_literal(const char* literal_text, const std::size_t length,
2660ccea Poul Sander 2023-09-22 19:25 8341
                            token_type return_type)
2660ccea Poul Sander 2023-09-22 19:25 8342
    {
2660ccea Poul Sander 2023-09-22 19:25 8343
        assert(current == literal_text[0]);
2660ccea Poul Sander 2023-09-22 19:25 8344
        for (std::size_t i = 1; i < length; ++i)
2660ccea Poul Sander 2023-09-22 19:25 8345
        {
2660ccea Poul Sander 2023-09-22 19:25 8346
            if (JSON_HEDLEY_UNLIKELY(get() != literal_text[i]))
2660ccea Poul Sander 2023-09-22 19:25 8347
            {
2660ccea Poul Sander 2023-09-22 19:25 8348
                error_message = "invalid literal";
2660ccea Poul Sander 2023-09-22 19:25 8349
                return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 8350
            }
2660ccea Poul Sander 2023-09-22 19:25 8351
        }
2660ccea Poul Sander 2023-09-22 19:25 8352
        return return_type;
2660ccea Poul Sander 2023-09-22 19:25 8353
    }
2660ccea Poul Sander 2023-09-22 19:25 8354
2660ccea Poul Sander 2023-09-22 19:25 8355
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 8356
    // input management
2660ccea Poul Sander 2023-09-22 19:25 8357
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 8358
2660ccea Poul Sander 2023-09-22 19:25 8359
    /// reset token_buffer; current character is beginning of token
2660ccea Poul Sander 2023-09-22 19:25 8360
    void reset() noexcept
2660ccea Poul Sander 2023-09-22 19:25 8361
    {
2660ccea Poul Sander 2023-09-22 19:25 8362
        token_buffer.clear();
2660ccea Poul Sander 2023-09-22 19:25 8363
        token_string.clear();
2660ccea Poul Sander 2023-09-22 19:25 8364
        token_string.push_back(std::char_traits<char>::to_char_type(current));
2660ccea Poul Sander 2023-09-22 19:25 8365
    }
2660ccea Poul Sander 2023-09-22 19:25 8366
2660ccea Poul Sander 2023-09-22 19:25 8367
    /*
2660ccea Poul Sander 2023-09-22 19:25 8368
    @brief get next character from the input
2660ccea Poul Sander 2023-09-22 19:25 8369
2660ccea Poul Sander 2023-09-22 19:25 8370
    This function provides the interface to the used input adapter. It does
2660ccea Poul Sander 2023-09-22 19:25 8371
    not throw in case the input reached EOF, but returns a
2660ccea Poul Sander 2023-09-22 19:25 8372
    `std::char_traits<char>::eof()` in that case.  Stores the scanned characters
2660ccea Poul Sander 2023-09-22 19:25 8373
    for use in error messages.
2660ccea Poul Sander 2023-09-22 19:25 8374
2660ccea Poul Sander 2023-09-22 19:25 8375
    @return character read from the input
2660ccea Poul Sander 2023-09-22 19:25 8376
    */
2660ccea Poul Sander 2023-09-22 19:25 8377
    std::char_traits<char>::int_type get()
2660ccea Poul Sander 2023-09-22 19:25 8378
    {
2660ccea Poul Sander 2023-09-22 19:25 8379
        ++position.chars_read_total;
2660ccea Poul Sander 2023-09-22 19:25 8380
        ++position.chars_read_current_line;
2660ccea Poul Sander 2023-09-22 19:25 8381
2660ccea Poul Sander 2023-09-22 19:25 8382
        if (next_unget)
2660ccea Poul Sander 2023-09-22 19:25 8383
        {
2660ccea Poul Sander 2023-09-22 19:25 8384
            // just reset the next_unget variable and work with current
2660ccea Poul Sander 2023-09-22 19:25 8385
            next_unget = false;
2660ccea Poul Sander 2023-09-22 19:25 8386
        }
2660ccea Poul Sander 2023-09-22 19:25 8387
        else
2660ccea Poul Sander 2023-09-22 19:25 8388
        {
2660ccea Poul Sander 2023-09-22 19:25 8389
            current = ia->get_character();
2660ccea Poul Sander 2023-09-22 19:25 8390
        }
2660ccea Poul Sander 2023-09-22 19:25 8391
2660ccea Poul Sander 2023-09-22 19:25 8392
        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
2660ccea Poul Sander 2023-09-22 19:25 8393
        {
2660ccea Poul Sander 2023-09-22 19:25 8394
            token_string.push_back(std::char_traits<char>::to_char_type(current));
2660ccea Poul Sander 2023-09-22 19:25 8395
        }
2660ccea Poul Sander 2023-09-22 19:25 8396
2660ccea Poul Sander 2023-09-22 19:25 8397
        if (current == '\n')
2660ccea Poul Sander 2023-09-22 19:25 8398
        {
2660ccea Poul Sander 2023-09-22 19:25 8399
            ++position.lines_read;
2660ccea Poul Sander 2023-09-22 19:25 8400
            position.chars_read_current_line = 0;
2660ccea Poul Sander 2023-09-22 19:25 8401
        }
2660ccea Poul Sander 2023-09-22 19:25 8402
2660ccea Poul Sander 2023-09-22 19:25 8403
        return current;
2660ccea Poul Sander 2023-09-22 19:25 8404
    }
2660ccea Poul Sander 2023-09-22 19:25 8405
2660ccea Poul Sander 2023-09-22 19:25 8406
    /*!
2660ccea Poul Sander 2023-09-22 19:25 8407
    @brief unget current character (read it again on next get)
2660ccea Poul Sander 2023-09-22 19:25 8408
2660ccea Poul Sander 2023-09-22 19:25 8409
    We implement unget by setting variable next_unget to true. The input is not
2660ccea Poul Sander 2023-09-22 19:25 8410
    changed - we just simulate ungetting by modifying chars_read_total,
2660ccea Poul Sander 2023-09-22 19:25 8411
    chars_read_current_line, and token_string. The next call to get() will
2660ccea Poul Sander 2023-09-22 19:25 8412
    behave as if the unget character is read again.
2660ccea Poul Sander 2023-09-22 19:25 8413
    */
2660ccea Poul Sander 2023-09-22 19:25 8414
    void unget()
2660ccea Poul Sander 2023-09-22 19:25 8415
    {
2660ccea Poul Sander 2023-09-22 19:25 8416
        next_unget = true;
2660ccea Poul Sander 2023-09-22 19:25 8417
2660ccea Poul Sander 2023-09-22 19:25 8418
        --position.chars_read_total;
2660ccea Poul Sander 2023-09-22 19:25 8419
2660ccea Poul Sander 2023-09-22 19:25 8420
        // in case we "unget" a newline, we have to also decrement the lines_read
2660ccea Poul Sander 2023-09-22 19:25 8421
        if (position.chars_read_current_line == 0)
2660ccea Poul Sander 2023-09-22 19:25 8422
        {
2660ccea Poul Sander 2023-09-22 19:25 8423
            if (position.lines_read > 0)
2660ccea Poul Sander 2023-09-22 19:25 8424
            {
2660ccea Poul Sander 2023-09-22 19:25 8425
                --position.lines_read;
2660ccea Poul Sander 2023-09-22 19:25 8426
            }
2660ccea Poul Sander 2023-09-22 19:25 8427
        }
2660ccea Poul Sander 2023-09-22 19:25 8428
        else
2660ccea Poul Sander 2023-09-22 19:25 8429
        {
2660ccea Poul Sander 2023-09-22 19:25 8430
            --position.chars_read_current_line;
2660ccea Poul Sander 2023-09-22 19:25 8431
        }
2660ccea Poul Sander 2023-09-22 19:25 8432
2660ccea Poul Sander 2023-09-22 19:25 8433
        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
2660ccea Poul Sander 2023-09-22 19:25 8434
        {
2660ccea Poul Sander 2023-09-22 19:25 8435
            assert(not token_string.empty());
2660ccea Poul Sander 2023-09-22 19:25 8436
            token_string.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 8437
        }
2660ccea Poul Sander 2023-09-22 19:25 8438
    }
2660ccea Poul Sander 2023-09-22 19:25 8439
2660ccea Poul Sander 2023-09-22 19:25 8440
    /// add a character to token_buffer
2660ccea Poul Sander 2023-09-22 19:25 8441
    void add(int c)
2660ccea Poul Sander 2023-09-22 19:25 8442
    {
2660ccea Poul Sander 2023-09-22 19:25 8443
        token_buffer.push_back(std::char_traits<char>::to_char_type(c));
2660ccea Poul Sander 2023-09-22 19:25 8444
    }
2660ccea Poul Sander 2023-09-22 19:25 8445
2660ccea Poul Sander 2023-09-22 19:25 8446
  public:
2660ccea Poul Sander 2023-09-22 19:25 8447
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 8448
    // value getters
2660ccea Poul Sander 2023-09-22 19:25 8449
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 8450
2660ccea Poul Sander 2023-09-22 19:25 8451
    /// return integer value
2660ccea Poul Sander 2023-09-22 19:25 8452
    constexpr number_integer_t get_number_integer() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 8453
    {
2660ccea Poul Sander 2023-09-22 19:25 8454
        return value_integer;
2660ccea Poul Sander 2023-09-22 19:25 8455
    }
2660ccea Poul Sander 2023-09-22 19:25 8456
2660ccea Poul Sander 2023-09-22 19:25 8457
    /// return unsigned integer value
2660ccea Poul Sander 2023-09-22 19:25 8458
    constexpr number_unsigned_t get_number_unsigned() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 8459
    {
2660ccea Poul Sander 2023-09-22 19:25 8460
        return value_unsigned;
2660ccea Poul Sander 2023-09-22 19:25 8461
    }
2660ccea Poul Sander 2023-09-22 19:25 8462
2660ccea Poul Sander 2023-09-22 19:25 8463
    /// return floating-point value
2660ccea Poul Sander 2023-09-22 19:25 8464
    constexpr number_float_t get_number_float() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 8465
    {
2660ccea Poul Sander 2023-09-22 19:25 8466
        return value_float;
2660ccea Poul Sander 2023-09-22 19:25 8467
    }
2660ccea Poul Sander 2023-09-22 19:25 8468
2660ccea Poul Sander 2023-09-22 19:25 8469
    /// return current string value (implicitly resets the token; useful only once)
2660ccea Poul Sander 2023-09-22 19:25 8470
    string_t& get_string()
2660ccea Poul Sander 2023-09-22 19:25 8471
    {
2660ccea Poul Sander 2023-09-22 19:25 8472
        return token_buffer;
2660ccea Poul Sander 2023-09-22 19:25 8473
    }
2660ccea Poul Sander 2023-09-22 19:25 8474
2660ccea Poul Sander 2023-09-22 19:25 8475
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 8476
    // diagnostics
2660ccea Poul Sander 2023-09-22 19:25 8477
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 8478
2660ccea Poul Sander 2023-09-22 19:25 8479
    /// return position of last read token
2660ccea Poul Sander 2023-09-22 19:25 8480
    constexpr position_t get_position() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 8481
    {
2660ccea Poul Sander 2023-09-22 19:25 8482
        return position;
2660ccea Poul Sander 2023-09-22 19:25 8483
    }
2660ccea Poul Sander 2023-09-22 19:25 8484
2660ccea Poul Sander 2023-09-22 19:25 8485
    /// return the last read token (for errors only).  Will never contain EOF
2660ccea Poul Sander 2023-09-22 19:25 8486
    /// (an arbitrary value that is not a valid char value, often -1), because
2660ccea Poul Sander 2023-09-22 19:25 8487
    /// 255 may legitimately occur.  May contain NUL, which should be escaped.
2660ccea Poul Sander 2023-09-22 19:25 8488
    std::string get_token_string() const
2660ccea Poul Sander 2023-09-22 19:25 8489
    {
2660ccea Poul Sander 2023-09-22 19:25 8490
        // escape control characters
2660ccea Poul Sander 2023-09-22 19:25 8491
        std::string result;
2660ccea Poul Sander 2023-09-22 19:25 8492
        for (const auto c : token_string)
2660ccea Poul Sander 2023-09-22 19:25 8493
        {
2660ccea Poul Sander 2023-09-22 19:25 8494
            if ('\x00' <= c and c <= '\x1F')
2660ccea Poul Sander 2023-09-22 19:25 8495
            {
2660ccea Poul Sander 2023-09-22 19:25 8496
                // escape control characters
2660ccea Poul Sander 2023-09-22 19:25 8497
                std::array<char, 9> cs{{}};
2660ccea Poul Sander 2023-09-22 19:25 8498
                (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
2660ccea Poul Sander 2023-09-22 19:25 8499
                result += cs.data();
2660ccea Poul Sander 2023-09-22 19:25 8500
            }
2660ccea Poul Sander 2023-09-22 19:25 8501
            else
2660ccea Poul Sander 2023-09-22 19:25 8502
            {
2660ccea Poul Sander 2023-09-22 19:25 8503
                // add character as is
2660ccea Poul Sander 2023-09-22 19:25 8504
                result.push_back(c);
2660ccea Poul Sander 2023-09-22 19:25 8505
            }
2660ccea Poul Sander 2023-09-22 19:25 8506
        }
2660ccea Poul Sander 2023-09-22 19:25 8507
2660ccea Poul Sander 2023-09-22 19:25 8508
        return result;
2660ccea Poul Sander 2023-09-22 19:25 8509
    }
2660ccea Poul Sander 2023-09-22 19:25 8510
2660ccea Poul Sander 2023-09-22 19:25 8511
    /// return syntax error message
2660ccea Poul Sander 2023-09-22 19:25 8512
    JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 8513
    constexpr const char* get_error_message() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 8514
    {
2660ccea Poul Sander 2023-09-22 19:25 8515
        return error_message;
2660ccea Poul Sander 2023-09-22 19:25 8516
    }
2660ccea Poul Sander 2023-09-22 19:25 8517
2660ccea Poul Sander 2023-09-22 19:25 8518
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 8519
    // actual scanner
2660ccea Poul Sander 2023-09-22 19:25 8520
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 8521
2660ccea Poul Sander 2023-09-22 19:25 8522
    /*!
2660ccea Poul Sander 2023-09-22 19:25 8523
    @brief skip the UTF-8 byte order mark
2660ccea Poul Sander 2023-09-22 19:25 8524
    @return true iff there is no BOM or the correct BOM has been skipped
2660ccea Poul Sander 2023-09-22 19:25 8525
    */
2660ccea Poul Sander 2023-09-22 19:25 8526
    bool skip_bom()
2660ccea Poul Sander 2023-09-22 19:25 8527
    {
2660ccea Poul Sander 2023-09-22 19:25 8528
        if (get() == 0xEF)
2660ccea Poul Sander 2023-09-22 19:25 8529
        {
2660ccea Poul Sander 2023-09-22 19:25 8530
            // check if we completely parse the BOM
2660ccea Poul Sander 2023-09-22 19:25 8531
            return get() == 0xBB and get() == 0xBF;
2660ccea Poul Sander 2023-09-22 19:25 8532
        }
2660ccea Poul Sander 2023-09-22 19:25 8533
2660ccea Poul Sander 2023-09-22 19:25 8534
        // the first character is not the beginning of the BOM; unget it to
2660ccea Poul Sander 2023-09-22 19:25 8535
        // process is later
2660ccea Poul Sander 2023-09-22 19:25 8536
        unget();
2660ccea Poul Sander 2023-09-22 19:25 8537
        return true;
2660ccea Poul Sander 2023-09-22 19:25 8538
    }
2660ccea Poul Sander 2023-09-22 19:25 8539
2660ccea Poul Sander 2023-09-22 19:25 8540
    token_type scan()
2660ccea Poul Sander 2023-09-22 19:25 8541
    {
2660ccea Poul Sander 2023-09-22 19:25 8542
        // initially, skip the BOM
2660ccea Poul Sander 2023-09-22 19:25 8543
        if (position.chars_read_total == 0 and not skip_bom())
2660ccea Poul Sander 2023-09-22 19:25 8544
        {
2660ccea Poul Sander 2023-09-22 19:25 8545
            error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
2660ccea Poul Sander 2023-09-22 19:25 8546
            return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 8547
        }
2660ccea Poul Sander 2023-09-22 19:25 8548
2660ccea Poul Sander 2023-09-22 19:25 8549
        // read next character and ignore whitespace
2660ccea Poul Sander 2023-09-22 19:25 8550
        do
2660ccea Poul Sander 2023-09-22 19:25 8551
        {
2660ccea Poul Sander 2023-09-22 19:25 8552
            get();
2660ccea Poul Sander 2023-09-22 19:25 8553
        }
2660ccea Poul Sander 2023-09-22 19:25 8554
        while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
2660ccea Poul Sander 2023-09-22 19:25 8555
2660ccea Poul Sander 2023-09-22 19:25 8556
        switch (current)
2660ccea Poul Sander 2023-09-22 19:25 8557
        {
2660ccea Poul Sander 2023-09-22 19:25 8558
            // structural characters
2660ccea Poul Sander 2023-09-22 19:25 8559
            case '[':
2660ccea Poul Sander 2023-09-22 19:25 8560
                return token_type::begin_array;
2660ccea Poul Sander 2023-09-22 19:25 8561
            case ']':
2660ccea Poul Sander 2023-09-22 19:25 8562
                return token_type::end_array;
2660ccea Poul Sander 2023-09-22 19:25 8563
            case '{':
2660ccea Poul Sander 2023-09-22 19:25 8564
                return token_type::begin_object;
2660ccea Poul Sander 2023-09-22 19:25 8565
            case '}':
2660ccea Poul Sander 2023-09-22 19:25 8566
                return token_type::end_object;
2660ccea Poul Sander 2023-09-22 19:25 8567
            case ':':
2660ccea Poul Sander 2023-09-22 19:25 8568
                return token_type::name_separator;
2660ccea Poul Sander 2023-09-22 19:25 8569
            case ',':
2660ccea Poul Sander 2023-09-22 19:25 8570
                return token_type::value_separator;
2660ccea Poul Sander 2023-09-22 19:25 8571
2660ccea Poul Sander 2023-09-22 19:25 8572
            // literals
2660ccea Poul Sander 2023-09-22 19:25 8573
            case 't':
2660ccea Poul Sander 2023-09-22 19:25 8574
                return scan_literal("true", 4, token_type::literal_true);
2660ccea Poul Sander 2023-09-22 19:25 8575
            case 'f':
2660ccea Poul Sander 2023-09-22 19:25 8576
                return scan_literal("false", 5, token_type::literal_false);
2660ccea Poul Sander 2023-09-22 19:25 8577
            case 'n':
2660ccea Poul Sander 2023-09-22 19:25 8578
                return scan_literal("null", 4, token_type::literal_null);
2660ccea Poul Sander 2023-09-22 19:25 8579
2660ccea Poul Sander 2023-09-22 19:25 8580
            // string
2660ccea Poul Sander 2023-09-22 19:25 8581
            case '\"':
2660ccea Poul Sander 2023-09-22 19:25 8582
                return scan_string();
2660ccea Poul Sander 2023-09-22 19:25 8583
2660ccea Poul Sander 2023-09-22 19:25 8584
            // number
2660ccea Poul Sander 2023-09-22 19:25 8585
            case '-':
2660ccea Poul Sander 2023-09-22 19:25 8586
            case '0':
2660ccea Poul Sander 2023-09-22 19:25 8587
            case '1':
2660ccea Poul Sander 2023-09-22 19:25 8588
            case '2':
2660ccea Poul Sander 2023-09-22 19:25 8589
            case '3':
2660ccea Poul Sander 2023-09-22 19:25 8590
            case '4':
2660ccea Poul Sander 2023-09-22 19:25 8591
            case '5':
2660ccea Poul Sander 2023-09-22 19:25 8592
            case '6':
2660ccea Poul Sander 2023-09-22 19:25 8593
            case '7':
2660ccea Poul Sander 2023-09-22 19:25 8594
            case '8':
2660ccea Poul Sander 2023-09-22 19:25 8595
            case '9':
2660ccea Poul Sander 2023-09-22 19:25 8596
                return scan_number();
2660ccea Poul Sander 2023-09-22 19:25 8597
2660ccea Poul Sander 2023-09-22 19:25 8598
            // end of input (the null byte is needed when parsing from
2660ccea Poul Sander 2023-09-22 19:25 8599
            // string literals)
2660ccea Poul Sander 2023-09-22 19:25 8600
            case '\0':
2660ccea Poul Sander 2023-09-22 19:25 8601
            case std::char_traits<char>::eof():
2660ccea Poul Sander 2023-09-22 19:25 8602
                return token_type::end_of_input;
2660ccea Poul Sander 2023-09-22 19:25 8603
2660ccea Poul Sander 2023-09-22 19:25 8604
            // error
2660ccea Poul Sander 2023-09-22 19:25 8605
            default:
2660ccea Poul Sander 2023-09-22 19:25 8606
                error_message = "invalid literal";
2660ccea Poul Sander 2023-09-22 19:25 8607
                return token_type::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 8608
        }
2660ccea Poul Sander 2023-09-22 19:25 8609
    }
2660ccea Poul Sander 2023-09-22 19:25 8610
2660ccea Poul Sander 2023-09-22 19:25 8611
  private:
2660ccea Poul Sander 2023-09-22 19:25 8612
    /// input adapter
2660ccea Poul Sander 2023-09-22 19:25 8613
    detail::input_adapter_t ia = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 8614
2660ccea Poul Sander 2023-09-22 19:25 8615
    /// the current character
2660ccea Poul Sander 2023-09-22 19:25 8616
    std::char_traits<char>::int_type current = std::char_traits<char>::eof();
2660ccea Poul Sander 2023-09-22 19:25 8617
2660ccea Poul Sander 2023-09-22 19:25 8618
    /// whether the next get() call should just return current
2660ccea Poul Sander 2023-09-22 19:25 8619
    bool next_unget = false;
2660ccea Poul Sander 2023-09-22 19:25 8620
2660ccea Poul Sander 2023-09-22 19:25 8621
    /// the start position of the current token
2660ccea Poul Sander 2023-09-22 19:25 8622
    position_t position {};
2660ccea Poul Sander 2023-09-22 19:25 8623
2660ccea Poul Sander 2023-09-22 19:25 8624
    /// raw input token string (for error messages)
2660ccea Poul Sander 2023-09-22 19:25 8625
    std::vector<char> token_string {};
2660ccea Poul Sander 2023-09-22 19:25 8626
2660ccea Poul Sander 2023-09-22 19:25 8627
    /// buffer for variable-length tokens (numbers, strings)
2660ccea Poul Sander 2023-09-22 19:25 8628
    string_t token_buffer {};
2660ccea Poul Sander 2023-09-22 19:25 8629
2660ccea Poul Sander 2023-09-22 19:25 8630
    /// a description of occurred lexer errors
2660ccea Poul Sander 2023-09-22 19:25 8631
    const char* error_message = "";
2660ccea Poul Sander 2023-09-22 19:25 8632
2660ccea Poul Sander 2023-09-22 19:25 8633
    // number values
2660ccea Poul Sander 2023-09-22 19:25 8634
    number_integer_t value_integer = 0;
2660ccea Poul Sander 2023-09-22 19:25 8635
    number_unsigned_t value_unsigned = 0;
2660ccea Poul Sander 2023-09-22 19:25 8636
    number_float_t value_float = 0;
2660ccea Poul Sander 2023-09-22 19:25 8637
2660ccea Poul Sander 2023-09-22 19:25 8638
    /// the decimal point
2660ccea Poul Sander 2023-09-22 19:25 8639
    const char decimal_point_char = '.';
2660ccea Poul Sander 2023-09-22 19:25 8640
};
2660ccea Poul Sander 2023-09-22 19:25 8641
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 8642
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 8643
2660ccea Poul Sander 2023-09-22 19:25 8644
// #include <nlohmann/detail/input/parser.hpp>
2660ccea Poul Sander 2023-09-22 19:25 8645
2660ccea Poul Sander 2023-09-22 19:25 8646
2660ccea Poul Sander 2023-09-22 19:25 8647
#include <cassert> // assert
2660ccea Poul Sander 2023-09-22 19:25 8648
#include <cmath> // isfinite
2660ccea Poul Sander 2023-09-22 19:25 8649
#include <cstdint> // uint8_t
2660ccea Poul Sander 2023-09-22 19:25 8650
#include <functional> // function
2660ccea Poul Sander 2023-09-22 19:25 8651
#include <string> // string
2660ccea Poul Sander 2023-09-22 19:25 8652
#include <utility> // move
2660ccea Poul Sander 2023-09-22 19:25 8653
#include <vector> // vector
2660ccea Poul Sander 2023-09-22 19:25 8654
2660ccea Poul Sander 2023-09-22 19:25 8655
// #include <nlohmann/detail/exceptions.hpp>
2660ccea Poul Sander 2023-09-22 19:25 8656
2660ccea Poul Sander 2023-09-22 19:25 8657
// #include <nlohmann/detail/input/input_adapters.hpp>
2660ccea Poul Sander 2023-09-22 19:25 8658
2660ccea Poul Sander 2023-09-22 19:25 8659
// #include <nlohmann/detail/input/json_sax.hpp>
2660ccea Poul Sander 2023-09-22 19:25 8660
2660ccea Poul Sander 2023-09-22 19:25 8661
// #include <nlohmann/detail/input/lexer.hpp>
2660ccea Poul Sander 2023-09-22 19:25 8662
2660ccea Poul Sander 2023-09-22 19:25 8663
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 8664
2660ccea Poul Sander 2023-09-22 19:25 8665
// #include <nlohmann/detail/meta/is_sax.hpp>
2660ccea Poul Sander 2023-09-22 19:25 8666
2660ccea Poul Sander 2023-09-22 19:25 8667
// #include <nlohmann/detail/value_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 8668
2660ccea Poul Sander 2023-09-22 19:25 8669
2660ccea Poul Sander 2023-09-22 19:25 8670
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 8671
{
2660ccea Poul Sander 2023-09-22 19:25 8672
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 8673
{
2660ccea Poul Sander 2023-09-22 19:25 8674
////////////
2660ccea Poul Sander 2023-09-22 19:25 8675
// parser //
2660ccea Poul Sander 2023-09-22 19:25 8676
////////////
2660ccea Poul Sander 2023-09-22 19:25 8677
2660ccea Poul Sander 2023-09-22 19:25 8678
/*!
2660ccea Poul Sander 2023-09-22 19:25 8679
@brief syntax analysis
2660ccea Poul Sander 2023-09-22 19:25 8680
2660ccea Poul Sander 2023-09-22 19:25 8681
This class implements a recursive decent parser.
2660ccea Poul Sander 2023-09-22 19:25 8682
*/
2660ccea Poul Sander 2023-09-22 19:25 8683
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 8684
class parser
2660ccea Poul Sander 2023-09-22 19:25 8685
{
2660ccea Poul Sander 2023-09-22 19:25 8686
    using number_integer_t = typename BasicJsonType::number_integer_t;
2660ccea Poul Sander 2023-09-22 19:25 8687
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2660ccea Poul Sander 2023-09-22 19:25 8688
    using number_float_t = typename BasicJsonType::number_float_t;
2660ccea Poul Sander 2023-09-22 19:25 8689
    using string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 8690
    using lexer_t = lexer<BasicJsonType>;
2660ccea Poul Sander 2023-09-22 19:25 8691
    using token_type = typename lexer_t::token_type;
2660ccea Poul Sander 2023-09-22 19:25 8692
2660ccea Poul Sander 2023-09-22 19:25 8693
  public:
2660ccea Poul Sander 2023-09-22 19:25 8694
    enum class parse_event_t : uint8_t
2660ccea Poul Sander 2023-09-22 19:25 8695
    {
2660ccea Poul Sander 2023-09-22 19:25 8696
        /// the parser read `{` and started to process a JSON object
2660ccea Poul Sander 2023-09-22 19:25 8697
        object_start,
2660ccea Poul Sander 2023-09-22 19:25 8698
        /// the parser read `}` and finished processing a JSON object
2660ccea Poul Sander 2023-09-22 19:25 8699
        object_end,
2660ccea Poul Sander 2023-09-22 19:25 8700
        /// the parser read `[` and started to process a JSON array
2660ccea Poul Sander 2023-09-22 19:25 8701
        array_start,
2660ccea Poul Sander 2023-09-22 19:25 8702
        /// the parser read `]` and finished processing a JSON array
2660ccea Poul Sander 2023-09-22 19:25 8703
        array_end,
2660ccea Poul Sander 2023-09-22 19:25 8704
        /// the parser read a key of a value in an object
2660ccea Poul Sander 2023-09-22 19:25 8705
        key,
2660ccea Poul Sander 2023-09-22 19:25 8706
        /// the parser finished reading a JSON value
2660ccea Poul Sander 2023-09-22 19:25 8707
        value
2660ccea Poul Sander 2023-09-22 19:25 8708
    };
2660ccea Poul Sander 2023-09-22 19:25 8709
2660ccea Poul Sander 2023-09-22 19:25 8710
    using parser_callback_t =
2660ccea Poul Sander 2023-09-22 19:25 8711
        std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
2660ccea Poul Sander 2023-09-22 19:25 8712
2660ccea Poul Sander 2023-09-22 19:25 8713
    /// a parser reading from an input adapter
2660ccea Poul Sander 2023-09-22 19:25 8714
    explicit parser(detail::input_adapter_t&& adapter,
2660ccea Poul Sander 2023-09-22 19:25 8715
                    const parser_callback_t cb = nullptr,
2660ccea Poul Sander 2023-09-22 19:25 8716
                    const bool allow_exceptions_ = true)
2660ccea Poul Sander 2023-09-22 19:25 8717
        : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
2660ccea Poul Sander 2023-09-22 19:25 8718
    {
2660ccea Poul Sander 2023-09-22 19:25 8719
        // read first token
2660ccea Poul Sander 2023-09-22 19:25 8720
        get_token();
2660ccea Poul Sander 2023-09-22 19:25 8721
    }
2660ccea Poul Sander 2023-09-22 19:25 8722
2660ccea Poul Sander 2023-09-22 19:25 8723
    /*!
2660ccea Poul Sander 2023-09-22 19:25 8724
    @brief public parser interface
2660ccea Poul Sander 2023-09-22 19:25 8725
2660ccea Poul Sander 2023-09-22 19:25 8726
    @param[in] strict      whether to expect the last token to be EOF
2660ccea Poul Sander 2023-09-22 19:25 8727
    @param[in,out] result  parsed JSON value
2660ccea Poul Sander 2023-09-22 19:25 8728
2660ccea Poul Sander 2023-09-22 19:25 8729
    @throw parse_error.101 in case of an unexpected token
2660ccea Poul Sander 2023-09-22 19:25 8730
    @throw parse_error.102 if to_unicode fails or surrogate error
2660ccea Poul Sander 2023-09-22 19:25 8731
    @throw parse_error.103 if to_unicode fails
2660ccea Poul Sander 2023-09-22 19:25 8732
    */
2660ccea Poul Sander 2023-09-22 19:25 8733
    void parse(const bool strict, BasicJsonType& result)
2660ccea Poul Sander 2023-09-22 19:25 8734
    {
2660ccea Poul Sander 2023-09-22 19:25 8735
        if (callback)
2660ccea Poul Sander 2023-09-22 19:25 8736
        {
2660ccea Poul Sander 2023-09-22 19:25 8737
            json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
2660ccea Poul Sander 2023-09-22 19:25 8738
            sax_parse_internal(&sdp);
2660ccea Poul Sander 2023-09-22 19:25 8739
            result.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 8740
2660ccea Poul Sander 2023-09-22 19:25 8741
            // in strict mode, input must be completely read
2660ccea Poul Sander 2023-09-22 19:25 8742
            if (strict and (get_token() != token_type::end_of_input))
2660ccea Poul Sander 2023-09-22 19:25 8743
            {
2660ccea Poul Sander 2023-09-22 19:25 8744
                sdp.parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8745
                                m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 8746
                                parse_error::create(101, m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8747
                                                    exception_message(token_type::end_of_input, "value")));
2660ccea Poul Sander 2023-09-22 19:25 8748
            }
2660ccea Poul Sander 2023-09-22 19:25 8749
2660ccea Poul Sander 2023-09-22 19:25 8750
            // in case of an error, return discarded value
2660ccea Poul Sander 2023-09-22 19:25 8751
            if (sdp.is_errored())
2660ccea Poul Sander 2023-09-22 19:25 8752
            {
2660ccea Poul Sander 2023-09-22 19:25 8753
                result = value_t::discarded;
2660ccea Poul Sander 2023-09-22 19:25 8754
                return;
2660ccea Poul Sander 2023-09-22 19:25 8755
            }
2660ccea Poul Sander 2023-09-22 19:25 8756
2660ccea Poul Sander 2023-09-22 19:25 8757
            // set top-level value to null if it was discarded by the callback
2660ccea Poul Sander 2023-09-22 19:25 8758
            // function
2660ccea Poul Sander 2023-09-22 19:25 8759
            if (result.is_discarded())
2660ccea Poul Sander 2023-09-22 19:25 8760
            {
2660ccea Poul Sander 2023-09-22 19:25 8761
                result = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 8762
            }
2660ccea Poul Sander 2023-09-22 19:25 8763
        }
2660ccea Poul Sander 2023-09-22 19:25 8764
        else
2660ccea Poul Sander 2023-09-22 19:25 8765
        {
2660ccea Poul Sander 2023-09-22 19:25 8766
            json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
2660ccea Poul Sander 2023-09-22 19:25 8767
            sax_parse_internal(&sdp);
2660ccea Poul Sander 2023-09-22 19:25 8768
            result.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 8769
2660ccea Poul Sander 2023-09-22 19:25 8770
            // in strict mode, input must be completely read
2660ccea Poul Sander 2023-09-22 19:25 8771
            if (strict and (get_token() != token_type::end_of_input))
2660ccea Poul Sander 2023-09-22 19:25 8772
            {
2660ccea Poul Sander 2023-09-22 19:25 8773
                sdp.parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8774
                                m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 8775
                                parse_error::create(101, m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8776
                                                    exception_message(token_type::end_of_input, "value")));
2660ccea Poul Sander 2023-09-22 19:25 8777
            }
2660ccea Poul Sander 2023-09-22 19:25 8778
2660ccea Poul Sander 2023-09-22 19:25 8779
            // in case of an error, return discarded value
2660ccea Poul Sander 2023-09-22 19:25 8780
            if (sdp.is_errored())
2660ccea Poul Sander 2023-09-22 19:25 8781
            {
2660ccea Poul Sander 2023-09-22 19:25 8782
                result = value_t::discarded;
2660ccea Poul Sander 2023-09-22 19:25 8783
                return;
2660ccea Poul Sander 2023-09-22 19:25 8784
            }
2660ccea Poul Sander 2023-09-22 19:25 8785
        }
2660ccea Poul Sander 2023-09-22 19:25 8786
    }
2660ccea Poul Sander 2023-09-22 19:25 8787
2660ccea Poul Sander 2023-09-22 19:25 8788
    /*!
2660ccea Poul Sander 2023-09-22 19:25 8789
    @brief public accept interface
2660ccea Poul Sander 2023-09-22 19:25 8790
2660ccea Poul Sander 2023-09-22 19:25 8791
    @param[in] strict  whether to expect the last token to be EOF
2660ccea Poul Sander 2023-09-22 19:25 8792
    @return whether the input is a proper JSON text
2660ccea Poul Sander 2023-09-22 19:25 8793
    */
2660ccea Poul Sander 2023-09-22 19:25 8794
    bool accept(const bool strict = true)
2660ccea Poul Sander 2023-09-22 19:25 8795
    {
2660ccea Poul Sander 2023-09-22 19:25 8796
        json_sax_acceptor<BasicJsonType> sax_acceptor;
2660ccea Poul Sander 2023-09-22 19:25 8797
        return sax_parse(&sax_acceptor, strict);
2660ccea Poul Sander 2023-09-22 19:25 8798
    }
2660ccea Poul Sander 2023-09-22 19:25 8799
2660ccea Poul Sander 2023-09-22 19:25 8800
    template <typename SAX>
2660ccea Poul Sander 2023-09-22 19:25 8801
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 8802
    bool sax_parse(SAX* sax, const bool strict = true)
2660ccea Poul Sander 2023-09-22 19:25 8803
    {
2660ccea Poul Sander 2023-09-22 19:25 8804
        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
2660ccea Poul Sander 2023-09-22 19:25 8805
        const bool result = sax_parse_internal(sax);
2660ccea Poul Sander 2023-09-22 19:25 8806
2660ccea Poul Sander 2023-09-22 19:25 8807
        // strict mode: next byte must be EOF
2660ccea Poul Sander 2023-09-22 19:25 8808
        if (result and strict and (get_token() != token_type::end_of_input))
2660ccea Poul Sander 2023-09-22 19:25 8809
        {
2660ccea Poul Sander 2023-09-22 19:25 8810
            return sax->parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8811
                                    m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 8812
                                    parse_error::create(101, m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8813
                                            exception_message(token_type::end_of_input, "value")));
2660ccea Poul Sander 2023-09-22 19:25 8814
        }
2660ccea Poul Sander 2023-09-22 19:25 8815
2660ccea Poul Sander 2023-09-22 19:25 8816
        return result;
2660ccea Poul Sander 2023-09-22 19:25 8817
    }
2660ccea Poul Sander 2023-09-22 19:25 8818
2660ccea Poul Sander 2023-09-22 19:25 8819
  private:
2660ccea Poul Sander 2023-09-22 19:25 8820
    template <typename SAX>
2660ccea Poul Sander 2023-09-22 19:25 8821
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 8822
    bool sax_parse_internal(SAX* sax)
2660ccea Poul Sander 2023-09-22 19:25 8823
    {
2660ccea Poul Sander 2023-09-22 19:25 8824
        // stack to remember the hierarchy of structured values we are parsing
2660ccea Poul Sander 2023-09-22 19:25 8825
        // true = array; false = object
2660ccea Poul Sander 2023-09-22 19:25 8826
        std::vector<bool> states;
2660ccea Poul Sander 2023-09-22 19:25 8827
        // value to avoid a goto (see comment where set to true)
2660ccea Poul Sander 2023-09-22 19:25 8828
        bool skip_to_state_evaluation = false;
2660ccea Poul Sander 2023-09-22 19:25 8829
2660ccea Poul Sander 2023-09-22 19:25 8830
        while (true)
2660ccea Poul Sander 2023-09-22 19:25 8831
        {
2660ccea Poul Sander 2023-09-22 19:25 8832
            if (not skip_to_state_evaluation)
2660ccea Poul Sander 2023-09-22 19:25 8833
            {
2660ccea Poul Sander 2023-09-22 19:25 8834
                // invariant: get_token() was called before each iteration
2660ccea Poul Sander 2023-09-22 19:25 8835
                switch (last_token)
2660ccea Poul Sander 2023-09-22 19:25 8836
                {
2660ccea Poul Sander 2023-09-22 19:25 8837
                    case token_type::begin_object:
2660ccea Poul Sander 2023-09-22 19:25 8838
                    {
2660ccea Poul Sander 2023-09-22 19:25 8839
                        if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
2660ccea Poul Sander 2023-09-22 19:25 8840
                        {
2660ccea Poul Sander 2023-09-22 19:25 8841
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 8842
                        }
2660ccea Poul Sander 2023-09-22 19:25 8843
2660ccea Poul Sander 2023-09-22 19:25 8844
                        // closing } -> we are done
2660ccea Poul Sander 2023-09-22 19:25 8845
                        if (get_token() == token_type::end_object)
2660ccea Poul Sander 2023-09-22 19:25 8846
                        {
2660ccea Poul Sander 2023-09-22 19:25 8847
                            if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
2660ccea Poul Sander 2023-09-22 19:25 8848
                            {
2660ccea Poul Sander 2023-09-22 19:25 8849
                                return false;
2660ccea Poul Sander 2023-09-22 19:25 8850
                            }
2660ccea Poul Sander 2023-09-22 19:25 8851
                            break;
2660ccea Poul Sander 2023-09-22 19:25 8852
                        }
2660ccea Poul Sander 2023-09-22 19:25 8853
2660ccea Poul Sander 2023-09-22 19:25 8854
                        // parse key
2660ccea Poul Sander 2023-09-22 19:25 8855
                        if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
2660ccea Poul Sander 2023-09-22 19:25 8856
                        {
2660ccea Poul Sander 2023-09-22 19:25 8857
                            return sax->parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8858
                                                    m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 8859
                                                    parse_error::create(101, m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8860
                                                            exception_message(token_type::value_string, "object key")));
2660ccea Poul Sander 2023-09-22 19:25 8861
                        }
2660ccea Poul Sander 2023-09-22 19:25 8862
                        if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
2660ccea Poul Sander 2023-09-22 19:25 8863
                        {
2660ccea Poul Sander 2023-09-22 19:25 8864
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 8865
                        }
2660ccea Poul Sander 2023-09-22 19:25 8866
2660ccea Poul Sander 2023-09-22 19:25 8867
                        // parse separator (:)
2660ccea Poul Sander 2023-09-22 19:25 8868
                        if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
2660ccea Poul Sander 2023-09-22 19:25 8869
                        {
2660ccea Poul Sander 2023-09-22 19:25 8870
                            return sax->parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8871
                                                    m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 8872
                                                    parse_error::create(101, m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8873
                                                            exception_message(token_type::name_separator, "object separator")));
2660ccea Poul Sander 2023-09-22 19:25 8874
                        }
2660ccea Poul Sander 2023-09-22 19:25 8875
2660ccea Poul Sander 2023-09-22 19:25 8876
                        // remember we are now inside an object
2660ccea Poul Sander 2023-09-22 19:25 8877
                        states.push_back(false);
2660ccea Poul Sander 2023-09-22 19:25 8878
2660ccea Poul Sander 2023-09-22 19:25 8879
                        // parse values
2660ccea Poul Sander 2023-09-22 19:25 8880
                        get_token();
2660ccea Poul Sander 2023-09-22 19:25 8881
                        continue;
2660ccea Poul Sander 2023-09-22 19:25 8882
                    }
2660ccea Poul Sander 2023-09-22 19:25 8883
2660ccea Poul Sander 2023-09-22 19:25 8884
                    case token_type::begin_array:
2660ccea Poul Sander 2023-09-22 19:25 8885
                    {
2660ccea Poul Sander 2023-09-22 19:25 8886
                        if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
2660ccea Poul Sander 2023-09-22 19:25 8887
                        {
2660ccea Poul Sander 2023-09-22 19:25 8888
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 8889
                        }
2660ccea Poul Sander 2023-09-22 19:25 8890
2660ccea Poul Sander 2023-09-22 19:25 8891
                        // closing ] -> we are done
2660ccea Poul Sander 2023-09-22 19:25 8892
                        if (get_token() == token_type::end_array)
2660ccea Poul Sander 2023-09-22 19:25 8893
                        {
2660ccea Poul Sander 2023-09-22 19:25 8894
                            if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
2660ccea Poul Sander 2023-09-22 19:25 8895
                            {
2660ccea Poul Sander 2023-09-22 19:25 8896
                                return false;
2660ccea Poul Sander 2023-09-22 19:25 8897
                            }
2660ccea Poul Sander 2023-09-22 19:25 8898
                            break;
2660ccea Poul Sander 2023-09-22 19:25 8899
                        }
2660ccea Poul Sander 2023-09-22 19:25 8900
2660ccea Poul Sander 2023-09-22 19:25 8901
                        // remember we are now inside an array
2660ccea Poul Sander 2023-09-22 19:25 8902
                        states.push_back(true);
2660ccea Poul Sander 2023-09-22 19:25 8903
2660ccea Poul Sander 2023-09-22 19:25 8904
                        // parse values (no need to call get_token)
2660ccea Poul Sander 2023-09-22 19:25 8905
                        continue;
2660ccea Poul Sander 2023-09-22 19:25 8906
                    }
2660ccea Poul Sander 2023-09-22 19:25 8907
2660ccea Poul Sander 2023-09-22 19:25 8908
                    case token_type::value_float:
2660ccea Poul Sander 2023-09-22 19:25 8909
                    {
2660ccea Poul Sander 2023-09-22 19:25 8910
                        const auto res = m_lexer.get_number_float();
2660ccea Poul Sander 2023-09-22 19:25 8911
2660ccea Poul Sander 2023-09-22 19:25 8912
                        if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res)))
2660ccea Poul Sander 2023-09-22 19:25 8913
                        {
2660ccea Poul Sander 2023-09-22 19:25 8914
                            return sax->parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8915
                                                    m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 8916
                                                    out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
2660ccea Poul Sander 2023-09-22 19:25 8917
                        }
2660ccea Poul Sander 2023-09-22 19:25 8918
2660ccea Poul Sander 2023-09-22 19:25 8919
                        if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
2660ccea Poul Sander 2023-09-22 19:25 8920
                        {
2660ccea Poul Sander 2023-09-22 19:25 8921
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 8922
                        }
2660ccea Poul Sander 2023-09-22 19:25 8923
2660ccea Poul Sander 2023-09-22 19:25 8924
                        break;
2660ccea Poul Sander 2023-09-22 19:25 8925
                    }
2660ccea Poul Sander 2023-09-22 19:25 8926
2660ccea Poul Sander 2023-09-22 19:25 8927
                    case token_type::literal_false:
2660ccea Poul Sander 2023-09-22 19:25 8928
                    {
2660ccea Poul Sander 2023-09-22 19:25 8929
                        if (JSON_HEDLEY_UNLIKELY(not sax->boolean(false)))
2660ccea Poul Sander 2023-09-22 19:25 8930
                        {
2660ccea Poul Sander 2023-09-22 19:25 8931
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 8932
                        }
2660ccea Poul Sander 2023-09-22 19:25 8933
                        break;
2660ccea Poul Sander 2023-09-22 19:25 8934
                    }
2660ccea Poul Sander 2023-09-22 19:25 8935
2660ccea Poul Sander 2023-09-22 19:25 8936
                    case token_type::literal_null:
2660ccea Poul Sander 2023-09-22 19:25 8937
                    {
2660ccea Poul Sander 2023-09-22 19:25 8938
                        if (JSON_HEDLEY_UNLIKELY(not sax->null()))
2660ccea Poul Sander 2023-09-22 19:25 8939
                        {
2660ccea Poul Sander 2023-09-22 19:25 8940
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 8941
                        }
2660ccea Poul Sander 2023-09-22 19:25 8942
                        break;
2660ccea Poul Sander 2023-09-22 19:25 8943
                    }
2660ccea Poul Sander 2023-09-22 19:25 8944
2660ccea Poul Sander 2023-09-22 19:25 8945
                    case token_type::literal_true:
2660ccea Poul Sander 2023-09-22 19:25 8946
                    {
2660ccea Poul Sander 2023-09-22 19:25 8947
                        if (JSON_HEDLEY_UNLIKELY(not sax->boolean(true)))
2660ccea Poul Sander 2023-09-22 19:25 8948
                        {
2660ccea Poul Sander 2023-09-22 19:25 8949
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 8950
                        }
2660ccea Poul Sander 2023-09-22 19:25 8951
                        break;
2660ccea Poul Sander 2023-09-22 19:25 8952
                    }
2660ccea Poul Sander 2023-09-22 19:25 8953
2660ccea Poul Sander 2023-09-22 19:25 8954
                    case token_type::value_integer:
2660ccea Poul Sander 2023-09-22 19:25 8955
                    {
2660ccea Poul Sander 2023-09-22 19:25 8956
                        if (JSON_HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
2660ccea Poul Sander 2023-09-22 19:25 8957
                        {
2660ccea Poul Sander 2023-09-22 19:25 8958
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 8959
                        }
2660ccea Poul Sander 2023-09-22 19:25 8960
                        break;
2660ccea Poul Sander 2023-09-22 19:25 8961
                    }
2660ccea Poul Sander 2023-09-22 19:25 8962
2660ccea Poul Sander 2023-09-22 19:25 8963
                    case token_type::value_string:
2660ccea Poul Sander 2023-09-22 19:25 8964
                    {
2660ccea Poul Sander 2023-09-22 19:25 8965
                        if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string())))
2660ccea Poul Sander 2023-09-22 19:25 8966
                        {
2660ccea Poul Sander 2023-09-22 19:25 8967
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 8968
                        }
2660ccea Poul Sander 2023-09-22 19:25 8969
                        break;
2660ccea Poul Sander 2023-09-22 19:25 8970
                    }
2660ccea Poul Sander 2023-09-22 19:25 8971
2660ccea Poul Sander 2023-09-22 19:25 8972
                    case token_type::value_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 8973
                    {
2660ccea Poul Sander 2023-09-22 19:25 8974
                        if (JSON_HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
2660ccea Poul Sander 2023-09-22 19:25 8975
                        {
2660ccea Poul Sander 2023-09-22 19:25 8976
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 8977
                        }
2660ccea Poul Sander 2023-09-22 19:25 8978
                        break;
2660ccea Poul Sander 2023-09-22 19:25 8979
                    }
2660ccea Poul Sander 2023-09-22 19:25 8980
2660ccea Poul Sander 2023-09-22 19:25 8981
                    case token_type::parse_error:
2660ccea Poul Sander 2023-09-22 19:25 8982
                    {
2660ccea Poul Sander 2023-09-22 19:25 8983
                        // using "uninitialized" to avoid "expected" message
2660ccea Poul Sander 2023-09-22 19:25 8984
                        return sax->parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8985
                                                m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 8986
                                                parse_error::create(101, m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8987
                                                        exception_message(token_type::uninitialized, "value")));
2660ccea Poul Sander 2023-09-22 19:25 8988
                    }
2660ccea Poul Sander 2023-09-22 19:25 8989
2660ccea Poul Sander 2023-09-22 19:25 8990
                    default: // the last token was unexpected
2660ccea Poul Sander 2023-09-22 19:25 8991
                    {
2660ccea Poul Sander 2023-09-22 19:25 8992
                        return sax->parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8993
                                                m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 8994
                                                parse_error::create(101, m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 8995
                                                        exception_message(token_type::literal_or_value, "value")));
2660ccea Poul Sander 2023-09-22 19:25 8996
                    }
2660ccea Poul Sander 2023-09-22 19:25 8997
                }
2660ccea Poul Sander 2023-09-22 19:25 8998
            }
2660ccea Poul Sander 2023-09-22 19:25 8999
            else
2660ccea Poul Sander 2023-09-22 19:25 9000
            {
2660ccea Poul Sander 2023-09-22 19:25 9001
                skip_to_state_evaluation = false;
2660ccea Poul Sander 2023-09-22 19:25 9002
            }
2660ccea Poul Sander 2023-09-22 19:25 9003
2660ccea Poul Sander 2023-09-22 19:25 9004
            // we reached this line after we successfully parsed a value
2660ccea Poul Sander 2023-09-22 19:25 9005
            if (states.empty())
2660ccea Poul Sander 2023-09-22 19:25 9006
            {
2660ccea Poul Sander 2023-09-22 19:25 9007
                // empty stack: we reached the end of the hierarchy: done
2660ccea Poul Sander 2023-09-22 19:25 9008
                return true;
2660ccea Poul Sander 2023-09-22 19:25 9009
            }
2660ccea Poul Sander 2023-09-22 19:25 9010
2660ccea Poul Sander 2023-09-22 19:25 9011
            if (states.back())  // array
2660ccea Poul Sander 2023-09-22 19:25 9012
            {
2660ccea Poul Sander 2023-09-22 19:25 9013
                // comma -> next value
2660ccea Poul Sander 2023-09-22 19:25 9014
                if (get_token() == token_type::value_separator)
2660ccea Poul Sander 2023-09-22 19:25 9015
                {
2660ccea Poul Sander 2023-09-22 19:25 9016
                    // parse a new value
2660ccea Poul Sander 2023-09-22 19:25 9017
                    get_token();
2660ccea Poul Sander 2023-09-22 19:25 9018
                    continue;
2660ccea Poul Sander 2023-09-22 19:25 9019
                }
2660ccea Poul Sander 2023-09-22 19:25 9020
2660ccea Poul Sander 2023-09-22 19:25 9021
                // closing ]
2660ccea Poul Sander 2023-09-22 19:25 9022
                if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
2660ccea Poul Sander 2023-09-22 19:25 9023
                {
2660ccea Poul Sander 2023-09-22 19:25 9024
                    if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
2660ccea Poul Sander 2023-09-22 19:25 9025
                    {
2660ccea Poul Sander 2023-09-22 19:25 9026
                        return false;
2660ccea Poul Sander 2023-09-22 19:25 9027
                    }
2660ccea Poul Sander 2023-09-22 19:25 9028
2660ccea Poul Sander 2023-09-22 19:25 9029
                    // We are done with this array. Before we can parse a
2660ccea Poul Sander 2023-09-22 19:25 9030
                    // new value, we need to evaluate the new state first.
2660ccea Poul Sander 2023-09-22 19:25 9031
                    // By setting skip_to_state_evaluation to false, we
2660ccea Poul Sander 2023-09-22 19:25 9032
                    // are effectively jumping to the beginning of this if.
2660ccea Poul Sander 2023-09-22 19:25 9033
                    assert(not states.empty());
2660ccea Poul Sander 2023-09-22 19:25 9034
                    states.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 9035
                    skip_to_state_evaluation = true;
2660ccea Poul Sander 2023-09-22 19:25 9036
                    continue;
2660ccea Poul Sander 2023-09-22 19:25 9037
                }
2660ccea Poul Sander 2023-09-22 19:25 9038
2660ccea Poul Sander 2023-09-22 19:25 9039
                return sax->parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 9040
                                        m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 9041
                                        parse_error::create(101, m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 9042
                                                exception_message(token_type::end_array, "array")));
2660ccea Poul Sander 2023-09-22 19:25 9043
            }
2660ccea Poul Sander 2023-09-22 19:25 9044
            else  // object
2660ccea Poul Sander 2023-09-22 19:25 9045
            {
2660ccea Poul Sander 2023-09-22 19:25 9046
                // comma -> next value
2660ccea Poul Sander 2023-09-22 19:25 9047
                if (get_token() == token_type::value_separator)
2660ccea Poul Sander 2023-09-22 19:25 9048
                {
2660ccea Poul Sander 2023-09-22 19:25 9049
                    // parse key
2660ccea Poul Sander 2023-09-22 19:25 9050
                    if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
2660ccea Poul Sander 2023-09-22 19:25 9051
                    {
2660ccea Poul Sander 2023-09-22 19:25 9052
                        return sax->parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 9053
                                                m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 9054
                                                parse_error::create(101, m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 9055
                                                        exception_message(token_type::value_string, "object key")));
2660ccea Poul Sander 2023-09-22 19:25 9056
                    }
2660ccea Poul Sander 2023-09-22 19:25 9057
2660ccea Poul Sander 2023-09-22 19:25 9058
                    if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
2660ccea Poul Sander 2023-09-22 19:25 9059
                    {
2660ccea Poul Sander 2023-09-22 19:25 9060
                        return false;
2660ccea Poul Sander 2023-09-22 19:25 9061
                    }
2660ccea Poul Sander 2023-09-22 19:25 9062
2660ccea Poul Sander 2023-09-22 19:25 9063
                    // parse separator (:)
2660ccea Poul Sander 2023-09-22 19:25 9064
                    if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
2660ccea Poul Sander 2023-09-22 19:25 9065
                    {
2660ccea Poul Sander 2023-09-22 19:25 9066
                        return sax->parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 9067
                                                m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 9068
                                                parse_error::create(101, m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 9069
                                                        exception_message(token_type::name_separator, "object separator")));
2660ccea Poul Sander 2023-09-22 19:25 9070
                    }
2660ccea Poul Sander 2023-09-22 19:25 9071
2660ccea Poul Sander 2023-09-22 19:25 9072
                    // parse values
2660ccea Poul Sander 2023-09-22 19:25 9073
                    get_token();
2660ccea Poul Sander 2023-09-22 19:25 9074
                    continue;
2660ccea Poul Sander 2023-09-22 19:25 9075
                }
2660ccea Poul Sander 2023-09-22 19:25 9076
2660ccea Poul Sander 2023-09-22 19:25 9077
                // closing }
2660ccea Poul Sander 2023-09-22 19:25 9078
                if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
2660ccea Poul Sander 2023-09-22 19:25 9079
                {
2660ccea Poul Sander 2023-09-22 19:25 9080
                    if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
2660ccea Poul Sander 2023-09-22 19:25 9081
                    {
2660ccea Poul Sander 2023-09-22 19:25 9082
                        return false;
2660ccea Poul Sander 2023-09-22 19:25 9083
                    }
2660ccea Poul Sander 2023-09-22 19:25 9084
2660ccea Poul Sander 2023-09-22 19:25 9085
                    // We are done with this object. Before we can parse a
2660ccea Poul Sander 2023-09-22 19:25 9086
                    // new value, we need to evaluate the new state first.
2660ccea Poul Sander 2023-09-22 19:25 9087
                    // By setting skip_to_state_evaluation to false, we
2660ccea Poul Sander 2023-09-22 19:25 9088
                    // are effectively jumping to the beginning of this if.
2660ccea Poul Sander 2023-09-22 19:25 9089
                    assert(not states.empty());
2660ccea Poul Sander 2023-09-22 19:25 9090
                    states.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 9091
                    skip_to_state_evaluation = true;
2660ccea Poul Sander 2023-09-22 19:25 9092
                    continue;
2660ccea Poul Sander 2023-09-22 19:25 9093
                }
2660ccea Poul Sander 2023-09-22 19:25 9094
2660ccea Poul Sander 2023-09-22 19:25 9095
                return sax->parse_error(m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 9096
                                        m_lexer.get_token_string(),
2660ccea Poul Sander 2023-09-22 19:25 9097
                                        parse_error::create(101, m_lexer.get_position(),
2660ccea Poul Sander 2023-09-22 19:25 9098
                                                exception_message(token_type::end_object, "object")));
2660ccea Poul Sander 2023-09-22 19:25 9099
            }
2660ccea Poul Sander 2023-09-22 19:25 9100
        }
2660ccea Poul Sander 2023-09-22 19:25 9101
    }
2660ccea Poul Sander 2023-09-22 19:25 9102
2660ccea Poul Sander 2023-09-22 19:25 9103
    /// get next token from lexer
2660ccea Poul Sander 2023-09-22 19:25 9104
    token_type get_token()
2660ccea Poul Sander 2023-09-22 19:25 9105
    {
2660ccea Poul Sander 2023-09-22 19:25 9106
        return last_token = m_lexer.scan();
2660ccea Poul Sander 2023-09-22 19:25 9107
    }
2660ccea Poul Sander 2023-09-22 19:25 9108
2660ccea Poul Sander 2023-09-22 19:25 9109
    std::string exception_message(const token_type expected, const std::string& context)
2660ccea Poul Sander 2023-09-22 19:25 9110
    {
2660ccea Poul Sander 2023-09-22 19:25 9111
        std::string error_msg = "syntax error ";
2660ccea Poul Sander 2023-09-22 19:25 9112
2660ccea Poul Sander 2023-09-22 19:25 9113
        if (not context.empty())
2660ccea Poul Sander 2023-09-22 19:25 9114
        {
2660ccea Poul Sander 2023-09-22 19:25 9115
            error_msg += "while parsing " + context + " ";
2660ccea Poul Sander 2023-09-22 19:25 9116
        }
2660ccea Poul Sander 2023-09-22 19:25 9117
2660ccea Poul Sander 2023-09-22 19:25 9118
        error_msg += "- ";
2660ccea Poul Sander 2023-09-22 19:25 9119
2660ccea Poul Sander 2023-09-22 19:25 9120
        if (last_token == token_type::parse_error)
2660ccea Poul Sander 2023-09-22 19:25 9121
        {
2660ccea Poul Sander 2023-09-22 19:25 9122
            error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
2660ccea Poul Sander 2023-09-22 19:25 9123
                         m_lexer.get_token_string() + "'";
2660ccea Poul Sander 2023-09-22 19:25 9124
        }
2660ccea Poul Sander 2023-09-22 19:25 9125
        else
2660ccea Poul Sander 2023-09-22 19:25 9126
        {
2660ccea Poul Sander 2023-09-22 19:25 9127
            error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
2660ccea Poul Sander 2023-09-22 19:25 9128
        }
2660ccea Poul Sander 2023-09-22 19:25 9129
2660ccea Poul Sander 2023-09-22 19:25 9130
        if (expected != token_type::uninitialized)
2660ccea Poul Sander 2023-09-22 19:25 9131
        {
2660ccea Poul Sander 2023-09-22 19:25 9132
            error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
2660ccea Poul Sander 2023-09-22 19:25 9133
        }
2660ccea Poul Sander 2023-09-22 19:25 9134
2660ccea Poul Sander 2023-09-22 19:25 9135
        return error_msg;
2660ccea Poul Sander 2023-09-22 19:25 9136
    }
2660ccea Poul Sander 2023-09-22 19:25 9137
2660ccea Poul Sander 2023-09-22 19:25 9138
  private:
2660ccea Poul Sander 2023-09-22 19:25 9139
    /// callback function
2660ccea Poul Sander 2023-09-22 19:25 9140
    const parser_callback_t callback = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 9141
    /// the type of the last read token
2660ccea Poul Sander 2023-09-22 19:25 9142
    token_type last_token = token_type::uninitialized;
2660ccea Poul Sander 2023-09-22 19:25 9143
    /// the lexer
2660ccea Poul Sander 2023-09-22 19:25 9144
    lexer_t m_lexer;
2660ccea Poul Sander 2023-09-22 19:25 9145
    /// whether to throw exceptions in case of errors
2660ccea Poul Sander 2023-09-22 19:25 9146
    const bool allow_exceptions = true;
2660ccea Poul Sander 2023-09-22 19:25 9147
};
2660ccea Poul Sander 2023-09-22 19:25 9148
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 9149
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 9150
2660ccea Poul Sander 2023-09-22 19:25 9151
// #include <nlohmann/detail/iterators/internal_iterator.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9152
2660ccea Poul Sander 2023-09-22 19:25 9153
2660ccea Poul Sander 2023-09-22 19:25 9154
// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9155
2660ccea Poul Sander 2023-09-22 19:25 9156
2660ccea Poul Sander 2023-09-22 19:25 9157
#include <cstddef> // ptrdiff_t
2660ccea Poul Sander 2023-09-22 19:25 9158
#include <limits>  // numeric_limits
2660ccea Poul Sander 2023-09-22 19:25 9159
2660ccea Poul Sander 2023-09-22 19:25 9160
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 9161
{
2660ccea Poul Sander 2023-09-22 19:25 9162
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 9163
{
2660ccea Poul Sander 2023-09-22 19:25 9164
/*
2660ccea Poul Sander 2023-09-22 19:25 9165
@brief an iterator for primitive JSON types
2660ccea Poul Sander 2023-09-22 19:25 9166
2660ccea Poul Sander 2023-09-22 19:25 9167
This class models an iterator for primitive JSON types (boolean, number,
2660ccea Poul Sander 2023-09-22 19:25 9168
string). It's only purpose is to allow the iterator/const_iterator classes
2660ccea Poul Sander 2023-09-22 19:25 9169
to "iterate" over primitive values. Internally, the iterator is modeled by
2660ccea Poul Sander 2023-09-22 19:25 9170
a `difference_type` variable. Value begin_value (`0`) models the begin,
2660ccea Poul Sander 2023-09-22 19:25 9171
end_value (`1`) models past the end.
2660ccea Poul Sander 2023-09-22 19:25 9172
*/
2660ccea Poul Sander 2023-09-22 19:25 9173
class primitive_iterator_t
2660ccea Poul Sander 2023-09-22 19:25 9174
{
2660ccea Poul Sander 2023-09-22 19:25 9175
  private:
2660ccea Poul Sander 2023-09-22 19:25 9176
    using difference_type = std::ptrdiff_t;
2660ccea Poul Sander 2023-09-22 19:25 9177
    static constexpr difference_type begin_value = 0;
2660ccea Poul Sander 2023-09-22 19:25 9178
    static constexpr difference_type end_value = begin_value + 1;
2660ccea Poul Sander 2023-09-22 19:25 9179
2660ccea Poul Sander 2023-09-22 19:25 9180
    /// iterator as signed integer type
2660ccea Poul Sander 2023-09-22 19:25 9181
    difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
2660ccea Poul Sander 2023-09-22 19:25 9182
2660ccea Poul Sander 2023-09-22 19:25 9183
  public:
2660ccea Poul Sander 2023-09-22 19:25 9184
    constexpr difference_type get_value() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 9185
    {
2660ccea Poul Sander 2023-09-22 19:25 9186
        return m_it;
2660ccea Poul Sander 2023-09-22 19:25 9187
    }
2660ccea Poul Sander 2023-09-22 19:25 9188
2660ccea Poul Sander 2023-09-22 19:25 9189
    /// set iterator to a defined beginning
2660ccea Poul Sander 2023-09-22 19:25 9190
    void set_begin() noexcept
2660ccea Poul Sander 2023-09-22 19:25 9191
    {
2660ccea Poul Sander 2023-09-22 19:25 9192
        m_it = begin_value;
2660ccea Poul Sander 2023-09-22 19:25 9193
    }
2660ccea Poul Sander 2023-09-22 19:25 9194
2660ccea Poul Sander 2023-09-22 19:25 9195
    /// set iterator to a defined past the end
2660ccea Poul Sander 2023-09-22 19:25 9196
    void set_end() noexcept
2660ccea Poul Sander 2023-09-22 19:25 9197
    {
2660ccea Poul Sander 2023-09-22 19:25 9198
        m_it = end_value;
2660ccea Poul Sander 2023-09-22 19:25 9199
    }
2660ccea Poul Sander 2023-09-22 19:25 9200
2660ccea Poul Sander 2023-09-22 19:25 9201
    /// return whether the iterator can be dereferenced
2660ccea Poul Sander 2023-09-22 19:25 9202
    constexpr bool is_begin() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 9203
    {
2660ccea Poul Sander 2023-09-22 19:25 9204
        return m_it == begin_value;
2660ccea Poul Sander 2023-09-22 19:25 9205
    }
2660ccea Poul Sander 2023-09-22 19:25 9206
2660ccea Poul Sander 2023-09-22 19:25 9207
    /// return whether the iterator is at end
2660ccea Poul Sander 2023-09-22 19:25 9208
    constexpr bool is_end() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 9209
    {
2660ccea Poul Sander 2023-09-22 19:25 9210
        return m_it == end_value;
2660ccea Poul Sander 2023-09-22 19:25 9211
    }
2660ccea Poul Sander 2023-09-22 19:25 9212
2660ccea Poul Sander 2023-09-22 19:25 9213
    friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9214
    {
2660ccea Poul Sander 2023-09-22 19:25 9215
        return lhs.m_it == rhs.m_it;
2660ccea Poul Sander 2023-09-22 19:25 9216
    }
2660ccea Poul Sander 2023-09-22 19:25 9217
2660ccea Poul Sander 2023-09-22 19:25 9218
    friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9219
    {
2660ccea Poul Sander 2023-09-22 19:25 9220
        return lhs.m_it < rhs.m_it;
2660ccea Poul Sander 2023-09-22 19:25 9221
    }
2660ccea Poul Sander 2023-09-22 19:25 9222
2660ccea Poul Sander 2023-09-22 19:25 9223
    primitive_iterator_t operator+(difference_type n) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9224
    {
2660ccea Poul Sander 2023-09-22 19:25 9225
        auto result = *this;
2660ccea Poul Sander 2023-09-22 19:25 9226
        result += n;
2660ccea Poul Sander 2023-09-22 19:25 9227
        return result;
2660ccea Poul Sander 2023-09-22 19:25 9228
    }
2660ccea Poul Sander 2023-09-22 19:25 9229
2660ccea Poul Sander 2023-09-22 19:25 9230
    friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9231
    {
2660ccea Poul Sander 2023-09-22 19:25 9232
        return lhs.m_it - rhs.m_it;
2660ccea Poul Sander 2023-09-22 19:25 9233
    }
2660ccea Poul Sander 2023-09-22 19:25 9234
2660ccea Poul Sander 2023-09-22 19:25 9235
    primitive_iterator_t& operator++() noexcept
2660ccea Poul Sander 2023-09-22 19:25 9236
    {
2660ccea Poul Sander 2023-09-22 19:25 9237
        ++m_it;
2660ccea Poul Sander 2023-09-22 19:25 9238
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 9239
    }
2660ccea Poul Sander 2023-09-22 19:25 9240
2660ccea Poul Sander 2023-09-22 19:25 9241
    primitive_iterator_t const operator++(int) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9242
    {
2660ccea Poul Sander 2023-09-22 19:25 9243
        auto result = *this;
2660ccea Poul Sander 2023-09-22 19:25 9244
        ++m_it;
2660ccea Poul Sander 2023-09-22 19:25 9245
        return result;
2660ccea Poul Sander 2023-09-22 19:25 9246
    }
2660ccea Poul Sander 2023-09-22 19:25 9247
2660ccea Poul Sander 2023-09-22 19:25 9248
    primitive_iterator_t& operator--() noexcept
2660ccea Poul Sander 2023-09-22 19:25 9249
    {
2660ccea Poul Sander 2023-09-22 19:25 9250
        --m_it;
2660ccea Poul Sander 2023-09-22 19:25 9251
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 9252
    }
2660ccea Poul Sander 2023-09-22 19:25 9253
2660ccea Poul Sander 2023-09-22 19:25 9254
    primitive_iterator_t const operator--(int) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9255
    {
2660ccea Poul Sander 2023-09-22 19:25 9256
        auto result = *this;
2660ccea Poul Sander 2023-09-22 19:25 9257
        --m_it;
2660ccea Poul Sander 2023-09-22 19:25 9258
        return result;
2660ccea Poul Sander 2023-09-22 19:25 9259
    }
2660ccea Poul Sander 2023-09-22 19:25 9260
2660ccea Poul Sander 2023-09-22 19:25 9261
    primitive_iterator_t& operator+=(difference_type n) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9262
    {
2660ccea Poul Sander 2023-09-22 19:25 9263
        m_it += n;
2660ccea Poul Sander 2023-09-22 19:25 9264
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 9265
    }
2660ccea Poul Sander 2023-09-22 19:25 9266
2660ccea Poul Sander 2023-09-22 19:25 9267
    primitive_iterator_t& operator-=(difference_type n) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9268
    {
2660ccea Poul Sander 2023-09-22 19:25 9269
        m_it -= n;
2660ccea Poul Sander 2023-09-22 19:25 9270
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 9271
    }
2660ccea Poul Sander 2023-09-22 19:25 9272
};
2660ccea Poul Sander 2023-09-22 19:25 9273
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 9274
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 9275
2660ccea Poul Sander 2023-09-22 19:25 9276
2660ccea Poul Sander 2023-09-22 19:25 9277
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 9278
{
2660ccea Poul Sander 2023-09-22 19:25 9279
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 9280
{
2660ccea Poul Sander 2023-09-22 19:25 9281
/*!
2660ccea Poul Sander 2023-09-22 19:25 9282
@brief an iterator value
2660ccea Poul Sander 2023-09-22 19:25 9283
2660ccea Poul Sander 2023-09-22 19:25 9284
@note This structure could easily be a union, but MSVC currently does not allow
2660ccea Poul Sander 2023-09-22 19:25 9285
unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
2660ccea Poul Sander 2023-09-22 19:25 9286
*/
2660ccea Poul Sander 2023-09-22 19:25 9287
template<typename BasicJsonType> struct internal_iterator
2660ccea Poul Sander 2023-09-22 19:25 9288
{
2660ccea Poul Sander 2023-09-22 19:25 9289
    /// iterator for JSON objects
2660ccea Poul Sander 2023-09-22 19:25 9290
    typename BasicJsonType::object_t::iterator object_iterator {};
2660ccea Poul Sander 2023-09-22 19:25 9291
    /// iterator for JSON arrays
2660ccea Poul Sander 2023-09-22 19:25 9292
    typename BasicJsonType::array_t::iterator array_iterator {};
2660ccea Poul Sander 2023-09-22 19:25 9293
    /// generic iterator for all other types
2660ccea Poul Sander 2023-09-22 19:25 9294
    primitive_iterator_t primitive_iterator {};
2660ccea Poul Sander 2023-09-22 19:25 9295
};
2660ccea Poul Sander 2023-09-22 19:25 9296
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 9297
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 9298
2660ccea Poul Sander 2023-09-22 19:25 9299
// #include <nlohmann/detail/iterators/iter_impl.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9300
2660ccea Poul Sander 2023-09-22 19:25 9301
2660ccea Poul Sander 2023-09-22 19:25 9302
#include <ciso646> // not
2660ccea Poul Sander 2023-09-22 19:25 9303
#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
2660ccea Poul Sander 2023-09-22 19:25 9304
#include <type_traits> // conditional, is_const, remove_const
2660ccea Poul Sander 2023-09-22 19:25 9305
2660ccea Poul Sander 2023-09-22 19:25 9306
// #include <nlohmann/detail/exceptions.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9307
2660ccea Poul Sander 2023-09-22 19:25 9308
// #include <nlohmann/detail/iterators/internal_iterator.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9309
2660ccea Poul Sander 2023-09-22 19:25 9310
// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9311
2660ccea Poul Sander 2023-09-22 19:25 9312
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9313
2660ccea Poul Sander 2023-09-22 19:25 9314
// #include <nlohmann/detail/meta/cpp_future.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9315
2660ccea Poul Sander 2023-09-22 19:25 9316
// #include <nlohmann/detail/meta/type_traits.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9317
2660ccea Poul Sander 2023-09-22 19:25 9318
// #include <nlohmann/detail/value_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9319
2660ccea Poul Sander 2023-09-22 19:25 9320
2660ccea Poul Sander 2023-09-22 19:25 9321
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 9322
{
2660ccea Poul Sander 2023-09-22 19:25 9323
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 9324
{
2660ccea Poul Sander 2023-09-22 19:25 9325
// forward declare, to be able to friend it later on
2660ccea Poul Sander 2023-09-22 19:25 9326
template<typename IteratorType> class iteration_proxy;
2660ccea Poul Sander 2023-09-22 19:25 9327
template<typename IteratorType> class iteration_proxy_value;
2660ccea Poul Sander 2023-09-22 19:25 9328
2660ccea Poul Sander 2023-09-22 19:25 9329
/*!
2660ccea Poul Sander 2023-09-22 19:25 9330
@brief a template for a bidirectional iterator for the @ref basic_json class
2660ccea Poul Sander 2023-09-22 19:25 9331
This class implements a both iterators (iterator and const_iterator) for the
2660ccea Poul Sander 2023-09-22 19:25 9332
@ref basic_json class.
2660ccea Poul Sander 2023-09-22 19:25 9333
@note An iterator is called *initialized* when a pointer to a JSON value has
2660ccea Poul Sander 2023-09-22 19:25 9334
      been set (e.g., by a constructor or a copy assignment). If the iterator is
2660ccea Poul Sander 2023-09-22 19:25 9335
      default-constructed, it is *uninitialized* and most methods are undefined.
2660ccea Poul Sander 2023-09-22 19:25 9336
      **The library uses assertions to detect calls on uninitialized iterators.**
2660ccea Poul Sander 2023-09-22 19:25 9337
@requirement The class satisfies the following concept requirements:
2660ccea Poul Sander 2023-09-22 19:25 9338
-
2660ccea Poul Sander 2023-09-22 19:25 9339
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
2660ccea Poul Sander 2023-09-22 19:25 9340
  The iterator that can be moved can be moved in both directions (i.e.
2660ccea Poul Sander 2023-09-22 19:25 9341
  incremented and decremented).
2660ccea Poul Sander 2023-09-22 19:25 9342
@since version 1.0.0, simplified in version 2.0.9, change to bidirectional
2660ccea Poul Sander 2023-09-22 19:25 9343
       iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
2660ccea Poul Sander 2023-09-22 19:25 9344
*/
2660ccea Poul Sander 2023-09-22 19:25 9345
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 9346
class iter_impl
2660ccea Poul Sander 2023-09-22 19:25 9347
{
2660ccea Poul Sander 2023-09-22 19:25 9348
    /// allow basic_json to access private members
2660ccea Poul Sander 2023-09-22 19:25 9349
    friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
2660ccea Poul Sander 2023-09-22 19:25 9350
    friend BasicJsonType;
2660ccea Poul Sander 2023-09-22 19:25 9351
    friend iteration_proxy<iter_impl>;
2660ccea Poul Sander 2023-09-22 19:25 9352
    friend iteration_proxy_value<iter_impl>;
2660ccea Poul Sander 2023-09-22 19:25 9353
2660ccea Poul Sander 2023-09-22 19:25 9354
    using object_t = typename BasicJsonType::object_t;
2660ccea Poul Sander 2023-09-22 19:25 9355
    using array_t = typename BasicJsonType::array_t;
2660ccea Poul Sander 2023-09-22 19:25 9356
    // make sure BasicJsonType is basic_json or const basic_json
2660ccea Poul Sander 2023-09-22 19:25 9357
    static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
2660ccea Poul Sander 2023-09-22 19:25 9358
                  "iter_impl only accepts (const) basic_json");
2660ccea Poul Sander 2023-09-22 19:25 9359
2660ccea Poul Sander 2023-09-22 19:25 9360
  public:
2660ccea Poul Sander 2023-09-22 19:25 9361
2660ccea Poul Sander 2023-09-22 19:25 9362
    /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
2660ccea Poul Sander 2023-09-22 19:25 9363
    /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
2660ccea Poul Sander 2023-09-22 19:25 9364
    /// A user-defined iterator should provide publicly accessible typedefs named
2660ccea Poul Sander 2023-09-22 19:25 9365
    /// iterator_category, value_type, difference_type, pointer, and reference.
2660ccea Poul Sander 2023-09-22 19:25 9366
    /// Note that value_type is required to be non-const, even for constant iterators.
2660ccea Poul Sander 2023-09-22 19:25 9367
    using iterator_category = std::bidirectional_iterator_tag;
2660ccea Poul Sander 2023-09-22 19:25 9368
2660ccea Poul Sander 2023-09-22 19:25 9369
    /// the type of the values when the iterator is dereferenced
2660ccea Poul Sander 2023-09-22 19:25 9370
    using value_type = typename BasicJsonType::value_type;
2660ccea Poul Sander 2023-09-22 19:25 9371
    /// a type to represent differences between iterators
2660ccea Poul Sander 2023-09-22 19:25 9372
    using difference_type = typename BasicJsonType::difference_type;
2660ccea Poul Sander 2023-09-22 19:25 9373
    /// defines a pointer to the type iterated over (value_type)
2660ccea Poul Sander 2023-09-22 19:25 9374
    using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
2660ccea Poul Sander 2023-09-22 19:25 9375
          typename BasicJsonType::const_pointer,
2660ccea Poul Sander 2023-09-22 19:25 9376
          typename BasicJsonType::pointer>::type;
2660ccea Poul Sander 2023-09-22 19:25 9377
    /// defines a reference to the type iterated over (value_type)
2660ccea Poul Sander 2023-09-22 19:25 9378
    using reference =
2660ccea Poul Sander 2023-09-22 19:25 9379
        typename std::conditional<std::is_const<BasicJsonType>::value,
2660ccea Poul Sander 2023-09-22 19:25 9380
        typename BasicJsonType::const_reference,
2660ccea Poul Sander 2023-09-22 19:25 9381
        typename BasicJsonType::reference>::type;
2660ccea Poul Sander 2023-09-22 19:25 9382
2660ccea Poul Sander 2023-09-22 19:25 9383
    /// default constructor
2660ccea Poul Sander 2023-09-22 19:25 9384
    iter_impl() = default;
2660ccea Poul Sander 2023-09-22 19:25 9385
2660ccea Poul Sander 2023-09-22 19:25 9386
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9387
    @brief constructor for a given JSON instance
2660ccea Poul Sander 2023-09-22 19:25 9388
    @param[in] object  pointer to a JSON object for this iterator
2660ccea Poul Sander 2023-09-22 19:25 9389
    @pre object != nullptr
2660ccea Poul Sander 2023-09-22 19:25 9390
    @post The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9391
    */
2660ccea Poul Sander 2023-09-22 19:25 9392
    explicit iter_impl(pointer object) noexcept : m_object(object)
2660ccea Poul Sander 2023-09-22 19:25 9393
    {
2660ccea Poul Sander 2023-09-22 19:25 9394
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9395
2660ccea Poul Sander 2023-09-22 19:25 9396
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9397
        {
2660ccea Poul Sander 2023-09-22 19:25 9398
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9399
            {
2660ccea Poul Sander 2023-09-22 19:25 9400
                m_it.object_iterator = typename object_t::iterator();
2660ccea Poul Sander 2023-09-22 19:25 9401
                break;
2660ccea Poul Sander 2023-09-22 19:25 9402
            }
2660ccea Poul Sander 2023-09-22 19:25 9403
2660ccea Poul Sander 2023-09-22 19:25 9404
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9405
            {
2660ccea Poul Sander 2023-09-22 19:25 9406
                m_it.array_iterator = typename array_t::iterator();
2660ccea Poul Sander 2023-09-22 19:25 9407
                break;
2660ccea Poul Sander 2023-09-22 19:25 9408
            }
2660ccea Poul Sander 2023-09-22 19:25 9409
2660ccea Poul Sander 2023-09-22 19:25 9410
            default:
2660ccea Poul Sander 2023-09-22 19:25 9411
            {
2660ccea Poul Sander 2023-09-22 19:25 9412
                m_it.primitive_iterator = primitive_iterator_t();
2660ccea Poul Sander 2023-09-22 19:25 9413
                break;
2660ccea Poul Sander 2023-09-22 19:25 9414
            }
2660ccea Poul Sander 2023-09-22 19:25 9415
        }
2660ccea Poul Sander 2023-09-22 19:25 9416
    }
2660ccea Poul Sander 2023-09-22 19:25 9417
2660ccea Poul Sander 2023-09-22 19:25 9418
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9419
    @note The conventional copy constructor and copy assignment are implicitly
2660ccea Poul Sander 2023-09-22 19:25 9420
          defined. Combined with the following converting constructor and
2660ccea Poul Sander 2023-09-22 19:25 9421
          assignment, they support: (1) copy from iterator to iterator, (2)
2660ccea Poul Sander 2023-09-22 19:25 9422
          copy from const iterator to const iterator, and (3) conversion from
2660ccea Poul Sander 2023-09-22 19:25 9423
          iterator to const iterator. However conversion from const iterator
2660ccea Poul Sander 2023-09-22 19:25 9424
          to iterator is not defined.
2660ccea Poul Sander 2023-09-22 19:25 9425
    */
2660ccea Poul Sander 2023-09-22 19:25 9426
2660ccea Poul Sander 2023-09-22 19:25 9427
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9428
    @brief const copy constructor
2660ccea Poul Sander 2023-09-22 19:25 9429
    @param[in] other const iterator to copy from
2660ccea Poul Sander 2023-09-22 19:25 9430
    @note This copy constructor had to be defined explicitly to circumvent a bug
2660ccea Poul Sander 2023-09-22 19:25 9431
          occurring on msvc v19.0 compiler (VS 2015) debug build. For more
2660ccea Poul Sander 2023-09-22 19:25 9432
          information refer to: https://github.com/nlohmann/json/issues/1608
2660ccea Poul Sander 2023-09-22 19:25 9433
    */
2660ccea Poul Sander 2023-09-22 19:25 9434
    iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9435
        : m_object(other.m_object), m_it(other.m_it)
2660ccea Poul Sander 2023-09-22 19:25 9436
    {}
2660ccea Poul Sander 2023-09-22 19:25 9437
2660ccea Poul Sander 2023-09-22 19:25 9438
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9439
    @brief converting assignment
2660ccea Poul Sander 2023-09-22 19:25 9440
    @param[in] other const iterator to copy from
2660ccea Poul Sander 2023-09-22 19:25 9441
    @return const/non-const iterator
2660ccea Poul Sander 2023-09-22 19:25 9442
    @note It is not checked whether @a other is initialized.
2660ccea Poul Sander 2023-09-22 19:25 9443
    */
2660ccea Poul Sander 2023-09-22 19:25 9444
    iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9445
    {
2660ccea Poul Sander 2023-09-22 19:25 9446
        m_object = other.m_object;
2660ccea Poul Sander 2023-09-22 19:25 9447
        m_it = other.m_it;
2660ccea Poul Sander 2023-09-22 19:25 9448
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 9449
    }
2660ccea Poul Sander 2023-09-22 19:25 9450
2660ccea Poul Sander 2023-09-22 19:25 9451
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9452
    @brief converting constructor
2660ccea Poul Sander 2023-09-22 19:25 9453
    @param[in] other  non-const iterator to copy from
2660ccea Poul Sander 2023-09-22 19:25 9454
    @note It is not checked whether @a other is initialized.
2660ccea Poul Sander 2023-09-22 19:25 9455
    */
2660ccea Poul Sander 2023-09-22 19:25 9456
    iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9457
        : m_object(other.m_object), m_it(other.m_it)
2660ccea Poul Sander 2023-09-22 19:25 9458
    {}
2660ccea Poul Sander 2023-09-22 19:25 9459
2660ccea Poul Sander 2023-09-22 19:25 9460
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9461
    @brief converting assignment
2660ccea Poul Sander 2023-09-22 19:25 9462
    @param[in] other  non-const iterator to copy from
2660ccea Poul Sander 2023-09-22 19:25 9463
    @return const/non-const iterator
2660ccea Poul Sander 2023-09-22 19:25 9464
    @note It is not checked whether @a other is initialized.
2660ccea Poul Sander 2023-09-22 19:25 9465
    */
2660ccea Poul Sander 2023-09-22 19:25 9466
    iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9467
    {
2660ccea Poul Sander 2023-09-22 19:25 9468
        m_object = other.m_object;
2660ccea Poul Sander 2023-09-22 19:25 9469
        m_it = other.m_it;
2660ccea Poul Sander 2023-09-22 19:25 9470
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 9471
    }
2660ccea Poul Sander 2023-09-22 19:25 9472
2660ccea Poul Sander 2023-09-22 19:25 9473
  private:
2660ccea Poul Sander 2023-09-22 19:25 9474
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9475
    @brief set the iterator to the first value
2660ccea Poul Sander 2023-09-22 19:25 9476
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9477
    */
2660ccea Poul Sander 2023-09-22 19:25 9478
    void set_begin() noexcept
2660ccea Poul Sander 2023-09-22 19:25 9479
    {
2660ccea Poul Sander 2023-09-22 19:25 9480
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9481
2660ccea Poul Sander 2023-09-22 19:25 9482
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9483
        {
2660ccea Poul Sander 2023-09-22 19:25 9484
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9485
            {
2660ccea Poul Sander 2023-09-22 19:25 9486
                m_it.object_iterator = m_object->m_value.object->begin();
2660ccea Poul Sander 2023-09-22 19:25 9487
                break;
2660ccea Poul Sander 2023-09-22 19:25 9488
            }
2660ccea Poul Sander 2023-09-22 19:25 9489
2660ccea Poul Sander 2023-09-22 19:25 9490
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9491
            {
2660ccea Poul Sander 2023-09-22 19:25 9492
                m_it.array_iterator = m_object->m_value.array->begin();
2660ccea Poul Sander 2023-09-22 19:25 9493
                break;
2660ccea Poul Sander 2023-09-22 19:25 9494
            }
2660ccea Poul Sander 2023-09-22 19:25 9495
2660ccea Poul Sander 2023-09-22 19:25 9496
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 9497
            {
2660ccea Poul Sander 2023-09-22 19:25 9498
                // set to end so begin()==end() is true: null is empty
2660ccea Poul Sander 2023-09-22 19:25 9499
                m_it.primitive_iterator.set_end();
2660ccea Poul Sander 2023-09-22 19:25 9500
                break;
2660ccea Poul Sander 2023-09-22 19:25 9501
            }
2660ccea Poul Sander 2023-09-22 19:25 9502
2660ccea Poul Sander 2023-09-22 19:25 9503
            default:
2660ccea Poul Sander 2023-09-22 19:25 9504
            {
2660ccea Poul Sander 2023-09-22 19:25 9505
                m_it.primitive_iterator.set_begin();
2660ccea Poul Sander 2023-09-22 19:25 9506
                break;
2660ccea Poul Sander 2023-09-22 19:25 9507
            }
2660ccea Poul Sander 2023-09-22 19:25 9508
        }
2660ccea Poul Sander 2023-09-22 19:25 9509
    }
2660ccea Poul Sander 2023-09-22 19:25 9510
2660ccea Poul Sander 2023-09-22 19:25 9511
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9512
    @brief set the iterator past the last value
2660ccea Poul Sander 2023-09-22 19:25 9513
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9514
    */
2660ccea Poul Sander 2023-09-22 19:25 9515
    void set_end() noexcept
2660ccea Poul Sander 2023-09-22 19:25 9516
    {
2660ccea Poul Sander 2023-09-22 19:25 9517
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9518
2660ccea Poul Sander 2023-09-22 19:25 9519
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9520
        {
2660ccea Poul Sander 2023-09-22 19:25 9521
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9522
            {
2660ccea Poul Sander 2023-09-22 19:25 9523
                m_it.object_iterator = m_object->m_value.object->end();
2660ccea Poul Sander 2023-09-22 19:25 9524
                break;
2660ccea Poul Sander 2023-09-22 19:25 9525
            }
2660ccea Poul Sander 2023-09-22 19:25 9526
2660ccea Poul Sander 2023-09-22 19:25 9527
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9528
            {
2660ccea Poul Sander 2023-09-22 19:25 9529
                m_it.array_iterator = m_object->m_value.array->end();
2660ccea Poul Sander 2023-09-22 19:25 9530
                break;
2660ccea Poul Sander 2023-09-22 19:25 9531
            }
2660ccea Poul Sander 2023-09-22 19:25 9532
2660ccea Poul Sander 2023-09-22 19:25 9533
            default:
2660ccea Poul Sander 2023-09-22 19:25 9534
            {
2660ccea Poul Sander 2023-09-22 19:25 9535
                m_it.primitive_iterator.set_end();
2660ccea Poul Sander 2023-09-22 19:25 9536
                break;
2660ccea Poul Sander 2023-09-22 19:25 9537
            }
2660ccea Poul Sander 2023-09-22 19:25 9538
        }
2660ccea Poul Sander 2023-09-22 19:25 9539
    }
2660ccea Poul Sander 2023-09-22 19:25 9540
2660ccea Poul Sander 2023-09-22 19:25 9541
  public:
2660ccea Poul Sander 2023-09-22 19:25 9542
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9543
    @brief return a reference to the value pointed to by the iterator
2660ccea Poul Sander 2023-09-22 19:25 9544
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9545
    */
2660ccea Poul Sander 2023-09-22 19:25 9546
    reference operator*() const
2660ccea Poul Sander 2023-09-22 19:25 9547
    {
2660ccea Poul Sander 2023-09-22 19:25 9548
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9549
2660ccea Poul Sander 2023-09-22 19:25 9550
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9551
        {
2660ccea Poul Sander 2023-09-22 19:25 9552
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9553
            {
2660ccea Poul Sander 2023-09-22 19:25 9554
                assert(m_it.object_iterator != m_object->m_value.object->end());
2660ccea Poul Sander 2023-09-22 19:25 9555
                return m_it.object_iterator->second;
2660ccea Poul Sander 2023-09-22 19:25 9556
            }
2660ccea Poul Sander 2023-09-22 19:25 9557
2660ccea Poul Sander 2023-09-22 19:25 9558
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9559
            {
2660ccea Poul Sander 2023-09-22 19:25 9560
                assert(m_it.array_iterator != m_object->m_value.array->end());
2660ccea Poul Sander 2023-09-22 19:25 9561
                return *m_it.array_iterator;
2660ccea Poul Sander 2023-09-22 19:25 9562
            }
2660ccea Poul Sander 2023-09-22 19:25 9563
2660ccea Poul Sander 2023-09-22 19:25 9564
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 9565
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
2660ccea Poul Sander 2023-09-22 19:25 9566
2660ccea Poul Sander 2023-09-22 19:25 9567
            default:
2660ccea Poul Sander 2023-09-22 19:25 9568
            {
2660ccea Poul Sander 2023-09-22 19:25 9569
                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
2660ccea Poul Sander 2023-09-22 19:25 9570
                {
2660ccea Poul Sander 2023-09-22 19:25 9571
                    return *m_object;
2660ccea Poul Sander 2023-09-22 19:25 9572
                }
2660ccea Poul Sander 2023-09-22 19:25 9573
2660ccea Poul Sander 2023-09-22 19:25 9574
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
2660ccea Poul Sander 2023-09-22 19:25 9575
            }
2660ccea Poul Sander 2023-09-22 19:25 9576
        }
2660ccea Poul Sander 2023-09-22 19:25 9577
    }
2660ccea Poul Sander 2023-09-22 19:25 9578
2660ccea Poul Sander 2023-09-22 19:25 9579
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9580
    @brief dereference the iterator
2660ccea Poul Sander 2023-09-22 19:25 9581
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9582
    */
2660ccea Poul Sander 2023-09-22 19:25 9583
    pointer operator->() const
2660ccea Poul Sander 2023-09-22 19:25 9584
    {
2660ccea Poul Sander 2023-09-22 19:25 9585
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9586
2660ccea Poul Sander 2023-09-22 19:25 9587
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9588
        {
2660ccea Poul Sander 2023-09-22 19:25 9589
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9590
            {
2660ccea Poul Sander 2023-09-22 19:25 9591
                assert(m_it.object_iterator != m_object->m_value.object->end());
2660ccea Poul Sander 2023-09-22 19:25 9592
                return &(m_it.object_iterator->second);
2660ccea Poul Sander 2023-09-22 19:25 9593
            }
2660ccea Poul Sander 2023-09-22 19:25 9594
2660ccea Poul Sander 2023-09-22 19:25 9595
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9596
            {
2660ccea Poul Sander 2023-09-22 19:25 9597
                assert(m_it.array_iterator != m_object->m_value.array->end());
2660ccea Poul Sander 2023-09-22 19:25 9598
                return &*m_it.array_iterator;
2660ccea Poul Sander 2023-09-22 19:25 9599
            }
2660ccea Poul Sander 2023-09-22 19:25 9600
2660ccea Poul Sander 2023-09-22 19:25 9601
            default:
2660ccea Poul Sander 2023-09-22 19:25 9602
            {
2660ccea Poul Sander 2023-09-22 19:25 9603
                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
2660ccea Poul Sander 2023-09-22 19:25 9604
                {
2660ccea Poul Sander 2023-09-22 19:25 9605
                    return m_object;
2660ccea Poul Sander 2023-09-22 19:25 9606
                }
2660ccea Poul Sander 2023-09-22 19:25 9607
2660ccea Poul Sander 2023-09-22 19:25 9608
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
2660ccea Poul Sander 2023-09-22 19:25 9609
            }
2660ccea Poul Sander 2023-09-22 19:25 9610
        }
2660ccea Poul Sander 2023-09-22 19:25 9611
    }
2660ccea Poul Sander 2023-09-22 19:25 9612
2660ccea Poul Sander 2023-09-22 19:25 9613
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9614
    @brief post-increment (it++)
2660ccea Poul Sander 2023-09-22 19:25 9615
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9616
    */
2660ccea Poul Sander 2023-09-22 19:25 9617
    iter_impl const operator++(int)
2660ccea Poul Sander 2023-09-22 19:25 9618
    {
2660ccea Poul Sander 2023-09-22 19:25 9619
        auto result = *this;
2660ccea Poul Sander 2023-09-22 19:25 9620
        ++(*this);
2660ccea Poul Sander 2023-09-22 19:25 9621
        return result;
2660ccea Poul Sander 2023-09-22 19:25 9622
    }
2660ccea Poul Sander 2023-09-22 19:25 9623
2660ccea Poul Sander 2023-09-22 19:25 9624
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9625
    @brief pre-increment (++it)
2660ccea Poul Sander 2023-09-22 19:25 9626
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9627
    */
2660ccea Poul Sander 2023-09-22 19:25 9628
    iter_impl& operator++()
2660ccea Poul Sander 2023-09-22 19:25 9629
    {
2660ccea Poul Sander 2023-09-22 19:25 9630
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9631
2660ccea Poul Sander 2023-09-22 19:25 9632
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9633
        {
2660ccea Poul Sander 2023-09-22 19:25 9634
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9635
            {
2660ccea Poul Sander 2023-09-22 19:25 9636
                std::advance(m_it.object_iterator, 1);
2660ccea Poul Sander 2023-09-22 19:25 9637
                break;
2660ccea Poul Sander 2023-09-22 19:25 9638
            }
2660ccea Poul Sander 2023-09-22 19:25 9639
2660ccea Poul Sander 2023-09-22 19:25 9640
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9641
            {
2660ccea Poul Sander 2023-09-22 19:25 9642
                std::advance(m_it.array_iterator, 1);
2660ccea Poul Sander 2023-09-22 19:25 9643
                break;
2660ccea Poul Sander 2023-09-22 19:25 9644
            }
2660ccea Poul Sander 2023-09-22 19:25 9645
2660ccea Poul Sander 2023-09-22 19:25 9646
            default:
2660ccea Poul Sander 2023-09-22 19:25 9647
            {
2660ccea Poul Sander 2023-09-22 19:25 9648
                ++m_it.primitive_iterator;
2660ccea Poul Sander 2023-09-22 19:25 9649
                break;
2660ccea Poul Sander 2023-09-22 19:25 9650
            }
2660ccea Poul Sander 2023-09-22 19:25 9651
        }
2660ccea Poul Sander 2023-09-22 19:25 9652
2660ccea Poul Sander 2023-09-22 19:25 9653
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 9654
    }
2660ccea Poul Sander 2023-09-22 19:25 9655
2660ccea Poul Sander 2023-09-22 19:25 9656
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9657
    @brief post-decrement (it--)
2660ccea Poul Sander 2023-09-22 19:25 9658
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9659
    */
2660ccea Poul Sander 2023-09-22 19:25 9660
    iter_impl const operator--(int)
2660ccea Poul Sander 2023-09-22 19:25 9661
    {
2660ccea Poul Sander 2023-09-22 19:25 9662
        auto result = *this;
2660ccea Poul Sander 2023-09-22 19:25 9663
        --(*this);
2660ccea Poul Sander 2023-09-22 19:25 9664
        return result;
2660ccea Poul Sander 2023-09-22 19:25 9665
    }
2660ccea Poul Sander 2023-09-22 19:25 9666
2660ccea Poul Sander 2023-09-22 19:25 9667
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9668
    @brief pre-decrement (--it)
2660ccea Poul Sander 2023-09-22 19:25 9669
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9670
    */
2660ccea Poul Sander 2023-09-22 19:25 9671
    iter_impl& operator--()
2660ccea Poul Sander 2023-09-22 19:25 9672
    {
2660ccea Poul Sander 2023-09-22 19:25 9673
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9674
2660ccea Poul Sander 2023-09-22 19:25 9675
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9676
        {
2660ccea Poul Sander 2023-09-22 19:25 9677
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9678
            {
2660ccea Poul Sander 2023-09-22 19:25 9679
                std::advance(m_it.object_iterator, -1);
2660ccea Poul Sander 2023-09-22 19:25 9680
                break;
2660ccea Poul Sander 2023-09-22 19:25 9681
            }
2660ccea Poul Sander 2023-09-22 19:25 9682
2660ccea Poul Sander 2023-09-22 19:25 9683
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9684
            {
2660ccea Poul Sander 2023-09-22 19:25 9685
                std::advance(m_it.array_iterator, -1);
2660ccea Poul Sander 2023-09-22 19:25 9686
                break;
2660ccea Poul Sander 2023-09-22 19:25 9687
            }
2660ccea Poul Sander 2023-09-22 19:25 9688
2660ccea Poul Sander 2023-09-22 19:25 9689
            default:
2660ccea Poul Sander 2023-09-22 19:25 9690
            {
2660ccea Poul Sander 2023-09-22 19:25 9691
                --m_it.primitive_iterator;
2660ccea Poul Sander 2023-09-22 19:25 9692
                break;
2660ccea Poul Sander 2023-09-22 19:25 9693
            }
2660ccea Poul Sander 2023-09-22 19:25 9694
        }
2660ccea Poul Sander 2023-09-22 19:25 9695
2660ccea Poul Sander 2023-09-22 19:25 9696
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 9697
    }
2660ccea Poul Sander 2023-09-22 19:25 9698
2660ccea Poul Sander 2023-09-22 19:25 9699
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9700
    @brief  comparison: equal
2660ccea Poul Sander 2023-09-22 19:25 9701
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9702
    */
2660ccea Poul Sander 2023-09-22 19:25 9703
    bool operator==(const iter_impl& other) const
2660ccea Poul Sander 2023-09-22 19:25 9704
    {
2660ccea Poul Sander 2023-09-22 19:25 9705
        // if objects are not the same, the comparison is undefined
2660ccea Poul Sander 2023-09-22 19:25 9706
        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
2660ccea Poul Sander 2023-09-22 19:25 9707
        {
2660ccea Poul Sander 2023-09-22 19:25 9708
            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
2660ccea Poul Sander 2023-09-22 19:25 9709
        }
2660ccea Poul Sander 2023-09-22 19:25 9710
2660ccea Poul Sander 2023-09-22 19:25 9711
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9712
2660ccea Poul Sander 2023-09-22 19:25 9713
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9714
        {
2660ccea Poul Sander 2023-09-22 19:25 9715
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9716
                return (m_it.object_iterator == other.m_it.object_iterator);
2660ccea Poul Sander 2023-09-22 19:25 9717
2660ccea Poul Sander 2023-09-22 19:25 9718
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9719
                return (m_it.array_iterator == other.m_it.array_iterator);
2660ccea Poul Sander 2023-09-22 19:25 9720
2660ccea Poul Sander 2023-09-22 19:25 9721
            default:
2660ccea Poul Sander 2023-09-22 19:25 9722
                return (m_it.primitive_iterator == other.m_it.primitive_iterator);
2660ccea Poul Sander 2023-09-22 19:25 9723
        }
2660ccea Poul Sander 2023-09-22 19:25 9724
    }
2660ccea Poul Sander 2023-09-22 19:25 9725
2660ccea Poul Sander 2023-09-22 19:25 9726
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9727
    @brief  comparison: not equal
2660ccea Poul Sander 2023-09-22 19:25 9728
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9729
    */
2660ccea Poul Sander 2023-09-22 19:25 9730
    bool operator!=(const iter_impl& other) const
2660ccea Poul Sander 2023-09-22 19:25 9731
    {
2660ccea Poul Sander 2023-09-22 19:25 9732
        return not operator==(other);
2660ccea Poul Sander 2023-09-22 19:25 9733
    }
2660ccea Poul Sander 2023-09-22 19:25 9734
2660ccea Poul Sander 2023-09-22 19:25 9735
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9736
    @brief  comparison: smaller
2660ccea Poul Sander 2023-09-22 19:25 9737
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9738
    */
2660ccea Poul Sander 2023-09-22 19:25 9739
    bool operator<(const iter_impl& other) const
2660ccea Poul Sander 2023-09-22 19:25 9740
    {
2660ccea Poul Sander 2023-09-22 19:25 9741
        // if objects are not the same, the comparison is undefined
2660ccea Poul Sander 2023-09-22 19:25 9742
        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
2660ccea Poul Sander 2023-09-22 19:25 9743
        {
2660ccea Poul Sander 2023-09-22 19:25 9744
            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
2660ccea Poul Sander 2023-09-22 19:25 9745
        }
2660ccea Poul Sander 2023-09-22 19:25 9746
2660ccea Poul Sander 2023-09-22 19:25 9747
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9748
2660ccea Poul Sander 2023-09-22 19:25 9749
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9750
        {
2660ccea Poul Sander 2023-09-22 19:25 9751
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9752
                JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
2660ccea Poul Sander 2023-09-22 19:25 9753
2660ccea Poul Sander 2023-09-22 19:25 9754
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9755
                return (m_it.array_iterator < other.m_it.array_iterator);
2660ccea Poul Sander 2023-09-22 19:25 9756
2660ccea Poul Sander 2023-09-22 19:25 9757
            default:
2660ccea Poul Sander 2023-09-22 19:25 9758
                return (m_it.primitive_iterator < other.m_it.primitive_iterator);
2660ccea Poul Sander 2023-09-22 19:25 9759
        }
2660ccea Poul Sander 2023-09-22 19:25 9760
    }
2660ccea Poul Sander 2023-09-22 19:25 9761
2660ccea Poul Sander 2023-09-22 19:25 9762
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9763
    @brief  comparison: less than or equal
2660ccea Poul Sander 2023-09-22 19:25 9764
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9765
    */
2660ccea Poul Sander 2023-09-22 19:25 9766
    bool operator<=(const iter_impl& other) const
2660ccea Poul Sander 2023-09-22 19:25 9767
    {
2660ccea Poul Sander 2023-09-22 19:25 9768
        return not other.operator < (*this);
2660ccea Poul Sander 2023-09-22 19:25 9769
    }
2660ccea Poul Sander 2023-09-22 19:25 9770
2660ccea Poul Sander 2023-09-22 19:25 9771
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9772
    @brief  comparison: greater than
2660ccea Poul Sander 2023-09-22 19:25 9773
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9774
    */
2660ccea Poul Sander 2023-09-22 19:25 9775
    bool operator>(const iter_impl& other) const
2660ccea Poul Sander 2023-09-22 19:25 9776
    {
2660ccea Poul Sander 2023-09-22 19:25 9777
        return not operator<=(other);
2660ccea Poul Sander 2023-09-22 19:25 9778
    }
2660ccea Poul Sander 2023-09-22 19:25 9779
2660ccea Poul Sander 2023-09-22 19:25 9780
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9781
    @brief  comparison: greater than or equal
2660ccea Poul Sander 2023-09-22 19:25 9782
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9783
    */
2660ccea Poul Sander 2023-09-22 19:25 9784
    bool operator>=(const iter_impl& other) const
2660ccea Poul Sander 2023-09-22 19:25 9785
    {
2660ccea Poul Sander 2023-09-22 19:25 9786
        return not operator<(other);
2660ccea Poul Sander 2023-09-22 19:25 9787
    }
2660ccea Poul Sander 2023-09-22 19:25 9788
2660ccea Poul Sander 2023-09-22 19:25 9789
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9790
    @brief  add to iterator
2660ccea Poul Sander 2023-09-22 19:25 9791
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9792
    */
2660ccea Poul Sander 2023-09-22 19:25 9793
    iter_impl& operator+=(difference_type i)
2660ccea Poul Sander 2023-09-22 19:25 9794
    {
2660ccea Poul Sander 2023-09-22 19:25 9795
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9796
2660ccea Poul Sander 2023-09-22 19:25 9797
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9798
        {
2660ccea Poul Sander 2023-09-22 19:25 9799
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9800
                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
2660ccea Poul Sander 2023-09-22 19:25 9801
2660ccea Poul Sander 2023-09-22 19:25 9802
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9803
            {
2660ccea Poul Sander 2023-09-22 19:25 9804
                std::advance(m_it.array_iterator, i);
2660ccea Poul Sander 2023-09-22 19:25 9805
                break;
2660ccea Poul Sander 2023-09-22 19:25 9806
            }
2660ccea Poul Sander 2023-09-22 19:25 9807
2660ccea Poul Sander 2023-09-22 19:25 9808
            default:
2660ccea Poul Sander 2023-09-22 19:25 9809
            {
2660ccea Poul Sander 2023-09-22 19:25 9810
                m_it.primitive_iterator += i;
2660ccea Poul Sander 2023-09-22 19:25 9811
                break;
2660ccea Poul Sander 2023-09-22 19:25 9812
            }
2660ccea Poul Sander 2023-09-22 19:25 9813
        }
2660ccea Poul Sander 2023-09-22 19:25 9814
2660ccea Poul Sander 2023-09-22 19:25 9815
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 9816
    }
2660ccea Poul Sander 2023-09-22 19:25 9817
2660ccea Poul Sander 2023-09-22 19:25 9818
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9819
    @brief  subtract from iterator
2660ccea Poul Sander 2023-09-22 19:25 9820
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9821
    */
2660ccea Poul Sander 2023-09-22 19:25 9822
    iter_impl& operator-=(difference_type i)
2660ccea Poul Sander 2023-09-22 19:25 9823
    {
2660ccea Poul Sander 2023-09-22 19:25 9824
        return operator+=(-i);
2660ccea Poul Sander 2023-09-22 19:25 9825
    }
2660ccea Poul Sander 2023-09-22 19:25 9826
2660ccea Poul Sander 2023-09-22 19:25 9827
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9828
    @brief  add to iterator
2660ccea Poul Sander 2023-09-22 19:25 9829
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9830
    */
2660ccea Poul Sander 2023-09-22 19:25 9831
    iter_impl operator+(difference_type i) const
2660ccea Poul Sander 2023-09-22 19:25 9832
    {
2660ccea Poul Sander 2023-09-22 19:25 9833
        auto result = *this;
2660ccea Poul Sander 2023-09-22 19:25 9834
        result += i;
2660ccea Poul Sander 2023-09-22 19:25 9835
        return result;
2660ccea Poul Sander 2023-09-22 19:25 9836
    }
2660ccea Poul Sander 2023-09-22 19:25 9837
2660ccea Poul Sander 2023-09-22 19:25 9838
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9839
    @brief  addition of distance and iterator
2660ccea Poul Sander 2023-09-22 19:25 9840
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9841
    */
2660ccea Poul Sander 2023-09-22 19:25 9842
    friend iter_impl operator+(difference_type i, const iter_impl& it)
2660ccea Poul Sander 2023-09-22 19:25 9843
    {
2660ccea Poul Sander 2023-09-22 19:25 9844
        auto result = it;
2660ccea Poul Sander 2023-09-22 19:25 9845
        result += i;
2660ccea Poul Sander 2023-09-22 19:25 9846
        return result;
2660ccea Poul Sander 2023-09-22 19:25 9847
    }
2660ccea Poul Sander 2023-09-22 19:25 9848
2660ccea Poul Sander 2023-09-22 19:25 9849
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9850
    @brief  subtract from iterator
2660ccea Poul Sander 2023-09-22 19:25 9851
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9852
    */
2660ccea Poul Sander 2023-09-22 19:25 9853
    iter_impl operator-(difference_type i) const
2660ccea Poul Sander 2023-09-22 19:25 9854
    {
2660ccea Poul Sander 2023-09-22 19:25 9855
        auto result = *this;
2660ccea Poul Sander 2023-09-22 19:25 9856
        result -= i;
2660ccea Poul Sander 2023-09-22 19:25 9857
        return result;
2660ccea Poul Sander 2023-09-22 19:25 9858
    }
2660ccea Poul Sander 2023-09-22 19:25 9859
2660ccea Poul Sander 2023-09-22 19:25 9860
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9861
    @brief  return difference
2660ccea Poul Sander 2023-09-22 19:25 9862
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9863
    */
2660ccea Poul Sander 2023-09-22 19:25 9864
    difference_type operator-(const iter_impl& other) const
2660ccea Poul Sander 2023-09-22 19:25 9865
    {
2660ccea Poul Sander 2023-09-22 19:25 9866
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9867
2660ccea Poul Sander 2023-09-22 19:25 9868
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9869
        {
2660ccea Poul Sander 2023-09-22 19:25 9870
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9871
                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
2660ccea Poul Sander 2023-09-22 19:25 9872
2660ccea Poul Sander 2023-09-22 19:25 9873
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9874
                return m_it.array_iterator - other.m_it.array_iterator;
2660ccea Poul Sander 2023-09-22 19:25 9875
2660ccea Poul Sander 2023-09-22 19:25 9876
            default:
2660ccea Poul Sander 2023-09-22 19:25 9877
                return m_it.primitive_iterator - other.m_it.primitive_iterator;
2660ccea Poul Sander 2023-09-22 19:25 9878
        }
2660ccea Poul Sander 2023-09-22 19:25 9879
    }
2660ccea Poul Sander 2023-09-22 19:25 9880
2660ccea Poul Sander 2023-09-22 19:25 9881
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9882
    @brief  access to successor
2660ccea Poul Sander 2023-09-22 19:25 9883
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9884
    */
2660ccea Poul Sander 2023-09-22 19:25 9885
    reference operator[](difference_type n) const
2660ccea Poul Sander 2023-09-22 19:25 9886
    {
2660ccea Poul Sander 2023-09-22 19:25 9887
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9888
2660ccea Poul Sander 2023-09-22 19:25 9889
        switch (m_object->m_type)
2660ccea Poul Sander 2023-09-22 19:25 9890
        {
2660ccea Poul Sander 2023-09-22 19:25 9891
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 9892
                JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
2660ccea Poul Sander 2023-09-22 19:25 9893
2660ccea Poul Sander 2023-09-22 19:25 9894
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 9895
                return *std::next(m_it.array_iterator, n);
2660ccea Poul Sander 2023-09-22 19:25 9896
2660ccea Poul Sander 2023-09-22 19:25 9897
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 9898
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
2660ccea Poul Sander 2023-09-22 19:25 9899
2660ccea Poul Sander 2023-09-22 19:25 9900
            default:
2660ccea Poul Sander 2023-09-22 19:25 9901
            {
2660ccea Poul Sander 2023-09-22 19:25 9902
                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
2660ccea Poul Sander 2023-09-22 19:25 9903
                {
2660ccea Poul Sander 2023-09-22 19:25 9904
                    return *m_object;
2660ccea Poul Sander 2023-09-22 19:25 9905
                }
2660ccea Poul Sander 2023-09-22 19:25 9906
2660ccea Poul Sander 2023-09-22 19:25 9907
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
2660ccea Poul Sander 2023-09-22 19:25 9908
            }
2660ccea Poul Sander 2023-09-22 19:25 9909
        }
2660ccea Poul Sander 2023-09-22 19:25 9910
    }
2660ccea Poul Sander 2023-09-22 19:25 9911
2660ccea Poul Sander 2023-09-22 19:25 9912
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9913
    @brief  return the key of an object iterator
2660ccea Poul Sander 2023-09-22 19:25 9914
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9915
    */
2660ccea Poul Sander 2023-09-22 19:25 9916
    const typename object_t::key_type& key() const
2660ccea Poul Sander 2023-09-22 19:25 9917
    {
2660ccea Poul Sander 2023-09-22 19:25 9918
        assert(m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 9919
2660ccea Poul Sander 2023-09-22 19:25 9920
        if (JSON_HEDLEY_LIKELY(m_object->is_object()))
2660ccea Poul Sander 2023-09-22 19:25 9921
        {
2660ccea Poul Sander 2023-09-22 19:25 9922
            return m_it.object_iterator->first;
2660ccea Poul Sander 2023-09-22 19:25 9923
        }
2660ccea Poul Sander 2023-09-22 19:25 9924
2660ccea Poul Sander 2023-09-22 19:25 9925
        JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
2660ccea Poul Sander 2023-09-22 19:25 9926
    }
2660ccea Poul Sander 2023-09-22 19:25 9927
2660ccea Poul Sander 2023-09-22 19:25 9928
    /*!
2660ccea Poul Sander 2023-09-22 19:25 9929
    @brief  return the value of an iterator
2660ccea Poul Sander 2023-09-22 19:25 9930
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 9931
    */
2660ccea Poul Sander 2023-09-22 19:25 9932
    reference value() const
2660ccea Poul Sander 2023-09-22 19:25 9933
    {
2660ccea Poul Sander 2023-09-22 19:25 9934
        return operator*();
2660ccea Poul Sander 2023-09-22 19:25 9935
    }
2660ccea Poul Sander 2023-09-22 19:25 9936
2660ccea Poul Sander 2023-09-22 19:25 9937
  private:
2660ccea Poul Sander 2023-09-22 19:25 9938
    /// associated JSON instance
2660ccea Poul Sander 2023-09-22 19:25 9939
    pointer m_object = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 9940
    /// the actual iterator of the associated instance
2660ccea Poul Sander 2023-09-22 19:25 9941
    internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
2660ccea Poul Sander 2023-09-22 19:25 9942
};
2660ccea Poul Sander 2023-09-22 19:25 9943
} // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 9944
} // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 9945
2660ccea Poul Sander 2023-09-22 19:25 9946
// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9947
2660ccea Poul Sander 2023-09-22 19:25 9948
// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
2660ccea Poul Sander 2023-09-22 19:25 9949
2660ccea Poul Sander 2023-09-22 19:25 9950
2660ccea Poul Sander 2023-09-22 19:25 9951
#include <cstddef> // ptrdiff_t
2660ccea Poul Sander 2023-09-22 19:25 9952
#include <iterator> // reverse_iterator
2660ccea Poul Sander 2023-09-22 19:25 9953
#include <utility> // declval
2660ccea Poul Sander 2023-09-22 19:25 9954
2660ccea Poul Sander 2023-09-22 19:25 9955
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 9956
{
2660ccea Poul Sander 2023-09-22 19:25 9957
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 9958
{
2660ccea Poul Sander 2023-09-22 19:25 9959
//////////////////////
2660ccea Poul Sander 2023-09-22 19:25 9960
// reverse_iterator //
2660ccea Poul Sander 2023-09-22 19:25 9961
//////////////////////
2660ccea Poul Sander 2023-09-22 19:25 9962
2660ccea Poul Sander 2023-09-22 19:25 9963
/*!
2660ccea Poul Sander 2023-09-22 19:25 9964
@brief a template for a reverse iterator class
2660ccea Poul Sander 2023-09-22 19:25 9965
2660ccea Poul Sander 2023-09-22 19:25 9966
@tparam Base the base iterator type to reverse. Valid types are @ref
2660ccea Poul Sander 2023-09-22 19:25 9967
iterator (to create @ref reverse_iterator) and @ref const_iterator (to
2660ccea Poul Sander 2023-09-22 19:25 9968
create @ref const_reverse_iterator).
2660ccea Poul Sander 2023-09-22 19:25 9969
2660ccea Poul Sander 2023-09-22 19:25 9970
@requirement The class satisfies the following concept requirements:
2660ccea Poul Sander 2023-09-22 19:25 9971
-
2660ccea Poul Sander 2023-09-22 19:25 9972
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
2660ccea Poul Sander 2023-09-22 19:25 9973
  The iterator that can be moved can be moved in both directions (i.e.
2660ccea Poul Sander 2023-09-22 19:25 9974
  incremented and decremented).
2660ccea Poul Sander 2023-09-22 19:25 9975
- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
2660ccea Poul Sander 2023-09-22 19:25 9976
  It is possible to write to the pointed-to element (only if @a Base is
2660ccea Poul Sander 2023-09-22 19:25 9977
  @ref iterator).
2660ccea Poul Sander 2023-09-22 19:25 9978
2660ccea Poul Sander 2023-09-22 19:25 9979
@since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 9980
*/
2660ccea Poul Sander 2023-09-22 19:25 9981
template<typename Base>
2660ccea Poul Sander 2023-09-22 19:25 9982
class json_reverse_iterator : public std::reverse_iterator<Base>
2660ccea Poul Sander 2023-09-22 19:25 9983
{
2660ccea Poul Sander 2023-09-22 19:25 9984
  public:
2660ccea Poul Sander 2023-09-22 19:25 9985
    using difference_type = std::ptrdiff_t;
2660ccea Poul Sander 2023-09-22 19:25 9986
    /// shortcut to the reverse iterator adapter
2660ccea Poul Sander 2023-09-22 19:25 9987
    using base_iterator = std::reverse_iterator<Base>;
2660ccea Poul Sander 2023-09-22 19:25 9988
    /// the reference type for the pointed-to element
2660ccea Poul Sander 2023-09-22 19:25 9989
    using reference = typename Base::reference;
2660ccea Poul Sander 2023-09-22 19:25 9990
2660ccea Poul Sander 2023-09-22 19:25 9991
    /// create reverse iterator from iterator
2660ccea Poul Sander 2023-09-22 19:25 9992
    explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
2660ccea Poul Sander 2023-09-22 19:25 9993
        : base_iterator(it) {}
2660ccea Poul Sander 2023-09-22 19:25 9994
2660ccea Poul Sander 2023-09-22 19:25 9995
    /// create reverse iterator from base class
2660ccea Poul Sander 2023-09-22 19:25 9996
    explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
2660ccea Poul Sander 2023-09-22 19:25 9997
2660ccea Poul Sander 2023-09-22 19:25 9998
    /// post-increment (it++)
2660ccea Poul Sander 2023-09-22 19:25 9999
    json_reverse_iterator const operator++(int)
2660ccea Poul Sander 2023-09-22 19:25 10000
    {
2660ccea Poul Sander 2023-09-22 19:25 10001
        return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
2660ccea Poul Sander 2023-09-22 19:25 10002
    }
2660ccea Poul Sander 2023-09-22 19:25 10003
2660ccea Poul Sander 2023-09-22 19:25 10004
    /// pre-increment (++it)
2660ccea Poul Sander 2023-09-22 19:25 10005
    json_reverse_iterator& operator++()
2660ccea Poul Sander 2023-09-22 19:25 10006
    {
2660ccea Poul Sander 2023-09-22 19:25 10007
        return static_cast<json_reverse_iterator&>(base_iterator::operator++());
2660ccea Poul Sander 2023-09-22 19:25 10008
    }
2660ccea Poul Sander 2023-09-22 19:25 10009
2660ccea Poul Sander 2023-09-22 19:25 10010
    /// post-decrement (it--)
2660ccea Poul Sander 2023-09-22 19:25 10011
    json_reverse_iterator const operator--(int)
2660ccea Poul Sander 2023-09-22 19:25 10012
    {
2660ccea Poul Sander 2023-09-22 19:25 10013
        return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
2660ccea Poul Sander 2023-09-22 19:25 10014
    }
2660ccea Poul Sander 2023-09-22 19:25 10015
2660ccea Poul Sander 2023-09-22 19:25 10016
    /// pre-decrement (--it)
2660ccea Poul Sander 2023-09-22 19:25 10017
    json_reverse_iterator& operator--()
2660ccea Poul Sander 2023-09-22 19:25 10018
    {
2660ccea Poul Sander 2023-09-22 19:25 10019
        return static_cast<json_reverse_iterator&>(base_iterator::operator--());
2660ccea Poul Sander 2023-09-22 19:25 10020
    }
2660ccea Poul Sander 2023-09-22 19:25 10021
2660ccea Poul Sander 2023-09-22 19:25 10022
    /// add to iterator
2660ccea Poul Sander 2023-09-22 19:25 10023
    json_reverse_iterator& operator+=(difference_type i)
2660ccea Poul Sander 2023-09-22 19:25 10024
    {
2660ccea Poul Sander 2023-09-22 19:25 10025
        return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
2660ccea Poul Sander 2023-09-22 19:25 10026
    }
2660ccea Poul Sander 2023-09-22 19:25 10027
2660ccea Poul Sander 2023-09-22 19:25 10028
    /// add to iterator
2660ccea Poul Sander 2023-09-22 19:25 10029
    json_reverse_iterator operator+(difference_type i) const
2660ccea Poul Sander 2023-09-22 19:25 10030
    {
2660ccea Poul Sander 2023-09-22 19:25 10031
        return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
2660ccea Poul Sander 2023-09-22 19:25 10032
    }
2660ccea Poul Sander 2023-09-22 19:25 10033
2660ccea Poul Sander 2023-09-22 19:25 10034
    /// subtract from iterator
2660ccea Poul Sander 2023-09-22 19:25 10035
    json_reverse_iterator operator-(difference_type i) const
2660ccea Poul Sander 2023-09-22 19:25 10036
    {
2660ccea Poul Sander 2023-09-22 19:25 10037
        return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
2660ccea Poul Sander 2023-09-22 19:25 10038
    }
2660ccea Poul Sander 2023-09-22 19:25 10039
2660ccea Poul Sander 2023-09-22 19:25 10040
    /// return difference
2660ccea Poul Sander 2023-09-22 19:25 10041
    difference_type operator-(const json_reverse_iterator& other) const
2660ccea Poul Sander 2023-09-22 19:25 10042
    {
2660ccea Poul Sander 2023-09-22 19:25 10043
        return base_iterator(*this) - base_iterator(other);
2660ccea Poul Sander 2023-09-22 19:25 10044
    }
2660ccea Poul Sander 2023-09-22 19:25 10045
2660ccea Poul Sander 2023-09-22 19:25 10046
    /// access to successor
2660ccea Poul Sander 2023-09-22 19:25 10047
    reference operator[](difference_type n) const
2660ccea Poul Sander 2023-09-22 19:25 10048
    {
2660ccea Poul Sander 2023-09-22 19:25 10049
        return *(this->operator+(n));
2660ccea Poul Sander 2023-09-22 19:25 10050
    }
2660ccea Poul Sander 2023-09-22 19:25 10051
2660ccea Poul Sander 2023-09-22 19:25 10052
    /// return the key of an object iterator
2660ccea Poul Sander 2023-09-22 19:25 10053
    auto key() const -> decltype(std::declval<Base>().key())
2660ccea Poul Sander 2023-09-22 19:25 10054
    {
2660ccea Poul Sander 2023-09-22 19:25 10055
        auto it = --this->base();
2660ccea Poul Sander 2023-09-22 19:25 10056
        return it.key();
2660ccea Poul Sander 2023-09-22 19:25 10057
    }
2660ccea Poul Sander 2023-09-22 19:25 10058
2660ccea Poul Sander 2023-09-22 19:25 10059
    /// return the value of an iterator
2660ccea Poul Sander 2023-09-22 19:25 10060
    reference value() const
2660ccea Poul Sander 2023-09-22 19:25 10061
    {
2660ccea Poul Sander 2023-09-22 19:25 10062
        auto it = --this->base();
2660ccea Poul Sander 2023-09-22 19:25 10063
        return it.operator * ();
2660ccea Poul Sander 2023-09-22 19:25 10064
    }
2660ccea Poul Sander 2023-09-22 19:25 10065
};
2660ccea Poul Sander 2023-09-22 19:25 10066
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 10067
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 10068
2660ccea Poul Sander 2023-09-22 19:25 10069
// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
2660ccea Poul Sander 2023-09-22 19:25 10070
2660ccea Poul Sander 2023-09-22 19:25 10071
// #include <nlohmann/detail/json_pointer.hpp>
2660ccea Poul Sander 2023-09-22 19:25 10072
2660ccea Poul Sander 2023-09-22 19:25 10073
2660ccea Poul Sander 2023-09-22 19:25 10074
#include <algorithm> // all_of
2660ccea Poul Sander 2023-09-22 19:25 10075
#include <cassert> // assert
2660ccea Poul Sander 2023-09-22 19:25 10076
#include <cctype> // isdigit
2660ccea Poul Sander 2023-09-22 19:25 10077
#include <numeric> // accumulate
2660ccea Poul Sander 2023-09-22 19:25 10078
#include <string> // string
2660ccea Poul Sander 2023-09-22 19:25 10079
#include <utility> // move
2660ccea Poul Sander 2023-09-22 19:25 10080
#include <vector> // vector
2660ccea Poul Sander 2023-09-22 19:25 10081
2660ccea Poul Sander 2023-09-22 19:25 10082
// #include <nlohmann/detail/exceptions.hpp>
2660ccea Poul Sander 2023-09-22 19:25 10083
2660ccea Poul Sander 2023-09-22 19:25 10084
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 10085
2660ccea Poul Sander 2023-09-22 19:25 10086
// #include <nlohmann/detail/value_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 10087
2660ccea Poul Sander 2023-09-22 19:25 10088
2660ccea Poul Sander 2023-09-22 19:25 10089
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 10090
{
2660ccea Poul Sander 2023-09-22 19:25 10091
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 10092
class json_pointer
2660ccea Poul Sander 2023-09-22 19:25 10093
{
2660ccea Poul Sander 2023-09-22 19:25 10094
    // allow basic_json to access private members
2660ccea Poul Sander 2023-09-22 19:25 10095
    NLOHMANN_BASIC_JSON_TPL_DECLARATION
2660ccea Poul Sander 2023-09-22 19:25 10096
    friend class basic_json;
2660ccea Poul Sander 2023-09-22 19:25 10097
2660ccea Poul Sander 2023-09-22 19:25 10098
  public:
2660ccea Poul Sander 2023-09-22 19:25 10099
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10100
    @brief create JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10101
2660ccea Poul Sander 2023-09-22 19:25 10102
    Create a JSON pointer according to the syntax described in
2660ccea Poul Sander 2023-09-22 19:25 10103
    [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
2660ccea Poul Sander 2023-09-22 19:25 10104
2660ccea Poul Sander 2023-09-22 19:25 10105
    @param[in] s  string representing the JSON pointer; if omitted, the empty
2660ccea Poul Sander 2023-09-22 19:25 10106
                  string is assumed which references the whole JSON value
2660ccea Poul Sander 2023-09-22 19:25 10107
2660ccea Poul Sander 2023-09-22 19:25 10108
    @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
2660ccea Poul Sander 2023-09-22 19:25 10109
                           not begin with a slash (`/`); see example below
2660ccea Poul Sander 2023-09-22 19:25 10110
2660ccea Poul Sander 2023-09-22 19:25 10111
    @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
2660ccea Poul Sander 2023-09-22 19:25 10112
    not followed by `0` (representing `~`) or `1` (representing `/`); see
2660ccea Poul Sander 2023-09-22 19:25 10113
    example below
2660ccea Poul Sander 2023-09-22 19:25 10114
2660ccea Poul Sander 2023-09-22 19:25 10115
    @liveexample{The example shows the construction several valid JSON pointers
2660ccea Poul Sander 2023-09-22 19:25 10116
    as well as the exceptional behavior.,json_pointer}
2660ccea Poul Sander 2023-09-22 19:25 10117
2660ccea Poul Sander 2023-09-22 19:25 10118
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 10119
    */
2660ccea Poul Sander 2023-09-22 19:25 10120
    explicit json_pointer(const std::string& s = "")
2660ccea Poul Sander 2023-09-22 19:25 10121
        : reference_tokens(split(s))
2660ccea Poul Sander 2023-09-22 19:25 10122
    {}
2660ccea Poul Sander 2023-09-22 19:25 10123
2660ccea Poul Sander 2023-09-22 19:25 10124
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10125
    @brief return a string representation of the JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10126
2660ccea Poul Sander 2023-09-22 19:25 10127
    @invariant For each JSON pointer `ptr`, it holds:
2660ccea Poul Sander 2023-09-22 19:25 10128
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 10129
    ptr == json_pointer(ptr.to_string());
2660ccea Poul Sander 2023-09-22 19:25 10130
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 10131
2660ccea Poul Sander 2023-09-22 19:25 10132
    @return a string representation of the JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10133
2660ccea Poul Sander 2023-09-22 19:25 10134
    @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
2660ccea Poul Sander 2023-09-22 19:25 10135
2660ccea Poul Sander 2023-09-22 19:25 10136
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 10137
    */
2660ccea Poul Sander 2023-09-22 19:25 10138
    std::string to_string() const
2660ccea Poul Sander 2023-09-22 19:25 10139
    {
2660ccea Poul Sander 2023-09-22 19:25 10140
        return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
2660ccea Poul Sander 2023-09-22 19:25 10141
                               std::string{},
2660ccea Poul Sander 2023-09-22 19:25 10142
                               [](const std::string & a, const std::string & b)
2660ccea Poul Sander 2023-09-22 19:25 10143
        {
2660ccea Poul Sander 2023-09-22 19:25 10144
            return a + "/" + escape(b);
2660ccea Poul Sander 2023-09-22 19:25 10145
        });
2660ccea Poul Sander 2023-09-22 19:25 10146
    }
2660ccea Poul Sander 2023-09-22 19:25 10147
2660ccea Poul Sander 2023-09-22 19:25 10148
    /// @copydoc to_string()
2660ccea Poul Sander 2023-09-22 19:25 10149
    operator std::string() const
2660ccea Poul Sander 2023-09-22 19:25 10150
    {
2660ccea Poul Sander 2023-09-22 19:25 10151
        return to_string();
2660ccea Poul Sander 2023-09-22 19:25 10152
    }
2660ccea Poul Sander 2023-09-22 19:25 10153
2660ccea Poul Sander 2023-09-22 19:25 10154
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10155
    @brief append another JSON pointer at the end of this JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10156
2660ccea Poul Sander 2023-09-22 19:25 10157
    @param[in] ptr  JSON pointer to append
2660ccea Poul Sander 2023-09-22 19:25 10158
    @return JSON pointer with @a ptr appended
2660ccea Poul Sander 2023-09-22 19:25 10159
2660ccea Poul Sander 2023-09-22 19:25 10160
    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
2660ccea Poul Sander 2023-09-22 19:25 10161
2660ccea Poul Sander 2023-09-22 19:25 10162
    @complexity Linear in the length of @a ptr.
2660ccea Poul Sander 2023-09-22 19:25 10163
2660ccea Poul Sander 2023-09-22 19:25 10164
    @sa @ref operator/=(std::string) to append a reference token
2660ccea Poul Sander 2023-09-22 19:25 10165
    @sa @ref operator/=(std::size_t) to append an array index
2660ccea Poul Sander 2023-09-22 19:25 10166
    @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
2660ccea Poul Sander 2023-09-22 19:25 10167
2660ccea Poul Sander 2023-09-22 19:25 10168
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 10169
    */
2660ccea Poul Sander 2023-09-22 19:25 10170
    json_pointer& operator/=(const json_pointer& ptr)
2660ccea Poul Sander 2023-09-22 19:25 10171
    {
2660ccea Poul Sander 2023-09-22 19:25 10172
        reference_tokens.insert(reference_tokens.end(),
2660ccea Poul Sander 2023-09-22 19:25 10173
                                ptr.reference_tokens.begin(),
2660ccea Poul Sander 2023-09-22 19:25 10174
                                ptr.reference_tokens.end());
2660ccea Poul Sander 2023-09-22 19:25 10175
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 10176
    }
2660ccea Poul Sander 2023-09-22 19:25 10177
2660ccea Poul Sander 2023-09-22 19:25 10178
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10179
    @brief append an unescaped reference token at the end of this JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10180
2660ccea Poul Sander 2023-09-22 19:25 10181
    @param[in] token  reference token to append
2660ccea Poul Sander 2023-09-22 19:25 10182
    @return JSON pointer with @a token appended without escaping @a token
2660ccea Poul Sander 2023-09-22 19:25 10183
2660ccea Poul Sander 2023-09-22 19:25 10184
    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
2660ccea Poul Sander 2023-09-22 19:25 10185
2660ccea Poul Sander 2023-09-22 19:25 10186
    @complexity Amortized constant.
2660ccea Poul Sander 2023-09-22 19:25 10187
2660ccea Poul Sander 2023-09-22 19:25 10188
    @sa @ref operator/=(const json_pointer&) to append a JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10189
    @sa @ref operator/=(std::size_t) to append an array index
2660ccea Poul Sander 2023-09-22 19:25 10190
    @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator
2660ccea Poul Sander 2023-09-22 19:25 10191
2660ccea Poul Sander 2023-09-22 19:25 10192
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 10193
    */
2660ccea Poul Sander 2023-09-22 19:25 10194
    json_pointer& operator/=(std::string token)
2660ccea Poul Sander 2023-09-22 19:25 10195
    {
2660ccea Poul Sander 2023-09-22 19:25 10196
        push_back(std::move(token));
2660ccea Poul Sander 2023-09-22 19:25 10197
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 10198
    }
2660ccea Poul Sander 2023-09-22 19:25 10199
2660ccea Poul Sander 2023-09-22 19:25 10200
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10201
    @brief append an array index at the end of this JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10202
2660ccea Poul Sander 2023-09-22 19:25 10203
    @param[in] array_index  array index to append
2660ccea Poul Sander 2023-09-22 19:25 10204
    @return JSON pointer with @a array_index appended
2660ccea Poul Sander 2023-09-22 19:25 10205
2660ccea Poul Sander 2023-09-22 19:25 10206
    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
2660ccea Poul Sander 2023-09-22 19:25 10207
2660ccea Poul Sander 2023-09-22 19:25 10208
    @complexity Amortized constant.
2660ccea Poul Sander 2023-09-22 19:25 10209
2660ccea Poul Sander 2023-09-22 19:25 10210
    @sa @ref operator/=(const json_pointer&) to append a JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10211
    @sa @ref operator/=(std::string) to append a reference token
2660ccea Poul Sander 2023-09-22 19:25 10212
    @sa @ref operator/(const json_pointer&, std::string) for a binary operator
2660ccea Poul Sander 2023-09-22 19:25 10213
2660ccea Poul Sander 2023-09-22 19:25 10214
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 10215
    */
2660ccea Poul Sander 2023-09-22 19:25 10216
    json_pointer& operator/=(std::size_t array_index)
2660ccea Poul Sander 2023-09-22 19:25 10217
    {
2660ccea Poul Sander 2023-09-22 19:25 10218
        return *this /= std::to_string(array_index);
2660ccea Poul Sander 2023-09-22 19:25 10219
    }
2660ccea Poul Sander 2023-09-22 19:25 10220
2660ccea Poul Sander 2023-09-22 19:25 10221
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10222
    @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10223
2660ccea Poul Sander 2023-09-22 19:25 10224
    @param[in] lhs  JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10225
    @param[in] rhs  JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10226
    @return a new JSON pointer with @a rhs appended to @a lhs
2660ccea Poul Sander 2023-09-22 19:25 10227
2660ccea Poul Sander 2023-09-22 19:25 10228
    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
2660ccea Poul Sander 2023-09-22 19:25 10229
2660ccea Poul Sander 2023-09-22 19:25 10230
    @complexity Linear in the length of @a lhs and @a rhs.
2660ccea Poul Sander 2023-09-22 19:25 10231
2660ccea Poul Sander 2023-09-22 19:25 10232
    @sa @ref operator/=(const json_pointer&) to append a JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10233
2660ccea Poul Sander 2023-09-22 19:25 10234
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 10235
    */
2660ccea Poul Sander 2023-09-22 19:25 10236
    friend json_pointer operator/(const json_pointer& lhs,
2660ccea Poul Sander 2023-09-22 19:25 10237
                                  const json_pointer& rhs)
2660ccea Poul Sander 2023-09-22 19:25 10238
    {
2660ccea Poul Sander 2023-09-22 19:25 10239
        return json_pointer(lhs) /= rhs;
2660ccea Poul Sander 2023-09-22 19:25 10240
    }
2660ccea Poul Sander 2023-09-22 19:25 10241
2660ccea Poul Sander 2023-09-22 19:25 10242
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10243
    @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10244
2660ccea Poul Sander 2023-09-22 19:25 10245
    @param[in] ptr  JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10246
    @param[in] token  reference token
2660ccea Poul Sander 2023-09-22 19:25 10247
    @return a new JSON pointer with unescaped @a token appended to @a ptr
2660ccea Poul Sander 2023-09-22 19:25 10248
2660ccea Poul Sander 2023-09-22 19:25 10249
    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
2660ccea Poul Sander 2023-09-22 19:25 10250
2660ccea Poul Sander 2023-09-22 19:25 10251
    @complexity Linear in the length of @a ptr.
2660ccea Poul Sander 2023-09-22 19:25 10252
2660ccea Poul Sander 2023-09-22 19:25 10253
    @sa @ref operator/=(std::string) to append a reference token
2660ccea Poul Sander 2023-09-22 19:25 10254
2660ccea Poul Sander 2023-09-22 19:25 10255
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 10256
    */
2660ccea Poul Sander 2023-09-22 19:25 10257
    friend json_pointer operator/(const json_pointer& ptr, std::string token)
2660ccea Poul Sander 2023-09-22 19:25 10258
    {
2660ccea Poul Sander 2023-09-22 19:25 10259
        return json_pointer(ptr) /= std::move(token);
2660ccea Poul Sander 2023-09-22 19:25 10260
    }
2660ccea Poul Sander 2023-09-22 19:25 10261
2660ccea Poul Sander 2023-09-22 19:25 10262
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10263
    @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10264
2660ccea Poul Sander 2023-09-22 19:25 10265
    @param[in] ptr  JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10266
    @param[in] array_index  array index
2660ccea Poul Sander 2023-09-22 19:25 10267
    @return a new JSON pointer with @a array_index appended to @a ptr
2660ccea Poul Sander 2023-09-22 19:25 10268
2660ccea Poul Sander 2023-09-22 19:25 10269
    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
2660ccea Poul Sander 2023-09-22 19:25 10270
2660ccea Poul Sander 2023-09-22 19:25 10271
    @complexity Linear in the length of @a ptr.
2660ccea Poul Sander 2023-09-22 19:25 10272
2660ccea Poul Sander 2023-09-22 19:25 10273
    @sa @ref operator/=(std::size_t) to append an array index
2660ccea Poul Sander 2023-09-22 19:25 10274
2660ccea Poul Sander 2023-09-22 19:25 10275
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 10276
    */
2660ccea Poul Sander 2023-09-22 19:25 10277
    friend json_pointer operator/(const json_pointer& ptr, std::size_t array_index)
2660ccea Poul Sander 2023-09-22 19:25 10278
    {
2660ccea Poul Sander 2023-09-22 19:25 10279
        return json_pointer(ptr) /= array_index;
2660ccea Poul Sander 2023-09-22 19:25 10280
    }
2660ccea Poul Sander 2023-09-22 19:25 10281
2660ccea Poul Sander 2023-09-22 19:25 10282
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10283
    @brief returns the parent of this JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10284
2660ccea Poul Sander 2023-09-22 19:25 10285
    @return parent of this JSON pointer; in case this JSON pointer is the root,
2660ccea Poul Sander 2023-09-22 19:25 10286
            the root itself is returned
2660ccea Poul Sander 2023-09-22 19:25 10287
2660ccea Poul Sander 2023-09-22 19:25 10288
    @complexity Linear in the length of the JSON pointer.
2660ccea Poul Sander 2023-09-22 19:25 10289
2660ccea Poul Sander 2023-09-22 19:25 10290
    @liveexample{The example shows the result of `parent_pointer` for different
2660ccea Poul Sander 2023-09-22 19:25 10291
    JSON Pointers.,json_pointer__parent_pointer}
2660ccea Poul Sander 2023-09-22 19:25 10292
2660ccea Poul Sander 2023-09-22 19:25 10293
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 10294
    */
2660ccea Poul Sander 2023-09-22 19:25 10295
    json_pointer parent_pointer() const
2660ccea Poul Sander 2023-09-22 19:25 10296
    {
2660ccea Poul Sander 2023-09-22 19:25 10297
        if (empty())
2660ccea Poul Sander 2023-09-22 19:25 10298
        {
2660ccea Poul Sander 2023-09-22 19:25 10299
            return *this;
2660ccea Poul Sander 2023-09-22 19:25 10300
        }
2660ccea Poul Sander 2023-09-22 19:25 10301
2660ccea Poul Sander 2023-09-22 19:25 10302
        json_pointer res = *this;
2660ccea Poul Sander 2023-09-22 19:25 10303
        res.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 10304
        return res;
2660ccea Poul Sander 2023-09-22 19:25 10305
    }
2660ccea Poul Sander 2023-09-22 19:25 10306
2660ccea Poul Sander 2023-09-22 19:25 10307
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10308
    @brief remove last reference token
2660ccea Poul Sander 2023-09-22 19:25 10309
2660ccea Poul Sander 2023-09-22 19:25 10310
    @pre not `empty()`
2660ccea Poul Sander 2023-09-22 19:25 10311
2660ccea Poul Sander 2023-09-22 19:25 10312
    @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
2660ccea Poul Sander 2023-09-22 19:25 10313
2660ccea Poul Sander 2023-09-22 19:25 10314
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 10315
2660ccea Poul Sander 2023-09-22 19:25 10316
    @throw out_of_range.405 if JSON pointer has no parent
2660ccea Poul Sander 2023-09-22 19:25 10317
2660ccea Poul Sander 2023-09-22 19:25 10318
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 10319
    */
2660ccea Poul Sander 2023-09-22 19:25 10320
    void pop_back()
2660ccea Poul Sander 2023-09-22 19:25 10321
    {
2660ccea Poul Sander 2023-09-22 19:25 10322
        if (JSON_HEDLEY_UNLIKELY(empty()))
2660ccea Poul Sander 2023-09-22 19:25 10323
        {
2660ccea Poul Sander 2023-09-22 19:25 10324
            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
2660ccea Poul Sander 2023-09-22 19:25 10325
        }
2660ccea Poul Sander 2023-09-22 19:25 10326
2660ccea Poul Sander 2023-09-22 19:25 10327
        reference_tokens.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 10328
    }
2660ccea Poul Sander 2023-09-22 19:25 10329
2660ccea Poul Sander 2023-09-22 19:25 10330
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10331
    @brief return last reference token
2660ccea Poul Sander 2023-09-22 19:25 10332
2660ccea Poul Sander 2023-09-22 19:25 10333
    @pre not `empty()`
2660ccea Poul Sander 2023-09-22 19:25 10334
    @return last reference token
2660ccea Poul Sander 2023-09-22 19:25 10335
2660ccea Poul Sander 2023-09-22 19:25 10336
    @liveexample{The example shows the usage of `back`.,json_pointer__back}
2660ccea Poul Sander 2023-09-22 19:25 10337
2660ccea Poul Sander 2023-09-22 19:25 10338
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 10339
2660ccea Poul Sander 2023-09-22 19:25 10340
    @throw out_of_range.405 if JSON pointer has no parent
2660ccea Poul Sander 2023-09-22 19:25 10341
2660ccea Poul Sander 2023-09-22 19:25 10342
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 10343
    */
2660ccea Poul Sander 2023-09-22 19:25 10344
    const std::string& back() const
2660ccea Poul Sander 2023-09-22 19:25 10345
    {
2660ccea Poul Sander 2023-09-22 19:25 10346
        if (JSON_HEDLEY_UNLIKELY(empty()))
2660ccea Poul Sander 2023-09-22 19:25 10347
        {
2660ccea Poul Sander 2023-09-22 19:25 10348
            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
2660ccea Poul Sander 2023-09-22 19:25 10349
        }
2660ccea Poul Sander 2023-09-22 19:25 10350
2660ccea Poul Sander 2023-09-22 19:25 10351
        return reference_tokens.back();
2660ccea Poul Sander 2023-09-22 19:25 10352
    }
2660ccea Poul Sander 2023-09-22 19:25 10353
2660ccea Poul Sander 2023-09-22 19:25 10354
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10355
    @brief append an unescaped token at the end of the reference pointer
2660ccea Poul Sander 2023-09-22 19:25 10356
2660ccea Poul Sander 2023-09-22 19:25 10357
    @param[in] token  token to add
2660ccea Poul Sander 2023-09-22 19:25 10358
2660ccea Poul Sander 2023-09-22 19:25 10359
    @complexity Amortized constant.
2660ccea Poul Sander 2023-09-22 19:25 10360
2660ccea Poul Sander 2023-09-22 19:25 10361
    @liveexample{The example shows the result of `push_back` for different
2660ccea Poul Sander 2023-09-22 19:25 10362
    JSON Pointers.,json_pointer__push_back}
2660ccea Poul Sander 2023-09-22 19:25 10363
2660ccea Poul Sander 2023-09-22 19:25 10364
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 10365
    */
2660ccea Poul Sander 2023-09-22 19:25 10366
    void push_back(const std::string& token)
2660ccea Poul Sander 2023-09-22 19:25 10367
    {
2660ccea Poul Sander 2023-09-22 19:25 10368
        reference_tokens.push_back(token);
2660ccea Poul Sander 2023-09-22 19:25 10369
    }
2660ccea Poul Sander 2023-09-22 19:25 10370
2660ccea Poul Sander 2023-09-22 19:25 10371
    /// @copydoc push_back(const std::string&)
2660ccea Poul Sander 2023-09-22 19:25 10372
    void push_back(std::string&& token)
2660ccea Poul Sander 2023-09-22 19:25 10373
    {
2660ccea Poul Sander 2023-09-22 19:25 10374
        reference_tokens.push_back(std::move(token));
2660ccea Poul Sander 2023-09-22 19:25 10375
    }
2660ccea Poul Sander 2023-09-22 19:25 10376
2660ccea Poul Sander 2023-09-22 19:25 10377
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10378
    @brief return whether pointer points to the root document
2660ccea Poul Sander 2023-09-22 19:25 10379
2660ccea Poul Sander 2023-09-22 19:25 10380
    @return true iff the JSON pointer points to the root document
2660ccea Poul Sander 2023-09-22 19:25 10381
2660ccea Poul Sander 2023-09-22 19:25 10382
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 10383
2660ccea Poul Sander 2023-09-22 19:25 10384
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 10385
2660ccea Poul Sander 2023-09-22 19:25 10386
    @liveexample{The example shows the result of `empty` for different JSON
2660ccea Poul Sander 2023-09-22 19:25 10387
    Pointers.,json_pointer__empty}
2660ccea Poul Sander 2023-09-22 19:25 10388
2660ccea Poul Sander 2023-09-22 19:25 10389
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 10390
    */
2660ccea Poul Sander 2023-09-22 19:25 10391
    bool empty() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 10392
    {
2660ccea Poul Sander 2023-09-22 19:25 10393
        return reference_tokens.empty();
2660ccea Poul Sander 2023-09-22 19:25 10394
    }
2660ccea Poul Sander 2023-09-22 19:25 10395
2660ccea Poul Sander 2023-09-22 19:25 10396
  private:
2660ccea Poul Sander 2023-09-22 19:25 10397
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10398
    @param[in] s  reference token to be converted into an array index
2660ccea Poul Sander 2023-09-22 19:25 10399
2660ccea Poul Sander 2023-09-22 19:25 10400
    @return integer representation of @a s
2660ccea Poul Sander 2023-09-22 19:25 10401
2660ccea Poul Sander 2023-09-22 19:25 10402
    @throw out_of_range.404 if string @a s could not be converted to an integer
2660ccea Poul Sander 2023-09-22 19:25 10403
    */
2660ccea Poul Sander 2023-09-22 19:25 10404
    static int array_index(const std::string& s)
2660ccea Poul Sander 2023-09-22 19:25 10405
    {
2660ccea Poul Sander 2023-09-22 19:25 10406
        std::size_t processed_chars = 0;
2660ccea Poul Sander 2023-09-22 19:25 10407
        const int res = std::stoi(s, &processed_chars);
2660ccea Poul Sander 2023-09-22 19:25 10408
2660ccea Poul Sander 2023-09-22 19:25 10409
        // check if the string was completely read
2660ccea Poul Sander 2023-09-22 19:25 10410
        if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
2660ccea Poul Sander 2023-09-22 19:25 10411
        {
2660ccea Poul Sander 2023-09-22 19:25 10412
            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
2660ccea Poul Sander 2023-09-22 19:25 10413
        }
2660ccea Poul Sander 2023-09-22 19:25 10414
2660ccea Poul Sander 2023-09-22 19:25 10415
        return res;
2660ccea Poul Sander 2023-09-22 19:25 10416
    }
2660ccea Poul Sander 2023-09-22 19:25 10417
2660ccea Poul Sander 2023-09-22 19:25 10418
    json_pointer top() const
2660ccea Poul Sander 2023-09-22 19:25 10419
    {
2660ccea Poul Sander 2023-09-22 19:25 10420
        if (JSON_HEDLEY_UNLIKELY(empty()))
2660ccea Poul Sander 2023-09-22 19:25 10421
        {
2660ccea Poul Sander 2023-09-22 19:25 10422
            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
2660ccea Poul Sander 2023-09-22 19:25 10423
        }
2660ccea Poul Sander 2023-09-22 19:25 10424
2660ccea Poul Sander 2023-09-22 19:25 10425
        json_pointer result = *this;
2660ccea Poul Sander 2023-09-22 19:25 10426
        result.reference_tokens = {reference_tokens[0]};
2660ccea Poul Sander 2023-09-22 19:25 10427
        return result;
2660ccea Poul Sander 2023-09-22 19:25 10428
    }
2660ccea Poul Sander 2023-09-22 19:25 10429
2660ccea Poul Sander 2023-09-22 19:25 10430
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10431
    @brief create and return a reference to the pointed to value
2660ccea Poul Sander 2023-09-22 19:25 10432
2660ccea Poul Sander 2023-09-22 19:25 10433
    @complexity Linear in the number of reference tokens.
2660ccea Poul Sander 2023-09-22 19:25 10434
2660ccea Poul Sander 2023-09-22 19:25 10435
    @throw parse_error.109 if array index is not a number
2660ccea Poul Sander 2023-09-22 19:25 10436
    @throw type_error.313 if value cannot be unflattened
2660ccea Poul Sander 2023-09-22 19:25 10437
    */
2660ccea Poul Sander 2023-09-22 19:25 10438
    BasicJsonType& get_and_create(BasicJsonType& j) const
2660ccea Poul Sander 2023-09-22 19:25 10439
    {
2660ccea Poul Sander 2023-09-22 19:25 10440
        using size_type = typename BasicJsonType::size_type;
2660ccea Poul Sander 2023-09-22 19:25 10441
        auto result = &j;
2660ccea Poul Sander 2023-09-22 19:25 10442
2660ccea Poul Sander 2023-09-22 19:25 10443
        // in case no reference tokens exist, return a reference to the JSON value
2660ccea Poul Sander 2023-09-22 19:25 10444
        // j which will be overwritten by a primitive value
2660ccea Poul Sander 2023-09-22 19:25 10445
        for (const auto& reference_token : reference_tokens)
2660ccea Poul Sander 2023-09-22 19:25 10446
        {
2660ccea Poul Sander 2023-09-22 19:25 10447
            switch (result->type())
2660ccea Poul Sander 2023-09-22 19:25 10448
            {
2660ccea Poul Sander 2023-09-22 19:25 10449
                case detail::value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 10450
                {
2660ccea Poul Sander 2023-09-22 19:25 10451
                    if (reference_token == "0")
2660ccea Poul Sander 2023-09-22 19:25 10452
                    {
2660ccea Poul Sander 2023-09-22 19:25 10453
                        // start a new array if reference token is 0
2660ccea Poul Sander 2023-09-22 19:25 10454
                        result = &result->operator[](0);
2660ccea Poul Sander 2023-09-22 19:25 10455
                    }
2660ccea Poul Sander 2023-09-22 19:25 10456
                    else
2660ccea Poul Sander 2023-09-22 19:25 10457
                    {
2660ccea Poul Sander 2023-09-22 19:25 10458
                        // start a new object otherwise
2660ccea Poul Sander 2023-09-22 19:25 10459
                        result = &result->operator[](reference_token);
2660ccea Poul Sander 2023-09-22 19:25 10460
                    }
2660ccea Poul Sander 2023-09-22 19:25 10461
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10462
                }
2660ccea Poul Sander 2023-09-22 19:25 10463
2660ccea Poul Sander 2023-09-22 19:25 10464
                case detail::value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 10465
                {
2660ccea Poul Sander 2023-09-22 19:25 10466
                    // create an entry in the object
2660ccea Poul Sander 2023-09-22 19:25 10467
                    result = &result->operator[](reference_token);
2660ccea Poul Sander 2023-09-22 19:25 10468
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10469
                }
2660ccea Poul Sander 2023-09-22 19:25 10470
2660ccea Poul Sander 2023-09-22 19:25 10471
                case detail::value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 10472
                {
2660ccea Poul Sander 2023-09-22 19:25 10473
                    // create an entry in the array
2660ccea Poul Sander 2023-09-22 19:25 10474
                    JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 10475
                    {
2660ccea Poul Sander 2023-09-22 19:25 10476
                        result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
2660ccea Poul Sander 2023-09-22 19:25 10477
                    }
2660ccea Poul Sander 2023-09-22 19:25 10478
                    JSON_CATCH(std::invalid_argument&)
2660ccea Poul Sander 2023-09-22 19:25 10479
                    {
2660ccea Poul Sander 2023-09-22 19:25 10480
                        JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
2660ccea Poul Sander 2023-09-22 19:25 10481
                    }
2660ccea Poul Sander 2023-09-22 19:25 10482
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10483
                }
2660ccea Poul Sander 2023-09-22 19:25 10484
2660ccea Poul Sander 2023-09-22 19:25 10485
                /*
2660ccea Poul Sander 2023-09-22 19:25 10486
                The following code is only reached if there exists a reference
2660ccea Poul Sander 2023-09-22 19:25 10487
                token _and_ the current value is primitive. In this case, we have
2660ccea Poul Sander 2023-09-22 19:25 10488
                an error situation, because primitive values may only occur as
2660ccea Poul Sander 2023-09-22 19:25 10489
                single value; that is, with an empty list of reference tokens.
2660ccea Poul Sander 2023-09-22 19:25 10490
                */
2660ccea Poul Sander 2023-09-22 19:25 10491
                default:
2660ccea Poul Sander 2023-09-22 19:25 10492
                    JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
2660ccea Poul Sander 2023-09-22 19:25 10493
            }
2660ccea Poul Sander 2023-09-22 19:25 10494
        }
2660ccea Poul Sander 2023-09-22 19:25 10495
2660ccea Poul Sander 2023-09-22 19:25 10496
        return *result;
2660ccea Poul Sander 2023-09-22 19:25 10497
    }
2660ccea Poul Sander 2023-09-22 19:25 10498
2660ccea Poul Sander 2023-09-22 19:25 10499
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10500
    @brief return a reference to the pointed to value
2660ccea Poul Sander 2023-09-22 19:25 10501
2660ccea Poul Sander 2023-09-22 19:25 10502
    @note This version does not throw if a value is not present, but tries to
2660ccea Poul Sander 2023-09-22 19:25 10503
          create nested values instead. For instance, calling this function
2660ccea Poul Sander 2023-09-22 19:25 10504
          with pointer `"/this/that"` on a null value is equivalent to calling
2660ccea Poul Sander 2023-09-22 19:25 10505
          `operator[]("this").operator[]("that")` on that value, effectively
2660ccea Poul Sander 2023-09-22 19:25 10506
          changing the null value to an object.
2660ccea Poul Sander 2023-09-22 19:25 10507
2660ccea Poul Sander 2023-09-22 19:25 10508
    @param[in] ptr  a JSON value
2660ccea Poul Sander 2023-09-22 19:25 10509
2660ccea Poul Sander 2023-09-22 19:25 10510
    @return reference to the JSON value pointed to by the JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 10511
2660ccea Poul Sander 2023-09-22 19:25 10512
    @complexity Linear in the length of the JSON pointer.
2660ccea Poul Sander 2023-09-22 19:25 10513
2660ccea Poul Sander 2023-09-22 19:25 10514
    @throw parse_error.106   if an array index begins with '0'
2660ccea Poul Sander 2023-09-22 19:25 10515
    @throw parse_error.109   if an array index was not a number
2660ccea Poul Sander 2023-09-22 19:25 10516
    @throw out_of_range.404  if the JSON pointer can not be resolved
2660ccea Poul Sander 2023-09-22 19:25 10517
    */
2660ccea Poul Sander 2023-09-22 19:25 10518
    BasicJsonType& get_unchecked(BasicJsonType* ptr) const
2660ccea Poul Sander 2023-09-22 19:25 10519
    {
2660ccea Poul Sander 2023-09-22 19:25 10520
        using size_type = typename BasicJsonType::size_type;
2660ccea Poul Sander 2023-09-22 19:25 10521
        for (const auto& reference_token : reference_tokens)
2660ccea Poul Sander 2023-09-22 19:25 10522
        {
2660ccea Poul Sander 2023-09-22 19:25 10523
            // convert null values to arrays or objects before continuing
2660ccea Poul Sander 2023-09-22 19:25 10524
            if (ptr->is_null())
2660ccea Poul Sander 2023-09-22 19:25 10525
            {
2660ccea Poul Sander 2023-09-22 19:25 10526
                // check if reference token is a number
2660ccea Poul Sander 2023-09-22 19:25 10527
                const bool nums =
2660ccea Poul Sander 2023-09-22 19:25 10528
                    std::all_of(reference_token.begin(), reference_token.end(),
2660ccea Poul Sander 2023-09-22 19:25 10529
                                [](const unsigned char x)
2660ccea Poul Sander 2023-09-22 19:25 10530
                {
2660ccea Poul Sander 2023-09-22 19:25 10531
                    return std::isdigit(x);
2660ccea Poul Sander 2023-09-22 19:25 10532
                });
2660ccea Poul Sander 2023-09-22 19:25 10533
2660ccea Poul Sander 2023-09-22 19:25 10534
                // change value to array for numbers or "-" or to object otherwise
2660ccea Poul Sander 2023-09-22 19:25 10535
                *ptr = (nums or reference_token == "-")
2660ccea Poul Sander 2023-09-22 19:25 10536
                       ? detail::value_t::array
2660ccea Poul Sander 2023-09-22 19:25 10537
                       : detail::value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 10538
            }
2660ccea Poul Sander 2023-09-22 19:25 10539
2660ccea Poul Sander 2023-09-22 19:25 10540
            switch (ptr->type())
2660ccea Poul Sander 2023-09-22 19:25 10541
            {
2660ccea Poul Sander 2023-09-22 19:25 10542
                case detail::value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 10543
                {
2660ccea Poul Sander 2023-09-22 19:25 10544
                    // use unchecked object access
2660ccea Poul Sander 2023-09-22 19:25 10545
                    ptr = &ptr->operator[](reference_token);
2660ccea Poul Sander 2023-09-22 19:25 10546
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10547
                }
2660ccea Poul Sander 2023-09-22 19:25 10548
2660ccea Poul Sander 2023-09-22 19:25 10549
                case detail::value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 10550
                {
2660ccea Poul Sander 2023-09-22 19:25 10551
                    // error condition (cf. RFC 6901, Sect. 4)
2660ccea Poul Sander 2023-09-22 19:25 10552
                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
2660ccea Poul Sander 2023-09-22 19:25 10553
                    {
2660ccea Poul Sander 2023-09-22 19:25 10554
                        JSON_THROW(detail::parse_error::create(106, 0,
2660ccea Poul Sander 2023-09-22 19:25 10555
                                                               "array index '" + reference_token +
2660ccea Poul Sander 2023-09-22 19:25 10556
                                                               "' must not begin with '0'"));
2660ccea Poul Sander 2023-09-22 19:25 10557
                    }
2660ccea Poul Sander 2023-09-22 19:25 10558
2660ccea Poul Sander 2023-09-22 19:25 10559
                    if (reference_token == "-")
2660ccea Poul Sander 2023-09-22 19:25 10560
                    {
2660ccea Poul Sander 2023-09-22 19:25 10561
                        // explicitly treat "-" as index beyond the end
2660ccea Poul Sander 2023-09-22 19:25 10562
                        ptr = &ptr->operator[](ptr->m_value.array->size());
2660ccea Poul Sander 2023-09-22 19:25 10563
                    }
2660ccea Poul Sander 2023-09-22 19:25 10564
                    else
2660ccea Poul Sander 2023-09-22 19:25 10565
                    {
2660ccea Poul Sander 2023-09-22 19:25 10566
                        // convert array index to number; unchecked access
2660ccea Poul Sander 2023-09-22 19:25 10567
                        JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 10568
                        {
2660ccea Poul Sander 2023-09-22 19:25 10569
                            ptr = &ptr->operator[](
2660ccea Poul Sander 2023-09-22 19:25 10570
                                static_cast<size_type>(array_index(reference_token)));
2660ccea Poul Sander 2023-09-22 19:25 10571
                        }
2660ccea Poul Sander 2023-09-22 19:25 10572
                        JSON_CATCH(std::invalid_argument&)
2660ccea Poul Sander 2023-09-22 19:25 10573
                        {
2660ccea Poul Sander 2023-09-22 19:25 10574
                            JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
2660ccea Poul Sander 2023-09-22 19:25 10575
                        }
2660ccea Poul Sander 2023-09-22 19:25 10576
                    }
2660ccea Poul Sander 2023-09-22 19:25 10577
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10578
                }
2660ccea Poul Sander 2023-09-22 19:25 10579
2660ccea Poul Sander 2023-09-22 19:25 10580
                default:
2660ccea Poul Sander 2023-09-22 19:25 10581
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
2660ccea Poul Sander 2023-09-22 19:25 10582
            }
2660ccea Poul Sander 2023-09-22 19:25 10583
        }
2660ccea Poul Sander 2023-09-22 19:25 10584
2660ccea Poul Sander 2023-09-22 19:25 10585
        return *ptr;
2660ccea Poul Sander 2023-09-22 19:25 10586
    }
2660ccea Poul Sander 2023-09-22 19:25 10587
2660ccea Poul Sander 2023-09-22 19:25 10588
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10589
    @throw parse_error.106   if an array index begins with '0'
2660ccea Poul Sander 2023-09-22 19:25 10590
    @throw parse_error.109   if an array index was not a number
2660ccea Poul Sander 2023-09-22 19:25 10591
    @throw out_of_range.402  if the array index '-' is used
2660ccea Poul Sander 2023-09-22 19:25 10592
    @throw out_of_range.404  if the JSON pointer can not be resolved
2660ccea Poul Sander 2023-09-22 19:25 10593
    */
2660ccea Poul Sander 2023-09-22 19:25 10594
    BasicJsonType& get_checked(BasicJsonType* ptr) const
2660ccea Poul Sander 2023-09-22 19:25 10595
    {
2660ccea Poul Sander 2023-09-22 19:25 10596
        using size_type = typename BasicJsonType::size_type;
2660ccea Poul Sander 2023-09-22 19:25 10597
        for (const auto& reference_token : reference_tokens)
2660ccea Poul Sander 2023-09-22 19:25 10598
        {
2660ccea Poul Sander 2023-09-22 19:25 10599
            switch (ptr->type())
2660ccea Poul Sander 2023-09-22 19:25 10600
            {
2660ccea Poul Sander 2023-09-22 19:25 10601
                case detail::value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 10602
                {
2660ccea Poul Sander 2023-09-22 19:25 10603
                    // note: at performs range check
2660ccea Poul Sander 2023-09-22 19:25 10604
                    ptr = &ptr->at(reference_token);
2660ccea Poul Sander 2023-09-22 19:25 10605
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10606
                }
2660ccea Poul Sander 2023-09-22 19:25 10607
2660ccea Poul Sander 2023-09-22 19:25 10608
                case detail::value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 10609
                {
2660ccea Poul Sander 2023-09-22 19:25 10610
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
2660ccea Poul Sander 2023-09-22 19:25 10611
                    {
2660ccea Poul Sander 2023-09-22 19:25 10612
                        // "-" always fails the range check
2660ccea Poul Sander 2023-09-22 19:25 10613
                        JSON_THROW(detail::out_of_range::create(402,
2660ccea Poul Sander 2023-09-22 19:25 10614
                                                                "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
2660ccea Poul Sander 2023-09-22 19:25 10615
                                                                ") is out of range"));
2660ccea Poul Sander 2023-09-22 19:25 10616
                    }
2660ccea Poul Sander 2023-09-22 19:25 10617
2660ccea Poul Sander 2023-09-22 19:25 10618
                    // error condition (cf. RFC 6901, Sect. 4)
2660ccea Poul Sander 2023-09-22 19:25 10619
                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
2660ccea Poul Sander 2023-09-22 19:25 10620
                    {
2660ccea Poul Sander 2023-09-22 19:25 10621
                        JSON_THROW(detail::parse_error::create(106, 0,
2660ccea Poul Sander 2023-09-22 19:25 10622
                                                               "array index '" + reference_token +
2660ccea Poul Sander 2023-09-22 19:25 10623
                                                               "' must not begin with '0'"));
2660ccea Poul Sander 2023-09-22 19:25 10624
                    }
2660ccea Poul Sander 2023-09-22 19:25 10625
2660ccea Poul Sander 2023-09-22 19:25 10626
                    // note: at performs range check
2660ccea Poul Sander 2023-09-22 19:25 10627
                    JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 10628
                    {
2660ccea Poul Sander 2023-09-22 19:25 10629
                        ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
2660ccea Poul Sander 2023-09-22 19:25 10630
                    }
2660ccea Poul Sander 2023-09-22 19:25 10631
                    JSON_CATCH(std::invalid_argument&)
2660ccea Poul Sander 2023-09-22 19:25 10632
                    {
2660ccea Poul Sander 2023-09-22 19:25 10633
                        JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
2660ccea Poul Sander 2023-09-22 19:25 10634
                    }
2660ccea Poul Sander 2023-09-22 19:25 10635
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10636
                }
2660ccea Poul Sander 2023-09-22 19:25 10637
2660ccea Poul Sander 2023-09-22 19:25 10638
                default:
2660ccea Poul Sander 2023-09-22 19:25 10639
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
2660ccea Poul Sander 2023-09-22 19:25 10640
            }
2660ccea Poul Sander 2023-09-22 19:25 10641
        }
2660ccea Poul Sander 2023-09-22 19:25 10642
2660ccea Poul Sander 2023-09-22 19:25 10643
        return *ptr;
2660ccea Poul Sander 2023-09-22 19:25 10644
    }
2660ccea Poul Sander 2023-09-22 19:25 10645
2660ccea Poul Sander 2023-09-22 19:25 10646
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10647
    @brief return a const reference to the pointed to value
2660ccea Poul Sander 2023-09-22 19:25 10648
2660ccea Poul Sander 2023-09-22 19:25 10649
    @param[in] ptr  a JSON value
2660ccea Poul Sander 2023-09-22 19:25 10650
2660ccea Poul Sander 2023-09-22 19:25 10651
    @return const reference to the JSON value pointed to by the JSON
2660ccea Poul Sander 2023-09-22 19:25 10652
    pointer
2660ccea Poul Sander 2023-09-22 19:25 10653
2660ccea Poul Sander 2023-09-22 19:25 10654
    @throw parse_error.106   if an array index begins with '0'
2660ccea Poul Sander 2023-09-22 19:25 10655
    @throw parse_error.109   if an array index was not a number
2660ccea Poul Sander 2023-09-22 19:25 10656
    @throw out_of_range.402  if the array index '-' is used
2660ccea Poul Sander 2023-09-22 19:25 10657
    @throw out_of_range.404  if the JSON pointer can not be resolved
2660ccea Poul Sander 2023-09-22 19:25 10658
    */
2660ccea Poul Sander 2023-09-22 19:25 10659
    const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
2660ccea Poul Sander 2023-09-22 19:25 10660
    {
2660ccea Poul Sander 2023-09-22 19:25 10661
        using size_type = typename BasicJsonType::size_type;
2660ccea Poul Sander 2023-09-22 19:25 10662
        for (const auto& reference_token : reference_tokens)
2660ccea Poul Sander 2023-09-22 19:25 10663
        {
2660ccea Poul Sander 2023-09-22 19:25 10664
            switch (ptr->type())
2660ccea Poul Sander 2023-09-22 19:25 10665
            {
2660ccea Poul Sander 2023-09-22 19:25 10666
                case detail::value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 10667
                {
2660ccea Poul Sander 2023-09-22 19:25 10668
                    // use unchecked object access
2660ccea Poul Sander 2023-09-22 19:25 10669
                    ptr = &ptr->operator[](reference_token);
2660ccea Poul Sander 2023-09-22 19:25 10670
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10671
                }
2660ccea Poul Sander 2023-09-22 19:25 10672
2660ccea Poul Sander 2023-09-22 19:25 10673
                case detail::value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 10674
                {
2660ccea Poul Sander 2023-09-22 19:25 10675
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
2660ccea Poul Sander 2023-09-22 19:25 10676
                    {
2660ccea Poul Sander 2023-09-22 19:25 10677
                        // "-" cannot be used for const access
2660ccea Poul Sander 2023-09-22 19:25 10678
                        JSON_THROW(detail::out_of_range::create(402,
2660ccea Poul Sander 2023-09-22 19:25 10679
                                                                "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
2660ccea Poul Sander 2023-09-22 19:25 10680
                                                                ") is out of range"));
2660ccea Poul Sander 2023-09-22 19:25 10681
                    }
2660ccea Poul Sander 2023-09-22 19:25 10682
2660ccea Poul Sander 2023-09-22 19:25 10683
                    // error condition (cf. RFC 6901, Sect. 4)
2660ccea Poul Sander 2023-09-22 19:25 10684
                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
2660ccea Poul Sander 2023-09-22 19:25 10685
                    {
2660ccea Poul Sander 2023-09-22 19:25 10686
                        JSON_THROW(detail::parse_error::create(106, 0,
2660ccea Poul Sander 2023-09-22 19:25 10687
                                                               "array index '" + reference_token +
2660ccea Poul Sander 2023-09-22 19:25 10688
                                                               "' must not begin with '0'"));
2660ccea Poul Sander 2023-09-22 19:25 10689
                    }
2660ccea Poul Sander 2023-09-22 19:25 10690
2660ccea Poul Sander 2023-09-22 19:25 10691
                    // use unchecked array access
2660ccea Poul Sander 2023-09-22 19:25 10692
                    JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 10693
                    {
2660ccea Poul Sander 2023-09-22 19:25 10694
                        ptr = &ptr->operator[](
2660ccea Poul Sander 2023-09-22 19:25 10695
                            static_cast<size_type>(array_index(reference_token)));
2660ccea Poul Sander 2023-09-22 19:25 10696
                    }
2660ccea Poul Sander 2023-09-22 19:25 10697
                    JSON_CATCH(std::invalid_argument&)
2660ccea Poul Sander 2023-09-22 19:25 10698
                    {
2660ccea Poul Sander 2023-09-22 19:25 10699
                        JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
2660ccea Poul Sander 2023-09-22 19:25 10700
                    }
2660ccea Poul Sander 2023-09-22 19:25 10701
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10702
                }
2660ccea Poul Sander 2023-09-22 19:25 10703
2660ccea Poul Sander 2023-09-22 19:25 10704
                default:
2660ccea Poul Sander 2023-09-22 19:25 10705
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
2660ccea Poul Sander 2023-09-22 19:25 10706
            }
2660ccea Poul Sander 2023-09-22 19:25 10707
        }
2660ccea Poul Sander 2023-09-22 19:25 10708
2660ccea Poul Sander 2023-09-22 19:25 10709
        return *ptr;
2660ccea Poul Sander 2023-09-22 19:25 10710
    }
2660ccea Poul Sander 2023-09-22 19:25 10711
2660ccea Poul Sander 2023-09-22 19:25 10712
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10713
    @throw parse_error.106   if an array index begins with '0'
2660ccea Poul Sander 2023-09-22 19:25 10714
    @throw parse_error.109   if an array index was not a number
2660ccea Poul Sander 2023-09-22 19:25 10715
    @throw out_of_range.402  if the array index '-' is used
2660ccea Poul Sander 2023-09-22 19:25 10716
    @throw out_of_range.404  if the JSON pointer can not be resolved
2660ccea Poul Sander 2023-09-22 19:25 10717
    */
2660ccea Poul Sander 2023-09-22 19:25 10718
    const BasicJsonType& get_checked(const BasicJsonType* ptr) const
2660ccea Poul Sander 2023-09-22 19:25 10719
    {
2660ccea Poul Sander 2023-09-22 19:25 10720
        using size_type = typename BasicJsonType::size_type;
2660ccea Poul Sander 2023-09-22 19:25 10721
        for (const auto& reference_token : reference_tokens)
2660ccea Poul Sander 2023-09-22 19:25 10722
        {
2660ccea Poul Sander 2023-09-22 19:25 10723
            switch (ptr->type())
2660ccea Poul Sander 2023-09-22 19:25 10724
            {
2660ccea Poul Sander 2023-09-22 19:25 10725
                case detail::value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 10726
                {
2660ccea Poul Sander 2023-09-22 19:25 10727
                    // note: at performs range check
2660ccea Poul Sander 2023-09-22 19:25 10728
                    ptr = &ptr->at(reference_token);
2660ccea Poul Sander 2023-09-22 19:25 10729
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10730
                }
2660ccea Poul Sander 2023-09-22 19:25 10731
2660ccea Poul Sander 2023-09-22 19:25 10732
                case detail::value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 10733
                {
2660ccea Poul Sander 2023-09-22 19:25 10734
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
2660ccea Poul Sander 2023-09-22 19:25 10735
                    {
2660ccea Poul Sander 2023-09-22 19:25 10736
                        // "-" always fails the range check
2660ccea Poul Sander 2023-09-22 19:25 10737
                        JSON_THROW(detail::out_of_range::create(402,
2660ccea Poul Sander 2023-09-22 19:25 10738
                                                                "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
2660ccea Poul Sander 2023-09-22 19:25 10739
                                                                ") is out of range"));
2660ccea Poul Sander 2023-09-22 19:25 10740
                    }
2660ccea Poul Sander 2023-09-22 19:25 10741
2660ccea Poul Sander 2023-09-22 19:25 10742
                    // error condition (cf. RFC 6901, Sect. 4)
2660ccea Poul Sander 2023-09-22 19:25 10743
                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
2660ccea Poul Sander 2023-09-22 19:25 10744
                    {
2660ccea Poul Sander 2023-09-22 19:25 10745
                        JSON_THROW(detail::parse_error::create(106, 0,
2660ccea Poul Sander 2023-09-22 19:25 10746
                                                               "array index '" + reference_token +
2660ccea Poul Sander 2023-09-22 19:25 10747
                                                               "' must not begin with '0'"));
2660ccea Poul Sander 2023-09-22 19:25 10748
                    }
2660ccea Poul Sander 2023-09-22 19:25 10749
2660ccea Poul Sander 2023-09-22 19:25 10750
                    // note: at performs range check
2660ccea Poul Sander 2023-09-22 19:25 10751
                    JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 10752
                    {
2660ccea Poul Sander 2023-09-22 19:25 10753
                        ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
2660ccea Poul Sander 2023-09-22 19:25 10754
                    }
2660ccea Poul Sander 2023-09-22 19:25 10755
                    JSON_CATCH(std::invalid_argument&)
2660ccea Poul Sander 2023-09-22 19:25 10756
                    {
2660ccea Poul Sander 2023-09-22 19:25 10757
                        JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
2660ccea Poul Sander 2023-09-22 19:25 10758
                    }
2660ccea Poul Sander 2023-09-22 19:25 10759
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10760
                }
2660ccea Poul Sander 2023-09-22 19:25 10761
2660ccea Poul Sander 2023-09-22 19:25 10762
                default:
2660ccea Poul Sander 2023-09-22 19:25 10763
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
2660ccea Poul Sander 2023-09-22 19:25 10764
            }
2660ccea Poul Sander 2023-09-22 19:25 10765
        }
2660ccea Poul Sander 2023-09-22 19:25 10766
2660ccea Poul Sander 2023-09-22 19:25 10767
        return *ptr;
2660ccea Poul Sander 2023-09-22 19:25 10768
    }
2660ccea Poul Sander 2023-09-22 19:25 10769
2660ccea Poul Sander 2023-09-22 19:25 10770
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10771
    @throw parse_error.106   if an array index begins with '0'
2660ccea Poul Sander 2023-09-22 19:25 10772
    @throw parse_error.109   if an array index was not a number
2660ccea Poul Sander 2023-09-22 19:25 10773
    */
2660ccea Poul Sander 2023-09-22 19:25 10774
    bool contains(const BasicJsonType* ptr) const
2660ccea Poul Sander 2023-09-22 19:25 10775
    {
2660ccea Poul Sander 2023-09-22 19:25 10776
        using size_type = typename BasicJsonType::size_type;
2660ccea Poul Sander 2023-09-22 19:25 10777
        for (const auto& reference_token : reference_tokens)
2660ccea Poul Sander 2023-09-22 19:25 10778
        {
2660ccea Poul Sander 2023-09-22 19:25 10779
            switch (ptr->type())
2660ccea Poul Sander 2023-09-22 19:25 10780
            {
2660ccea Poul Sander 2023-09-22 19:25 10781
                case detail::value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 10782
                {
2660ccea Poul Sander 2023-09-22 19:25 10783
                    if (not ptr->contains(reference_token))
2660ccea Poul Sander 2023-09-22 19:25 10784
                    {
2660ccea Poul Sander 2023-09-22 19:25 10785
                        // we did not find the key in the object
2660ccea Poul Sander 2023-09-22 19:25 10786
                        return false;
2660ccea Poul Sander 2023-09-22 19:25 10787
                    }
2660ccea Poul Sander 2023-09-22 19:25 10788
2660ccea Poul Sander 2023-09-22 19:25 10789
                    ptr = &ptr->operator[](reference_token);
2660ccea Poul Sander 2023-09-22 19:25 10790
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10791
                }
2660ccea Poul Sander 2023-09-22 19:25 10792
2660ccea Poul Sander 2023-09-22 19:25 10793
                case detail::value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 10794
                {
2660ccea Poul Sander 2023-09-22 19:25 10795
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
2660ccea Poul Sander 2023-09-22 19:25 10796
                    {
2660ccea Poul Sander 2023-09-22 19:25 10797
                        // "-" always fails the range check
2660ccea Poul Sander 2023-09-22 19:25 10798
                        return false;
2660ccea Poul Sander 2023-09-22 19:25 10799
                    }
2660ccea Poul Sander 2023-09-22 19:25 10800
2660ccea Poul Sander 2023-09-22 19:25 10801
                    // error condition (cf. RFC 6901, Sect. 4)
2660ccea Poul Sander 2023-09-22 19:25 10802
                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
2660ccea Poul Sander 2023-09-22 19:25 10803
                    {
2660ccea Poul Sander 2023-09-22 19:25 10804
                        JSON_THROW(detail::parse_error::create(106, 0,
2660ccea Poul Sander 2023-09-22 19:25 10805
                                                               "array index '" + reference_token +
2660ccea Poul Sander 2023-09-22 19:25 10806
                                                               "' must not begin with '0'"));
2660ccea Poul Sander 2023-09-22 19:25 10807
                    }
2660ccea Poul Sander 2023-09-22 19:25 10808
2660ccea Poul Sander 2023-09-22 19:25 10809
                    JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 10810
                    {
2660ccea Poul Sander 2023-09-22 19:25 10811
                        const auto idx = static_cast<size_type>(array_index(reference_token));
2660ccea Poul Sander 2023-09-22 19:25 10812
                        if (idx >= ptr->size())
2660ccea Poul Sander 2023-09-22 19:25 10813
                        {
2660ccea Poul Sander 2023-09-22 19:25 10814
                            // index out of range
2660ccea Poul Sander 2023-09-22 19:25 10815
                            return false;
2660ccea Poul Sander 2023-09-22 19:25 10816
                        }
2660ccea Poul Sander 2023-09-22 19:25 10817
2660ccea Poul Sander 2023-09-22 19:25 10818
                        ptr = &ptr->operator[](idx);
2660ccea Poul Sander 2023-09-22 19:25 10819
                        break;
2660ccea Poul Sander 2023-09-22 19:25 10820
                    }
2660ccea Poul Sander 2023-09-22 19:25 10821
                    JSON_CATCH(std::invalid_argument&)
2660ccea Poul Sander 2023-09-22 19:25 10822
                    {
2660ccea Poul Sander 2023-09-22 19:25 10823
                        JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
2660ccea Poul Sander 2023-09-22 19:25 10824
                    }
2660ccea Poul Sander 2023-09-22 19:25 10825
                    break;
2660ccea Poul Sander 2023-09-22 19:25 10826
                }
2660ccea Poul Sander 2023-09-22 19:25 10827
2660ccea Poul Sander 2023-09-22 19:25 10828
                default:
2660ccea Poul Sander 2023-09-22 19:25 10829
                {
2660ccea Poul Sander 2023-09-22 19:25 10830
                    // we do not expect primitive values if there is still a
2660ccea Poul Sander 2023-09-22 19:25 10831
                    // reference token to process
2660ccea Poul Sander 2023-09-22 19:25 10832
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 10833
                }
2660ccea Poul Sander 2023-09-22 19:25 10834
            }
2660ccea Poul Sander 2023-09-22 19:25 10835
        }
2660ccea Poul Sander 2023-09-22 19:25 10836
2660ccea Poul Sander 2023-09-22 19:25 10837
        // no reference token left means we found a primitive value
2660ccea Poul Sander 2023-09-22 19:25 10838
        return true;
2660ccea Poul Sander 2023-09-22 19:25 10839
    }
2660ccea Poul Sander 2023-09-22 19:25 10840
2660ccea Poul Sander 2023-09-22 19:25 10841
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10842
    @brief split the string input to reference tokens
2660ccea Poul Sander 2023-09-22 19:25 10843
2660ccea Poul Sander 2023-09-22 19:25 10844
    @note This function is only called by the json_pointer constructor.
2660ccea Poul Sander 2023-09-22 19:25 10845
          All exceptions below are documented there.
2660ccea Poul Sander 2023-09-22 19:25 10846
2660ccea Poul Sander 2023-09-22 19:25 10847
    @throw parse_error.107  if the pointer is not empty or begins with '/'
2660ccea Poul Sander 2023-09-22 19:25 10848
    @throw parse_error.108  if character '~' is not followed by '0' or '1'
2660ccea Poul Sander 2023-09-22 19:25 10849
    */
2660ccea Poul Sander 2023-09-22 19:25 10850
    static std::vector<std::string> split(const std::string& reference_string)
2660ccea Poul Sander 2023-09-22 19:25 10851
    {
2660ccea Poul Sander 2023-09-22 19:25 10852
        std::vector<std::string> result;
2660ccea Poul Sander 2023-09-22 19:25 10853
2660ccea Poul Sander 2023-09-22 19:25 10854
        // special case: empty reference string -> no reference tokens
2660ccea Poul Sander 2023-09-22 19:25 10855
        if (reference_string.empty())
2660ccea Poul Sander 2023-09-22 19:25 10856
        {
2660ccea Poul Sander 2023-09-22 19:25 10857
            return result;
2660ccea Poul Sander 2023-09-22 19:25 10858
        }
2660ccea Poul Sander 2023-09-22 19:25 10859
2660ccea Poul Sander 2023-09-22 19:25 10860
        // check if nonempty reference string begins with slash
2660ccea Poul Sander 2023-09-22 19:25 10861
        if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
2660ccea Poul Sander 2023-09-22 19:25 10862
        {
2660ccea Poul Sander 2023-09-22 19:25 10863
            JSON_THROW(detail::parse_error::create(107, 1,
2660ccea Poul Sander 2023-09-22 19:25 10864
                                                   "JSON pointer must be empty or begin with '/' - was: '" +
2660ccea Poul Sander 2023-09-22 19:25 10865
                                                   reference_string + "'"));
2660ccea Poul Sander 2023-09-22 19:25 10866
        }
2660ccea Poul Sander 2023-09-22 19:25 10867
2660ccea Poul Sander 2023-09-22 19:25 10868
        // extract the reference tokens:
2660ccea Poul Sander 2023-09-22 19:25 10869
        // - slash: position of the last read slash (or end of string)
2660ccea Poul Sander 2023-09-22 19:25 10870
        // - start: position after the previous slash
2660ccea Poul Sander 2023-09-22 19:25 10871
        for (
2660ccea Poul Sander 2023-09-22 19:25 10872
            // search for the first slash after the first character
2660ccea Poul Sander 2023-09-22 19:25 10873
            std::size_t slash = reference_string.find_first_of('/', 1),
2660ccea Poul Sander 2023-09-22 19:25 10874
            // set the beginning of the first reference token
2660ccea Poul Sander 2023-09-22 19:25 10875
            start = 1;
2660ccea Poul Sander 2023-09-22 19:25 10876
            // we can stop if start == 0 (if slash == std::string::npos)
2660ccea Poul Sander 2023-09-22 19:25 10877
            start != 0;
2660ccea Poul Sander 2023-09-22 19:25 10878
            // set the beginning of the next reference token
2660ccea Poul Sander 2023-09-22 19:25 10879
            // (will eventually be 0 if slash == std::string::npos)
2660ccea Poul Sander 2023-09-22 19:25 10880
            start = (slash == std::string::npos) ? 0 : slash + 1,
2660ccea Poul Sander 2023-09-22 19:25 10881
            // find next slash
2660ccea Poul Sander 2023-09-22 19:25 10882
            slash = reference_string.find_first_of('/', start))
2660ccea Poul Sander 2023-09-22 19:25 10883
        {
2660ccea Poul Sander 2023-09-22 19:25 10884
            // use the text between the beginning of the reference token
2660ccea Poul Sander 2023-09-22 19:25 10885
            // (start) and the last slash (slash).
2660ccea Poul Sander 2023-09-22 19:25 10886
            auto reference_token = reference_string.substr(start, slash - start);
2660ccea Poul Sander 2023-09-22 19:25 10887
2660ccea Poul Sander 2023-09-22 19:25 10888
            // check reference tokens are properly escaped
2660ccea Poul Sander 2023-09-22 19:25 10889
            for (std::size_t pos = reference_token.find_first_of('~');
2660ccea Poul Sander 2023-09-22 19:25 10890
                    pos != std::string::npos;
2660ccea Poul Sander 2023-09-22 19:25 10891
                    pos = reference_token.find_first_of('~', pos + 1))
2660ccea Poul Sander 2023-09-22 19:25 10892
            {
2660ccea Poul Sander 2023-09-22 19:25 10893
                assert(reference_token[pos] == '~');
2660ccea Poul Sander 2023-09-22 19:25 10894
2660ccea Poul Sander 2023-09-22 19:25 10895
                // ~ must be followed by 0 or 1
2660ccea Poul Sander 2023-09-22 19:25 10896
                if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or
2660ccea Poul Sander 2023-09-22 19:25 10897
                                         (reference_token[pos + 1] != '0' and
2660ccea Poul Sander 2023-09-22 19:25 10898
                                          reference_token[pos + 1] != '1')))
2660ccea Poul Sander 2023-09-22 19:25 10899
                {
2660ccea Poul Sander 2023-09-22 19:25 10900
                    JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
2660ccea Poul Sander 2023-09-22 19:25 10901
                }
2660ccea Poul Sander 2023-09-22 19:25 10902
            }
2660ccea Poul Sander 2023-09-22 19:25 10903
2660ccea Poul Sander 2023-09-22 19:25 10904
            // finally, store the reference token
2660ccea Poul Sander 2023-09-22 19:25 10905
            unescape(reference_token);
2660ccea Poul Sander 2023-09-22 19:25 10906
            result.push_back(reference_token);
2660ccea Poul Sander 2023-09-22 19:25 10907
        }
2660ccea Poul Sander 2023-09-22 19:25 10908
2660ccea Poul Sander 2023-09-22 19:25 10909
        return result;
2660ccea Poul Sander 2023-09-22 19:25 10910
    }
2660ccea Poul Sander 2023-09-22 19:25 10911
2660ccea Poul Sander 2023-09-22 19:25 10912
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10913
    @brief replace all occurrences of a substring by another string
2660ccea Poul Sander 2023-09-22 19:25 10914
2660ccea Poul Sander 2023-09-22 19:25 10915
    @param[in,out] s  the string to manipulate; changed so that all
2660ccea Poul Sander 2023-09-22 19:25 10916
                   occurrences of @a f are replaced with @a t
2660ccea Poul Sander 2023-09-22 19:25 10917
    @param[in]     f  the substring to replace with @a t
2660ccea Poul Sander 2023-09-22 19:25 10918
    @param[in]     t  the string to replace @a f
2660ccea Poul Sander 2023-09-22 19:25 10919
2660ccea Poul Sander 2023-09-22 19:25 10920
    @pre The search string @a f must not be empty. **This precondition is
2660ccea Poul Sander 2023-09-22 19:25 10921
    enforced with an assertion.**
2660ccea Poul Sander 2023-09-22 19:25 10922
2660ccea Poul Sander 2023-09-22 19:25 10923
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 10924
    */
2660ccea Poul Sander 2023-09-22 19:25 10925
    static void replace_substring(std::string& s, const std::string& f,
2660ccea Poul Sander 2023-09-22 19:25 10926
                                  const std::string& t)
2660ccea Poul Sander 2023-09-22 19:25 10927
    {
2660ccea Poul Sander 2023-09-22 19:25 10928
        assert(not f.empty());
2660ccea Poul Sander 2023-09-22 19:25 10929
        for (auto pos = s.find(f);                // find first occurrence of f
2660ccea Poul Sander 2023-09-22 19:25 10930
                pos != std::string::npos;         // make sure f was found
2660ccea Poul Sander 2023-09-22 19:25 10931
                s.replace(pos, f.size(), t),      // replace with t, and
2660ccea Poul Sander 2023-09-22 19:25 10932
                pos = s.find(f, pos + t.size()))  // find next occurrence of f
2660ccea Poul Sander 2023-09-22 19:25 10933
        {}
2660ccea Poul Sander 2023-09-22 19:25 10934
    }
2660ccea Poul Sander 2023-09-22 19:25 10935
2660ccea Poul Sander 2023-09-22 19:25 10936
    /// escape "~" to "~0" and "/" to "~1"
2660ccea Poul Sander 2023-09-22 19:25 10937
    static std::string escape(std::string s)
2660ccea Poul Sander 2023-09-22 19:25 10938
    {
2660ccea Poul Sander 2023-09-22 19:25 10939
        replace_substring(s, "~", "~0");
2660ccea Poul Sander 2023-09-22 19:25 10940
        replace_substring(s, "/", "~1");
2660ccea Poul Sander 2023-09-22 19:25 10941
        return s;
2660ccea Poul Sander 2023-09-22 19:25 10942
    }
2660ccea Poul Sander 2023-09-22 19:25 10943
2660ccea Poul Sander 2023-09-22 19:25 10944
    /// unescape "~1" to tilde and "~0" to slash (order is important!)
2660ccea Poul Sander 2023-09-22 19:25 10945
    static void unescape(std::string& s)
2660ccea Poul Sander 2023-09-22 19:25 10946
    {
2660ccea Poul Sander 2023-09-22 19:25 10947
        replace_substring(s, "~1", "/");
2660ccea Poul Sander 2023-09-22 19:25 10948
        replace_substring(s, "~0", "~");
2660ccea Poul Sander 2023-09-22 19:25 10949
    }
2660ccea Poul Sander 2023-09-22 19:25 10950
2660ccea Poul Sander 2023-09-22 19:25 10951
    /*!
2660ccea Poul Sander 2023-09-22 19:25 10952
    @param[in] reference_string  the reference string to the current value
2660ccea Poul Sander 2023-09-22 19:25 10953
    @param[in] value             the value to consider
2660ccea Poul Sander 2023-09-22 19:25 10954
    @param[in,out] result        the result object to insert values to
2660ccea Poul Sander 2023-09-22 19:25 10955
2660ccea Poul Sander 2023-09-22 19:25 10956
    @note Empty objects or arrays are flattened to `null`.
2660ccea Poul Sander 2023-09-22 19:25 10957
    */
2660ccea Poul Sander 2023-09-22 19:25 10958
    static void flatten(const std::string& reference_string,
2660ccea Poul Sander 2023-09-22 19:25 10959
                        const BasicJsonType& value,
2660ccea Poul Sander 2023-09-22 19:25 10960
                        BasicJsonType& result)
2660ccea Poul Sander 2023-09-22 19:25 10961
    {
2660ccea Poul Sander 2023-09-22 19:25 10962
        switch (value.type())
2660ccea Poul Sander 2023-09-22 19:25 10963
        {
2660ccea Poul Sander 2023-09-22 19:25 10964
            case detail::value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 10965
            {
2660ccea Poul Sander 2023-09-22 19:25 10966
                if (value.m_value.array->empty())
2660ccea Poul Sander 2023-09-22 19:25 10967
                {
2660ccea Poul Sander 2023-09-22 19:25 10968
                    // flatten empty array as null
2660ccea Poul Sander 2023-09-22 19:25 10969
                    result[reference_string] = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 10970
                }
2660ccea Poul Sander 2023-09-22 19:25 10971
                else
2660ccea Poul Sander 2023-09-22 19:25 10972
                {
2660ccea Poul Sander 2023-09-22 19:25 10973
                    // iterate array and use index as reference string
2660ccea Poul Sander 2023-09-22 19:25 10974
                    for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
2660ccea Poul Sander 2023-09-22 19:25 10975
                    {
2660ccea Poul Sander 2023-09-22 19:25 10976
                        flatten(reference_string + "/" + std::to_string(i),
2660ccea Poul Sander 2023-09-22 19:25 10977
                                value.m_value.array->operator[](i), result);
2660ccea Poul Sander 2023-09-22 19:25 10978
                    }
2660ccea Poul Sander 2023-09-22 19:25 10979
                }
2660ccea Poul Sander 2023-09-22 19:25 10980
                break;
2660ccea Poul Sander 2023-09-22 19:25 10981
            }
2660ccea Poul Sander 2023-09-22 19:25 10982
2660ccea Poul Sander 2023-09-22 19:25 10983
            case detail::value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 10984
            {
2660ccea Poul Sander 2023-09-22 19:25 10985
                if (value.m_value.object->empty())
2660ccea Poul Sander 2023-09-22 19:25 10986
                {
2660ccea Poul Sander 2023-09-22 19:25 10987
                    // flatten empty object as null
2660ccea Poul Sander 2023-09-22 19:25 10988
                    result[reference_string] = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 10989
                }
2660ccea Poul Sander 2023-09-22 19:25 10990
                else
2660ccea Poul Sander 2023-09-22 19:25 10991
                {
2660ccea Poul Sander 2023-09-22 19:25 10992
                    // iterate object and use keys as reference string
2660ccea Poul Sander 2023-09-22 19:25 10993
                    for (const auto& element : *value.m_value.object)
2660ccea Poul Sander 2023-09-22 19:25 10994
                    {
2660ccea Poul Sander 2023-09-22 19:25 10995
                        flatten(reference_string + "/" + escape(element.first), element.second, result);
2660ccea Poul Sander 2023-09-22 19:25 10996
                    }
2660ccea Poul Sander 2023-09-22 19:25 10997
                }
2660ccea Poul Sander 2023-09-22 19:25 10998
                break;
2660ccea Poul Sander 2023-09-22 19:25 10999
            }
2660ccea Poul Sander 2023-09-22 19:25 11000
2660ccea Poul Sander 2023-09-22 19:25 11001
            default:
2660ccea Poul Sander 2023-09-22 19:25 11002
            {
2660ccea Poul Sander 2023-09-22 19:25 11003
                // add primitive value with its reference string
2660ccea Poul Sander 2023-09-22 19:25 11004
                result[reference_string] = value;
2660ccea Poul Sander 2023-09-22 19:25 11005
                break;
2660ccea Poul Sander 2023-09-22 19:25 11006
            }
2660ccea Poul Sander 2023-09-22 19:25 11007
        }
2660ccea Poul Sander 2023-09-22 19:25 11008
    }
2660ccea Poul Sander 2023-09-22 19:25 11009
2660ccea Poul Sander 2023-09-22 19:25 11010
    /*!
2660ccea Poul Sander 2023-09-22 19:25 11011
    @param[in] value  flattened JSON
2660ccea Poul Sander 2023-09-22 19:25 11012
2660ccea Poul Sander 2023-09-22 19:25 11013
    @return unflattened JSON
2660ccea Poul Sander 2023-09-22 19:25 11014
2660ccea Poul Sander 2023-09-22 19:25 11015
    @throw parse_error.109 if array index is not a number
2660ccea Poul Sander 2023-09-22 19:25 11016
    @throw type_error.314  if value is not an object
2660ccea Poul Sander 2023-09-22 19:25 11017
    @throw type_error.315  if object values are not primitive
2660ccea Poul Sander 2023-09-22 19:25 11018
    @throw type_error.313  if value cannot be unflattened
2660ccea Poul Sander 2023-09-22 19:25 11019
    */
2660ccea Poul Sander 2023-09-22 19:25 11020
    static BasicJsonType
2660ccea Poul Sander 2023-09-22 19:25 11021
    unflatten(const BasicJsonType& value)
2660ccea Poul Sander 2023-09-22 19:25 11022
    {
2660ccea Poul Sander 2023-09-22 19:25 11023
        if (JSON_HEDLEY_UNLIKELY(not value.is_object()))
2660ccea Poul Sander 2023-09-22 19:25 11024
        {
2660ccea Poul Sander 2023-09-22 19:25 11025
            JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
2660ccea Poul Sander 2023-09-22 19:25 11026
        }
2660ccea Poul Sander 2023-09-22 19:25 11027
2660ccea Poul Sander 2023-09-22 19:25 11028
        BasicJsonType result;
2660ccea Poul Sander 2023-09-22 19:25 11029
2660ccea Poul Sander 2023-09-22 19:25 11030
        // iterate the JSON object values
2660ccea Poul Sander 2023-09-22 19:25 11031
        for (const auto& element : *value.m_value.object)
2660ccea Poul Sander 2023-09-22 19:25 11032
        {
2660ccea Poul Sander 2023-09-22 19:25 11033
            if (JSON_HEDLEY_UNLIKELY(not element.second.is_primitive()))
2660ccea Poul Sander 2023-09-22 19:25 11034
            {
2660ccea Poul Sander 2023-09-22 19:25 11035
                JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
2660ccea Poul Sander 2023-09-22 19:25 11036
            }
2660ccea Poul Sander 2023-09-22 19:25 11037
2660ccea Poul Sander 2023-09-22 19:25 11038
            // assign value to reference pointed to by JSON pointer; Note that if
2660ccea Poul Sander 2023-09-22 19:25 11039
            // the JSON pointer is "" (i.e., points to the whole value), function
2660ccea Poul Sander 2023-09-22 19:25 11040
            // get_and_create returns a reference to result itself. An assignment
2660ccea Poul Sander 2023-09-22 19:25 11041
            // will then create a primitive value.
2660ccea Poul Sander 2023-09-22 19:25 11042
            json_pointer(element.first).get_and_create(result) = element.second;
2660ccea Poul Sander 2023-09-22 19:25 11043
        }
2660ccea Poul Sander 2023-09-22 19:25 11044
2660ccea Poul Sander 2023-09-22 19:25 11045
        return result;
2660ccea Poul Sander 2023-09-22 19:25 11046
    }
2660ccea Poul Sander 2023-09-22 19:25 11047
2660ccea Poul Sander 2023-09-22 19:25 11048
    /*!
2660ccea Poul Sander 2023-09-22 19:25 11049
    @brief compares two JSON pointers for equality
2660ccea Poul Sander 2023-09-22 19:25 11050
2660ccea Poul Sander 2023-09-22 19:25 11051
    @param[in] lhs  JSON pointer to compare
2660ccea Poul Sander 2023-09-22 19:25 11052
    @param[in] rhs  JSON pointer to compare
2660ccea Poul Sander 2023-09-22 19:25 11053
    @return whether @a lhs is equal to @a rhs
2660ccea Poul Sander 2023-09-22 19:25 11054
2660ccea Poul Sander 2023-09-22 19:25 11055
    @complexity Linear in the length of the JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 11056
2660ccea Poul Sander 2023-09-22 19:25 11057
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 11058
    */
2660ccea Poul Sander 2023-09-22 19:25 11059
    friend bool operator==(json_pointer const& lhs,
2660ccea Poul Sander 2023-09-22 19:25 11060
                           json_pointer const& rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 11061
    {
2660ccea Poul Sander 2023-09-22 19:25 11062
        return lhs.reference_tokens == rhs.reference_tokens;
2660ccea Poul Sander 2023-09-22 19:25 11063
    }
2660ccea Poul Sander 2023-09-22 19:25 11064
2660ccea Poul Sander 2023-09-22 19:25 11065
    /*!
2660ccea Poul Sander 2023-09-22 19:25 11066
    @brief compares two JSON pointers for inequality
2660ccea Poul Sander 2023-09-22 19:25 11067
2660ccea Poul Sander 2023-09-22 19:25 11068
    @param[in] lhs  JSON pointer to compare
2660ccea Poul Sander 2023-09-22 19:25 11069
    @param[in] rhs  JSON pointer to compare
2660ccea Poul Sander 2023-09-22 19:25 11070
    @return whether @a lhs is not equal @a rhs
2660ccea Poul Sander 2023-09-22 19:25 11071
2660ccea Poul Sander 2023-09-22 19:25 11072
    @complexity Linear in the length of the JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 11073
2660ccea Poul Sander 2023-09-22 19:25 11074
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 11075
    */
2660ccea Poul Sander 2023-09-22 19:25 11076
    friend bool operator!=(json_pointer const& lhs,
2660ccea Poul Sander 2023-09-22 19:25 11077
                           json_pointer const& rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 11078
    {
2660ccea Poul Sander 2023-09-22 19:25 11079
        return not (lhs == rhs);
2660ccea Poul Sander 2023-09-22 19:25 11080
    }
2660ccea Poul Sander 2023-09-22 19:25 11081
2660ccea Poul Sander 2023-09-22 19:25 11082
    /// the reference tokens
2660ccea Poul Sander 2023-09-22 19:25 11083
    std::vector<std::string> reference_tokens;
2660ccea Poul Sander 2023-09-22 19:25 11084
};
2660ccea Poul Sander 2023-09-22 19:25 11085
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 11086
2660ccea Poul Sander 2023-09-22 19:25 11087
// #include <nlohmann/detail/json_ref.hpp>
2660ccea Poul Sander 2023-09-22 19:25 11088
2660ccea Poul Sander 2023-09-22 19:25 11089
2660ccea Poul Sander 2023-09-22 19:25 11090
#include <initializer_list>
2660ccea Poul Sander 2023-09-22 19:25 11091
#include <utility>
2660ccea Poul Sander 2023-09-22 19:25 11092
2660ccea Poul Sander 2023-09-22 19:25 11093
// #include <nlohmann/detail/meta/type_traits.hpp>
2660ccea Poul Sander 2023-09-22 19:25 11094
2660ccea Poul Sander 2023-09-22 19:25 11095
2660ccea Poul Sander 2023-09-22 19:25 11096
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 11097
{
2660ccea Poul Sander 2023-09-22 19:25 11098
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 11099
{
2660ccea Poul Sander 2023-09-22 19:25 11100
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 11101
class json_ref
2660ccea Poul Sander 2023-09-22 19:25 11102
{
2660ccea Poul Sander 2023-09-22 19:25 11103
  public:
2660ccea Poul Sander 2023-09-22 19:25 11104
    using value_type = BasicJsonType;
2660ccea Poul Sander 2023-09-22 19:25 11105
2660ccea Poul Sander 2023-09-22 19:25 11106
    json_ref(value_type&& value)
2660ccea Poul Sander 2023-09-22 19:25 11107
        : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
2660ccea Poul Sander 2023-09-22 19:25 11108
    {}
2660ccea Poul Sander 2023-09-22 19:25 11109
2660ccea Poul Sander 2023-09-22 19:25 11110
    json_ref(const value_type& value)
2660ccea Poul Sander 2023-09-22 19:25 11111
        : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
2660ccea Poul Sander 2023-09-22 19:25 11112
    {}
2660ccea Poul Sander 2023-09-22 19:25 11113
2660ccea Poul Sander 2023-09-22 19:25 11114
    json_ref(std::initializer_list<json_ref> init)
2660ccea Poul Sander 2023-09-22 19:25 11115
        : owned_value(init), value_ref(&owned_value), is_rvalue(true)
2660ccea Poul Sander 2023-09-22 19:25 11116
    {}
2660ccea Poul Sander 2023-09-22 19:25 11117
2660ccea Poul Sander 2023-09-22 19:25 11118
    template <
2660ccea Poul Sander 2023-09-22 19:25 11119
        class... Args,
2660ccea Poul Sander 2023-09-22 19:25 11120
        enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
2660ccea Poul Sander 2023-09-22 19:25 11121
    json_ref(Args && ... args)
2660ccea Poul Sander 2023-09-22 19:25 11122
        : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
2660ccea Poul Sander 2023-09-22 19:25 11123
          is_rvalue(true) {}
2660ccea Poul Sander 2023-09-22 19:25 11124
2660ccea Poul Sander 2023-09-22 19:25 11125
    // class should be movable only
2660ccea Poul Sander 2023-09-22 19:25 11126
    json_ref(json_ref&&) = default;
2660ccea Poul Sander 2023-09-22 19:25 11127
    json_ref(const json_ref&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 11128
    json_ref& operator=(const json_ref&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 11129
    json_ref& operator=(json_ref&&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 11130
    ~json_ref() = default;
2660ccea Poul Sander 2023-09-22 19:25 11131
2660ccea Poul Sander 2023-09-22 19:25 11132
    value_type moved_or_copied() const
2660ccea Poul Sander 2023-09-22 19:25 11133
    {
2660ccea Poul Sander 2023-09-22 19:25 11134
        if (is_rvalue)
2660ccea Poul Sander 2023-09-22 19:25 11135
        {
2660ccea Poul Sander 2023-09-22 19:25 11136
            return std::move(*value_ref);
2660ccea Poul Sander 2023-09-22 19:25 11137
        }
2660ccea Poul Sander 2023-09-22 19:25 11138
        return *value_ref;
2660ccea Poul Sander 2023-09-22 19:25 11139
    }
2660ccea Poul Sander 2023-09-22 19:25 11140
2660ccea Poul Sander 2023-09-22 19:25 11141
    value_type const& operator*() const
2660ccea Poul Sander 2023-09-22 19:25 11142
    {
2660ccea Poul Sander 2023-09-22 19:25 11143
        return *static_cast<value_type const*>(value_ref);
2660ccea Poul Sander 2023-09-22 19:25 11144
    }
2660ccea Poul Sander 2023-09-22 19:25 11145
2660ccea Poul Sander 2023-09-22 19:25 11146
    value_type const* operator->() const
2660ccea Poul Sander 2023-09-22 19:25 11147
    {
2660ccea Poul Sander 2023-09-22 19:25 11148
        return static_cast<value_type const*>(value_ref);
2660ccea Poul Sander 2023-09-22 19:25 11149
    }
2660ccea Poul Sander 2023-09-22 19:25 11150
2660ccea Poul Sander 2023-09-22 19:25 11151
  private:
2660ccea Poul Sander 2023-09-22 19:25 11152
    mutable value_type owned_value = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 11153
    value_type* value_ref = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 11154
    const bool is_rvalue;
2660ccea Poul Sander 2023-09-22 19:25 11155
};
2660ccea Poul Sander 2023-09-22 19:25 11156
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 11157
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 11158
2660ccea Poul Sander 2023-09-22 19:25 11159
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 11160
2660ccea Poul Sander 2023-09-22 19:25 11161
// #include <nlohmann/detail/meta/cpp_future.hpp>
2660ccea Poul Sander 2023-09-22 19:25 11162
2660ccea Poul Sander 2023-09-22 19:25 11163
// #include <nlohmann/detail/meta/type_traits.hpp>
2660ccea Poul Sander 2023-09-22 19:25 11164
2660ccea Poul Sander 2023-09-22 19:25 11165
// #include <nlohmann/detail/output/binary_writer.hpp>
2660ccea Poul Sander 2023-09-22 19:25 11166
2660ccea Poul Sander 2023-09-22 19:25 11167
2660ccea Poul Sander 2023-09-22 19:25 11168
#include <algorithm> // reverse
2660ccea Poul Sander 2023-09-22 19:25 11169
#include <array> // array
2660ccea Poul Sander 2023-09-22 19:25 11170
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
2660ccea Poul Sander 2023-09-22 19:25 11171
#include <cstring> // memcpy
2660ccea Poul Sander 2023-09-22 19:25 11172
#include <limits> // numeric_limits
2660ccea Poul Sander 2023-09-22 19:25 11173
#include <string> // string
2660ccea Poul Sander 2023-09-22 19:25 11174
2660ccea Poul Sander 2023-09-22 19:25 11175
// #include <nlohmann/detail/input/binary_reader.hpp>
2660ccea Poul Sander 2023-09-22 19:25 11176
2660ccea Poul Sander 2023-09-22 19:25 11177
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 11178
2660ccea Poul Sander 2023-09-22 19:25 11179
// #include <nlohmann/detail/output/output_adapters.hpp>
2660ccea Poul Sander 2023-09-22 19:25 11180
2660ccea Poul Sander 2023-09-22 19:25 11181
2660ccea Poul Sander 2023-09-22 19:25 11182
#include <algorithm> // copy
2660ccea Poul Sander 2023-09-22 19:25 11183
#include <cstddef> // size_t
2660ccea Poul Sander 2023-09-22 19:25 11184
#include <ios> // streamsize
2660ccea Poul Sander 2023-09-22 19:25 11185
#include <iterator> // back_inserter
2660ccea Poul Sander 2023-09-22 19:25 11186
#include <memory> // shared_ptr, make_shared
2660ccea Poul Sander 2023-09-22 19:25 11187
#include <ostream> // basic_ostream
2660ccea Poul Sander 2023-09-22 19:25 11188
#include <string> // basic_string
2660ccea Poul Sander 2023-09-22 19:25 11189
#include <vector> // vector
2660ccea Poul Sander 2023-09-22 19:25 11190
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 11191
2660ccea Poul Sander 2023-09-22 19:25 11192
2660ccea Poul Sander 2023-09-22 19:25 11193
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 11194
{
2660ccea Poul Sander 2023-09-22 19:25 11195
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 11196
{
2660ccea Poul Sander 2023-09-22 19:25 11197
/// abstract output adapter interface
2660ccea Poul Sander 2023-09-22 19:25 11198
template<typename CharType> struct output_adapter_protocol
2660ccea Poul Sander 2023-09-22 19:25 11199
{
2660ccea Poul Sander 2023-09-22 19:25 11200
    virtual void write_character(CharType c) = 0;
2660ccea Poul Sander 2023-09-22 19:25 11201
    virtual void write_characters(const CharType* s, std::size_t length) = 0;
2660ccea Poul Sander 2023-09-22 19:25 11202
    virtual ~output_adapter_protocol() = default;
2660ccea Poul Sander 2023-09-22 19:25 11203
};
2660ccea Poul Sander 2023-09-22 19:25 11204
2660ccea Poul Sander 2023-09-22 19:25 11205
/// a type to simplify interfaces
2660ccea Poul Sander 2023-09-22 19:25 11206
template<typename CharType>
2660ccea Poul Sander 2023-09-22 19:25 11207
using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
2660ccea Poul Sander 2023-09-22 19:25 11208
2660ccea Poul Sander 2023-09-22 19:25 11209
/// output adapter for byte vectors
2660ccea Poul Sander 2023-09-22 19:25 11210
template<typename CharType>
2660ccea Poul Sander 2023-09-22 19:25 11211
class output_vector_adapter : public output_adapter_protocol<CharType>
2660ccea Poul Sander 2023-09-22 19:25 11212
{
2660ccea Poul Sander 2023-09-22 19:25 11213
  public:
2660ccea Poul Sander 2023-09-22 19:25 11214
    explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
2660ccea Poul Sander 2023-09-22 19:25 11215
        : v(vec)
2660ccea Poul Sander 2023-09-22 19:25 11216
    {}
2660ccea Poul Sander 2023-09-22 19:25 11217
2660ccea Poul Sander 2023-09-22 19:25 11218
    void write_character(CharType c) override
2660ccea Poul Sander 2023-09-22 19:25 11219
    {
2660ccea Poul Sander 2023-09-22 19:25 11220
        v.push_back(c);
2660ccea Poul Sander 2023-09-22 19:25 11221
    }
2660ccea Poul Sander 2023-09-22 19:25 11222
2660ccea Poul Sander 2023-09-22 19:25 11223
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 11224
    void write_characters(const CharType* s, std::size_t length) override
2660ccea Poul Sander 2023-09-22 19:25 11225
    {
2660ccea Poul Sander 2023-09-22 19:25 11226
        std::copy(s, s + length, std::back_inserter(v));
2660ccea Poul Sander 2023-09-22 19:25 11227
    }
2660ccea Poul Sander 2023-09-22 19:25 11228
2660ccea Poul Sander 2023-09-22 19:25 11229
  private:
2660ccea Poul Sander 2023-09-22 19:25 11230
    std::vector<CharType>& v;
2660ccea Poul Sander 2023-09-22 19:25 11231
};
2660ccea Poul Sander 2023-09-22 19:25 11232
2660ccea Poul Sander 2023-09-22 19:25 11233
/// output adapter for output streams
2660ccea Poul Sander 2023-09-22 19:25 11234
template<typename CharType>
2660ccea Poul Sander 2023-09-22 19:25 11235
class output_stream_adapter : public output_adapter_protocol<CharType>
2660ccea Poul Sander 2023-09-22 19:25 11236
{
2660ccea Poul Sander 2023-09-22 19:25 11237
  public:
2660ccea Poul Sander 2023-09-22 19:25 11238
    explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
2660ccea Poul Sander 2023-09-22 19:25 11239
        : stream(s)
2660ccea Poul Sander 2023-09-22 19:25 11240
    {}
2660ccea Poul Sander 2023-09-22 19:25 11241
2660ccea Poul Sander 2023-09-22 19:25 11242
    void write_character(CharType c) override
2660ccea Poul Sander 2023-09-22 19:25 11243
    {
2660ccea Poul Sander 2023-09-22 19:25 11244
        stream.put(c);
2660ccea Poul Sander 2023-09-22 19:25 11245
    }
2660ccea Poul Sander 2023-09-22 19:25 11246
2660ccea Poul Sander 2023-09-22 19:25 11247
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 11248
    void write_characters(const CharType* s, std::size_t length) override
2660ccea Poul Sander 2023-09-22 19:25 11249
    {
2660ccea Poul Sander 2023-09-22 19:25 11250
        stream.write(s, static_cast<std::streamsize>(length));
2660ccea Poul Sander 2023-09-22 19:25 11251
    }
2660ccea Poul Sander 2023-09-22 19:25 11252
2660ccea Poul Sander 2023-09-22 19:25 11253
  private:
2660ccea Poul Sander 2023-09-22 19:25 11254
    std::basic_ostream<CharType>& stream;
2660ccea Poul Sander 2023-09-22 19:25 11255
};
2660ccea Poul Sander 2023-09-22 19:25 11256
2660ccea Poul Sander 2023-09-22 19:25 11257
/// output adapter for basic_string
2660ccea Poul Sander 2023-09-22 19:25 11258
template<typename CharType, typename StringType = std::basic_string<CharType>>
2660ccea Poul Sander 2023-09-22 19:25 11259
class output_string_adapter : public output_adapter_protocol<CharType>
2660ccea Poul Sander 2023-09-22 19:25 11260
{
2660ccea Poul Sander 2023-09-22 19:25 11261
  public:
2660ccea Poul Sander 2023-09-22 19:25 11262
    explicit output_string_adapter(StringType& s) noexcept
2660ccea Poul Sander 2023-09-22 19:25 11263
        : str(s)
2660ccea Poul Sander 2023-09-22 19:25 11264
    {}
2660ccea Poul Sander 2023-09-22 19:25 11265
2660ccea Poul Sander 2023-09-22 19:25 11266
    void write_character(CharType c) override
2660ccea Poul Sander 2023-09-22 19:25 11267
    {
2660ccea Poul Sander 2023-09-22 19:25 11268
        str.push_back(c);
2660ccea Poul Sander 2023-09-22 19:25 11269
    }
2660ccea Poul Sander 2023-09-22 19:25 11270
2660ccea Poul Sander 2023-09-22 19:25 11271
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 11272
    void write_characters(const CharType* s, std::size_t length) override
2660ccea Poul Sander 2023-09-22 19:25 11273
    {
2660ccea Poul Sander 2023-09-22 19:25 11274
        str.append(s, length);
2660ccea Poul Sander 2023-09-22 19:25 11275
    }
2660ccea Poul Sander 2023-09-22 19:25 11276
2660ccea Poul Sander 2023-09-22 19:25 11277
  private:
2660ccea Poul Sander 2023-09-22 19:25 11278
    StringType& str;
2660ccea Poul Sander 2023-09-22 19:25 11279
};
2660ccea Poul Sander 2023-09-22 19:25 11280
2660ccea Poul Sander 2023-09-22 19:25 11281
template<typename CharType, typename StringType = std::basic_string<CharType>>
2660ccea Poul Sander 2023-09-22 19:25 11282
class output_adapter
2660ccea Poul Sander 2023-09-22 19:25 11283
{
2660ccea Poul Sander 2023-09-22 19:25 11284
  public:
2660ccea Poul Sander 2023-09-22 19:25 11285
    output_adapter(std::vector<CharType>& vec)
2660ccea Poul Sander 2023-09-22 19:25 11286
        : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
2660ccea Poul Sander 2023-09-22 19:25 11287
2660ccea Poul Sander 2023-09-22 19:25 11288
    output_adapter(std::basic_ostream<CharType>& s)
2660ccea Poul Sander 2023-09-22 19:25 11289
        : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
2660ccea Poul Sander 2023-09-22 19:25 11290
2660ccea Poul Sander 2023-09-22 19:25 11291
    output_adapter(StringType& s)
2660ccea Poul Sander 2023-09-22 19:25 11292
        : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
2660ccea Poul Sander 2023-09-22 19:25 11293
2660ccea Poul Sander 2023-09-22 19:25 11294
    operator output_adapter_t<CharType>()
2660ccea Poul Sander 2023-09-22 19:25 11295
    {
2660ccea Poul Sander 2023-09-22 19:25 11296
        return oa;
2660ccea Poul Sander 2023-09-22 19:25 11297
    }
2660ccea Poul Sander 2023-09-22 19:25 11298
2660ccea Poul Sander 2023-09-22 19:25 11299
  private:
2660ccea Poul Sander 2023-09-22 19:25 11300
    output_adapter_t<CharType> oa = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 11301
};
2660ccea Poul Sander 2023-09-22 19:25 11302
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 11303
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 11304
2660ccea Poul Sander 2023-09-22 19:25 11305
2660ccea Poul Sander 2023-09-22 19:25 11306
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 11307
{
2660ccea Poul Sander 2023-09-22 19:25 11308
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 11309
{
2660ccea Poul Sander 2023-09-22 19:25 11310
///////////////////
2660ccea Poul Sander 2023-09-22 19:25 11311
// binary writer //
2660ccea Poul Sander 2023-09-22 19:25 11312
///////////////////
2660ccea Poul Sander 2023-09-22 19:25 11313
2660ccea Poul Sander 2023-09-22 19:25 11314
/*!
2660ccea Poul Sander 2023-09-22 19:25 11315
@brief serialization to CBOR and MessagePack values
2660ccea Poul Sander 2023-09-22 19:25 11316
*/
2660ccea Poul Sander 2023-09-22 19:25 11317
template<typename BasicJsonType, typename CharType>
2660ccea Poul Sander 2023-09-22 19:25 11318
class binary_writer
2660ccea Poul Sander 2023-09-22 19:25 11319
{
2660ccea Poul Sander 2023-09-22 19:25 11320
    using string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 11321
2660ccea Poul Sander 2023-09-22 19:25 11322
  public:
2660ccea Poul Sander 2023-09-22 19:25 11323
    /*!
2660ccea Poul Sander 2023-09-22 19:25 11324
    @brief create a binary writer
2660ccea Poul Sander 2023-09-22 19:25 11325
2660ccea Poul Sander 2023-09-22 19:25 11326
    @param[in] adapter  output adapter to write to
2660ccea Poul Sander 2023-09-22 19:25 11327
    */
2660ccea Poul Sander 2023-09-22 19:25 11328
    explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
2660ccea Poul Sander 2023-09-22 19:25 11329
    {
2660ccea Poul Sander 2023-09-22 19:25 11330
        assert(oa);
2660ccea Poul Sander 2023-09-22 19:25 11331
    }
2660ccea Poul Sander 2023-09-22 19:25 11332
2660ccea Poul Sander 2023-09-22 19:25 11333
    /*!
2660ccea Poul Sander 2023-09-22 19:25 11334
    @param[in] j  JSON value to serialize
2660ccea Poul Sander 2023-09-22 19:25 11335
    @pre       j.type() == value_t::object
2660ccea Poul Sander 2023-09-22 19:25 11336
    */
2660ccea Poul Sander 2023-09-22 19:25 11337
    void write_bson(const BasicJsonType& j)
2660ccea Poul Sander 2023-09-22 19:25 11338
    {
2660ccea Poul Sander 2023-09-22 19:25 11339
        switch (j.type())
2660ccea Poul Sander 2023-09-22 19:25 11340
        {
2660ccea Poul Sander 2023-09-22 19:25 11341
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 11342
            {
2660ccea Poul Sander 2023-09-22 19:25 11343
                write_bson_object(*j.m_value.object);
2660ccea Poul Sander 2023-09-22 19:25 11344
                break;
2660ccea Poul Sander 2023-09-22 19:25 11345
            }
2660ccea Poul Sander 2023-09-22 19:25 11346
2660ccea Poul Sander 2023-09-22 19:25 11347
            default:
2660ccea Poul Sander 2023-09-22 19:25 11348
            {
2660ccea Poul Sander 2023-09-22 19:25 11349
                JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 11350
            }
2660ccea Poul Sander 2023-09-22 19:25 11351
        }
2660ccea Poul Sander 2023-09-22 19:25 11352
    }
2660ccea Poul Sander 2023-09-22 19:25 11353
2660ccea Poul Sander 2023-09-22 19:25 11354
    /*!
2660ccea Poul Sander 2023-09-22 19:25 11355
    @param[in] j  JSON value to serialize
2660ccea Poul Sander 2023-09-22 19:25 11356
    */
2660ccea Poul Sander 2023-09-22 19:25 11357
    void write_cbor(const BasicJsonType& j)
2660ccea Poul Sander 2023-09-22 19:25 11358
    {
2660ccea Poul Sander 2023-09-22 19:25 11359
        switch (j.type())
2660ccea Poul Sander 2023-09-22 19:25 11360
        {
2660ccea Poul Sander 2023-09-22 19:25 11361
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 11362
            {
2660ccea Poul Sander 2023-09-22 19:25 11363
                oa->write_character(to_char_type(0xF6));
2660ccea Poul Sander 2023-09-22 19:25 11364
                break;
2660ccea Poul Sander 2023-09-22 19:25 11365
            }
2660ccea Poul Sander 2023-09-22 19:25 11366
2660ccea Poul Sander 2023-09-22 19:25 11367
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 11368
            {
2660ccea Poul Sander 2023-09-22 19:25 11369
                oa->write_character(j.m_value.boolean
2660ccea Poul Sander 2023-09-22 19:25 11370
                                    ? to_char_type(0xF5)
2660ccea Poul Sander 2023-09-22 19:25 11371
                                    : to_char_type(0xF4));
2660ccea Poul Sander 2023-09-22 19:25 11372
                break;
2660ccea Poul Sander 2023-09-22 19:25 11373
            }
2660ccea Poul Sander 2023-09-22 19:25 11374
2660ccea Poul Sander 2023-09-22 19:25 11375
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 11376
            {
2660ccea Poul Sander 2023-09-22 19:25 11377
                if (j.m_value.number_integer >= 0)
2660ccea Poul Sander 2023-09-22 19:25 11378
                {
2660ccea Poul Sander 2023-09-22 19:25 11379
                    // CBOR does not differentiate between positive signed
2660ccea Poul Sander 2023-09-22 19:25 11380
                    // integers and unsigned integers. Therefore, we used the
2660ccea Poul Sander 2023-09-22 19:25 11381
                    // code from the value_t::number_unsigned case here.
2660ccea Poul Sander 2023-09-22 19:25 11382
                    if (j.m_value.number_integer <= 0x17)
2660ccea Poul Sander 2023-09-22 19:25 11383
                    {
2660ccea Poul Sander 2023-09-22 19:25 11384
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11385
                    }
2660ccea Poul Sander 2023-09-22 19:25 11386
                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11387
                    {
2660ccea Poul Sander 2023-09-22 19:25 11388
                        oa->write_character(to_char_type(0x18));
2660ccea Poul Sander 2023-09-22 19:25 11389
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11390
                    }
2660ccea Poul Sander 2023-09-22 19:25 11391
                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11392
                    {
2660ccea Poul Sander 2023-09-22 19:25 11393
                        oa->write_character(to_char_type(0x19));
2660ccea Poul Sander 2023-09-22 19:25 11394
                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11395
                    }
2660ccea Poul Sander 2023-09-22 19:25 11396
                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11397
                    {
2660ccea Poul Sander 2023-09-22 19:25 11398
                        oa->write_character(to_char_type(0x1A));
2660ccea Poul Sander 2023-09-22 19:25 11399
                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11400
                    }
2660ccea Poul Sander 2023-09-22 19:25 11401
                    else
2660ccea Poul Sander 2023-09-22 19:25 11402
                    {
2660ccea Poul Sander 2023-09-22 19:25 11403
                        oa->write_character(to_char_type(0x1B));
2660ccea Poul Sander 2023-09-22 19:25 11404
                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11405
                    }
2660ccea Poul Sander 2023-09-22 19:25 11406
                }
2660ccea Poul Sander 2023-09-22 19:25 11407
                else
2660ccea Poul Sander 2023-09-22 19:25 11408
                {
2660ccea Poul Sander 2023-09-22 19:25 11409
                    // The conversions below encode the sign in the first
2660ccea Poul Sander 2023-09-22 19:25 11410
                    // byte, and the value is converted to a positive number.
2660ccea Poul Sander 2023-09-22 19:25 11411
                    const auto positive_number = -1 - j.m_value.number_integer;
2660ccea Poul Sander 2023-09-22 19:25 11412
                    if (j.m_value.number_integer >= -24)
2660ccea Poul Sander 2023-09-22 19:25 11413
                    {
2660ccea Poul Sander 2023-09-22 19:25 11414
                        write_number(static_cast<std::uint8_t>(0x20 + positive_number));
2660ccea Poul Sander 2023-09-22 19:25 11415
                    }
2660ccea Poul Sander 2023-09-22 19:25 11416
                    else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11417
                    {
2660ccea Poul Sander 2023-09-22 19:25 11418
                        oa->write_character(to_char_type(0x38));
2660ccea Poul Sander 2023-09-22 19:25 11419
                        write_number(static_cast<std::uint8_t>(positive_number));
2660ccea Poul Sander 2023-09-22 19:25 11420
                    }
2660ccea Poul Sander 2023-09-22 19:25 11421
                    else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11422
                    {
2660ccea Poul Sander 2023-09-22 19:25 11423
                        oa->write_character(to_char_type(0x39));
2660ccea Poul Sander 2023-09-22 19:25 11424
                        write_number(static_cast<std::uint16_t>(positive_number));
2660ccea Poul Sander 2023-09-22 19:25 11425
                    }
2660ccea Poul Sander 2023-09-22 19:25 11426
                    else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11427
                    {
2660ccea Poul Sander 2023-09-22 19:25 11428
                        oa->write_character(to_char_type(0x3A));
2660ccea Poul Sander 2023-09-22 19:25 11429
                        write_number(static_cast<std::uint32_t>(positive_number));
2660ccea Poul Sander 2023-09-22 19:25 11430
                    }
2660ccea Poul Sander 2023-09-22 19:25 11431
                    else
2660ccea Poul Sander 2023-09-22 19:25 11432
                    {
2660ccea Poul Sander 2023-09-22 19:25 11433
                        oa->write_character(to_char_type(0x3B));
2660ccea Poul Sander 2023-09-22 19:25 11434
                        write_number(static_cast<std::uint64_t>(positive_number));
2660ccea Poul Sander 2023-09-22 19:25 11435
                    }
2660ccea Poul Sander 2023-09-22 19:25 11436
                }
2660ccea Poul Sander 2023-09-22 19:25 11437
                break;
2660ccea Poul Sander 2023-09-22 19:25 11438
            }
2660ccea Poul Sander 2023-09-22 19:25 11439
2660ccea Poul Sander 2023-09-22 19:25 11440
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 11441
            {
2660ccea Poul Sander 2023-09-22 19:25 11442
                if (j.m_value.number_unsigned <= 0x17)
2660ccea Poul Sander 2023-09-22 19:25 11443
                {
2660ccea Poul Sander 2023-09-22 19:25 11444
                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
2660ccea Poul Sander 2023-09-22 19:25 11445
                }
2660ccea Poul Sander 2023-09-22 19:25 11446
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11447
                {
2660ccea Poul Sander 2023-09-22 19:25 11448
                    oa->write_character(to_char_type(0x18));
2660ccea Poul Sander 2023-09-22 19:25 11449
                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
2660ccea Poul Sander 2023-09-22 19:25 11450
                }
2660ccea Poul Sander 2023-09-22 19:25 11451
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11452
                {
2660ccea Poul Sander 2023-09-22 19:25 11453
                    oa->write_character(to_char_type(0x19));
2660ccea Poul Sander 2023-09-22 19:25 11454
                    write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
2660ccea Poul Sander 2023-09-22 19:25 11455
                }
2660ccea Poul Sander 2023-09-22 19:25 11456
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11457
                {
2660ccea Poul Sander 2023-09-22 19:25 11458
                    oa->write_character(to_char_type(0x1A));
2660ccea Poul Sander 2023-09-22 19:25 11459
                    write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
2660ccea Poul Sander 2023-09-22 19:25 11460
                }
2660ccea Poul Sander 2023-09-22 19:25 11461
                else
2660ccea Poul Sander 2023-09-22 19:25 11462
                {
2660ccea Poul Sander 2023-09-22 19:25 11463
                    oa->write_character(to_char_type(0x1B));
2660ccea Poul Sander 2023-09-22 19:25 11464
                    write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
2660ccea Poul Sander 2023-09-22 19:25 11465
                }
2660ccea Poul Sander 2023-09-22 19:25 11466
                break;
2660ccea Poul Sander 2023-09-22 19:25 11467
            }
2660ccea Poul Sander 2023-09-22 19:25 11468
2660ccea Poul Sander 2023-09-22 19:25 11469
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 11470
            {
2660ccea Poul Sander 2023-09-22 19:25 11471
                oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
2660ccea Poul Sander 2023-09-22 19:25 11472
                write_number(j.m_value.number_float);
2660ccea Poul Sander 2023-09-22 19:25 11473
                break;
2660ccea Poul Sander 2023-09-22 19:25 11474
            }
2660ccea Poul Sander 2023-09-22 19:25 11475
2660ccea Poul Sander 2023-09-22 19:25 11476
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 11477
            {
2660ccea Poul Sander 2023-09-22 19:25 11478
                // step 1: write control byte and the string length
2660ccea Poul Sander 2023-09-22 19:25 11479
                const auto N = j.m_value.string->size();
2660ccea Poul Sander 2023-09-22 19:25 11480
                if (N <= 0x17)
2660ccea Poul Sander 2023-09-22 19:25 11481
                {
2660ccea Poul Sander 2023-09-22 19:25 11482
                    write_number(static_cast<std::uint8_t>(0x60 + N));
2660ccea Poul Sander 2023-09-22 19:25 11483
                }
2660ccea Poul Sander 2023-09-22 19:25 11484
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11485
                {
2660ccea Poul Sander 2023-09-22 19:25 11486
                    oa->write_character(to_char_type(0x78));
2660ccea Poul Sander 2023-09-22 19:25 11487
                    write_number(static_cast<std::uint8_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11488
                }
2660ccea Poul Sander 2023-09-22 19:25 11489
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11490
                {
2660ccea Poul Sander 2023-09-22 19:25 11491
                    oa->write_character(to_char_type(0x79));
2660ccea Poul Sander 2023-09-22 19:25 11492
                    write_number(static_cast<std::uint16_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11493
                }
2660ccea Poul Sander 2023-09-22 19:25 11494
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11495
                {
2660ccea Poul Sander 2023-09-22 19:25 11496
                    oa->write_character(to_char_type(0x7A));
2660ccea Poul Sander 2023-09-22 19:25 11497
                    write_number(static_cast<std::uint32_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11498
                }
2660ccea Poul Sander 2023-09-22 19:25 11499
                // LCOV_EXCL_START
2660ccea Poul Sander 2023-09-22 19:25 11500
                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11501
                {
2660ccea Poul Sander 2023-09-22 19:25 11502
                    oa->write_character(to_char_type(0x7B));
2660ccea Poul Sander 2023-09-22 19:25 11503
                    write_number(static_cast<std::uint64_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11504
                }
2660ccea Poul Sander 2023-09-22 19:25 11505
                // LCOV_EXCL_STOP
2660ccea Poul Sander 2023-09-22 19:25 11506
2660ccea Poul Sander 2023-09-22 19:25 11507
                // step 2: write the string
2660ccea Poul Sander 2023-09-22 19:25 11508
                oa->write_characters(
2660ccea Poul Sander 2023-09-22 19:25 11509
                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
2660ccea Poul Sander 2023-09-22 19:25 11510
                    j.m_value.string->size());
2660ccea Poul Sander 2023-09-22 19:25 11511
                break;
2660ccea Poul Sander 2023-09-22 19:25 11512
            }
2660ccea Poul Sander 2023-09-22 19:25 11513
2660ccea Poul Sander 2023-09-22 19:25 11514
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 11515
            {
2660ccea Poul Sander 2023-09-22 19:25 11516
                // step 1: write control byte and the array size
2660ccea Poul Sander 2023-09-22 19:25 11517
                const auto N = j.m_value.array->size();
2660ccea Poul Sander 2023-09-22 19:25 11518
                if (N <= 0x17)
2660ccea Poul Sander 2023-09-22 19:25 11519
                {
2660ccea Poul Sander 2023-09-22 19:25 11520
                    write_number(static_cast<std::uint8_t>(0x80 + N));
2660ccea Poul Sander 2023-09-22 19:25 11521
                }
2660ccea Poul Sander 2023-09-22 19:25 11522
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11523
                {
2660ccea Poul Sander 2023-09-22 19:25 11524
                    oa->write_character(to_char_type(0x98));
2660ccea Poul Sander 2023-09-22 19:25 11525
                    write_number(static_cast<std::uint8_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11526
                }
2660ccea Poul Sander 2023-09-22 19:25 11527
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11528
                {
2660ccea Poul Sander 2023-09-22 19:25 11529
                    oa->write_character(to_char_type(0x99));
2660ccea Poul Sander 2023-09-22 19:25 11530
                    write_number(static_cast<std::uint16_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11531
                }
2660ccea Poul Sander 2023-09-22 19:25 11532
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11533
                {
2660ccea Poul Sander 2023-09-22 19:25 11534
                    oa->write_character(to_char_type(0x9A));
2660ccea Poul Sander 2023-09-22 19:25 11535
                    write_number(static_cast<std::uint32_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11536
                }
2660ccea Poul Sander 2023-09-22 19:25 11537
                // LCOV_EXCL_START
2660ccea Poul Sander 2023-09-22 19:25 11538
                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11539
                {
2660ccea Poul Sander 2023-09-22 19:25 11540
                    oa->write_character(to_char_type(0x9B));
2660ccea Poul Sander 2023-09-22 19:25 11541
                    write_number(static_cast<std::uint64_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11542
                }
2660ccea Poul Sander 2023-09-22 19:25 11543
                // LCOV_EXCL_STOP
2660ccea Poul Sander 2023-09-22 19:25 11544
2660ccea Poul Sander 2023-09-22 19:25 11545
                // step 2: write each element
2660ccea Poul Sander 2023-09-22 19:25 11546
                for (const auto& el : *j.m_value.array)
2660ccea Poul Sander 2023-09-22 19:25 11547
                {
2660ccea Poul Sander 2023-09-22 19:25 11548
                    write_cbor(el);
2660ccea Poul Sander 2023-09-22 19:25 11549
                }
2660ccea Poul Sander 2023-09-22 19:25 11550
                break;
2660ccea Poul Sander 2023-09-22 19:25 11551
            }
2660ccea Poul Sander 2023-09-22 19:25 11552
2660ccea Poul Sander 2023-09-22 19:25 11553
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 11554
            {
2660ccea Poul Sander 2023-09-22 19:25 11555
                // step 1: write control byte and the object size
2660ccea Poul Sander 2023-09-22 19:25 11556
                const auto N = j.m_value.object->size();
2660ccea Poul Sander 2023-09-22 19:25 11557
                if (N <= 0x17)
2660ccea Poul Sander 2023-09-22 19:25 11558
                {
2660ccea Poul Sander 2023-09-22 19:25 11559
                    write_number(static_cast<std::uint8_t>(0xA0 + N));
2660ccea Poul Sander 2023-09-22 19:25 11560
                }
2660ccea Poul Sander 2023-09-22 19:25 11561
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11562
                {
2660ccea Poul Sander 2023-09-22 19:25 11563
                    oa->write_character(to_char_type(0xB8));
2660ccea Poul Sander 2023-09-22 19:25 11564
                    write_number(static_cast<std::uint8_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11565
                }
2660ccea Poul Sander 2023-09-22 19:25 11566
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11567
                {
2660ccea Poul Sander 2023-09-22 19:25 11568
                    oa->write_character(to_char_type(0xB9));
2660ccea Poul Sander 2023-09-22 19:25 11569
                    write_number(static_cast<std::uint16_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11570
                }
2660ccea Poul Sander 2023-09-22 19:25 11571
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11572
                {
2660ccea Poul Sander 2023-09-22 19:25 11573
                    oa->write_character(to_char_type(0xBA));
2660ccea Poul Sander 2023-09-22 19:25 11574
                    write_number(static_cast<std::uint32_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11575
                }
2660ccea Poul Sander 2023-09-22 19:25 11576
                // LCOV_EXCL_START
2660ccea Poul Sander 2023-09-22 19:25 11577
                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11578
                {
2660ccea Poul Sander 2023-09-22 19:25 11579
                    oa->write_character(to_char_type(0xBB));
2660ccea Poul Sander 2023-09-22 19:25 11580
                    write_number(static_cast<std::uint64_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11581
                }
2660ccea Poul Sander 2023-09-22 19:25 11582
                // LCOV_EXCL_STOP
2660ccea Poul Sander 2023-09-22 19:25 11583
2660ccea Poul Sander 2023-09-22 19:25 11584
                // step 2: write each element
2660ccea Poul Sander 2023-09-22 19:25 11585
                for (const auto& el : *j.m_value.object)
2660ccea Poul Sander 2023-09-22 19:25 11586
                {
2660ccea Poul Sander 2023-09-22 19:25 11587
                    write_cbor(el.first);
2660ccea Poul Sander 2023-09-22 19:25 11588
                    write_cbor(el.second);
2660ccea Poul Sander 2023-09-22 19:25 11589
                }
2660ccea Poul Sander 2023-09-22 19:25 11590
                break;
2660ccea Poul Sander 2023-09-22 19:25 11591
            }
2660ccea Poul Sander 2023-09-22 19:25 11592
2660ccea Poul Sander 2023-09-22 19:25 11593
            default:
2660ccea Poul Sander 2023-09-22 19:25 11594
                break;
2660ccea Poul Sander 2023-09-22 19:25 11595
        }
2660ccea Poul Sander 2023-09-22 19:25 11596
    }
2660ccea Poul Sander 2023-09-22 19:25 11597
2660ccea Poul Sander 2023-09-22 19:25 11598
    /*!
2660ccea Poul Sander 2023-09-22 19:25 11599
    @param[in] j  JSON value to serialize
2660ccea Poul Sander 2023-09-22 19:25 11600
    */
2660ccea Poul Sander 2023-09-22 19:25 11601
    void write_msgpack(const BasicJsonType& j)
2660ccea Poul Sander 2023-09-22 19:25 11602
    {
2660ccea Poul Sander 2023-09-22 19:25 11603
        switch (j.type())
2660ccea Poul Sander 2023-09-22 19:25 11604
        {
2660ccea Poul Sander 2023-09-22 19:25 11605
            case value_t::null: // nil
2660ccea Poul Sander 2023-09-22 19:25 11606
            {
2660ccea Poul Sander 2023-09-22 19:25 11607
                oa->write_character(to_char_type(0xC0));
2660ccea Poul Sander 2023-09-22 19:25 11608
                break;
2660ccea Poul Sander 2023-09-22 19:25 11609
            }
2660ccea Poul Sander 2023-09-22 19:25 11610
2660ccea Poul Sander 2023-09-22 19:25 11611
            case value_t::boolean: // true and false
2660ccea Poul Sander 2023-09-22 19:25 11612
            {
2660ccea Poul Sander 2023-09-22 19:25 11613
                oa->write_character(j.m_value.boolean
2660ccea Poul Sander 2023-09-22 19:25 11614
                                    ? to_char_type(0xC3)
2660ccea Poul Sander 2023-09-22 19:25 11615
                                    : to_char_type(0xC2));
2660ccea Poul Sander 2023-09-22 19:25 11616
                break;
2660ccea Poul Sander 2023-09-22 19:25 11617
            }
2660ccea Poul Sander 2023-09-22 19:25 11618
2660ccea Poul Sander 2023-09-22 19:25 11619
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 11620
            {
2660ccea Poul Sander 2023-09-22 19:25 11621
                if (j.m_value.number_integer >= 0)
2660ccea Poul Sander 2023-09-22 19:25 11622
                {
2660ccea Poul Sander 2023-09-22 19:25 11623
                    // MessagePack does not differentiate between positive
2660ccea Poul Sander 2023-09-22 19:25 11624
                    // signed integers and unsigned integers. Therefore, we used
2660ccea Poul Sander 2023-09-22 19:25 11625
                    // the code from the value_t::number_unsigned case here.
2660ccea Poul Sander 2023-09-22 19:25 11626
                    if (j.m_value.number_unsigned < 128)
2660ccea Poul Sander 2023-09-22 19:25 11627
                    {
2660ccea Poul Sander 2023-09-22 19:25 11628
                        // positive fixnum
2660ccea Poul Sander 2023-09-22 19:25 11629
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11630
                    }
2660ccea Poul Sander 2023-09-22 19:25 11631
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11632
                    {
2660ccea Poul Sander 2023-09-22 19:25 11633
                        // uint 8
2660ccea Poul Sander 2023-09-22 19:25 11634
                        oa->write_character(to_char_type(0xCC));
2660ccea Poul Sander 2023-09-22 19:25 11635
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11636
                    }
2660ccea Poul Sander 2023-09-22 19:25 11637
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11638
                    {
2660ccea Poul Sander 2023-09-22 19:25 11639
                        // uint 16
2660ccea Poul Sander 2023-09-22 19:25 11640
                        oa->write_character(to_char_type(0xCD));
2660ccea Poul Sander 2023-09-22 19:25 11641
                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11642
                    }
2660ccea Poul Sander 2023-09-22 19:25 11643
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11644
                    {
2660ccea Poul Sander 2023-09-22 19:25 11645
                        // uint 32
2660ccea Poul Sander 2023-09-22 19:25 11646
                        oa->write_character(to_char_type(0xCE));
2660ccea Poul Sander 2023-09-22 19:25 11647
                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11648
                    }
2660ccea Poul Sander 2023-09-22 19:25 11649
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11650
                    {
2660ccea Poul Sander 2023-09-22 19:25 11651
                        // uint 64
2660ccea Poul Sander 2023-09-22 19:25 11652
                        oa->write_character(to_char_type(0xCF));
2660ccea Poul Sander 2023-09-22 19:25 11653
                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11654
                    }
2660ccea Poul Sander 2023-09-22 19:25 11655
                }
2660ccea Poul Sander 2023-09-22 19:25 11656
                else
2660ccea Poul Sander 2023-09-22 19:25 11657
                {
2660ccea Poul Sander 2023-09-22 19:25 11658
                    if (j.m_value.number_integer >= -32)
2660ccea Poul Sander 2023-09-22 19:25 11659
                    {
2660ccea Poul Sander 2023-09-22 19:25 11660
                        // negative fixnum
2660ccea Poul Sander 2023-09-22 19:25 11661
                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11662
                    }
2660ccea Poul Sander 2023-09-22 19:25 11663
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
2660ccea Poul Sander 2023-09-22 19:25 11664
                             j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11665
                    {
2660ccea Poul Sander 2023-09-22 19:25 11666
                        // int 8
2660ccea Poul Sander 2023-09-22 19:25 11667
                        oa->write_character(to_char_type(0xD0));
2660ccea Poul Sander 2023-09-22 19:25 11668
                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11669
                    }
2660ccea Poul Sander 2023-09-22 19:25 11670
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
2660ccea Poul Sander 2023-09-22 19:25 11671
                             j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11672
                    {
2660ccea Poul Sander 2023-09-22 19:25 11673
                        // int 16
2660ccea Poul Sander 2023-09-22 19:25 11674
                        oa->write_character(to_char_type(0xD1));
2660ccea Poul Sander 2023-09-22 19:25 11675
                        write_number(static_cast<std::int16_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11676
                    }
2660ccea Poul Sander 2023-09-22 19:25 11677
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
2660ccea Poul Sander 2023-09-22 19:25 11678
                             j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11679
                    {
2660ccea Poul Sander 2023-09-22 19:25 11680
                        // int 32
2660ccea Poul Sander 2023-09-22 19:25 11681
                        oa->write_character(to_char_type(0xD2));
2660ccea Poul Sander 2023-09-22 19:25 11682
                        write_number(static_cast<std::int32_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11683
                    }
2660ccea Poul Sander 2023-09-22 19:25 11684
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
2660ccea Poul Sander 2023-09-22 19:25 11685
                             j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11686
                    {
2660ccea Poul Sander 2023-09-22 19:25 11687
                        // int 64
2660ccea Poul Sander 2023-09-22 19:25 11688
                        oa->write_character(to_char_type(0xD3));
2660ccea Poul Sander 2023-09-22 19:25 11689
                        write_number(static_cast<std::int64_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11690
                    }
2660ccea Poul Sander 2023-09-22 19:25 11691
                }
2660ccea Poul Sander 2023-09-22 19:25 11692
                break;
2660ccea Poul Sander 2023-09-22 19:25 11693
            }
2660ccea Poul Sander 2023-09-22 19:25 11694
2660ccea Poul Sander 2023-09-22 19:25 11695
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 11696
            {
2660ccea Poul Sander 2023-09-22 19:25 11697
                if (j.m_value.number_unsigned < 128)
2660ccea Poul Sander 2023-09-22 19:25 11698
                {
2660ccea Poul Sander 2023-09-22 19:25 11699
                    // positive fixnum
2660ccea Poul Sander 2023-09-22 19:25 11700
                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11701
                }
2660ccea Poul Sander 2023-09-22 19:25 11702
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11703
                {
2660ccea Poul Sander 2023-09-22 19:25 11704
                    // uint 8
2660ccea Poul Sander 2023-09-22 19:25 11705
                    oa->write_character(to_char_type(0xCC));
2660ccea Poul Sander 2023-09-22 19:25 11706
                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11707
                }
2660ccea Poul Sander 2023-09-22 19:25 11708
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11709
                {
2660ccea Poul Sander 2023-09-22 19:25 11710
                    // uint 16
2660ccea Poul Sander 2023-09-22 19:25 11711
                    oa->write_character(to_char_type(0xCD));
2660ccea Poul Sander 2023-09-22 19:25 11712
                    write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11713
                }
2660ccea Poul Sander 2023-09-22 19:25 11714
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11715
                {
2660ccea Poul Sander 2023-09-22 19:25 11716
                    // uint 32
2660ccea Poul Sander 2023-09-22 19:25 11717
                    oa->write_character(to_char_type(0xCE));
2660ccea Poul Sander 2023-09-22 19:25 11718
                    write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11719
                }
2660ccea Poul Sander 2023-09-22 19:25 11720
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11721
                {
2660ccea Poul Sander 2023-09-22 19:25 11722
                    // uint 64
2660ccea Poul Sander 2023-09-22 19:25 11723
                    oa->write_character(to_char_type(0xCF));
2660ccea Poul Sander 2023-09-22 19:25 11724
                    write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
2660ccea Poul Sander 2023-09-22 19:25 11725
                }
2660ccea Poul Sander 2023-09-22 19:25 11726
                break;
2660ccea Poul Sander 2023-09-22 19:25 11727
            }
2660ccea Poul Sander 2023-09-22 19:25 11728
2660ccea Poul Sander 2023-09-22 19:25 11729
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 11730
            {
2660ccea Poul Sander 2023-09-22 19:25 11731
                oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
2660ccea Poul Sander 2023-09-22 19:25 11732
                write_number(j.m_value.number_float);
2660ccea Poul Sander 2023-09-22 19:25 11733
                break;
2660ccea Poul Sander 2023-09-22 19:25 11734
            }
2660ccea Poul Sander 2023-09-22 19:25 11735
2660ccea Poul Sander 2023-09-22 19:25 11736
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 11737
            {
2660ccea Poul Sander 2023-09-22 19:25 11738
                // step 1: write control byte and the string length
2660ccea Poul Sander 2023-09-22 19:25 11739
                const auto N = j.m_value.string->size();
2660ccea Poul Sander 2023-09-22 19:25 11740
                if (N <= 31)
2660ccea Poul Sander 2023-09-22 19:25 11741
                {
2660ccea Poul Sander 2023-09-22 19:25 11742
                    // fixstr
2660ccea Poul Sander 2023-09-22 19:25 11743
                    write_number(static_cast<std::uint8_t>(0xA0 | N));
2660ccea Poul Sander 2023-09-22 19:25 11744
                }
2660ccea Poul Sander 2023-09-22 19:25 11745
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11746
                {
2660ccea Poul Sander 2023-09-22 19:25 11747
                    // str 8
2660ccea Poul Sander 2023-09-22 19:25 11748
                    oa->write_character(to_char_type(0xD9));
2660ccea Poul Sander 2023-09-22 19:25 11749
                    write_number(static_cast<std::uint8_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11750
                }
2660ccea Poul Sander 2023-09-22 19:25 11751
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11752
                {
2660ccea Poul Sander 2023-09-22 19:25 11753
                    // str 16
2660ccea Poul Sander 2023-09-22 19:25 11754
                    oa->write_character(to_char_type(0xDA));
2660ccea Poul Sander 2023-09-22 19:25 11755
                    write_number(static_cast<std::uint16_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11756
                }
2660ccea Poul Sander 2023-09-22 19:25 11757
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11758
                {
2660ccea Poul Sander 2023-09-22 19:25 11759
                    // str 32
2660ccea Poul Sander 2023-09-22 19:25 11760
                    oa->write_character(to_char_type(0xDB));
2660ccea Poul Sander 2023-09-22 19:25 11761
                    write_number(static_cast<std::uint32_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11762
                }
2660ccea Poul Sander 2023-09-22 19:25 11763
2660ccea Poul Sander 2023-09-22 19:25 11764
                // step 2: write the string
2660ccea Poul Sander 2023-09-22 19:25 11765
                oa->write_characters(
2660ccea Poul Sander 2023-09-22 19:25 11766
                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
2660ccea Poul Sander 2023-09-22 19:25 11767
                    j.m_value.string->size());
2660ccea Poul Sander 2023-09-22 19:25 11768
                break;
2660ccea Poul Sander 2023-09-22 19:25 11769
            }
2660ccea Poul Sander 2023-09-22 19:25 11770
2660ccea Poul Sander 2023-09-22 19:25 11771
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 11772
            {
2660ccea Poul Sander 2023-09-22 19:25 11773
                // step 1: write control byte and the array size
2660ccea Poul Sander 2023-09-22 19:25 11774
                const auto N = j.m_value.array->size();
2660ccea Poul Sander 2023-09-22 19:25 11775
                if (N <= 15)
2660ccea Poul Sander 2023-09-22 19:25 11776
                {
2660ccea Poul Sander 2023-09-22 19:25 11777
                    // fixarray
2660ccea Poul Sander 2023-09-22 19:25 11778
                    write_number(static_cast<std::uint8_t>(0x90 | N));
2660ccea Poul Sander 2023-09-22 19:25 11779
                }
2660ccea Poul Sander 2023-09-22 19:25 11780
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11781
                {
2660ccea Poul Sander 2023-09-22 19:25 11782
                    // array 16
2660ccea Poul Sander 2023-09-22 19:25 11783
                    oa->write_character(to_char_type(0xDC));
2660ccea Poul Sander 2023-09-22 19:25 11784
                    write_number(static_cast<std::uint16_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11785
                }
2660ccea Poul Sander 2023-09-22 19:25 11786
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11787
                {
2660ccea Poul Sander 2023-09-22 19:25 11788
                    // array 32
2660ccea Poul Sander 2023-09-22 19:25 11789
                    oa->write_character(to_char_type(0xDD));
2660ccea Poul Sander 2023-09-22 19:25 11790
                    write_number(static_cast<std::uint32_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11791
                }
2660ccea Poul Sander 2023-09-22 19:25 11792
2660ccea Poul Sander 2023-09-22 19:25 11793
                // step 2: write each element
2660ccea Poul Sander 2023-09-22 19:25 11794
                for (const auto& el : *j.m_value.array)
2660ccea Poul Sander 2023-09-22 19:25 11795
                {
2660ccea Poul Sander 2023-09-22 19:25 11796
                    write_msgpack(el);
2660ccea Poul Sander 2023-09-22 19:25 11797
                }
2660ccea Poul Sander 2023-09-22 19:25 11798
                break;
2660ccea Poul Sander 2023-09-22 19:25 11799
            }
2660ccea Poul Sander 2023-09-22 19:25 11800
2660ccea Poul Sander 2023-09-22 19:25 11801
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 11802
            {
2660ccea Poul Sander 2023-09-22 19:25 11803
                // step 1: write control byte and the object size
2660ccea Poul Sander 2023-09-22 19:25 11804
                const auto N = j.m_value.object->size();
2660ccea Poul Sander 2023-09-22 19:25 11805
                if (N <= 15)
2660ccea Poul Sander 2023-09-22 19:25 11806
                {
2660ccea Poul Sander 2023-09-22 19:25 11807
                    // fixmap
2660ccea Poul Sander 2023-09-22 19:25 11808
                    write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
2660ccea Poul Sander 2023-09-22 19:25 11809
                }
2660ccea Poul Sander 2023-09-22 19:25 11810
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11811
                {
2660ccea Poul Sander 2023-09-22 19:25 11812
                    // map 16
2660ccea Poul Sander 2023-09-22 19:25 11813
                    oa->write_character(to_char_type(0xDE));
2660ccea Poul Sander 2023-09-22 19:25 11814
                    write_number(static_cast<std::uint16_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11815
                }
2660ccea Poul Sander 2023-09-22 19:25 11816
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 11817
                {
2660ccea Poul Sander 2023-09-22 19:25 11818
                    // map 32
2660ccea Poul Sander 2023-09-22 19:25 11819
                    oa->write_character(to_char_type(0xDF));
2660ccea Poul Sander 2023-09-22 19:25 11820
                    write_number(static_cast<std::uint32_t>(N));
2660ccea Poul Sander 2023-09-22 19:25 11821
                }
2660ccea Poul Sander 2023-09-22 19:25 11822
2660ccea Poul Sander 2023-09-22 19:25 11823
                // step 2: write each element
2660ccea Poul Sander 2023-09-22 19:25 11824
                for (const auto& el : *j.m_value.object)
2660ccea Poul Sander 2023-09-22 19:25 11825
                {
2660ccea Poul Sander 2023-09-22 19:25 11826
                    write_msgpack(el.first);
2660ccea Poul Sander 2023-09-22 19:25 11827
                    write_msgpack(el.second);
2660ccea Poul Sander 2023-09-22 19:25 11828
                }
2660ccea Poul Sander 2023-09-22 19:25 11829
                break;
2660ccea Poul Sander 2023-09-22 19:25 11830
            }
2660ccea Poul Sander 2023-09-22 19:25 11831
2660ccea Poul Sander 2023-09-22 19:25 11832
            default:
2660ccea Poul Sander 2023-09-22 19:25 11833
                break;
2660ccea Poul Sander 2023-09-22 19:25 11834
        }
2660ccea Poul Sander 2023-09-22 19:25 11835
    }
2660ccea Poul Sander 2023-09-22 19:25 11836
2660ccea Poul Sander 2023-09-22 19:25 11837
    /*!
2660ccea Poul Sander 2023-09-22 19:25 11838
    @param[in] j  JSON value to serialize
2660ccea Poul Sander 2023-09-22 19:25 11839
    @param[in] use_count   whether to use '#' prefixes (optimized format)
2660ccea Poul Sander 2023-09-22 19:25 11840
    @param[in] use_type    whether to use '$' prefixes (optimized format)
2660ccea Poul Sander 2023-09-22 19:25 11841
    @param[in] add_prefix  whether prefixes need to be used for this value
2660ccea Poul Sander 2023-09-22 19:25 11842
    */
2660ccea Poul Sander 2023-09-22 19:25 11843
    void write_ubjson(const BasicJsonType& j, const bool use_count,
2660ccea Poul Sander 2023-09-22 19:25 11844
                      const bool use_type, const bool add_prefix = true)
2660ccea Poul Sander 2023-09-22 19:25 11845
    {
2660ccea Poul Sander 2023-09-22 19:25 11846
        switch (j.type())
2660ccea Poul Sander 2023-09-22 19:25 11847
        {
2660ccea Poul Sander 2023-09-22 19:25 11848
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 11849
            {
2660ccea Poul Sander 2023-09-22 19:25 11850
                if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 11851
                {
2660ccea Poul Sander 2023-09-22 19:25 11852
                    oa->write_character(to_char_type('Z'));
2660ccea Poul Sander 2023-09-22 19:25 11853
                }
2660ccea Poul Sander 2023-09-22 19:25 11854
                break;
2660ccea Poul Sander 2023-09-22 19:25 11855
            }
2660ccea Poul Sander 2023-09-22 19:25 11856
2660ccea Poul Sander 2023-09-22 19:25 11857
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 11858
            {
2660ccea Poul Sander 2023-09-22 19:25 11859
                if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 11860
                {
2660ccea Poul Sander 2023-09-22 19:25 11861
                    oa->write_character(j.m_value.boolean
2660ccea Poul Sander 2023-09-22 19:25 11862
                                        ? to_char_type('T')
2660ccea Poul Sander 2023-09-22 19:25 11863
                                        : to_char_type('F'));
2660ccea Poul Sander 2023-09-22 19:25 11864
                }
2660ccea Poul Sander 2023-09-22 19:25 11865
                break;
2660ccea Poul Sander 2023-09-22 19:25 11866
            }
2660ccea Poul Sander 2023-09-22 19:25 11867
2660ccea Poul Sander 2023-09-22 19:25 11868
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 11869
            {
2660ccea Poul Sander 2023-09-22 19:25 11870
                write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
2660ccea Poul Sander 2023-09-22 19:25 11871
                break;
2660ccea Poul Sander 2023-09-22 19:25 11872
            }
2660ccea Poul Sander 2023-09-22 19:25 11873
2660ccea Poul Sander 2023-09-22 19:25 11874
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 11875
            {
2660ccea Poul Sander 2023-09-22 19:25 11876
                write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
2660ccea Poul Sander 2023-09-22 19:25 11877
                break;
2660ccea Poul Sander 2023-09-22 19:25 11878
            }
2660ccea Poul Sander 2023-09-22 19:25 11879
2660ccea Poul Sander 2023-09-22 19:25 11880
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 11881
            {
2660ccea Poul Sander 2023-09-22 19:25 11882
                write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
2660ccea Poul Sander 2023-09-22 19:25 11883
                break;
2660ccea Poul Sander 2023-09-22 19:25 11884
            }
2660ccea Poul Sander 2023-09-22 19:25 11885
2660ccea Poul Sander 2023-09-22 19:25 11886
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 11887
            {
2660ccea Poul Sander 2023-09-22 19:25 11888
                if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 11889
                {
2660ccea Poul Sander 2023-09-22 19:25 11890
                    oa->write_character(to_char_type('S'));
2660ccea Poul Sander 2023-09-22 19:25 11891
                }
2660ccea Poul Sander 2023-09-22 19:25 11892
                write_number_with_ubjson_prefix(j.m_value.string->size(), true);
2660ccea Poul Sander 2023-09-22 19:25 11893
                oa->write_characters(
2660ccea Poul Sander 2023-09-22 19:25 11894
                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
2660ccea Poul Sander 2023-09-22 19:25 11895
                    j.m_value.string->size());
2660ccea Poul Sander 2023-09-22 19:25 11896
                break;
2660ccea Poul Sander 2023-09-22 19:25 11897
            }
2660ccea Poul Sander 2023-09-22 19:25 11898
2660ccea Poul Sander 2023-09-22 19:25 11899
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 11900
            {
2660ccea Poul Sander 2023-09-22 19:25 11901
                if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 11902
                {
2660ccea Poul Sander 2023-09-22 19:25 11903
                    oa->write_character(to_char_type('['));
2660ccea Poul Sander 2023-09-22 19:25 11904
                }
2660ccea Poul Sander 2023-09-22 19:25 11905
2660ccea Poul Sander 2023-09-22 19:25 11906
                bool prefix_required = true;
2660ccea Poul Sander 2023-09-22 19:25 11907
                if (use_type and not j.m_value.array->empty())
2660ccea Poul Sander 2023-09-22 19:25 11908
                {
2660ccea Poul Sander 2023-09-22 19:25 11909
                    assert(use_count);
2660ccea Poul Sander 2023-09-22 19:25 11910
                    const CharType first_prefix = ubjson_prefix(j.front());
2660ccea Poul Sander 2023-09-22 19:25 11911
                    const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
2660ccea Poul Sander 2023-09-22 19:25 11912
                                                         [this, first_prefix](const BasicJsonType & v)
2660ccea Poul Sander 2023-09-22 19:25 11913
                    {
2660ccea Poul Sander 2023-09-22 19:25 11914
                        return ubjson_prefix(v) == first_prefix;
2660ccea Poul Sander 2023-09-22 19:25 11915
                    });
2660ccea Poul Sander 2023-09-22 19:25 11916
2660ccea Poul Sander 2023-09-22 19:25 11917
                    if (same_prefix)
2660ccea Poul Sander 2023-09-22 19:25 11918
                    {
2660ccea Poul Sander 2023-09-22 19:25 11919
                        prefix_required = false;
2660ccea Poul Sander 2023-09-22 19:25 11920
                        oa->write_character(to_char_type('$'));
2660ccea Poul Sander 2023-09-22 19:25 11921
                        oa->write_character(first_prefix);
2660ccea Poul Sander 2023-09-22 19:25 11922
                    }
2660ccea Poul Sander 2023-09-22 19:25 11923
                }
2660ccea Poul Sander 2023-09-22 19:25 11924
2660ccea Poul Sander 2023-09-22 19:25 11925
                if (use_count)
2660ccea Poul Sander 2023-09-22 19:25 11926
                {
2660ccea Poul Sander 2023-09-22 19:25 11927
                    oa->write_character(to_char_type('#'));
2660ccea Poul Sander 2023-09-22 19:25 11928
                    write_number_with_ubjson_prefix(j.m_value.array->size(), true);
2660ccea Poul Sander 2023-09-22 19:25 11929
                }
2660ccea Poul Sander 2023-09-22 19:25 11930
2660ccea Poul Sander 2023-09-22 19:25 11931
                for (const auto& el : *j.m_value.array)
2660ccea Poul Sander 2023-09-22 19:25 11932
                {
2660ccea Poul Sander 2023-09-22 19:25 11933
                    write_ubjson(el, use_count, use_type, prefix_required);
2660ccea Poul Sander 2023-09-22 19:25 11934
                }
2660ccea Poul Sander 2023-09-22 19:25 11935
2660ccea Poul Sander 2023-09-22 19:25 11936
                if (not use_count)
2660ccea Poul Sander 2023-09-22 19:25 11937
                {
2660ccea Poul Sander 2023-09-22 19:25 11938
                    oa->write_character(to_char_type(']'));
2660ccea Poul Sander 2023-09-22 19:25 11939
                }
2660ccea Poul Sander 2023-09-22 19:25 11940
2660ccea Poul Sander 2023-09-22 19:25 11941
                break;
2660ccea Poul Sander 2023-09-22 19:25 11942
            }
2660ccea Poul Sander 2023-09-22 19:25 11943
2660ccea Poul Sander 2023-09-22 19:25 11944
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 11945
            {
2660ccea Poul Sander 2023-09-22 19:25 11946
                if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 11947
                {
2660ccea Poul Sander 2023-09-22 19:25 11948
                    oa->write_character(to_char_type('{'));
2660ccea Poul Sander 2023-09-22 19:25 11949
                }
2660ccea Poul Sander 2023-09-22 19:25 11950
2660ccea Poul Sander 2023-09-22 19:25 11951
                bool prefix_required = true;
2660ccea Poul Sander 2023-09-22 19:25 11952
                if (use_type and not j.m_value.object->empty())
2660ccea Poul Sander 2023-09-22 19:25 11953
                {
2660ccea Poul Sander 2023-09-22 19:25 11954
                    assert(use_count);
2660ccea Poul Sander 2023-09-22 19:25 11955
                    const CharType first_prefix = ubjson_prefix(j.front());
2660ccea Poul Sander 2023-09-22 19:25 11956
                    const bool same_prefix = std::all_of(j.begin(), j.end(),
2660ccea Poul Sander 2023-09-22 19:25 11957
                                                         [this, first_prefix](const BasicJsonType & v)
2660ccea Poul Sander 2023-09-22 19:25 11958
                    {
2660ccea Poul Sander 2023-09-22 19:25 11959
                        return ubjson_prefix(v) == first_prefix;
2660ccea Poul Sander 2023-09-22 19:25 11960
                    });
2660ccea Poul Sander 2023-09-22 19:25 11961
2660ccea Poul Sander 2023-09-22 19:25 11962
                    if (same_prefix)
2660ccea Poul Sander 2023-09-22 19:25 11963
                    {
2660ccea Poul Sander 2023-09-22 19:25 11964
                        prefix_required = false;
2660ccea Poul Sander 2023-09-22 19:25 11965
                        oa->write_character(to_char_type('$'));
2660ccea Poul Sander 2023-09-22 19:25 11966
                        oa->write_character(first_prefix);
2660ccea Poul Sander 2023-09-22 19:25 11967
                    }
2660ccea Poul Sander 2023-09-22 19:25 11968
                }
2660ccea Poul Sander 2023-09-22 19:25 11969
2660ccea Poul Sander 2023-09-22 19:25 11970
                if (use_count)
2660ccea Poul Sander 2023-09-22 19:25 11971
                {
2660ccea Poul Sander 2023-09-22 19:25 11972
                    oa->write_character(to_char_type('#'));
2660ccea Poul Sander 2023-09-22 19:25 11973
                    write_number_with_ubjson_prefix(j.m_value.object->size(), true);
2660ccea Poul Sander 2023-09-22 19:25 11974
                }
2660ccea Poul Sander 2023-09-22 19:25 11975
2660ccea Poul Sander 2023-09-22 19:25 11976
                for (const auto& el : *j.m_value.object)
2660ccea Poul Sander 2023-09-22 19:25 11977
                {
2660ccea Poul Sander 2023-09-22 19:25 11978
                    write_number_with_ubjson_prefix(el.first.size(), true);
2660ccea Poul Sander 2023-09-22 19:25 11979
                    oa->write_characters(
2660ccea Poul Sander 2023-09-22 19:25 11980
                        reinterpret_cast<const CharType*>(el.first.c_str()),
2660ccea Poul Sander 2023-09-22 19:25 11981
                        el.first.size());
2660ccea Poul Sander 2023-09-22 19:25 11982
                    write_ubjson(el.second, use_count, use_type, prefix_required);
2660ccea Poul Sander 2023-09-22 19:25 11983
                }
2660ccea Poul Sander 2023-09-22 19:25 11984
2660ccea Poul Sander 2023-09-22 19:25 11985
                if (not use_count)
2660ccea Poul Sander 2023-09-22 19:25 11986
                {
2660ccea Poul Sander 2023-09-22 19:25 11987
                    oa->write_character(to_char_type('}'));
2660ccea Poul Sander 2023-09-22 19:25 11988
                }
2660ccea Poul Sander 2023-09-22 19:25 11989
2660ccea Poul Sander 2023-09-22 19:25 11990
                break;
2660ccea Poul Sander 2023-09-22 19:25 11991
            }
2660ccea Poul Sander 2023-09-22 19:25 11992
2660ccea Poul Sander 2023-09-22 19:25 11993
            default:
2660ccea Poul Sander 2023-09-22 19:25 11994
                break;
2660ccea Poul Sander 2023-09-22 19:25 11995
        }
2660ccea Poul Sander 2023-09-22 19:25 11996
    }
2660ccea Poul Sander 2023-09-22 19:25 11997
2660ccea Poul Sander 2023-09-22 19:25 11998
  private:
2660ccea Poul Sander 2023-09-22 19:25 11999
    //////////
2660ccea Poul Sander 2023-09-22 19:25 12000
    // BSON //
2660ccea Poul Sander 2023-09-22 19:25 12001
    //////////
2660ccea Poul Sander 2023-09-22 19:25 12002
2660ccea Poul Sander 2023-09-22 19:25 12003
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12004
    @return The size of a BSON document entry header, including the id marker
2660ccea Poul Sander 2023-09-22 19:25 12005
            and the entry name size (and its null-terminator).
2660ccea Poul Sander 2023-09-22 19:25 12006
    */
2660ccea Poul Sander 2023-09-22 19:25 12007
    static std::size_t calc_bson_entry_header_size(const string_t& name)
2660ccea Poul Sander 2023-09-22 19:25 12008
    {
2660ccea Poul Sander 2023-09-22 19:25 12009
        const auto it = name.find(static_cast<typename string_t::value_type>(0));
2660ccea Poul Sander 2023-09-22 19:25 12010
        if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
2660ccea Poul Sander 2023-09-22 19:25 12011
        {
2660ccea Poul Sander 2023-09-22 19:25 12012
            JSON_THROW(out_of_range::create(409,
2660ccea Poul Sander 2023-09-22 19:25 12013
                                            "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
2660ccea Poul Sander 2023-09-22 19:25 12014
        }
2660ccea Poul Sander 2023-09-22 19:25 12015
2660ccea Poul Sander 2023-09-22 19:25 12016
        return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
2660ccea Poul Sander 2023-09-22 19:25 12017
    }
2660ccea Poul Sander 2023-09-22 19:25 12018
2660ccea Poul Sander 2023-09-22 19:25 12019
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12020
    @brief Writes the given @a element_type and @a name to the output adapter
2660ccea Poul Sander 2023-09-22 19:25 12021
    */
2660ccea Poul Sander 2023-09-22 19:25 12022
    void write_bson_entry_header(const string_t& name,
2660ccea Poul Sander 2023-09-22 19:25 12023
                                 const std::uint8_t element_type)
2660ccea Poul Sander 2023-09-22 19:25 12024
    {
2660ccea Poul Sander 2023-09-22 19:25 12025
        oa->write_character(to_char_type(element_type)); // boolean
2660ccea Poul Sander 2023-09-22 19:25 12026
        oa->write_characters(
2660ccea Poul Sander 2023-09-22 19:25 12027
            reinterpret_cast<const CharType*>(name.c_str()),
2660ccea Poul Sander 2023-09-22 19:25 12028
            name.size() + 1u);
2660ccea Poul Sander 2023-09-22 19:25 12029
    }
2660ccea Poul Sander 2023-09-22 19:25 12030
2660ccea Poul Sander 2023-09-22 19:25 12031
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12032
    @brief Writes a BSON element with key @a name and boolean value @a value
2660ccea Poul Sander 2023-09-22 19:25 12033
    */
2660ccea Poul Sander 2023-09-22 19:25 12034
    void write_bson_boolean(const string_t& name,
2660ccea Poul Sander 2023-09-22 19:25 12035
                            const bool value)
2660ccea Poul Sander 2023-09-22 19:25 12036
    {
2660ccea Poul Sander 2023-09-22 19:25 12037
        write_bson_entry_header(name, 0x08);
2660ccea Poul Sander 2023-09-22 19:25 12038
        oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
2660ccea Poul Sander 2023-09-22 19:25 12039
    }
2660ccea Poul Sander 2023-09-22 19:25 12040
2660ccea Poul Sander 2023-09-22 19:25 12041
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12042
    @brief Writes a BSON element with key @a name and double value @a value
2660ccea Poul Sander 2023-09-22 19:25 12043
    */
2660ccea Poul Sander 2023-09-22 19:25 12044
    void write_bson_double(const string_t& name,
2660ccea Poul Sander 2023-09-22 19:25 12045
                           const double value)
2660ccea Poul Sander 2023-09-22 19:25 12046
    {
2660ccea Poul Sander 2023-09-22 19:25 12047
        write_bson_entry_header(name, 0x01);
2660ccea Poul Sander 2023-09-22 19:25 12048
        write_number<double, true>(value);
2660ccea Poul Sander 2023-09-22 19:25 12049
    }
2660ccea Poul Sander 2023-09-22 19:25 12050
2660ccea Poul Sander 2023-09-22 19:25 12051
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12052
    @return The size of the BSON-encoded string in @a value
2660ccea Poul Sander 2023-09-22 19:25 12053
    */
2660ccea Poul Sander 2023-09-22 19:25 12054
    static std::size_t calc_bson_string_size(const string_t& value)
2660ccea Poul Sander 2023-09-22 19:25 12055
    {
2660ccea Poul Sander 2023-09-22 19:25 12056
        return sizeof(std::int32_t) + value.size() + 1ul;
2660ccea Poul Sander 2023-09-22 19:25 12057
    }
2660ccea Poul Sander 2023-09-22 19:25 12058
2660ccea Poul Sander 2023-09-22 19:25 12059
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12060
    @brief Writes a BSON element with key @a name and string value @a value
2660ccea Poul Sander 2023-09-22 19:25 12061
    */
2660ccea Poul Sander 2023-09-22 19:25 12062
    void write_bson_string(const string_t& name,
2660ccea Poul Sander 2023-09-22 19:25 12063
                           const string_t& value)
2660ccea Poul Sander 2023-09-22 19:25 12064
    {
2660ccea Poul Sander 2023-09-22 19:25 12065
        write_bson_entry_header(name, 0x02);
2660ccea Poul Sander 2023-09-22 19:25 12066
2660ccea Poul Sander 2023-09-22 19:25 12067
        write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
2660ccea Poul Sander 2023-09-22 19:25 12068
        oa->write_characters(
2660ccea Poul Sander 2023-09-22 19:25 12069
            reinterpret_cast<const CharType*>(value.c_str()),
2660ccea Poul Sander 2023-09-22 19:25 12070
            value.size() + 1);
2660ccea Poul Sander 2023-09-22 19:25 12071
    }
2660ccea Poul Sander 2023-09-22 19:25 12072
2660ccea Poul Sander 2023-09-22 19:25 12073
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12074
    @brief Writes a BSON element with key @a name and null value
2660ccea Poul Sander 2023-09-22 19:25 12075
    */
2660ccea Poul Sander 2023-09-22 19:25 12076
    void write_bson_null(const string_t& name)
2660ccea Poul Sander 2023-09-22 19:25 12077
    {
2660ccea Poul Sander 2023-09-22 19:25 12078
        write_bson_entry_header(name, 0x0A);
2660ccea Poul Sander 2023-09-22 19:25 12079
    }
2660ccea Poul Sander 2023-09-22 19:25 12080
2660ccea Poul Sander 2023-09-22 19:25 12081
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12082
    @return The size of the BSON-encoded integer @a value
2660ccea Poul Sander 2023-09-22 19:25 12083
    */
2660ccea Poul Sander 2023-09-22 19:25 12084
    static std::size_t calc_bson_integer_size(const std::int64_t value)
2660ccea Poul Sander 2023-09-22 19:25 12085
    {
2660ccea Poul Sander 2023-09-22 19:25 12086
        return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
2660ccea Poul Sander 2023-09-22 19:25 12087
               ? sizeof(std::int32_t)
2660ccea Poul Sander 2023-09-22 19:25 12088
               : sizeof(std::int64_t);
2660ccea Poul Sander 2023-09-22 19:25 12089
    }
2660ccea Poul Sander 2023-09-22 19:25 12090
2660ccea Poul Sander 2023-09-22 19:25 12091
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12092
    @brief Writes a BSON element with key @a name and integer @a value
2660ccea Poul Sander 2023-09-22 19:25 12093
    */
2660ccea Poul Sander 2023-09-22 19:25 12094
    void write_bson_integer(const string_t& name,
2660ccea Poul Sander 2023-09-22 19:25 12095
                            const std::int64_t value)
2660ccea Poul Sander 2023-09-22 19:25 12096
    {
2660ccea Poul Sander 2023-09-22 19:25 12097
        if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 12098
        {
2660ccea Poul Sander 2023-09-22 19:25 12099
            write_bson_entry_header(name, 0x10); // int32
2660ccea Poul Sander 2023-09-22 19:25 12100
            write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
2660ccea Poul Sander 2023-09-22 19:25 12101
        }
2660ccea Poul Sander 2023-09-22 19:25 12102
        else
2660ccea Poul Sander 2023-09-22 19:25 12103
        {
2660ccea Poul Sander 2023-09-22 19:25 12104
            write_bson_entry_header(name, 0x12); // int64
2660ccea Poul Sander 2023-09-22 19:25 12105
            write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
2660ccea Poul Sander 2023-09-22 19:25 12106
        }
2660ccea Poul Sander 2023-09-22 19:25 12107
    }
2660ccea Poul Sander 2023-09-22 19:25 12108
2660ccea Poul Sander 2023-09-22 19:25 12109
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12110
    @return The size of the BSON-encoded unsigned integer in @a j
2660ccea Poul Sander 2023-09-22 19:25 12111
    */
2660ccea Poul Sander 2023-09-22 19:25 12112
    static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
2660ccea Poul Sander 2023-09-22 19:25 12113
    {
2660ccea Poul Sander 2023-09-22 19:25 12114
        return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12115
               ? sizeof(std::int32_t)
2660ccea Poul Sander 2023-09-22 19:25 12116
               : sizeof(std::int64_t);
2660ccea Poul Sander 2023-09-22 19:25 12117
    }
2660ccea Poul Sander 2023-09-22 19:25 12118
2660ccea Poul Sander 2023-09-22 19:25 12119
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12120
    @brief Writes a BSON element with key @a name and unsigned @a value
2660ccea Poul Sander 2023-09-22 19:25 12121
    */
2660ccea Poul Sander 2023-09-22 19:25 12122
    void write_bson_unsigned(const string_t& name,
2660ccea Poul Sander 2023-09-22 19:25 12123
                             const std::uint64_t value)
2660ccea Poul Sander 2023-09-22 19:25 12124
    {
2660ccea Poul Sander 2023-09-22 19:25 12125
        if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12126
        {
2660ccea Poul Sander 2023-09-22 19:25 12127
            write_bson_entry_header(name, 0x10 /* int32 */);
2660ccea Poul Sander 2023-09-22 19:25 12128
            write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
2660ccea Poul Sander 2023-09-22 19:25 12129
        }
2660ccea Poul Sander 2023-09-22 19:25 12130
        else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12131
        {
2660ccea Poul Sander 2023-09-22 19:25 12132
            write_bson_entry_header(name, 0x12 /* int64 */);
2660ccea Poul Sander 2023-09-22 19:25 12133
            write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
2660ccea Poul Sander 2023-09-22 19:25 12134
        }
2660ccea Poul Sander 2023-09-22 19:25 12135
        else
2660ccea Poul Sander 2023-09-22 19:25 12136
        {
2660ccea Poul Sander 2023-09-22 19:25 12137
            JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
2660ccea Poul Sander 2023-09-22 19:25 12138
        }
2660ccea Poul Sander 2023-09-22 19:25 12139
    }
2660ccea Poul Sander 2023-09-22 19:25 12140
2660ccea Poul Sander 2023-09-22 19:25 12141
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12142
    @brief Writes a BSON element with key @a name and object @a value
2660ccea Poul Sander 2023-09-22 19:25 12143
    */
2660ccea Poul Sander 2023-09-22 19:25 12144
    void write_bson_object_entry(const string_t& name,
2660ccea Poul Sander 2023-09-22 19:25 12145
                                 const typename BasicJsonType::object_t& value)
2660ccea Poul Sander 2023-09-22 19:25 12146
    {
2660ccea Poul Sander 2023-09-22 19:25 12147
        write_bson_entry_header(name, 0x03); // object
2660ccea Poul Sander 2023-09-22 19:25 12148
        write_bson_object(value);
2660ccea Poul Sander 2023-09-22 19:25 12149
    }
2660ccea Poul Sander 2023-09-22 19:25 12150
2660ccea Poul Sander 2023-09-22 19:25 12151
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12152
    @return The size of the BSON-encoded array @a value
2660ccea Poul Sander 2023-09-22 19:25 12153
    */
2660ccea Poul Sander 2023-09-22 19:25 12154
    static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
2660ccea Poul Sander 2023-09-22 19:25 12155
    {
2660ccea Poul Sander 2023-09-22 19:25 12156
        std::size_t array_index = 0ul;
2660ccea Poul Sander 2023-09-22 19:25 12157
2660ccea Poul Sander 2023-09-22 19:25 12158
        const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), 0ul, [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
2660ccea Poul Sander 2023-09-22 19:25 12159
        {
2660ccea Poul Sander 2023-09-22 19:25 12160
            return result + calc_bson_element_size(std::to_string(array_index++), el);
2660ccea Poul Sander 2023-09-22 19:25 12161
        });
2660ccea Poul Sander 2023-09-22 19:25 12162
2660ccea Poul Sander 2023-09-22 19:25 12163
        return sizeof(std::int32_t) + embedded_document_size + 1ul;
2660ccea Poul Sander 2023-09-22 19:25 12164
    }
2660ccea Poul Sander 2023-09-22 19:25 12165
2660ccea Poul Sander 2023-09-22 19:25 12166
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12167
    @brief Writes a BSON element with key @a name and array @a value
2660ccea Poul Sander 2023-09-22 19:25 12168
    */
2660ccea Poul Sander 2023-09-22 19:25 12169
    void write_bson_array(const string_t& name,
2660ccea Poul Sander 2023-09-22 19:25 12170
                          const typename BasicJsonType::array_t& value)
2660ccea Poul Sander 2023-09-22 19:25 12171
    {
2660ccea Poul Sander 2023-09-22 19:25 12172
        write_bson_entry_header(name, 0x04); // array
2660ccea Poul Sander 2023-09-22 19:25 12173
        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
2660ccea Poul Sander 2023-09-22 19:25 12174
2660ccea Poul Sander 2023-09-22 19:25 12175
        std::size_t array_index = 0ul;
2660ccea Poul Sander 2023-09-22 19:25 12176
2660ccea Poul Sander 2023-09-22 19:25 12177
        for (const auto& el : value)
2660ccea Poul Sander 2023-09-22 19:25 12178
        {
2660ccea Poul Sander 2023-09-22 19:25 12179
            write_bson_element(std::to_string(array_index++), el);
2660ccea Poul Sander 2023-09-22 19:25 12180
        }
2660ccea Poul Sander 2023-09-22 19:25 12181
2660ccea Poul Sander 2023-09-22 19:25 12182
        oa->write_character(to_char_type(0x00));
2660ccea Poul Sander 2023-09-22 19:25 12183
    }
2660ccea Poul Sander 2023-09-22 19:25 12184
2660ccea Poul Sander 2023-09-22 19:25 12185
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12186
    @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
2660ccea Poul Sander 2023-09-22 19:25 12187
    @return The calculated size for the BSON document entry for @a j with the given @a name.
2660ccea Poul Sander 2023-09-22 19:25 12188
    */
2660ccea Poul Sander 2023-09-22 19:25 12189
    static std::size_t calc_bson_element_size(const string_t& name,
2660ccea Poul Sander 2023-09-22 19:25 12190
            const BasicJsonType& j)
2660ccea Poul Sander 2023-09-22 19:25 12191
    {
2660ccea Poul Sander 2023-09-22 19:25 12192
        const auto header_size = calc_bson_entry_header_size(name);
2660ccea Poul Sander 2023-09-22 19:25 12193
        switch (j.type())
2660ccea Poul Sander 2023-09-22 19:25 12194
        {
2660ccea Poul Sander 2023-09-22 19:25 12195
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 12196
                return header_size + calc_bson_object_size(*j.m_value.object);
2660ccea Poul Sander 2023-09-22 19:25 12197
2660ccea Poul Sander 2023-09-22 19:25 12198
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 12199
                return header_size + calc_bson_array_size(*j.m_value.array);
2660ccea Poul Sander 2023-09-22 19:25 12200
2660ccea Poul Sander 2023-09-22 19:25 12201
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 12202
                return header_size + 1ul;
2660ccea Poul Sander 2023-09-22 19:25 12203
2660ccea Poul Sander 2023-09-22 19:25 12204
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 12205
                return header_size + 8ul;
2660ccea Poul Sander 2023-09-22 19:25 12206
2660ccea Poul Sander 2023-09-22 19:25 12207
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 12208
                return header_size + calc_bson_integer_size(j.m_value.number_integer);
2660ccea Poul Sander 2023-09-22 19:25 12209
2660ccea Poul Sander 2023-09-22 19:25 12210
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 12211
                return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
2660ccea Poul Sander 2023-09-22 19:25 12212
2660ccea Poul Sander 2023-09-22 19:25 12213
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 12214
                return header_size + calc_bson_string_size(*j.m_value.string);
2660ccea Poul Sander 2023-09-22 19:25 12215
2660ccea Poul Sander 2023-09-22 19:25 12216
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 12217
                return header_size + 0ul;
2660ccea Poul Sander 2023-09-22 19:25 12218
2660ccea Poul Sander 2023-09-22 19:25 12219
            // LCOV_EXCL_START
2660ccea Poul Sander 2023-09-22 19:25 12220
            default:
2660ccea Poul Sander 2023-09-22 19:25 12221
                assert(false);
2660ccea Poul Sander 2023-09-22 19:25 12222
                return 0ul;
2660ccea Poul Sander 2023-09-22 19:25 12223
                // LCOV_EXCL_STOP
2660ccea Poul Sander 2023-09-22 19:25 12224
        }
2660ccea Poul Sander 2023-09-22 19:25 12225
    }
2660ccea Poul Sander 2023-09-22 19:25 12226
2660ccea Poul Sander 2023-09-22 19:25 12227
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12228
    @brief Serializes the JSON value @a j to BSON and associates it with the
2660ccea Poul Sander 2023-09-22 19:25 12229
           key @a name.
2660ccea Poul Sander 2023-09-22 19:25 12230
    @param name The name to associate with the JSON entity @a j within the
2660ccea Poul Sander 2023-09-22 19:25 12231
                current BSON document
2660ccea Poul Sander 2023-09-22 19:25 12232
    @return The size of the BSON entry
2660ccea Poul Sander 2023-09-22 19:25 12233
    */
2660ccea Poul Sander 2023-09-22 19:25 12234
    void write_bson_element(const string_t& name,
2660ccea Poul Sander 2023-09-22 19:25 12235
                            const BasicJsonType& j)
2660ccea Poul Sander 2023-09-22 19:25 12236
    {
2660ccea Poul Sander 2023-09-22 19:25 12237
        switch (j.type())
2660ccea Poul Sander 2023-09-22 19:25 12238
        {
2660ccea Poul Sander 2023-09-22 19:25 12239
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 12240
                return write_bson_object_entry(name, *j.m_value.object);
2660ccea Poul Sander 2023-09-22 19:25 12241
2660ccea Poul Sander 2023-09-22 19:25 12242
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 12243
                return write_bson_array(name, *j.m_value.array);
2660ccea Poul Sander 2023-09-22 19:25 12244
2660ccea Poul Sander 2023-09-22 19:25 12245
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 12246
                return write_bson_boolean(name, j.m_value.boolean);
2660ccea Poul Sander 2023-09-22 19:25 12247
2660ccea Poul Sander 2023-09-22 19:25 12248
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 12249
                return write_bson_double(name, j.m_value.number_float);
2660ccea Poul Sander 2023-09-22 19:25 12250
2660ccea Poul Sander 2023-09-22 19:25 12251
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 12252
                return write_bson_integer(name, j.m_value.number_integer);
2660ccea Poul Sander 2023-09-22 19:25 12253
2660ccea Poul Sander 2023-09-22 19:25 12254
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 12255
                return write_bson_unsigned(name, j.m_value.number_unsigned);
2660ccea Poul Sander 2023-09-22 19:25 12256
2660ccea Poul Sander 2023-09-22 19:25 12257
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 12258
                return write_bson_string(name, *j.m_value.string);
2660ccea Poul Sander 2023-09-22 19:25 12259
2660ccea Poul Sander 2023-09-22 19:25 12260
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 12261
                return write_bson_null(name);
2660ccea Poul Sander 2023-09-22 19:25 12262
2660ccea Poul Sander 2023-09-22 19:25 12263
            // LCOV_EXCL_START
2660ccea Poul Sander 2023-09-22 19:25 12264
            default:
2660ccea Poul Sander 2023-09-22 19:25 12265
                assert(false);
2660ccea Poul Sander 2023-09-22 19:25 12266
                return;
2660ccea Poul Sander 2023-09-22 19:25 12267
                // LCOV_EXCL_STOP
2660ccea Poul Sander 2023-09-22 19:25 12268
        }
2660ccea Poul Sander 2023-09-22 19:25 12269
    }
2660ccea Poul Sander 2023-09-22 19:25 12270
2660ccea Poul Sander 2023-09-22 19:25 12271
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12272
    @brief Calculates the size of the BSON serialization of the given
2660ccea Poul Sander 2023-09-22 19:25 12273
           JSON-object @a j.
2660ccea Poul Sander 2023-09-22 19:25 12274
    @param[in] j  JSON value to serialize
2660ccea Poul Sander 2023-09-22 19:25 12275
    @pre       j.type() == value_t::object
2660ccea Poul Sander 2023-09-22 19:25 12276
    */
2660ccea Poul Sander 2023-09-22 19:25 12277
    static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
2660ccea Poul Sander 2023-09-22 19:25 12278
    {
2660ccea Poul Sander 2023-09-22 19:25 12279
        std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
2660ccea Poul Sander 2023-09-22 19:25 12280
                                    [](size_t result, const typename BasicJsonType::object_t::value_type & el)
2660ccea Poul Sander 2023-09-22 19:25 12281
        {
2660ccea Poul Sander 2023-09-22 19:25 12282
            return result += calc_bson_element_size(el.first, el.second);
2660ccea Poul Sander 2023-09-22 19:25 12283
        });
2660ccea Poul Sander 2023-09-22 19:25 12284
2660ccea Poul Sander 2023-09-22 19:25 12285
        return sizeof(std::int32_t) + document_size + 1ul;
2660ccea Poul Sander 2023-09-22 19:25 12286
    }
2660ccea Poul Sander 2023-09-22 19:25 12287
2660ccea Poul Sander 2023-09-22 19:25 12288
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12289
    @param[in] j  JSON value to serialize
2660ccea Poul Sander 2023-09-22 19:25 12290
    @pre       j.type() == value_t::object
2660ccea Poul Sander 2023-09-22 19:25 12291
    */
2660ccea Poul Sander 2023-09-22 19:25 12292
    void write_bson_object(const typename BasicJsonType::object_t& value)
2660ccea Poul Sander 2023-09-22 19:25 12293
    {
2660ccea Poul Sander 2023-09-22 19:25 12294
        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
2660ccea Poul Sander 2023-09-22 19:25 12295
2660ccea Poul Sander 2023-09-22 19:25 12296
        for (const auto& el : value)
2660ccea Poul Sander 2023-09-22 19:25 12297
        {
2660ccea Poul Sander 2023-09-22 19:25 12298
            write_bson_element(el.first, el.second);
2660ccea Poul Sander 2023-09-22 19:25 12299
        }
2660ccea Poul Sander 2023-09-22 19:25 12300
2660ccea Poul Sander 2023-09-22 19:25 12301
        oa->write_character(to_char_type(0x00));
2660ccea Poul Sander 2023-09-22 19:25 12302
    }
2660ccea Poul Sander 2023-09-22 19:25 12303
2660ccea Poul Sander 2023-09-22 19:25 12304
    //////////
2660ccea Poul Sander 2023-09-22 19:25 12305
    // CBOR //
2660ccea Poul Sander 2023-09-22 19:25 12306
    //////////
2660ccea Poul Sander 2023-09-22 19:25 12307
2660ccea Poul Sander 2023-09-22 19:25 12308
    static constexpr CharType get_cbor_float_prefix(float /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 12309
    {
2660ccea Poul Sander 2023-09-22 19:25 12310
        return to_char_type(0xFA);  // Single-Precision Float
2660ccea Poul Sander 2023-09-22 19:25 12311
    }
2660ccea Poul Sander 2023-09-22 19:25 12312
2660ccea Poul Sander 2023-09-22 19:25 12313
    static constexpr CharType get_cbor_float_prefix(double /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 12314
    {
2660ccea Poul Sander 2023-09-22 19:25 12315
        return to_char_type(0xFB);  // Double-Precision Float
2660ccea Poul Sander 2023-09-22 19:25 12316
    }
2660ccea Poul Sander 2023-09-22 19:25 12317
2660ccea Poul Sander 2023-09-22 19:25 12318
    /////////////
2660ccea Poul Sander 2023-09-22 19:25 12319
    // MsgPack //
2660ccea Poul Sander 2023-09-22 19:25 12320
    /////////////
2660ccea Poul Sander 2023-09-22 19:25 12321
2660ccea Poul Sander 2023-09-22 19:25 12322
    static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 12323
    {
2660ccea Poul Sander 2023-09-22 19:25 12324
        return to_char_type(0xCA);  // float 32
2660ccea Poul Sander 2023-09-22 19:25 12325
    }
2660ccea Poul Sander 2023-09-22 19:25 12326
2660ccea Poul Sander 2023-09-22 19:25 12327
    static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 12328
    {
2660ccea Poul Sander 2023-09-22 19:25 12329
        return to_char_type(0xCB);  // float 64
2660ccea Poul Sander 2023-09-22 19:25 12330
    }
2660ccea Poul Sander 2023-09-22 19:25 12331
2660ccea Poul Sander 2023-09-22 19:25 12332
    ////////////
2660ccea Poul Sander 2023-09-22 19:25 12333
    // UBJSON //
2660ccea Poul Sander 2023-09-22 19:25 12334
    ////////////
2660ccea Poul Sander 2023-09-22 19:25 12335
2660ccea Poul Sander 2023-09-22 19:25 12336
    // UBJSON: write number (floating point)
2660ccea Poul Sander 2023-09-22 19:25 12337
    template<typename NumberType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 12338
                 std::is_floating_point<NumberType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 12339
    void write_number_with_ubjson_prefix(const NumberType n,
2660ccea Poul Sander 2023-09-22 19:25 12340
                                         const bool add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12341
    {
2660ccea Poul Sander 2023-09-22 19:25 12342
        if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12343
        {
2660ccea Poul Sander 2023-09-22 19:25 12344
            oa->write_character(get_ubjson_float_prefix(n));
2660ccea Poul Sander 2023-09-22 19:25 12345
        }
2660ccea Poul Sander 2023-09-22 19:25 12346
        write_number(n);
2660ccea Poul Sander 2023-09-22 19:25 12347
    }
2660ccea Poul Sander 2023-09-22 19:25 12348
2660ccea Poul Sander 2023-09-22 19:25 12349
    // UBJSON: write number (unsigned integer)
2660ccea Poul Sander 2023-09-22 19:25 12350
    template<typename NumberType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 12351
                 std::is_unsigned<NumberType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 12352
    void write_number_with_ubjson_prefix(const NumberType n,
2660ccea Poul Sander 2023-09-22 19:25 12353
                                         const bool add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12354
    {
2660ccea Poul Sander 2023-09-22 19:25 12355
        if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12356
        {
2660ccea Poul Sander 2023-09-22 19:25 12357
            if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12358
            {
2660ccea Poul Sander 2023-09-22 19:25 12359
                oa->write_character(to_char_type('i'));  // int8
2660ccea Poul Sander 2023-09-22 19:25 12360
            }
2660ccea Poul Sander 2023-09-22 19:25 12361
            write_number(static_cast<std::uint8_t>(n));
2660ccea Poul Sander 2023-09-22 19:25 12362
        }
2660ccea Poul Sander 2023-09-22 19:25 12363
        else if (n <= (std::numeric_limits<std::uint8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 12364
        {
2660ccea Poul Sander 2023-09-22 19:25 12365
            if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12366
            {
2660ccea Poul Sander 2023-09-22 19:25 12367
                oa->write_character(to_char_type('U'));  // uint8
2660ccea Poul Sander 2023-09-22 19:25 12368
            }
2660ccea Poul Sander 2023-09-22 19:25 12369
            write_number(static_cast<std::uint8_t>(n));
2660ccea Poul Sander 2023-09-22 19:25 12370
        }
2660ccea Poul Sander 2023-09-22 19:25 12371
        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12372
        {
2660ccea Poul Sander 2023-09-22 19:25 12373
            if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12374
            {
2660ccea Poul Sander 2023-09-22 19:25 12375
                oa->write_character(to_char_type('I'));  // int16
2660ccea Poul Sander 2023-09-22 19:25 12376
            }
2660ccea Poul Sander 2023-09-22 19:25 12377
            write_number(static_cast<std::int16_t>(n));
2660ccea Poul Sander 2023-09-22 19:25 12378
        }
2660ccea Poul Sander 2023-09-22 19:25 12379
        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12380
        {
2660ccea Poul Sander 2023-09-22 19:25 12381
            if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12382
            {
2660ccea Poul Sander 2023-09-22 19:25 12383
                oa->write_character(to_char_type('l'));  // int32
2660ccea Poul Sander 2023-09-22 19:25 12384
            }
2660ccea Poul Sander 2023-09-22 19:25 12385
            write_number(static_cast<std::int32_t>(n));
2660ccea Poul Sander 2023-09-22 19:25 12386
        }
2660ccea Poul Sander 2023-09-22 19:25 12387
        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12388
        {
2660ccea Poul Sander 2023-09-22 19:25 12389
            if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12390
            {
2660ccea Poul Sander 2023-09-22 19:25 12391
                oa->write_character(to_char_type('L'));  // int64
2660ccea Poul Sander 2023-09-22 19:25 12392
            }
2660ccea Poul Sander 2023-09-22 19:25 12393
            write_number(static_cast<std::int64_t>(n));
2660ccea Poul Sander 2023-09-22 19:25 12394
        }
2660ccea Poul Sander 2023-09-22 19:25 12395
        else
2660ccea Poul Sander 2023-09-22 19:25 12396
        {
2660ccea Poul Sander 2023-09-22 19:25 12397
            JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
2660ccea Poul Sander 2023-09-22 19:25 12398
        }
2660ccea Poul Sander 2023-09-22 19:25 12399
    }
2660ccea Poul Sander 2023-09-22 19:25 12400
2660ccea Poul Sander 2023-09-22 19:25 12401
    // UBJSON: write number (signed integer)
2660ccea Poul Sander 2023-09-22 19:25 12402
    template<typename NumberType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 12403
                 std::is_signed<NumberType>::value and
2660ccea Poul Sander 2023-09-22 19:25 12404
                 not std::is_floating_point<NumberType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 12405
    void write_number_with_ubjson_prefix(const NumberType n,
2660ccea Poul Sander 2023-09-22 19:25 12406
                                         const bool add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12407
    {
2660ccea Poul Sander 2023-09-22 19:25 12408
        if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 12409
        {
2660ccea Poul Sander 2023-09-22 19:25 12410
            if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12411
            {
2660ccea Poul Sander 2023-09-22 19:25 12412
                oa->write_character(to_char_type('i'));  // int8
2660ccea Poul Sander 2023-09-22 19:25 12413
            }
2660ccea Poul Sander 2023-09-22 19:25 12414
            write_number(static_cast<std::int8_t>(n));
2660ccea Poul Sander 2023-09-22 19:25 12415
        }
2660ccea Poul Sander 2023-09-22 19:25 12416
        else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n and n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12417
        {
2660ccea Poul Sander 2023-09-22 19:25 12418
            if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12419
            {
2660ccea Poul Sander 2023-09-22 19:25 12420
                oa->write_character(to_char_type('U'));  // uint8
2660ccea Poul Sander 2023-09-22 19:25 12421
            }
2660ccea Poul Sander 2023-09-22 19:25 12422
            write_number(static_cast<std::uint8_t>(n));
2660ccea Poul Sander 2023-09-22 19:25 12423
        }
2660ccea Poul Sander 2023-09-22 19:25 12424
        else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 12425
        {
2660ccea Poul Sander 2023-09-22 19:25 12426
            if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12427
            {
2660ccea Poul Sander 2023-09-22 19:25 12428
                oa->write_character(to_char_type('I'));  // int16
2660ccea Poul Sander 2023-09-22 19:25 12429
            }
2660ccea Poul Sander 2023-09-22 19:25 12430
            write_number(static_cast<std::int16_t>(n));
2660ccea Poul Sander 2023-09-22 19:25 12431
        }
2660ccea Poul Sander 2023-09-22 19:25 12432
        else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 12433
        {
2660ccea Poul Sander 2023-09-22 19:25 12434
            if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12435
            {
2660ccea Poul Sander 2023-09-22 19:25 12436
                oa->write_character(to_char_type('l'));  // int32
2660ccea Poul Sander 2023-09-22 19:25 12437
            }
2660ccea Poul Sander 2023-09-22 19:25 12438
            write_number(static_cast<std::int32_t>(n));
2660ccea Poul Sander 2023-09-22 19:25 12439
        }
2660ccea Poul Sander 2023-09-22 19:25 12440
        else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 12441
        {
2660ccea Poul Sander 2023-09-22 19:25 12442
            if (add_prefix)
2660ccea Poul Sander 2023-09-22 19:25 12443
            {
2660ccea Poul Sander 2023-09-22 19:25 12444
                oa->write_character(to_char_type('L'));  // int64
2660ccea Poul Sander 2023-09-22 19:25 12445
            }
2660ccea Poul Sander 2023-09-22 19:25 12446
            write_number(static_cast<std::int64_t>(n));
2660ccea Poul Sander 2023-09-22 19:25 12447
        }
2660ccea Poul Sander 2023-09-22 19:25 12448
        // LCOV_EXCL_START
2660ccea Poul Sander 2023-09-22 19:25 12449
        else
2660ccea Poul Sander 2023-09-22 19:25 12450
        {
2660ccea Poul Sander 2023-09-22 19:25 12451
            JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
2660ccea Poul Sander 2023-09-22 19:25 12452
        }
2660ccea Poul Sander 2023-09-22 19:25 12453
        // LCOV_EXCL_STOP
2660ccea Poul Sander 2023-09-22 19:25 12454
    }
2660ccea Poul Sander 2023-09-22 19:25 12455
2660ccea Poul Sander 2023-09-22 19:25 12456
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12457
    @brief determine the type prefix of container values
2660ccea Poul Sander 2023-09-22 19:25 12458
2660ccea Poul Sander 2023-09-22 19:25 12459
    @note This function does not need to be 100% accurate when it comes to
2660ccea Poul Sander 2023-09-22 19:25 12460
          integer limits. In case a number exceeds the limits of int64_t,
2660ccea Poul Sander 2023-09-22 19:25 12461
          this will be detected by a later call to function
2660ccea Poul Sander 2023-09-22 19:25 12462
          write_number_with_ubjson_prefix. Therefore, we return 'L' for any
2660ccea Poul Sander 2023-09-22 19:25 12463
          value that does not fit the previous limits.
2660ccea Poul Sander 2023-09-22 19:25 12464
    */
2660ccea Poul Sander 2023-09-22 19:25 12465
    CharType ubjson_prefix(const BasicJsonType& j) const noexcept
2660ccea Poul Sander 2023-09-22 19:25 12466
    {
2660ccea Poul Sander 2023-09-22 19:25 12467
        switch (j.type())
2660ccea Poul Sander 2023-09-22 19:25 12468
        {
2660ccea Poul Sander 2023-09-22 19:25 12469
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 12470
                return 'Z';
2660ccea Poul Sander 2023-09-22 19:25 12471
2660ccea Poul Sander 2023-09-22 19:25 12472
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 12473
                return j.m_value.boolean ? 'T' : 'F';
2660ccea Poul Sander 2023-09-22 19:25 12474
2660ccea Poul Sander 2023-09-22 19:25 12475
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 12476
            {
2660ccea Poul Sander 2023-09-22 19:25 12477
                if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 12478
                {
2660ccea Poul Sander 2023-09-22 19:25 12479
                    return 'i';
2660ccea Poul Sander 2023-09-22 19:25 12480
                }
2660ccea Poul Sander 2023-09-22 19:25 12481
                if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 12482
                {
2660ccea Poul Sander 2023-09-22 19:25 12483
                    return 'U';
2660ccea Poul Sander 2023-09-22 19:25 12484
                }
2660ccea Poul Sander 2023-09-22 19:25 12485
                if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 12486
                {
2660ccea Poul Sander 2023-09-22 19:25 12487
                    return 'I';
2660ccea Poul Sander 2023-09-22 19:25 12488
                }
2660ccea Poul Sander 2023-09-22 19:25 12489
                if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
2660ccea Poul Sander 2023-09-22 19:25 12490
                {
2660ccea Poul Sander 2023-09-22 19:25 12491
                    return 'l';
2660ccea Poul Sander 2023-09-22 19:25 12492
                }
2660ccea Poul Sander 2023-09-22 19:25 12493
                // no check and assume int64_t (see note above)
2660ccea Poul Sander 2023-09-22 19:25 12494
                return 'L';
2660ccea Poul Sander 2023-09-22 19:25 12495
            }
2660ccea Poul Sander 2023-09-22 19:25 12496
2660ccea Poul Sander 2023-09-22 19:25 12497
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 12498
            {
2660ccea Poul Sander 2023-09-22 19:25 12499
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12500
                {
2660ccea Poul Sander 2023-09-22 19:25 12501
                    return 'i';
2660ccea Poul Sander 2023-09-22 19:25 12502
                }
2660ccea Poul Sander 2023-09-22 19:25 12503
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12504
                {
2660ccea Poul Sander 2023-09-22 19:25 12505
                    return 'U';
2660ccea Poul Sander 2023-09-22 19:25 12506
                }
2660ccea Poul Sander 2023-09-22 19:25 12507
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12508
                {
2660ccea Poul Sander 2023-09-22 19:25 12509
                    return 'I';
2660ccea Poul Sander 2023-09-22 19:25 12510
                }
2660ccea Poul Sander 2023-09-22 19:25 12511
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
2660ccea Poul Sander 2023-09-22 19:25 12512
                {
2660ccea Poul Sander 2023-09-22 19:25 12513
                    return 'l';
2660ccea Poul Sander 2023-09-22 19:25 12514
                }
2660ccea Poul Sander 2023-09-22 19:25 12515
                // no check and assume int64_t (see note above)
2660ccea Poul Sander 2023-09-22 19:25 12516
                return 'L';
2660ccea Poul Sander 2023-09-22 19:25 12517
            }
2660ccea Poul Sander 2023-09-22 19:25 12518
2660ccea Poul Sander 2023-09-22 19:25 12519
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 12520
                return get_ubjson_float_prefix(j.m_value.number_float);
2660ccea Poul Sander 2023-09-22 19:25 12521
2660ccea Poul Sander 2023-09-22 19:25 12522
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 12523
                return 'S';
2660ccea Poul Sander 2023-09-22 19:25 12524
2660ccea Poul Sander 2023-09-22 19:25 12525
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 12526
                return '[';
2660ccea Poul Sander 2023-09-22 19:25 12527
2660ccea Poul Sander 2023-09-22 19:25 12528
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 12529
                return '{';
2660ccea Poul Sander 2023-09-22 19:25 12530
2660ccea Poul Sander 2023-09-22 19:25 12531
            default:  // discarded values
2660ccea Poul Sander 2023-09-22 19:25 12532
                return 'N';
2660ccea Poul Sander 2023-09-22 19:25 12533
        }
2660ccea Poul Sander 2023-09-22 19:25 12534
    }
2660ccea Poul Sander 2023-09-22 19:25 12535
2660ccea Poul Sander 2023-09-22 19:25 12536
    static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 12537
    {
2660ccea Poul Sander 2023-09-22 19:25 12538
        return 'd';  // float 32
2660ccea Poul Sander 2023-09-22 19:25 12539
    }
2660ccea Poul Sander 2023-09-22 19:25 12540
2660ccea Poul Sander 2023-09-22 19:25 12541
    static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
2660ccea Poul Sander 2023-09-22 19:25 12542
    {
2660ccea Poul Sander 2023-09-22 19:25 12543
        return 'D';  // float 64
2660ccea Poul Sander 2023-09-22 19:25 12544
    }
2660ccea Poul Sander 2023-09-22 19:25 12545
2660ccea Poul Sander 2023-09-22 19:25 12546
    ///////////////////////
2660ccea Poul Sander 2023-09-22 19:25 12547
    // Utility functions //
2660ccea Poul Sander 2023-09-22 19:25 12548
    ///////////////////////
2660ccea Poul Sander 2023-09-22 19:25 12549
2660ccea Poul Sander 2023-09-22 19:25 12550
    /*
2660ccea Poul Sander 2023-09-22 19:25 12551
    @brief write a number to output input
2660ccea Poul Sander 2023-09-22 19:25 12552
    @param[in] n number of type @a NumberType
2660ccea Poul Sander 2023-09-22 19:25 12553
    @tparam NumberType the type of the number
2660ccea Poul Sander 2023-09-22 19:25 12554
    @tparam OutputIsLittleEndian Set to true if output data is
2660ccea Poul Sander 2023-09-22 19:25 12555
                                 required to be little endian
2660ccea Poul Sander 2023-09-22 19:25 12556
2660ccea Poul Sander 2023-09-22 19:25 12557
    @note This function needs to respect the system's endianess, because bytes
2660ccea Poul Sander 2023-09-22 19:25 12558
          in CBOR, MessagePack, and UBJSON are stored in network order (big
2660ccea Poul Sander 2023-09-22 19:25 12559
          endian) and therefore need reordering on little endian systems.
2660ccea Poul Sander 2023-09-22 19:25 12560
    */
2660ccea Poul Sander 2023-09-22 19:25 12561
    template<typename NumberType, bool OutputIsLittleEndian = false>
2660ccea Poul Sander 2023-09-22 19:25 12562
    void write_number(const NumberType n)
2660ccea Poul Sander 2023-09-22 19:25 12563
    {
2660ccea Poul Sander 2023-09-22 19:25 12564
        // step 1: write number to array of length NumberType
2660ccea Poul Sander 2023-09-22 19:25 12565
        std::array<CharType, sizeof(NumberType)> vec;
2660ccea Poul Sander 2023-09-22 19:25 12566
        std::memcpy(vec.data(), &n, sizeof(NumberType));
2660ccea Poul Sander 2023-09-22 19:25 12567
2660ccea Poul Sander 2023-09-22 19:25 12568
        // step 2: write array to output (with possible reordering)
2660ccea Poul Sander 2023-09-22 19:25 12569
        if (is_little_endian != OutputIsLittleEndian)
2660ccea Poul Sander 2023-09-22 19:25 12570
        {
2660ccea Poul Sander 2023-09-22 19:25 12571
            // reverse byte order prior to conversion if necessary
2660ccea Poul Sander 2023-09-22 19:25 12572
            std::reverse(vec.begin(), vec.end());
2660ccea Poul Sander 2023-09-22 19:25 12573
        }
2660ccea Poul Sander 2023-09-22 19:25 12574
2660ccea Poul Sander 2023-09-22 19:25 12575
        oa->write_characters(vec.data(), sizeof(NumberType));
2660ccea Poul Sander 2023-09-22 19:25 12576
    }
2660ccea Poul Sander 2023-09-22 19:25 12577
2660ccea Poul Sander 2023-09-22 19:25 12578
  public:
2660ccea Poul Sander 2023-09-22 19:25 12579
    // The following to_char_type functions are implement the conversion
2660ccea Poul Sander 2023-09-22 19:25 12580
    // between uint8_t and CharType. In case CharType is not unsigned,
2660ccea Poul Sander 2023-09-22 19:25 12581
    // such a conversion is required to allow values greater than 128.
2660ccea Poul Sander 2023-09-22 19:25 12582
    // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
2660ccea Poul Sander 2023-09-22 19:25 12583
    template < typename C = CharType,
2660ccea Poul Sander 2023-09-22 19:25 12584
               enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr >
2660ccea Poul Sander 2023-09-22 19:25 12585
    static constexpr CharType to_char_type(std::uint8_t x) noexcept
2660ccea Poul Sander 2023-09-22 19:25 12586
    {
2660ccea Poul Sander 2023-09-22 19:25 12587
        return *reinterpret_cast<char*>(&x);
2660ccea Poul Sander 2023-09-22 19:25 12588
    }
2660ccea Poul Sander 2023-09-22 19:25 12589
2660ccea Poul Sander 2023-09-22 19:25 12590
    template < typename C = CharType,
2660ccea Poul Sander 2023-09-22 19:25 12591
               enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr >
2660ccea Poul Sander 2023-09-22 19:25 12592
    static CharType to_char_type(std::uint8_t x) noexcept
2660ccea Poul Sander 2023-09-22 19:25 12593
    {
2660ccea Poul Sander 2023-09-22 19:25 12594
        static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
2660ccea Poul Sander 2023-09-22 19:25 12595
        static_assert(std::is_pod<CharType>::value, "CharType must be POD");
2660ccea Poul Sander 2023-09-22 19:25 12596
        CharType result;
2660ccea Poul Sander 2023-09-22 19:25 12597
        std::memcpy(&result, &x, sizeof(x));
2660ccea Poul Sander 2023-09-22 19:25 12598
        return result;
2660ccea Poul Sander 2023-09-22 19:25 12599
    }
2660ccea Poul Sander 2023-09-22 19:25 12600
2660ccea Poul Sander 2023-09-22 19:25 12601
    template<typename C = CharType,
2660ccea Poul Sander 2023-09-22 19:25 12602
             enable_if_t<std::is_unsigned<C>::value>* = nullptr>
2660ccea Poul Sander 2023-09-22 19:25 12603
    static constexpr CharType to_char_type(std::uint8_t x) noexcept
2660ccea Poul Sander 2023-09-22 19:25 12604
    {
2660ccea Poul Sander 2023-09-22 19:25 12605
        return x;
2660ccea Poul Sander 2023-09-22 19:25 12606
    }
2660ccea Poul Sander 2023-09-22 19:25 12607
2660ccea Poul Sander 2023-09-22 19:25 12608
    template < typename InputCharType, typename C = CharType,
2660ccea Poul Sander 2023-09-22 19:25 12609
               enable_if_t <
2660ccea Poul Sander 2023-09-22 19:25 12610
                   std::is_signed<C>::value and
2660ccea Poul Sander 2023-09-22 19:25 12611
                   std::is_signed<char>::value and
2660ccea Poul Sander 2023-09-22 19:25 12612
                   std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
2660ccea Poul Sander 2023-09-22 19:25 12613
                   > * = nullptr >
2660ccea Poul Sander 2023-09-22 19:25 12614
    static constexpr CharType to_char_type(InputCharType x) noexcept
2660ccea Poul Sander 2023-09-22 19:25 12615
    {
2660ccea Poul Sander 2023-09-22 19:25 12616
        return x;
2660ccea Poul Sander 2023-09-22 19:25 12617
    }
2660ccea Poul Sander 2023-09-22 19:25 12618
2660ccea Poul Sander 2023-09-22 19:25 12619
  private:
2660ccea Poul Sander 2023-09-22 19:25 12620
    /// whether we can assume little endianess
2660ccea Poul Sander 2023-09-22 19:25 12621
    const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
2660ccea Poul Sander 2023-09-22 19:25 12622
2660ccea Poul Sander 2023-09-22 19:25 12623
    /// the output
2660ccea Poul Sander 2023-09-22 19:25 12624
    output_adapter_t<CharType> oa = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 12625
};
2660ccea Poul Sander 2023-09-22 19:25 12626
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 12627
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 12628
2660ccea Poul Sander 2023-09-22 19:25 12629
// #include <nlohmann/detail/output/output_adapters.hpp>
2660ccea Poul Sander 2023-09-22 19:25 12630
2660ccea Poul Sander 2023-09-22 19:25 12631
// #include <nlohmann/detail/output/serializer.hpp>
2660ccea Poul Sander 2023-09-22 19:25 12632
2660ccea Poul Sander 2023-09-22 19:25 12633
2660ccea Poul Sander 2023-09-22 19:25 12634
#include <algorithm> // reverse, remove, fill, find, none_of
2660ccea Poul Sander 2023-09-22 19:25 12635
#include <array> // array
2660ccea Poul Sander 2023-09-22 19:25 12636
#include <cassert> // assert
2660ccea Poul Sander 2023-09-22 19:25 12637
#include <ciso646> // and, or
2660ccea Poul Sander 2023-09-22 19:25 12638
#include <clocale> // localeconv, lconv
2660ccea Poul Sander 2023-09-22 19:25 12639
#include <cmath> // labs, isfinite, isnan, signbit
2660ccea Poul Sander 2023-09-22 19:25 12640
#include <cstddef> // size_t, ptrdiff_t
2660ccea Poul Sander 2023-09-22 19:25 12641
#include <cstdint> // uint8_t
2660ccea Poul Sander 2023-09-22 19:25 12642
#include <cstdio> // snprintf
2660ccea Poul Sander 2023-09-22 19:25 12643
#include <limits> // numeric_limits
2660ccea Poul Sander 2023-09-22 19:25 12644
#include <string> // string
2660ccea Poul Sander 2023-09-22 19:25 12645
#include <type_traits> // is_same
2660ccea Poul Sander 2023-09-22 19:25 12646
#include <utility> // move
2660ccea Poul Sander 2023-09-22 19:25 12647
2660ccea Poul Sander 2023-09-22 19:25 12648
// #include <nlohmann/detail/conversions/to_chars.hpp>
2660ccea Poul Sander 2023-09-22 19:25 12649
2660ccea Poul Sander 2023-09-22 19:25 12650
2660ccea Poul Sander 2023-09-22 19:25 12651
#include <array> // array
2660ccea Poul Sander 2023-09-22 19:25 12652
#include <cassert> // assert
2660ccea Poul Sander 2023-09-22 19:25 12653
#include <ciso646> // or, and, not
2660ccea Poul Sander 2023-09-22 19:25 12654
#include <cmath>   // signbit, isfinite
2660ccea Poul Sander 2023-09-22 19:25 12655
#include <cstdint> // intN_t, uintN_t
2660ccea Poul Sander 2023-09-22 19:25 12656
#include <cstring> // memcpy, memmove
2660ccea Poul Sander 2023-09-22 19:25 12657
#include <limits> // numeric_limits
2660ccea Poul Sander 2023-09-22 19:25 12658
#include <type_traits> // conditional
2660ccea Poul Sander 2023-09-22 19:25 12659
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 12660
2660ccea Poul Sander 2023-09-22 19:25 12661
2660ccea Poul Sander 2023-09-22 19:25 12662
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 12663
{
2660ccea Poul Sander 2023-09-22 19:25 12664
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 12665
{
2660ccea Poul Sander 2023-09-22 19:25 12666
2660ccea Poul Sander 2023-09-22 19:25 12667
/*!
2660ccea Poul Sander 2023-09-22 19:25 12668
@brief implements the Grisu2 algorithm for binary to decimal floating-point
2660ccea Poul Sander 2023-09-22 19:25 12669
conversion.
2660ccea Poul Sander 2023-09-22 19:25 12670
2660ccea Poul Sander 2023-09-22 19:25 12671
This implementation is a slightly modified version of the reference
2660ccea Poul Sander 2023-09-22 19:25 12672
implementation which may be obtained from
2660ccea Poul Sander 2023-09-22 19:25 12673
http://florian.loitsch.com/publications (bench.tar.gz).
2660ccea Poul Sander 2023-09-22 19:25 12674
2660ccea Poul Sander 2023-09-22 19:25 12675
The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
2660ccea Poul Sander 2023-09-22 19:25 12676
2660ccea Poul Sander 2023-09-22 19:25 12677
For a detailed description of the algorithm see:
2660ccea Poul Sander 2023-09-22 19:25 12678
2660ccea Poul Sander 2023-09-22 19:25 12679
[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
2660ccea Poul Sander 2023-09-22 19:25 12680
    Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
2660ccea Poul Sander 2023-09-22 19:25 12681
    Language Design and Implementation, PLDI 2010
2660ccea Poul Sander 2023-09-22 19:25 12682
[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
2660ccea Poul Sander 2023-09-22 19:25 12683
    Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
2660ccea Poul Sander 2023-09-22 19:25 12684
    Design and Implementation, PLDI 1996
2660ccea Poul Sander 2023-09-22 19:25 12685
*/
2660ccea Poul Sander 2023-09-22 19:25 12686
namespace dtoa_impl
2660ccea Poul Sander 2023-09-22 19:25 12687
{
2660ccea Poul Sander 2023-09-22 19:25 12688
2660ccea Poul Sander 2023-09-22 19:25 12689
template <typename Target, typename Source>
2660ccea Poul Sander 2023-09-22 19:25 12690
Target reinterpret_bits(const Source source)
2660ccea Poul Sander 2023-09-22 19:25 12691
{
2660ccea Poul Sander 2023-09-22 19:25 12692
    static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
2660ccea Poul Sander 2023-09-22 19:25 12693
2660ccea Poul Sander 2023-09-22 19:25 12694
    Target target;
2660ccea Poul Sander 2023-09-22 19:25 12695
    std::memcpy(&target, &source, sizeof(Source));
2660ccea Poul Sander 2023-09-22 19:25 12696
    return target;
2660ccea Poul Sander 2023-09-22 19:25 12697
}
2660ccea Poul Sander 2023-09-22 19:25 12698
2660ccea Poul Sander 2023-09-22 19:25 12699
struct diyfp // f * 2^e
2660ccea Poul Sander 2023-09-22 19:25 12700
{
2660ccea Poul Sander 2023-09-22 19:25 12701
    static constexpr int kPrecision = 64; // = q
2660ccea Poul Sander 2023-09-22 19:25 12702
2660ccea Poul Sander 2023-09-22 19:25 12703
    std::uint64_t f = 0;
2660ccea Poul Sander 2023-09-22 19:25 12704
    int e = 0;
2660ccea Poul Sander 2023-09-22 19:25 12705
2660ccea Poul Sander 2023-09-22 19:25 12706
    constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
2660ccea Poul Sander 2023-09-22 19:25 12707
2660ccea Poul Sander 2023-09-22 19:25 12708
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12709
    @brief returns x - y
2660ccea Poul Sander 2023-09-22 19:25 12710
    @pre x.e == y.e and x.f >= y.f
2660ccea Poul Sander 2023-09-22 19:25 12711
    */
2660ccea Poul Sander 2023-09-22 19:25 12712
    static diyfp sub(const diyfp& x, const diyfp& y) noexcept
2660ccea Poul Sander 2023-09-22 19:25 12713
    {
2660ccea Poul Sander 2023-09-22 19:25 12714
        assert(x.e == y.e);
2660ccea Poul Sander 2023-09-22 19:25 12715
        assert(x.f >= y.f);
2660ccea Poul Sander 2023-09-22 19:25 12716
2660ccea Poul Sander 2023-09-22 19:25 12717
        return {x.f - y.f, x.e};
2660ccea Poul Sander 2023-09-22 19:25 12718
    }
2660ccea Poul Sander 2023-09-22 19:25 12719
2660ccea Poul Sander 2023-09-22 19:25 12720
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12721
    @brief returns x * y
2660ccea Poul Sander 2023-09-22 19:25 12722
    @note The result is rounded. (Only the upper q bits are returned.)
2660ccea Poul Sander 2023-09-22 19:25 12723
    */
2660ccea Poul Sander 2023-09-22 19:25 12724
    static diyfp mul(const diyfp& x, const diyfp& y) noexcept
2660ccea Poul Sander 2023-09-22 19:25 12725
    {
2660ccea Poul Sander 2023-09-22 19:25 12726
        static_assert(kPrecision == 64, "internal error");
2660ccea Poul Sander 2023-09-22 19:25 12727
2660ccea Poul Sander 2023-09-22 19:25 12728
        // Computes:
2660ccea Poul Sander 2023-09-22 19:25 12729
        //  f = round((x.f * y.f) / 2^q)
2660ccea Poul Sander 2023-09-22 19:25 12730
        //  e = x.e + y.e + q
2660ccea Poul Sander 2023-09-22 19:25 12731
2660ccea Poul Sander 2023-09-22 19:25 12732
        // Emulate the 64-bit * 64-bit multiplication:
2660ccea Poul Sander 2023-09-22 19:25 12733
        //
2660ccea Poul Sander 2023-09-22 19:25 12734
        // p = u * v
2660ccea Poul Sander 2023-09-22 19:25 12735
        //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
2660ccea Poul Sander 2023-09-22 19:25 12736
        //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
2660ccea Poul Sander 2023-09-22 19:25 12737
        //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
2660ccea Poul Sander 2023-09-22 19:25 12738
        //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
2660ccea Poul Sander 2023-09-22 19:25 12739
        //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
2660ccea Poul Sander 2023-09-22 19:25 12740
        //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
2660ccea Poul Sander 2023-09-22 19:25 12741
        //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
2660ccea Poul Sander 2023-09-22 19:25 12742
        //
2660ccea Poul Sander 2023-09-22 19:25 12743
        // (Since Q might be larger than 2^32 - 1)
2660ccea Poul Sander 2023-09-22 19:25 12744
        //
2660ccea Poul Sander 2023-09-22 19:25 12745
        //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
2660ccea Poul Sander 2023-09-22 19:25 12746
        //
2660ccea Poul Sander 2023-09-22 19:25 12747
        // (Q_hi + H does not overflow a 64-bit int)
2660ccea Poul Sander 2023-09-22 19:25 12748
        //
2660ccea Poul Sander 2023-09-22 19:25 12749
        //   = p_lo + 2^64 p_hi
2660ccea Poul Sander 2023-09-22 19:25 12750
2660ccea Poul Sander 2023-09-22 19:25 12751
        const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
2660ccea Poul Sander 2023-09-22 19:25 12752
        const std::uint64_t u_hi = x.f >> 32u;
2660ccea Poul Sander 2023-09-22 19:25 12753
        const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
2660ccea Poul Sander 2023-09-22 19:25 12754
        const std::uint64_t v_hi = y.f >> 32u;
2660ccea Poul Sander 2023-09-22 19:25 12755
2660ccea Poul Sander 2023-09-22 19:25 12756
        const std::uint64_t p0 = u_lo * v_lo;
2660ccea Poul Sander 2023-09-22 19:25 12757
        const std::uint64_t p1 = u_lo * v_hi;
2660ccea Poul Sander 2023-09-22 19:25 12758
        const std::uint64_t p2 = u_hi * v_lo;
2660ccea Poul Sander 2023-09-22 19:25 12759
        const std::uint64_t p3 = u_hi * v_hi;
2660ccea Poul Sander 2023-09-22 19:25 12760
2660ccea Poul Sander 2023-09-22 19:25 12761
        const std::uint64_t p0_hi = p0 >> 32u;
2660ccea Poul Sander 2023-09-22 19:25 12762
        const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
2660ccea Poul Sander 2023-09-22 19:25 12763
        const std::uint64_t p1_hi = p1 >> 32u;
2660ccea Poul Sander 2023-09-22 19:25 12764
        const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
2660ccea Poul Sander 2023-09-22 19:25 12765
        const std::uint64_t p2_hi = p2 >> 32u;
2660ccea Poul Sander 2023-09-22 19:25 12766
2660ccea Poul Sander 2023-09-22 19:25 12767
        std::uint64_t Q = p0_hi + p1_lo + p2_lo;
2660ccea Poul Sander 2023-09-22 19:25 12768
2660ccea Poul Sander 2023-09-22 19:25 12769
        // The full product might now be computed as
2660ccea Poul Sander 2023-09-22 19:25 12770
        //
2660ccea Poul Sander 2023-09-22 19:25 12771
        // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
2660ccea Poul Sander 2023-09-22 19:25 12772
        // p_lo = p0_lo + (Q << 32)
2660ccea Poul Sander 2023-09-22 19:25 12773
        //
2660ccea Poul Sander 2023-09-22 19:25 12774
        // But in this particular case here, the full p_lo is not required.
2660ccea Poul Sander 2023-09-22 19:25 12775
        // Effectively we only need to add the highest bit in p_lo to p_hi (and
2660ccea Poul Sander 2023-09-22 19:25 12776
        // Q_hi + 1 does not overflow).
2660ccea Poul Sander 2023-09-22 19:25 12777
2660ccea Poul Sander 2023-09-22 19:25 12778
        Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
2660ccea Poul Sander 2023-09-22 19:25 12779
2660ccea Poul Sander 2023-09-22 19:25 12780
        const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
2660ccea Poul Sander 2023-09-22 19:25 12781
2660ccea Poul Sander 2023-09-22 19:25 12782
        return {h, x.e + y.e + 64};
2660ccea Poul Sander 2023-09-22 19:25 12783
    }
2660ccea Poul Sander 2023-09-22 19:25 12784
2660ccea Poul Sander 2023-09-22 19:25 12785
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12786
    @brief normalize x such that the significand is >= 2^(q-1)
2660ccea Poul Sander 2023-09-22 19:25 12787
    @pre x.f != 0
2660ccea Poul Sander 2023-09-22 19:25 12788
    */
2660ccea Poul Sander 2023-09-22 19:25 12789
    static diyfp normalize(diyfp x) noexcept
2660ccea Poul Sander 2023-09-22 19:25 12790
    {
2660ccea Poul Sander 2023-09-22 19:25 12791
        assert(x.f != 0);
2660ccea Poul Sander 2023-09-22 19:25 12792
2660ccea Poul Sander 2023-09-22 19:25 12793
        while ((x.f >> 63u) == 0)
2660ccea Poul Sander 2023-09-22 19:25 12794
        {
2660ccea Poul Sander 2023-09-22 19:25 12795
            x.f <<= 1u;
2660ccea Poul Sander 2023-09-22 19:25 12796
            x.e--;
2660ccea Poul Sander 2023-09-22 19:25 12797
        }
2660ccea Poul Sander 2023-09-22 19:25 12798
2660ccea Poul Sander 2023-09-22 19:25 12799
        return x;
2660ccea Poul Sander 2023-09-22 19:25 12800
    }
2660ccea Poul Sander 2023-09-22 19:25 12801
2660ccea Poul Sander 2023-09-22 19:25 12802
    /*!
2660ccea Poul Sander 2023-09-22 19:25 12803
    @brief normalize x such that the result has the exponent E
2660ccea Poul Sander 2023-09-22 19:25 12804
    @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
2660ccea Poul Sander 2023-09-22 19:25 12805
    */
2660ccea Poul Sander 2023-09-22 19:25 12806
    static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
2660ccea Poul Sander 2023-09-22 19:25 12807
    {
2660ccea Poul Sander 2023-09-22 19:25 12808
        const int delta = x.e - target_exponent;
2660ccea Poul Sander 2023-09-22 19:25 12809
2660ccea Poul Sander 2023-09-22 19:25 12810
        assert(delta >= 0);
2660ccea Poul Sander 2023-09-22 19:25 12811
        assert(((x.f << delta) >> delta) == x.f);
2660ccea Poul Sander 2023-09-22 19:25 12812
2660ccea Poul Sander 2023-09-22 19:25 12813
        return {x.f << delta, target_exponent};
2660ccea Poul Sander 2023-09-22 19:25 12814
    }
2660ccea Poul Sander 2023-09-22 19:25 12815
};
2660ccea Poul Sander 2023-09-22 19:25 12816
2660ccea Poul Sander 2023-09-22 19:25 12817
struct boundaries
2660ccea Poul Sander 2023-09-22 19:25 12818
{
2660ccea Poul Sander 2023-09-22 19:25 12819
    diyfp w;
2660ccea Poul Sander 2023-09-22 19:25 12820
    diyfp minus;
2660ccea Poul Sander 2023-09-22 19:25 12821
    diyfp plus;
2660ccea Poul Sander 2023-09-22 19:25 12822
};
2660ccea Poul Sander 2023-09-22 19:25 12823
2660ccea Poul Sander 2023-09-22 19:25 12824
/*!
2660ccea Poul Sander 2023-09-22 19:25 12825
Compute the (normalized) diyfp representing the input number 'value' and its
2660ccea Poul Sander 2023-09-22 19:25 12826
boundaries.
2660ccea Poul Sander 2023-09-22 19:25 12827
2660ccea Poul Sander 2023-09-22 19:25 12828
@pre value must be finite and positive
2660ccea Poul Sander 2023-09-22 19:25 12829
*/
2660ccea Poul Sander 2023-09-22 19:25 12830
template <typename FloatType>
2660ccea Poul Sander 2023-09-22 19:25 12831
boundaries compute_boundaries(FloatType value)
2660ccea Poul Sander 2023-09-22 19:25 12832
{
2660ccea Poul Sander 2023-09-22 19:25 12833
    assert(std::isfinite(value));
2660ccea Poul Sander 2023-09-22 19:25 12834
    assert(value > 0);
2660ccea Poul Sander 2023-09-22 19:25 12835
2660ccea Poul Sander 2023-09-22 19:25 12836
    // Convert the IEEE representation into a diyfp.
2660ccea Poul Sander 2023-09-22 19:25 12837
    //
2660ccea Poul Sander 2023-09-22 19:25 12838
    // If v is denormal:
2660ccea Poul Sander 2023-09-22 19:25 12839
    //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
2660ccea Poul Sander 2023-09-22 19:25 12840
    // If v is normalized:
2660ccea Poul Sander 2023-09-22 19:25 12841
    //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
2660ccea Poul Sander 2023-09-22 19:25 12842
2660ccea Poul Sander 2023-09-22 19:25 12843
    static_assert(std::numeric_limits<FloatType>::is_iec559,
2660ccea Poul Sander 2023-09-22 19:25 12844
                  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
2660ccea Poul Sander 2023-09-22 19:25 12845
2660ccea Poul Sander 2023-09-22 19:25 12846
    constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
2660ccea Poul Sander 2023-09-22 19:25 12847
    constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
2660ccea Poul Sander 2023-09-22 19:25 12848
    constexpr int      kMinExp    = 1 - kBias;
2660ccea Poul Sander 2023-09-22 19:25 12849
    constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
2660ccea Poul Sander 2023-09-22 19:25 12850
2660ccea Poul Sander 2023-09-22 19:25 12851
    using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
2660ccea Poul Sander 2023-09-22 19:25 12852
2660ccea Poul Sander 2023-09-22 19:25 12853
    const std::uint64_t bits = reinterpret_bits<bits_type>(value);
2660ccea Poul Sander 2023-09-22 19:25 12854
    const std::uint64_t E = bits >> (kPrecision - 1);
2660ccea Poul Sander 2023-09-22 19:25 12855
    const std::uint64_t F = bits & (kHiddenBit - 1);
2660ccea Poul Sander 2023-09-22 19:25 12856
2660ccea Poul Sander 2023-09-22 19:25 12857
    const bool is_denormal = E == 0;
2660ccea Poul Sander 2023-09-22 19:25 12858
    const diyfp v = is_denormal
2660ccea Poul Sander 2023-09-22 19:25 12859
                    ? diyfp(F, kMinExp)
2660ccea Poul Sander 2023-09-22 19:25 12860
                    : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
2660ccea Poul Sander 2023-09-22 19:25 12861
2660ccea Poul Sander 2023-09-22 19:25 12862
    // Compute the boundaries m- and m+ of the floating-point value
2660ccea Poul Sander 2023-09-22 19:25 12863
    // v = f * 2^e.
2660ccea Poul Sander 2023-09-22 19:25 12864
    //
2660ccea Poul Sander 2023-09-22 19:25 12865
    // Determine v- and v+, the floating-point predecessor and successor if v,
2660ccea Poul Sander 2023-09-22 19:25 12866
    // respectively.
2660ccea Poul Sander 2023-09-22 19:25 12867
    //
2660ccea Poul Sander 2023-09-22 19:25 12868
    //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
2660ccea Poul Sander 2023-09-22 19:25 12869
    //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
2660ccea Poul Sander 2023-09-22 19:25 12870
    //
2660ccea Poul Sander 2023-09-22 19:25 12871
    //      v+ = v + 2^e
2660ccea Poul Sander 2023-09-22 19:25 12872
    //
2660ccea Poul Sander 2023-09-22 19:25 12873
    // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
2660ccea Poul Sander 2023-09-22 19:25 12874
    // between m- and m+ round to v, regardless of how the input rounding
2660ccea Poul Sander 2023-09-22 19:25 12875
    // algorithm breaks ties.
2660ccea Poul Sander 2023-09-22 19:25 12876
    //
2660ccea Poul Sander 2023-09-22 19:25 12877
    //      ---+-------------+-------------+-------------+-------------+---  (A)
2660ccea Poul Sander 2023-09-22 19:25 12878
    //         v-            m-            v             m+            v+
2660ccea Poul Sander 2023-09-22 19:25 12879
    //
2660ccea Poul Sander 2023-09-22 19:25 12880
    //      -----------------+------+------+-------------+-------------+---  (B)
2660ccea Poul Sander 2023-09-22 19:25 12881
    //                       v-     m-     v             m+            v+
2660ccea Poul Sander 2023-09-22 19:25 12882
2660ccea Poul Sander 2023-09-22 19:25 12883
    const bool lower_boundary_is_closer = F == 0 and E > 1;
2660ccea Poul Sander 2023-09-22 19:25 12884
    const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
2660ccea Poul Sander 2023-09-22 19:25 12885
    const diyfp m_minus = lower_boundary_is_closer
2660ccea Poul Sander 2023-09-22 19:25 12886
                          ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
2660ccea Poul Sander 2023-09-22 19:25 12887
                          : diyfp(2 * v.f - 1, v.e - 1); // (A)
2660ccea Poul Sander 2023-09-22 19:25 12888
2660ccea Poul Sander 2023-09-22 19:25 12889
    // Determine the normalized w+ = m+.
2660ccea Poul Sander 2023-09-22 19:25 12890
    const diyfp w_plus = diyfp::normalize(m_plus);
2660ccea Poul Sander 2023-09-22 19:25 12891
2660ccea Poul Sander 2023-09-22 19:25 12892
    // Determine w- = m- such that e_(w-) = e_(w+).
2660ccea Poul Sander 2023-09-22 19:25 12893
    const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
2660ccea Poul Sander 2023-09-22 19:25 12894
2660ccea Poul Sander 2023-09-22 19:25 12895
    return {diyfp::normalize(v), w_minus, w_plus};
2660ccea Poul Sander 2023-09-22 19:25 12896
}
2660ccea Poul Sander 2023-09-22 19:25 12897
2660ccea Poul Sander 2023-09-22 19:25 12898
// Given normalized diyfp w, Grisu needs to find a (normalized) cached
2660ccea Poul Sander 2023-09-22 19:25 12899
// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
2660ccea Poul Sander 2023-09-22 19:25 12900
// within a certain range [alpha, gamma] (Definition 3.2 from [1])
2660ccea Poul Sander 2023-09-22 19:25 12901
//
2660ccea Poul Sander 2023-09-22 19:25 12902
//      alpha <= e = e_c + e_w + q <= gamma
2660ccea Poul Sander 2023-09-22 19:25 12903
//
2660ccea Poul Sander 2023-09-22 19:25 12904
// or
2660ccea Poul Sander 2023-09-22 19:25 12905
//
2660ccea Poul Sander 2023-09-22 19:25 12906
//      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
2660ccea Poul Sander 2023-09-22 19:25 12907
//                          <= f_c * f_w * 2^gamma
2660ccea Poul Sander 2023-09-22 19:25 12908
//
2660ccea Poul Sander 2023-09-22 19:25 12909
// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
2660ccea Poul Sander 2023-09-22 19:25 12910
//
2660ccea Poul Sander 2023-09-22 19:25 12911
//      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
2660ccea Poul Sander 2023-09-22 19:25 12912
//
2660ccea Poul Sander 2023-09-22 19:25 12913
// or
2660ccea Poul Sander 2023-09-22 19:25 12914
//
2660ccea Poul Sander 2023-09-22 19:25 12915
//      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
2660ccea Poul Sander 2023-09-22 19:25 12916
//
2660ccea Poul Sander 2023-09-22 19:25 12917
// The choice of (alpha,gamma) determines the size of the table and the form of
2660ccea Poul Sander 2023-09-22 19:25 12918
// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
2660ccea Poul Sander 2023-09-22 19:25 12919
// in practice:
2660ccea Poul Sander 2023-09-22 19:25 12920
//
2660ccea Poul Sander 2023-09-22 19:25 12921
// The idea is to cut the number c * w = f * 2^e into two parts, which can be
2660ccea Poul Sander 2023-09-22 19:25 12922
// processed independently: An integral part p1, and a fractional part p2:
2660ccea Poul Sander 2023-09-22 19:25 12923
//
2660ccea Poul Sander 2023-09-22 19:25 12924
//      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
2660ccea Poul Sander 2023-09-22 19:25 12925
//              = (f div 2^-e) + (f mod 2^-e) * 2^e
2660ccea Poul Sander 2023-09-22 19:25 12926
//              = p1 + p2 * 2^e
2660ccea Poul Sander 2023-09-22 19:25 12927
//
2660ccea Poul Sander 2023-09-22 19:25 12928
// The conversion of p1 into decimal form requires a series of divisions and
2660ccea Poul Sander 2023-09-22 19:25 12929
// modulos by (a power of) 10. These operations are faster for 32-bit than for
2660ccea Poul Sander 2023-09-22 19:25 12930
// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
2660ccea Poul Sander 2023-09-22 19:25 12931
// achieved by choosing
2660ccea Poul Sander 2023-09-22 19:25 12932
//
2660ccea Poul Sander 2023-09-22 19:25 12933
//      -e >= 32   or   e <= -32 := gamma
2660ccea Poul Sander 2023-09-22 19:25 12934
//
2660ccea Poul Sander 2023-09-22 19:25 12935
// In order to convert the fractional part
2660ccea Poul Sander 2023-09-22 19:25 12936
//
2660ccea Poul Sander 2023-09-22 19:25 12937
//      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
2660ccea Poul Sander 2023-09-22 19:25 12938
//
2660ccea Poul Sander 2023-09-22 19:25 12939
// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
2660ccea Poul Sander 2023-09-22 19:25 12940
// d[-i] are extracted in order:
2660ccea Poul Sander 2023-09-22 19:25 12941
//
2660ccea Poul Sander 2023-09-22 19:25 12942
//      (10 * p2) div 2^-e = d[-1]
2660ccea Poul Sander 2023-09-22 19:25 12943
//      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
2660ccea Poul Sander 2023-09-22 19:25 12944
//
2660ccea Poul Sander 2023-09-22 19:25 12945
// The multiplication by 10 must not overflow. It is sufficient to choose
2660ccea Poul Sander 2023-09-22 19:25 12946
//
2660ccea Poul Sander 2023-09-22 19:25 12947
//      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
2660ccea Poul Sander 2023-09-22 19:25 12948
//
2660ccea Poul Sander 2023-09-22 19:25 12949
// Since p2 = f mod 2^-e < 2^-e,
2660ccea Poul Sander 2023-09-22 19:25 12950
//
2660ccea Poul Sander 2023-09-22 19:25 12951
//      -e <= 60   or   e >= -60 := alpha
2660ccea Poul Sander 2023-09-22 19:25 12952
2660ccea Poul Sander 2023-09-22 19:25 12953
constexpr int kAlpha = -60;
2660ccea Poul Sander 2023-09-22 19:25 12954
constexpr int kGamma = -32;
2660ccea Poul Sander 2023-09-22 19:25 12955
2660ccea Poul Sander 2023-09-22 19:25 12956
struct cached_power // c = f * 2^e ~= 10^k
2660ccea Poul Sander 2023-09-22 19:25 12957
{
2660ccea Poul Sander 2023-09-22 19:25 12958
    std::uint64_t f;
2660ccea Poul Sander 2023-09-22 19:25 12959
    int e;
2660ccea Poul Sander 2023-09-22 19:25 12960
    int k;
2660ccea Poul Sander 2023-09-22 19:25 12961
};
2660ccea Poul Sander 2023-09-22 19:25 12962
2660ccea Poul Sander 2023-09-22 19:25 12963
/*!
2660ccea Poul Sander 2023-09-22 19:25 12964
For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
2660ccea Poul Sander 2023-09-22 19:25 12965
power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
2660ccea Poul Sander 2023-09-22 19:25 12966
satisfies (Definition 3.2 from [1])
2660ccea Poul Sander 2023-09-22 19:25 12967
2660ccea Poul Sander 2023-09-22 19:25 12968
     alpha <= e_c + e + q <= gamma.
2660ccea Poul Sander 2023-09-22 19:25 12969
*/
2660ccea Poul Sander 2023-09-22 19:25 12970
inline cached_power get_cached_power_for_binary_exponent(int e)
2660ccea Poul Sander 2023-09-22 19:25 12971
{
2660ccea Poul Sander 2023-09-22 19:25 12972
    // Now
2660ccea Poul Sander 2023-09-22 19:25 12973
    //
2660ccea Poul Sander 2023-09-22 19:25 12974
    //      alpha <= e_c + e + q <= gamma                                    (1)
2660ccea Poul Sander 2023-09-22 19:25 12975
    //      ==> f_c * 2^alpha <= c * 2^e * 2^q
2660ccea Poul Sander 2023-09-22 19:25 12976
    //
2660ccea Poul Sander 2023-09-22 19:25 12977
    // and since the c's are normalized, 2^(q-1) <= f_c,
2660ccea Poul Sander 2023-09-22 19:25 12978
    //
2660ccea Poul Sander 2023-09-22 19:25 12979
    //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
2660ccea Poul Sander 2023-09-22 19:25 12980
    //      ==> 2^(alpha - e - 1) <= c
2660ccea Poul Sander 2023-09-22 19:25 12981
    //
2660ccea Poul Sander 2023-09-22 19:25 12982
    // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
2660ccea Poul Sander 2023-09-22 19:25 12983
    //
2660ccea Poul Sander 2023-09-22 19:25 12984
    //      k = ceil( log_10( 2^(alpha - e - 1) ) )
2660ccea Poul Sander 2023-09-22 19:25 12985
    //        = ceil( (alpha - e - 1) * log_10(2) )
2660ccea Poul Sander 2023-09-22 19:25 12986
    //
2660ccea Poul Sander 2023-09-22 19:25 12987
    // From the paper:
2660ccea Poul Sander 2023-09-22 19:25 12988
    // "In theory the result of the procedure could be wrong since c is rounded,
2660ccea Poul Sander 2023-09-22 19:25 12989
    //  and the computation itself is approximated [...]. In practice, however,
2660ccea Poul Sander 2023-09-22 19:25 12990
    //  this simple function is sufficient."
2660ccea Poul Sander 2023-09-22 19:25 12991
    //
2660ccea Poul Sander 2023-09-22 19:25 12992
    // For IEEE double precision floating-point numbers converted into
2660ccea Poul Sander 2023-09-22 19:25 12993
    // normalized diyfp's w = f * 2^e, with q = 64,
2660ccea Poul Sander 2023-09-22 19:25 12994
    //
2660ccea Poul Sander 2023-09-22 19:25 12995
    //      e >= -1022      (min IEEE exponent)
2660ccea Poul Sander 2023-09-22 19:25 12996
    //           -52        (p - 1)
2660ccea Poul Sander 2023-09-22 19:25 12997
    //           -52        (p - 1, possibly normalize denormal IEEE numbers)
2660ccea Poul Sander 2023-09-22 19:25 12998
    //           -11        (normalize the diyfp)
2660ccea Poul Sander 2023-09-22 19:25 12999
    //         = -1137
2660ccea Poul Sander 2023-09-22 19:25 13000
    //
2660ccea Poul Sander 2023-09-22 19:25 13001
    // and
2660ccea Poul Sander 2023-09-22 19:25 13002
    //
2660ccea Poul Sander 2023-09-22 19:25 13003
    //      e <= +1023      (max IEEE exponent)
2660ccea Poul Sander 2023-09-22 19:25 13004
    //           -52        (p - 1)
2660ccea Poul Sander 2023-09-22 19:25 13005
    //           -11        (normalize the diyfp)
2660ccea Poul Sander 2023-09-22 19:25 13006
    //         = 960
2660ccea Poul Sander 2023-09-22 19:25 13007
    //
2660ccea Poul Sander 2023-09-22 19:25 13008
    // This binary exponent range [-1137,960] results in a decimal exponent
2660ccea Poul Sander 2023-09-22 19:25 13009
    // range [-307,324]. One does not need to store a cached power for each
2660ccea Poul Sander 2023-09-22 19:25 13010
    // k in this range. For each such k it suffices to find a cached power
2660ccea Poul Sander 2023-09-22 19:25 13011
    // such that the exponent of the product lies in [alpha,gamma].
2660ccea Poul Sander 2023-09-22 19:25 13012
    // This implies that the difference of the decimal exponents of adjacent
2660ccea Poul Sander 2023-09-22 19:25 13013
    // table entries must be less than or equal to
2660ccea Poul Sander 2023-09-22 19:25 13014
    //
2660ccea Poul Sander 2023-09-22 19:25 13015
    //      floor( (gamma - alpha) * log_10(2) ) = 8.
2660ccea Poul Sander 2023-09-22 19:25 13016
    //
2660ccea Poul Sander 2023-09-22 19:25 13017
    // (A smaller distance gamma-alpha would require a larger table.)
2660ccea Poul Sander 2023-09-22 19:25 13018
2660ccea Poul Sander 2023-09-22 19:25 13019
    // NB:
2660ccea Poul Sander 2023-09-22 19:25 13020
    // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
2660ccea Poul Sander 2023-09-22 19:25 13021
2660ccea Poul Sander 2023-09-22 19:25 13022
    constexpr int kCachedPowersMinDecExp = -300;
2660ccea Poul Sander 2023-09-22 19:25 13023
    constexpr int kCachedPowersDecStep = 8;
2660ccea Poul Sander 2023-09-22 19:25 13024
2660ccea Poul Sander 2023-09-22 19:25 13025
    static constexpr std::array<cached_power, 79> kCachedPowers =
2660ccea Poul Sander 2023-09-22 19:25 13026
    {
2660ccea Poul Sander 2023-09-22 19:25 13027
        {
2660ccea Poul Sander 2023-09-22 19:25 13028
            { 0xAB70FE17C79AC6CA, -1060, -300 },
2660ccea Poul Sander 2023-09-22 19:25 13029
            { 0xFF77B1FCBEBCDC4F, -1034, -292 },
2660ccea Poul Sander 2023-09-22 19:25 13030
            { 0xBE5691EF416BD60C, -1007, -284 },
2660ccea Poul Sander 2023-09-22 19:25 13031
            { 0x8DD01FAD907FFC3C,  -980, -276 },
2660ccea Poul Sander 2023-09-22 19:25 13032
            { 0xD3515C2831559A83,  -954, -268 },
2660ccea Poul Sander 2023-09-22 19:25 13033
            { 0x9D71AC8FADA6C9B5,  -927, -260 },
2660ccea Poul Sander 2023-09-22 19:25 13034
            { 0xEA9C227723EE8BCB,  -901, -252 },
2660ccea Poul Sander 2023-09-22 19:25 13035
            { 0xAECC49914078536D,  -874, -244 },
2660ccea Poul Sander 2023-09-22 19:25 13036
            { 0x823C12795DB6CE57,  -847, -236 },
2660ccea Poul Sander 2023-09-22 19:25 13037
            { 0xC21094364DFB5637,  -821, -228 },
2660ccea Poul Sander 2023-09-22 19:25 13038
            { 0x9096EA6F3848984F,  -794, -220 },
2660ccea Poul Sander 2023-09-22 19:25 13039
            { 0xD77485CB25823AC7,  -768, -212 },
2660ccea Poul Sander 2023-09-22 19:25 13040
            { 0xA086CFCD97BF97F4,  -741, -204 },
2660ccea Poul Sander 2023-09-22 19:25 13041
            { 0xEF340A98172AACE5,  -715, -196 },
2660ccea Poul Sander 2023-09-22 19:25 13042
            { 0xB23867FB2A35B28E,  -688, -188 },
2660ccea Poul Sander 2023-09-22 19:25 13043
            { 0x84C8D4DFD2C63F3B,  -661, -180 },
2660ccea Poul Sander 2023-09-22 19:25 13044
            { 0xC5DD44271AD3CDBA,  -635, -172 },
2660ccea Poul Sander 2023-09-22 19:25 13045
            { 0x936B9FCEBB25C996,  -608, -164 },
2660ccea Poul Sander 2023-09-22 19:25 13046
            { 0xDBAC6C247D62A584,  -582, -156 },
2660ccea Poul Sander 2023-09-22 19:25 13047
            { 0xA3AB66580D5FDAF6,  -555, -148 },
2660ccea Poul Sander 2023-09-22 19:25 13048
            { 0xF3E2F893DEC3F126,  -529, -140 },
2660ccea Poul Sander 2023-09-22 19:25 13049
            { 0xB5B5ADA8AAFF80B8,  -502, -132 },
2660ccea Poul Sander 2023-09-22 19:25 13050
            { 0x87625F056C7C4A8B,  -475, -124 },
2660ccea Poul Sander 2023-09-22 19:25 13051
            { 0xC9BCFF6034C13053,  -449, -116 },
2660ccea Poul Sander 2023-09-22 19:25 13052
            { 0x964E858C91BA2655,  -422, -108 },
2660ccea Poul Sander 2023-09-22 19:25 13053
            { 0xDFF9772470297EBD,  -396, -100 },
2660ccea Poul Sander 2023-09-22 19:25 13054
            { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
2660ccea Poul Sander 2023-09-22 19:25 13055
            { 0xF8A95FCF88747D94,  -343,  -84 },
2660ccea Poul Sander 2023-09-22 19:25 13056
            { 0xB94470938FA89BCF,  -316,  -76 },
2660ccea Poul Sander 2023-09-22 19:25 13057
            { 0x8A08F0F8BF0F156B,  -289,  -68 },
2660ccea Poul Sander 2023-09-22 19:25 13058
            { 0xCDB02555653131B6,  -263,  -60 },
2660ccea Poul Sander 2023-09-22 19:25 13059
            { 0x993FE2C6D07B7FAC,  -236,  -52 },
2660ccea Poul Sander 2023-09-22 19:25 13060
            { 0xE45C10C42A2B3B06,  -210,  -44 },
2660ccea Poul Sander 2023-09-22 19:25 13061
            { 0xAA242499697392D3,  -183,  -36 },
2660ccea Poul Sander 2023-09-22 19:25 13062
            { 0xFD87B5F28300CA0E,  -157,  -28 },
2660ccea Poul Sander 2023-09-22 19:25 13063
            { 0xBCE5086492111AEB,  -130,  -20 },
2660ccea Poul Sander 2023-09-22 19:25 13064
            { 0x8CBCCC096F5088CC,  -103,  -12 },
2660ccea Poul Sander 2023-09-22 19:25 13065
            { 0xD1B71758E219652C,   -77,   -4 },
2660ccea Poul Sander 2023-09-22 19:25 13066
            { 0x9C40000000000000,   -50,    4 },
2660ccea Poul Sander 2023-09-22 19:25 13067
            { 0xE8D4A51000000000,   -24,   12 },
2660ccea Poul Sander 2023-09-22 19:25 13068
            { 0xAD78EBC5AC620000,     3,   20 },
2660ccea Poul Sander 2023-09-22 19:25 13069
            { 0x813F3978F8940984,    30,   28 },
2660ccea Poul Sander 2023-09-22 19:25 13070
            { 0xC097CE7BC90715B3,    56,   36 },
2660ccea Poul Sander 2023-09-22 19:25 13071
            { 0x8F7E32CE7BEA5C70,    83,   44 },
2660ccea Poul Sander 2023-09-22 19:25 13072
            { 0xD5D238A4ABE98068,   109,   52 },
2660ccea Poul Sander 2023-09-22 19:25 13073
            { 0x9F4F2726179A2245,   136,   60 },
2660ccea Poul Sander 2023-09-22 19:25 13074
            { 0xED63A231D4C4FB27,   162,   68 },
2660ccea Poul Sander 2023-09-22 19:25 13075
            { 0xB0DE65388CC8ADA8,   189,   76 },
2660ccea Poul Sander 2023-09-22 19:25 13076
            { 0x83C7088E1AAB65DB,   216,   84 },
2660ccea Poul Sander 2023-09-22 19:25 13077
            { 0xC45D1DF942711D9A,   242,   92 },
2660ccea Poul Sander 2023-09-22 19:25 13078
            { 0x924D692CA61BE758,   269,  100 },
2660ccea Poul Sander 2023-09-22 19:25 13079
            { 0xDA01EE641A708DEA,   295,  108 },
2660ccea Poul Sander 2023-09-22 19:25 13080
            { 0xA26DA3999AEF774A,   322,  116 },
2660ccea Poul Sander 2023-09-22 19:25 13081
            { 0xF209787BB47D6B85,   348,  124 },
2660ccea Poul Sander 2023-09-22 19:25 13082
            { 0xB454E4A179DD1877,   375,  132 },
2660ccea Poul Sander 2023-09-22 19:25 13083
            { 0x865B86925B9BC5C2,   402,  140 },
2660ccea Poul Sander 2023-09-22 19:25 13084
            { 0xC83553C5C8965D3D,   428,  148 },
2660ccea Poul Sander 2023-09-22 19:25 13085
            { 0x952AB45CFA97A0B3,   455,  156 },
2660ccea Poul Sander 2023-09-22 19:25 13086
            { 0xDE469FBD99A05FE3,   481,  164 },
2660ccea Poul Sander 2023-09-22 19:25 13087
            { 0xA59BC234DB398C25,   508,  172 },
2660ccea Poul Sander 2023-09-22 19:25 13088
            { 0xF6C69A72A3989F5C,   534,  180 },
2660ccea Poul Sander 2023-09-22 19:25 13089
            { 0xB7DCBF5354E9BECE,   561,  188 },
2660ccea Poul Sander 2023-09-22 19:25 13090
            { 0x88FCF317F22241E2,   588,  196 },
2660ccea Poul Sander 2023-09-22 19:25 13091
            { 0xCC20CE9BD35C78A5,   614,  204 },
2660ccea Poul Sander 2023-09-22 19:25 13092
            { 0x98165AF37B2153DF,   641,  212 },
2660ccea Poul Sander 2023-09-22 19:25 13093
            { 0xE2A0B5DC971F303A,   667,  220 },
2660ccea Poul Sander 2023-09-22 19:25 13094
            { 0xA8D9D1535CE3B396,   694,  228 },
2660ccea Poul Sander 2023-09-22 19:25 13095
            { 0xFB9B7CD9A4A7443C,   720,  236 },
2660ccea Poul Sander 2023-09-22 19:25 13096
            { 0xBB764C4CA7A44410,   747,  244 },
2660ccea Poul Sander 2023-09-22 19:25 13097
            { 0x8BAB8EEFB6409C1A,   774,  252 },
2660ccea Poul Sander 2023-09-22 19:25 13098
            { 0xD01FEF10A657842C,   800,  260 },
2660ccea Poul Sander 2023-09-22 19:25 13099
            { 0x9B10A4E5E9913129,   827,  268 },
2660ccea Poul Sander 2023-09-22 19:25 13100
            { 0xE7109BFBA19C0C9D,   853,  276 },
2660ccea Poul Sander 2023-09-22 19:25 13101
            { 0xAC2820D9623BF429,   880,  284 },
2660ccea Poul Sander 2023-09-22 19:25 13102
            { 0x80444B5E7AA7CF85,   907,  292 },
2660ccea Poul Sander 2023-09-22 19:25 13103
            { 0xBF21E44003ACDD2D,   933,  300 },
2660ccea Poul Sander 2023-09-22 19:25 13104
            { 0x8E679C2F5E44FF8F,   960,  308 },
2660ccea Poul Sander 2023-09-22 19:25 13105
            { 0xD433179D9C8CB841,   986,  316 },
2660ccea Poul Sander 2023-09-22 19:25 13106
            { 0x9E19DB92B4E31BA9,  1013,  324 },
2660ccea Poul Sander 2023-09-22 19:25 13107
        }
2660ccea Poul Sander 2023-09-22 19:25 13108
    };
2660ccea Poul Sander 2023-09-22 19:25 13109
2660ccea Poul Sander 2023-09-22 19:25 13110
    // This computation gives exactly the same results for k as
2660ccea Poul Sander 2023-09-22 19:25 13111
    //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
2660ccea Poul Sander 2023-09-22 19:25 13112
    // for |e| <= 1500, but doesn't require floating-point operations.
2660ccea Poul Sander 2023-09-22 19:25 13113
    // NB: log_10(2) ~= 78913 / 2^18
2660ccea Poul Sander 2023-09-22 19:25 13114
    assert(e >= -1500);
2660ccea Poul Sander 2023-09-22 19:25 13115
    assert(e <=  1500);
2660ccea Poul Sander 2023-09-22 19:25 13116
    const int f = kAlpha - e - 1;
2660ccea Poul Sander 2023-09-22 19:25 13117
    const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
2660ccea Poul Sander 2023-09-22 19:25 13118
2660ccea Poul Sander 2023-09-22 19:25 13119
    const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
2660ccea Poul Sander 2023-09-22 19:25 13120
    assert(index >= 0);
2660ccea Poul Sander 2023-09-22 19:25 13121
    assert(static_cast<std::size_t>(index) < kCachedPowers.size());
2660ccea Poul Sander 2023-09-22 19:25 13122
2660ccea Poul Sander 2023-09-22 19:25 13123
    const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
2660ccea Poul Sander 2023-09-22 19:25 13124
    assert(kAlpha <= cached.e + e + 64);
2660ccea Poul Sander 2023-09-22 19:25 13125
    assert(kGamma >= cached.e + e + 64);
2660ccea Poul Sander 2023-09-22 19:25 13126
2660ccea Poul Sander 2023-09-22 19:25 13127
    return cached;
2660ccea Poul Sander 2023-09-22 19:25 13128
}
2660ccea Poul Sander 2023-09-22 19:25 13129
2660ccea Poul Sander 2023-09-22 19:25 13130
/*!
2660ccea Poul Sander 2023-09-22 19:25 13131
For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
2660ccea Poul Sander 2023-09-22 19:25 13132
For n == 0, returns 1 and sets pow10 := 1.
2660ccea Poul Sander 2023-09-22 19:25 13133
*/
2660ccea Poul Sander 2023-09-22 19:25 13134
inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
2660ccea Poul Sander 2023-09-22 19:25 13135
{
2660ccea Poul Sander 2023-09-22 19:25 13136
    // LCOV_EXCL_START
2660ccea Poul Sander 2023-09-22 19:25 13137
    if (n >= 1000000000)
2660ccea Poul Sander 2023-09-22 19:25 13138
    {
2660ccea Poul Sander 2023-09-22 19:25 13139
        pow10 = 1000000000;
2660ccea Poul Sander 2023-09-22 19:25 13140
        return 10;
2660ccea Poul Sander 2023-09-22 19:25 13141
    }
2660ccea Poul Sander 2023-09-22 19:25 13142
    // LCOV_EXCL_STOP
2660ccea Poul Sander 2023-09-22 19:25 13143
    else if (n >= 100000000)
2660ccea Poul Sander 2023-09-22 19:25 13144
    {
2660ccea Poul Sander 2023-09-22 19:25 13145
        pow10 = 100000000;
2660ccea Poul Sander 2023-09-22 19:25 13146
        return  9;
2660ccea Poul Sander 2023-09-22 19:25 13147
    }
2660ccea Poul Sander 2023-09-22 19:25 13148
    else if (n >= 10000000)
2660ccea Poul Sander 2023-09-22 19:25 13149
    {
2660ccea Poul Sander 2023-09-22 19:25 13150
        pow10 = 10000000;
2660ccea Poul Sander 2023-09-22 19:25 13151
        return  8;
2660ccea Poul Sander 2023-09-22 19:25 13152
    }
2660ccea Poul Sander 2023-09-22 19:25 13153
    else if (n >= 1000000)
2660ccea Poul Sander 2023-09-22 19:25 13154
    {
2660ccea Poul Sander 2023-09-22 19:25 13155
        pow10 = 1000000;
2660ccea Poul Sander 2023-09-22 19:25 13156
        return  7;
2660ccea Poul Sander 2023-09-22 19:25 13157
    }
2660ccea Poul Sander 2023-09-22 19:25 13158
    else if (n >= 100000)
2660ccea Poul Sander 2023-09-22 19:25 13159
    {
2660ccea Poul Sander 2023-09-22 19:25 13160
        pow10 = 100000;
2660ccea Poul Sander 2023-09-22 19:25 13161
        return  6;
2660ccea Poul Sander 2023-09-22 19:25 13162
    }
2660ccea Poul Sander 2023-09-22 19:25 13163
    else if (n >= 10000)
2660ccea Poul Sander 2023-09-22 19:25 13164
    {
2660ccea Poul Sander 2023-09-22 19:25 13165
        pow10 = 10000;
2660ccea Poul Sander 2023-09-22 19:25 13166
        return  5;
2660ccea Poul Sander 2023-09-22 19:25 13167
    }
2660ccea Poul Sander 2023-09-22 19:25 13168
    else if (n >= 1000)
2660ccea Poul Sander 2023-09-22 19:25 13169
    {
2660ccea Poul Sander 2023-09-22 19:25 13170
        pow10 = 1000;
2660ccea Poul Sander 2023-09-22 19:25 13171
        return  4;
2660ccea Poul Sander 2023-09-22 19:25 13172
    }
2660ccea Poul Sander 2023-09-22 19:25 13173
    else if (n >= 100)
2660ccea Poul Sander 2023-09-22 19:25 13174
    {
2660ccea Poul Sander 2023-09-22 19:25 13175
        pow10 = 100;
2660ccea Poul Sander 2023-09-22 19:25 13176
        return  3;
2660ccea Poul Sander 2023-09-22 19:25 13177
    }
2660ccea Poul Sander 2023-09-22 19:25 13178
    else if (n >= 10)
2660ccea Poul Sander 2023-09-22 19:25 13179
    {
2660ccea Poul Sander 2023-09-22 19:25 13180
        pow10 = 10;
2660ccea Poul Sander 2023-09-22 19:25 13181
        return  2;
2660ccea Poul Sander 2023-09-22 19:25 13182
    }
2660ccea Poul Sander 2023-09-22 19:25 13183
    else
2660ccea Poul Sander 2023-09-22 19:25 13184
    {
2660ccea Poul Sander 2023-09-22 19:25 13185
        pow10 = 1;
2660ccea Poul Sander 2023-09-22 19:25 13186
        return 1;
2660ccea Poul Sander 2023-09-22 19:25 13187
    }
2660ccea Poul Sander 2023-09-22 19:25 13188
}
2660ccea Poul Sander 2023-09-22 19:25 13189
2660ccea Poul Sander 2023-09-22 19:25 13190
inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
2660ccea Poul Sander 2023-09-22 19:25 13191
                         std::uint64_t rest, std::uint64_t ten_k)
2660ccea Poul Sander 2023-09-22 19:25 13192
{
2660ccea Poul Sander 2023-09-22 19:25 13193
    assert(len >= 1);
2660ccea Poul Sander 2023-09-22 19:25 13194
    assert(dist <= delta);
2660ccea Poul Sander 2023-09-22 19:25 13195
    assert(rest <= delta);
2660ccea Poul Sander 2023-09-22 19:25 13196
    assert(ten_k > 0);
2660ccea Poul Sander 2023-09-22 19:25 13197
2660ccea Poul Sander 2023-09-22 19:25 13198
    //               <--------------------------- delta ---->
2660ccea Poul Sander 2023-09-22 19:25 13199
    //                                  <---- dist --------->
2660ccea Poul Sander 2023-09-22 19:25 13200
    // --------------[------------------+-------------------]--------------
2660ccea Poul Sander 2023-09-22 19:25 13201
    //               M-                 w                   M+
2660ccea Poul Sander 2023-09-22 19:25 13202
    //
2660ccea Poul Sander 2023-09-22 19:25 13203
    //                                  ten_k
2660ccea Poul Sander 2023-09-22 19:25 13204
    //                                <------>
2660ccea Poul Sander 2023-09-22 19:25 13205
    //                                       <---- rest ---->
2660ccea Poul Sander 2023-09-22 19:25 13206
    // --------------[------------------+----+--------------]--------------
2660ccea Poul Sander 2023-09-22 19:25 13207
    //                                  w    V
2660ccea Poul Sander 2023-09-22 19:25 13208
    //                                       = buf * 10^k
2660ccea Poul Sander 2023-09-22 19:25 13209
    //
2660ccea Poul Sander 2023-09-22 19:25 13210
    // ten_k represents a unit-in-the-last-place in the decimal representation
2660ccea Poul Sander 2023-09-22 19:25 13211
    // stored in buf.
2660ccea Poul Sander 2023-09-22 19:25 13212
    // Decrement buf by ten_k while this takes buf closer to w.
2660ccea Poul Sander 2023-09-22 19:25 13213
2660ccea Poul Sander 2023-09-22 19:25 13214
    // The tests are written in this order to avoid overflow in unsigned
2660ccea Poul Sander 2023-09-22 19:25 13215
    // integer arithmetic.
2660ccea Poul Sander 2023-09-22 19:25 13216
2660ccea Poul Sander 2023-09-22 19:25 13217
    while (rest < dist
2660ccea Poul Sander 2023-09-22 19:25 13218
            and delta - rest >= ten_k
2660ccea Poul Sander 2023-09-22 19:25 13219
            and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
2660ccea Poul Sander 2023-09-22 19:25 13220
    {
2660ccea Poul Sander 2023-09-22 19:25 13221
        assert(buf[len - 1] != '0');
2660ccea Poul Sander 2023-09-22 19:25 13222
        buf[len - 1]--;
2660ccea Poul Sander 2023-09-22 19:25 13223
        rest += ten_k;
2660ccea Poul Sander 2023-09-22 19:25 13224
    }
2660ccea Poul Sander 2023-09-22 19:25 13225
}
2660ccea Poul Sander 2023-09-22 19:25 13226
2660ccea Poul Sander 2023-09-22 19:25 13227
/*!
2660ccea Poul Sander 2023-09-22 19:25 13228
Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
2660ccea Poul Sander 2023-09-22 19:25 13229
M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
2660ccea Poul Sander 2023-09-22 19:25 13230
*/
2660ccea Poul Sander 2023-09-22 19:25 13231
inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
2660ccea Poul Sander 2023-09-22 19:25 13232
                             diyfp M_minus, diyfp w, diyfp M_plus)
2660ccea Poul Sander 2023-09-22 19:25 13233
{
2660ccea Poul Sander 2023-09-22 19:25 13234
    static_assert(kAlpha >= -60, "internal error");
2660ccea Poul Sander 2023-09-22 19:25 13235
    static_assert(kGamma <= -32, "internal error");
2660ccea Poul Sander 2023-09-22 19:25 13236
2660ccea Poul Sander 2023-09-22 19:25 13237
    // Generates the digits (and the exponent) of a decimal floating-point
2660ccea Poul Sander 2023-09-22 19:25 13238
    // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
2660ccea Poul Sander 2023-09-22 19:25 13239
    // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
2660ccea Poul Sander 2023-09-22 19:25 13240
    //
2660ccea Poul Sander 2023-09-22 19:25 13241
    //               <--------------------------- delta ---->
2660ccea Poul Sander 2023-09-22 19:25 13242
    //                                  <---- dist --------->
2660ccea Poul Sander 2023-09-22 19:25 13243
    // --------------[------------------+-------------------]--------------
2660ccea Poul Sander 2023-09-22 19:25 13244
    //               M-                 w                   M+
2660ccea Poul Sander 2023-09-22 19:25 13245
    //
2660ccea Poul Sander 2023-09-22 19:25 13246
    // Grisu2 generates the digits of M+ from left to right and stops as soon as
2660ccea Poul Sander 2023-09-22 19:25 13247
    // V is in [M-,M+].
2660ccea Poul Sander 2023-09-22 19:25 13248
2660ccea Poul Sander 2023-09-22 19:25 13249
    assert(M_plus.e >= kAlpha);
2660ccea Poul Sander 2023-09-22 19:25 13250
    assert(M_plus.e <= kGamma);
2660ccea Poul Sander 2023-09-22 19:25 13251
2660ccea Poul Sander 2023-09-22 19:25 13252
    std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
2660ccea Poul Sander 2023-09-22 19:25 13253
    std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
2660ccea Poul Sander 2023-09-22 19:25 13254
2660ccea Poul Sander 2023-09-22 19:25 13255
    // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
2660ccea Poul Sander 2023-09-22 19:25 13256
    //
2660ccea Poul Sander 2023-09-22 19:25 13257
    //      M+ = f * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13258
    //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13259
    //         = ((p1        ) * 2^-e + (p2        )) * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13260
    //         = p1 + p2 * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13261
2660ccea Poul Sander 2023-09-22 19:25 13262
    const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
2660ccea Poul Sander 2023-09-22 19:25 13263
2660ccea Poul Sander 2023-09-22 19:25 13264
    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.)
2660ccea Poul Sander 2023-09-22 19:25 13265
    std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
2660ccea Poul Sander 2023-09-22 19:25 13266
2660ccea Poul Sander 2023-09-22 19:25 13267
    // 1)
2660ccea Poul Sander 2023-09-22 19:25 13268
    //
2660ccea Poul Sander 2023-09-22 19:25 13269
    // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
2660ccea Poul Sander 2023-09-22 19:25 13270
2660ccea Poul Sander 2023-09-22 19:25 13271
    assert(p1 > 0);
2660ccea Poul Sander 2023-09-22 19:25 13272
2660ccea Poul Sander 2023-09-22 19:25 13273
    std::uint32_t pow10;
2660ccea Poul Sander 2023-09-22 19:25 13274
    const int k = find_largest_pow10(p1, pow10);
2660ccea Poul Sander 2023-09-22 19:25 13275
2660ccea Poul Sander 2023-09-22 19:25 13276
    //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
2660ccea Poul Sander 2023-09-22 19:25 13277
    //
2660ccea Poul Sander 2023-09-22 19:25 13278
    //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
2660ccea Poul Sander 2023-09-22 19:25 13279
    //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
2660ccea Poul Sander 2023-09-22 19:25 13280
    //
2660ccea Poul Sander 2023-09-22 19:25 13281
    //      M+ = p1                                             + p2 * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13282
    //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13283
    //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13284
    //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13285
    //
2660ccea Poul Sander 2023-09-22 19:25 13286
    // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
2660ccea Poul Sander 2023-09-22 19:25 13287
    //
2660ccea Poul Sander 2023-09-22 19:25 13288
    //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
2660ccea Poul Sander 2023-09-22 19:25 13289
    //
2660ccea Poul Sander 2023-09-22 19:25 13290
    // but stop as soon as
2660ccea Poul Sander 2023-09-22 19:25 13291
    //
2660ccea Poul Sander 2023-09-22 19:25 13292
    //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13293
2660ccea Poul Sander 2023-09-22 19:25 13294
    int n = k;
2660ccea Poul Sander 2023-09-22 19:25 13295
    while (n > 0)
2660ccea Poul Sander 2023-09-22 19:25 13296
    {
2660ccea Poul Sander 2023-09-22 19:25 13297
        // Invariants:
2660ccea Poul Sander 2023-09-22 19:25 13298
        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
2660ccea Poul Sander 2023-09-22 19:25 13299
        //      pow10 = 10^(n-1) <= p1 < 10^n
2660ccea Poul Sander 2023-09-22 19:25 13300
        //
2660ccea Poul Sander 2023-09-22 19:25 13301
        const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
2660ccea Poul Sander 2023-09-22 19:25 13302
        const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
2660ccea Poul Sander 2023-09-22 19:25 13303
        //
2660ccea Poul Sander 2023-09-22 19:25 13304
        //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13305
        //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
2660ccea Poul Sander 2023-09-22 19:25 13306
        //
2660ccea Poul Sander 2023-09-22 19:25 13307
        assert(d <= 9);
2660ccea Poul Sander 2023-09-22 19:25 13308
        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
2660ccea Poul Sander 2023-09-22 19:25 13309
        //
2660ccea Poul Sander 2023-09-22 19:25 13310
        //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
2660ccea Poul Sander 2023-09-22 19:25 13311
        //
2660ccea Poul Sander 2023-09-22 19:25 13312
        p1 = r;
2660ccea Poul Sander 2023-09-22 19:25 13313
        n--;
2660ccea Poul Sander 2023-09-22 19:25 13314
        //
2660ccea Poul Sander 2023-09-22 19:25 13315
        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
2660ccea Poul Sander 2023-09-22 19:25 13316
        //      pow10 = 10^n
2660ccea Poul Sander 2023-09-22 19:25 13317
        //
2660ccea Poul Sander 2023-09-22 19:25 13318
2660ccea Poul Sander 2023-09-22 19:25 13319
        // Now check if enough digits have been generated.
2660ccea Poul Sander 2023-09-22 19:25 13320
        // Compute
2660ccea Poul Sander 2023-09-22 19:25 13321
        //
2660ccea Poul Sander 2023-09-22 19:25 13322
        //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13323
        //
2660ccea Poul Sander 2023-09-22 19:25 13324
        // Note:
2660ccea Poul Sander 2023-09-22 19:25 13325
        // Since rest and delta share the same exponent e, it suffices to
2660ccea Poul Sander 2023-09-22 19:25 13326
        // compare the significands.
2660ccea Poul Sander 2023-09-22 19:25 13327
        const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
2660ccea Poul Sander 2023-09-22 19:25 13328
        if (rest <= delta)
2660ccea Poul Sander 2023-09-22 19:25 13329
        {
2660ccea Poul Sander 2023-09-22 19:25 13330
            // V = buffer * 10^n, with M- <= V <= M+.
2660ccea Poul Sander 2023-09-22 19:25 13331
2660ccea Poul Sander 2023-09-22 19:25 13332
            decimal_exponent += n;
2660ccea Poul Sander 2023-09-22 19:25 13333
2660ccea Poul Sander 2023-09-22 19:25 13334
            // We may now just stop. But instead look if the buffer could be
2660ccea Poul Sander 2023-09-22 19:25 13335
            // decremented to bring V closer to w.
2660ccea Poul Sander 2023-09-22 19:25 13336
            //
2660ccea Poul Sander 2023-09-22 19:25 13337
            // pow10 = 10^n is now 1 ulp in the decimal representation V.
2660ccea Poul Sander 2023-09-22 19:25 13338
            // The rounding procedure works with diyfp's with an implicit
2660ccea Poul Sander 2023-09-22 19:25 13339
            // exponent of e.
2660ccea Poul Sander 2023-09-22 19:25 13340
            //
2660ccea Poul Sander 2023-09-22 19:25 13341
            //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13342
            //
2660ccea Poul Sander 2023-09-22 19:25 13343
            const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
2660ccea Poul Sander 2023-09-22 19:25 13344
            grisu2_round(buffer, length, dist, delta, rest, ten_n);
2660ccea Poul Sander 2023-09-22 19:25 13345
2660ccea Poul Sander 2023-09-22 19:25 13346
            return;
2660ccea Poul Sander 2023-09-22 19:25 13347
        }
2660ccea Poul Sander 2023-09-22 19:25 13348
2660ccea Poul Sander 2023-09-22 19:25 13349
        pow10 /= 10;
2660ccea Poul Sander 2023-09-22 19:25 13350
        //
2660ccea Poul Sander 2023-09-22 19:25 13351
        //      pow10 = 10^(n-1) <= p1 < 10^n
2660ccea Poul Sander 2023-09-22 19:25 13352
        // Invariants restored.
2660ccea Poul Sander 2023-09-22 19:25 13353
    }
2660ccea Poul Sander 2023-09-22 19:25 13354
2660ccea Poul Sander 2023-09-22 19:25 13355
    // 2)
2660ccea Poul Sander 2023-09-22 19:25 13356
    //
2660ccea Poul Sander 2023-09-22 19:25 13357
    // The digits of the integral part have been generated:
2660ccea Poul Sander 2023-09-22 19:25 13358
    //
2660ccea Poul Sander 2023-09-22 19:25 13359
    //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13360
    //         = buffer            + p2 * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13361
    //
2660ccea Poul Sander 2023-09-22 19:25 13362
    // Now generate the digits of the fractional part p2 * 2^e.
2660ccea Poul Sander 2023-09-22 19:25 13363
    //
2660ccea Poul Sander 2023-09-22 19:25 13364
    // Note:
2660ccea Poul Sander 2023-09-22 19:25 13365
    // No decimal point is generated: the exponent is adjusted instead.
2660ccea Poul Sander 2023-09-22 19:25 13366
    //
2660ccea Poul Sander 2023-09-22 19:25 13367
    // p2 actually represents the fraction
2660ccea Poul Sander 2023-09-22 19:25 13368
    //
2660ccea Poul Sander 2023-09-22 19:25 13369
    //      p2 * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13370
    //          = p2 / 2^-e
2660ccea Poul Sander 2023-09-22 19:25 13371
    //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
2660ccea Poul Sander 2023-09-22 19:25 13372
    //
2660ccea Poul Sander 2023-09-22 19:25 13373
    // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
2660ccea Poul Sander 2023-09-22 19:25 13374
    //
2660ccea Poul Sander 2023-09-22 19:25 13375
    //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
2660ccea Poul Sander 2023-09-22 19:25 13376
    //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
2660ccea Poul Sander 2023-09-22 19:25 13377
    //
2660ccea Poul Sander 2023-09-22 19:25 13378
    // using
2660ccea Poul Sander 2023-09-22 19:25 13379
    //
2660ccea Poul Sander 2023-09-22 19:25 13380
    //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
2660ccea Poul Sander 2023-09-22 19:25 13381
    //                = (                   d) * 2^-e + (                   r)
2660ccea Poul Sander 2023-09-22 19:25 13382
    //
2660ccea Poul Sander 2023-09-22 19:25 13383
    // or
2660ccea Poul Sander 2023-09-22 19:25 13384
    //      10^m * p2 * 2^e = d + r * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13385
    //
2660ccea Poul Sander 2023-09-22 19:25 13386
    // i.e.
2660ccea Poul Sander 2023-09-22 19:25 13387
    //
2660ccea Poul Sander 2023-09-22 19:25 13388
    //      M+ = buffer + p2 * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13389
    //         = buffer + 10^-m * (d + r * 2^e)
2660ccea Poul Sander 2023-09-22 19:25 13390
    //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13391
    //
2660ccea Poul Sander 2023-09-22 19:25 13392
    // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13393
2660ccea Poul Sander 2023-09-22 19:25 13394
    assert(p2 > delta);
2660ccea Poul Sander 2023-09-22 19:25 13395
2660ccea Poul Sander 2023-09-22 19:25 13396
    int m = 0;
2660ccea Poul Sander 2023-09-22 19:25 13397
    for (;;)
2660ccea Poul Sander 2023-09-22 19:25 13398
    {
2660ccea Poul Sander 2023-09-22 19:25 13399
        // Invariant:
2660ccea Poul Sander 2023-09-22 19:25 13400
        //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13401
        //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13402
        //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13403
        //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13404
        //
2660ccea Poul Sander 2023-09-22 19:25 13405
        assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
2660ccea Poul Sander 2023-09-22 19:25 13406
        p2 *= 10;
2660ccea Poul Sander 2023-09-22 19:25 13407
        const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
2660ccea Poul Sander 2023-09-22 19:25 13408
        const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
2660ccea Poul Sander 2023-09-22 19:25 13409
        //
2660ccea Poul Sander 2023-09-22 19:25 13410
        //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13411
        //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
2660ccea Poul Sander 2023-09-22 19:25 13412
        //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13413
        //
2660ccea Poul Sander 2023-09-22 19:25 13414
        assert(d <= 9);
2660ccea Poul Sander 2023-09-22 19:25 13415
        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
2660ccea Poul Sander 2023-09-22 19:25 13416
        //
2660ccea Poul Sander 2023-09-22 19:25 13417
        //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13418
        //
2660ccea Poul Sander 2023-09-22 19:25 13419
        p2 = r;
2660ccea Poul Sander 2023-09-22 19:25 13420
        m++;
2660ccea Poul Sander 2023-09-22 19:25 13421
        //
2660ccea Poul Sander 2023-09-22 19:25 13422
        //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13423
        // Invariant restored.
2660ccea Poul Sander 2023-09-22 19:25 13424
2660ccea Poul Sander 2023-09-22 19:25 13425
        // Check if enough digits have been generated.
2660ccea Poul Sander 2023-09-22 19:25 13426
        //
2660ccea Poul Sander 2023-09-22 19:25 13427
        //      10^-m * p2 * 2^e <= delta * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13428
        //              p2 * 2^e <= 10^m * delta * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13429
        //                    p2 <= 10^m * delta
2660ccea Poul Sander 2023-09-22 19:25 13430
        delta *= 10;
2660ccea Poul Sander 2023-09-22 19:25 13431
        dist  *= 10;
2660ccea Poul Sander 2023-09-22 19:25 13432
        if (p2 <= delta)
2660ccea Poul Sander 2023-09-22 19:25 13433
        {
2660ccea Poul Sander 2023-09-22 19:25 13434
            break;
2660ccea Poul Sander 2023-09-22 19:25 13435
        }
2660ccea Poul Sander 2023-09-22 19:25 13436
    }
2660ccea Poul Sander 2023-09-22 19:25 13437
2660ccea Poul Sander 2023-09-22 19:25 13438
    // V = buffer * 10^-m, with M- <= V <= M+.
2660ccea Poul Sander 2023-09-22 19:25 13439
2660ccea Poul Sander 2023-09-22 19:25 13440
    decimal_exponent -= m;
2660ccea Poul Sander 2023-09-22 19:25 13441
2660ccea Poul Sander 2023-09-22 19:25 13442
    // 1 ulp in the decimal representation is now 10^-m.
2660ccea Poul Sander 2023-09-22 19:25 13443
    // Since delta and dist are now scaled by 10^m, we need to do the
2660ccea Poul Sander 2023-09-22 19:25 13444
    // same with ulp in order to keep the units in sync.
2660ccea Poul Sander 2023-09-22 19:25 13445
    //
2660ccea Poul Sander 2023-09-22 19:25 13446
    //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
2660ccea Poul Sander 2023-09-22 19:25 13447
    //
2660ccea Poul Sander 2023-09-22 19:25 13448
    const std::uint64_t ten_m = one.f;
2660ccea Poul Sander 2023-09-22 19:25 13449
    grisu2_round(buffer, length, dist, delta, p2, ten_m);
2660ccea Poul Sander 2023-09-22 19:25 13450
2660ccea Poul Sander 2023-09-22 19:25 13451
    // By construction this algorithm generates the shortest possible decimal
2660ccea Poul Sander 2023-09-22 19:25 13452
    // number (Loitsch, Theorem 6.2) which rounds back to w.
2660ccea Poul Sander 2023-09-22 19:25 13453
    // For an input number of precision p, at least
2660ccea Poul Sander 2023-09-22 19:25 13454
    //
2660ccea Poul Sander 2023-09-22 19:25 13455
    //      N = 1 + ceil(p * log_10(2))
2660ccea Poul Sander 2023-09-22 19:25 13456
    //
2660ccea Poul Sander 2023-09-22 19:25 13457
    // decimal digits are sufficient to identify all binary floating-point
2660ccea Poul Sander 2023-09-22 19:25 13458
    // numbers (Matula, "In-and-Out conversions").
2660ccea Poul Sander 2023-09-22 19:25 13459
    // This implies that the algorithm does not produce more than N decimal
2660ccea Poul Sander 2023-09-22 19:25 13460
    // digits.
2660ccea Poul Sander 2023-09-22 19:25 13461
    //
2660ccea Poul Sander 2023-09-22 19:25 13462
    //      N = 17 for p = 53 (IEEE double precision)
2660ccea Poul Sander 2023-09-22 19:25 13463
    //      N = 9  for p = 24 (IEEE single precision)
2660ccea Poul Sander 2023-09-22 19:25 13464
}
2660ccea Poul Sander 2023-09-22 19:25 13465
2660ccea Poul Sander 2023-09-22 19:25 13466
/*!
2660ccea Poul Sander 2023-09-22 19:25 13467
v = buf * 10^decimal_exponent
2660ccea Poul Sander 2023-09-22 19:25 13468
len is the length of the buffer (number of decimal digits)
2660ccea Poul Sander 2023-09-22 19:25 13469
The buffer must be large enough, i.e. >= max_digits10.
2660ccea Poul Sander 2023-09-22 19:25 13470
*/
2660ccea Poul Sander 2023-09-22 19:25 13471
JSON_HEDLEY_NON_NULL(1)
2660ccea Poul Sander 2023-09-22 19:25 13472
inline void grisu2(char* buf, int& len, int& decimal_exponent,
2660ccea Poul Sander 2023-09-22 19:25 13473
                   diyfp m_minus, diyfp v, diyfp m_plus)
2660ccea Poul Sander 2023-09-22 19:25 13474
{
2660ccea Poul Sander 2023-09-22 19:25 13475
    assert(m_plus.e == m_minus.e);
2660ccea Poul Sander 2023-09-22 19:25 13476
    assert(m_plus.e == v.e);
2660ccea Poul Sander 2023-09-22 19:25 13477
2660ccea Poul Sander 2023-09-22 19:25 13478
    //  --------(-----------------------+-----------------------)--------    (A)
2660ccea Poul Sander 2023-09-22 19:25 13479
    //          m-                      v                       m+
2660ccea Poul Sander 2023-09-22 19:25 13480
    //
2660ccea Poul Sander 2023-09-22 19:25 13481
    //  --------------------(-----------+-----------------------)--------    (B)
2660ccea Poul Sander 2023-09-22 19:25 13482
    //                      m-          v                       m+
2660ccea Poul Sander 2023-09-22 19:25 13483
    //
2660ccea Poul Sander 2023-09-22 19:25 13484
    // First scale v (and m- and m+) such that the exponent is in the range
2660ccea Poul Sander 2023-09-22 19:25 13485
    // [alpha, gamma].
2660ccea Poul Sander 2023-09-22 19:25 13486
2660ccea Poul Sander 2023-09-22 19:25 13487
    const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
2660ccea Poul Sander 2023-09-22 19:25 13488
2660ccea Poul Sander 2023-09-22 19:25 13489
    const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
2660ccea Poul Sander 2023-09-22 19:25 13490
2660ccea Poul Sander 2023-09-22 19:25 13491
    // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
2660ccea Poul Sander 2023-09-22 19:25 13492
    const diyfp w       = diyfp::mul(v,       c_minus_k);
2660ccea Poul Sander 2023-09-22 19:25 13493
    const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
2660ccea Poul Sander 2023-09-22 19:25 13494
    const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
2660ccea Poul Sander 2023-09-22 19:25 13495
2660ccea Poul Sander 2023-09-22 19:25 13496
    //  ----(---+---)---------------(---+---)---------------(---+---)----
2660ccea Poul Sander 2023-09-22 19:25 13497
    //          w-                      w                       w+
2660ccea Poul Sander 2023-09-22 19:25 13498
    //          = c*m-                  = c*v                   = c*m+
2660ccea Poul Sander 2023-09-22 19:25 13499
    //
2660ccea Poul Sander 2023-09-22 19:25 13500
    // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
2660ccea Poul Sander 2023-09-22 19:25 13501
    // w+ are now off by a small amount.
2660ccea Poul Sander 2023-09-22 19:25 13502
    // In fact:
2660ccea Poul Sander 2023-09-22 19:25 13503
    //
2660ccea Poul Sander 2023-09-22 19:25 13504
    //      w - v * 10^k < 1 ulp
2660ccea Poul Sander 2023-09-22 19:25 13505
    //
2660ccea Poul Sander 2023-09-22 19:25 13506
    // To account for this inaccuracy, add resp. subtract 1 ulp.
2660ccea Poul Sander 2023-09-22 19:25 13507
    //
2660ccea Poul Sander 2023-09-22 19:25 13508
    //  --------+---[---------------(---+---)---------------]---+--------
2660ccea Poul Sander 2023-09-22 19:25 13509
    //          w-  M-                  w                   M+  w+
2660ccea Poul Sander 2023-09-22 19:25 13510
    //
2660ccea Poul Sander 2023-09-22 19:25 13511
    // Now any number in [M-, M+] (bounds included) will round to w when input,
2660ccea Poul Sander 2023-09-22 19:25 13512
    // regardless of how the input rounding algorithm breaks ties.
2660ccea Poul Sander 2023-09-22 19:25 13513
    //
2660ccea Poul Sander 2023-09-22 19:25 13514
    // And digit_gen generates the shortest possible such number in [M-, M+].
2660ccea Poul Sander 2023-09-22 19:25 13515
    // Note that this does not mean that Grisu2 always generates the shortest
2660ccea Poul Sander 2023-09-22 19:25 13516
    // possible number in the interval (m-, m+).
2660ccea Poul Sander 2023-09-22 19:25 13517
    const diyfp M_minus(w_minus.f + 1, w_minus.e);
2660ccea Poul Sander 2023-09-22 19:25 13518
    const diyfp M_plus (w_plus.f  - 1, w_plus.e );
2660ccea Poul Sander 2023-09-22 19:25 13519
2660ccea Poul Sander 2023-09-22 19:25 13520
    decimal_exponent = -cached.k; // = -(-k) = k
2660ccea Poul Sander 2023-09-22 19:25 13521
2660ccea Poul Sander 2023-09-22 19:25 13522
    grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
2660ccea Poul Sander 2023-09-22 19:25 13523
}
2660ccea Poul Sander 2023-09-22 19:25 13524
2660ccea Poul Sander 2023-09-22 19:25 13525
/*!
2660ccea Poul Sander 2023-09-22 19:25 13526
v = buf * 10^decimal_exponent
2660ccea Poul Sander 2023-09-22 19:25 13527
len is the length of the buffer (number of decimal digits)
2660ccea Poul Sander 2023-09-22 19:25 13528
The buffer must be large enough, i.e. >= max_digits10.
2660ccea Poul Sander 2023-09-22 19:25 13529
*/
2660ccea Poul Sander 2023-09-22 19:25 13530
template <typename FloatType>
2660ccea Poul Sander 2023-09-22 19:25 13531
JSON_HEDLEY_NON_NULL(1)
2660ccea Poul Sander 2023-09-22 19:25 13532
void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
2660ccea Poul Sander 2023-09-22 19:25 13533
{
2660ccea Poul Sander 2023-09-22 19:25 13534
    static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
2660ccea Poul Sander 2023-09-22 19:25 13535
                  "internal error: not enough precision");
2660ccea Poul Sander 2023-09-22 19:25 13536
2660ccea Poul Sander 2023-09-22 19:25 13537
    assert(std::isfinite(value));
2660ccea Poul Sander 2023-09-22 19:25 13538
    assert(value > 0);
2660ccea Poul Sander 2023-09-22 19:25 13539
2660ccea Poul Sander 2023-09-22 19:25 13540
    // If the neighbors (and boundaries) of 'value' are always computed for double-precision
2660ccea Poul Sander 2023-09-22 19:25 13541
    // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
2660ccea Poul Sander 2023-09-22 19:25 13542
    // decimal representations are not exactly "short".
2660ccea Poul Sander 2023-09-22 19:25 13543
    //
2660ccea Poul Sander 2023-09-22 19:25 13544
    // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
2660ccea Poul Sander 2023-09-22 19:25 13545
    // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
2660ccea Poul Sander 2023-09-22 19:25 13546
    // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
2660ccea Poul Sander 2023-09-22 19:25 13547
    // does.
2660ccea Poul Sander 2023-09-22 19:25 13548
    // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
2660ccea Poul Sander 2023-09-22 19:25 13549
    // representation using the corresponding std::from_chars function recovers value exactly". That
2660ccea Poul Sander 2023-09-22 19:25 13550
    // indicates that single precision floating-point numbers should be recovered using
2660ccea Poul Sander 2023-09-22 19:25 13551
    // 'std::strtof'.
2660ccea Poul Sander 2023-09-22 19:25 13552
    //
2660ccea Poul Sander 2023-09-22 19:25 13553
    // NB: If the neighbors are computed for single-precision numbers, there is a single float
2660ccea Poul Sander 2023-09-22 19:25 13554
    //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
2660ccea Poul Sander 2023-09-22 19:25 13555
    //     value is off by 1 ulp.
2660ccea Poul Sander 2023-09-22 19:25 13556
#if 0
2660ccea Poul Sander 2023-09-22 19:25 13557
    const boundaries w = compute_boundaries(static_cast<double>(value));
2660ccea Poul Sander 2023-09-22 19:25 13558
#else
2660ccea Poul Sander 2023-09-22 19:25 13559
    const boundaries w = compute_boundaries(value);
2660ccea Poul Sander 2023-09-22 19:25 13560
#endif
2660ccea Poul Sander 2023-09-22 19:25 13561
2660ccea Poul Sander 2023-09-22 19:25 13562
    grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
2660ccea Poul Sander 2023-09-22 19:25 13563
}
2660ccea Poul Sander 2023-09-22 19:25 13564
2660ccea Poul Sander 2023-09-22 19:25 13565
/*!
2660ccea Poul Sander 2023-09-22 19:25 13566
@brief appends a decimal representation of e to buf
2660ccea Poul Sander 2023-09-22 19:25 13567
@return a pointer to the element following the exponent.
2660ccea Poul Sander 2023-09-22 19:25 13568
@pre -1000 < e < 1000
2660ccea Poul Sander 2023-09-22 19:25 13569
*/
2660ccea Poul Sander 2023-09-22 19:25 13570
JSON_HEDLEY_NON_NULL(1)
2660ccea Poul Sander 2023-09-22 19:25 13571
JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 13572
inline char* append_exponent(char* buf, int e)
2660ccea Poul Sander 2023-09-22 19:25 13573
{
2660ccea Poul Sander 2023-09-22 19:25 13574
    assert(e > -1000);
2660ccea Poul Sander 2023-09-22 19:25 13575
    assert(e <  1000);
2660ccea Poul Sander 2023-09-22 19:25 13576
2660ccea Poul Sander 2023-09-22 19:25 13577
    if (e < 0)
2660ccea Poul Sander 2023-09-22 19:25 13578
    {
2660ccea Poul Sander 2023-09-22 19:25 13579
        e = -e;
2660ccea Poul Sander 2023-09-22 19:25 13580
        *buf++ = '-';
2660ccea Poul Sander 2023-09-22 19:25 13581
    }
2660ccea Poul Sander 2023-09-22 19:25 13582
    else
2660ccea Poul Sander 2023-09-22 19:25 13583
    {
2660ccea Poul Sander 2023-09-22 19:25 13584
        *buf++ = '+';
2660ccea Poul Sander 2023-09-22 19:25 13585
    }
2660ccea Poul Sander 2023-09-22 19:25 13586
2660ccea Poul Sander 2023-09-22 19:25 13587
    auto k = static_cast<std::uint32_t>(e);
2660ccea Poul Sander 2023-09-22 19:25 13588
    if (k < 10)
2660ccea Poul Sander 2023-09-22 19:25 13589
    {
2660ccea Poul Sander 2023-09-22 19:25 13590
        // Always print at least two digits in the exponent.
2660ccea Poul Sander 2023-09-22 19:25 13591
        // This is for compatibility with printf("%g").
2660ccea Poul Sander 2023-09-22 19:25 13592
        *buf++ = '0';
2660ccea Poul Sander 2023-09-22 19:25 13593
        *buf++ = static_cast<char>('0' + k);
2660ccea Poul Sander 2023-09-22 19:25 13594
    }
2660ccea Poul Sander 2023-09-22 19:25 13595
    else if (k < 100)
2660ccea Poul Sander 2023-09-22 19:25 13596
    {
2660ccea Poul Sander 2023-09-22 19:25 13597
        *buf++ = static_cast<char>('0' + k / 10);
2660ccea Poul Sander 2023-09-22 19:25 13598
        k %= 10;
2660ccea Poul Sander 2023-09-22 19:25 13599
        *buf++ = static_cast<char>('0' + k);
2660ccea Poul Sander 2023-09-22 19:25 13600
    }
2660ccea Poul Sander 2023-09-22 19:25 13601
    else
2660ccea Poul Sander 2023-09-22 19:25 13602
    {
2660ccea Poul Sander 2023-09-22 19:25 13603
        *buf++ = static_cast<char>('0' + k / 100);
2660ccea Poul Sander 2023-09-22 19:25 13604
        k %= 100;
2660ccea Poul Sander 2023-09-22 19:25 13605
        *buf++ = static_cast<char>('0' + k / 10);
2660ccea Poul Sander 2023-09-22 19:25 13606
        k %= 10;
2660ccea Poul Sander 2023-09-22 19:25 13607
        *buf++ = static_cast<char>('0' + k);
2660ccea Poul Sander 2023-09-22 19:25 13608
    }
2660ccea Poul Sander 2023-09-22 19:25 13609
2660ccea Poul Sander 2023-09-22 19:25 13610
    return buf;
2660ccea Poul Sander 2023-09-22 19:25 13611
}
2660ccea Poul Sander 2023-09-22 19:25 13612
2660ccea Poul Sander 2023-09-22 19:25 13613
/*!
2660ccea Poul Sander 2023-09-22 19:25 13614
@brief prettify v = buf * 10^decimal_exponent
2660ccea Poul Sander 2023-09-22 19:25 13615
2660ccea Poul Sander 2023-09-22 19:25 13616
If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
2660ccea Poul Sander 2023-09-22 19:25 13617
notation. Otherwise it will be printed in exponential notation.
2660ccea Poul Sander 2023-09-22 19:25 13618
2660ccea Poul Sander 2023-09-22 19:25 13619
@pre min_exp < 0
2660ccea Poul Sander 2023-09-22 19:25 13620
@pre max_exp > 0
2660ccea Poul Sander 2023-09-22 19:25 13621
*/
2660ccea Poul Sander 2023-09-22 19:25 13622
JSON_HEDLEY_NON_NULL(1)
2660ccea Poul Sander 2023-09-22 19:25 13623
JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 13624
inline char* format_buffer(char* buf, int len, int decimal_exponent,
2660ccea Poul Sander 2023-09-22 19:25 13625
                           int min_exp, int max_exp)
2660ccea Poul Sander 2023-09-22 19:25 13626
{
2660ccea Poul Sander 2023-09-22 19:25 13627
    assert(min_exp < 0);
2660ccea Poul Sander 2023-09-22 19:25 13628
    assert(max_exp > 0);
2660ccea Poul Sander 2023-09-22 19:25 13629
2660ccea Poul Sander 2023-09-22 19:25 13630
    const int k = len;
2660ccea Poul Sander 2023-09-22 19:25 13631
    const int n = len + decimal_exponent;
2660ccea Poul Sander 2023-09-22 19:25 13632
2660ccea Poul Sander 2023-09-22 19:25 13633
    // v = buf * 10^(n-k)
2660ccea Poul Sander 2023-09-22 19:25 13634
    // k is the length of the buffer (number of decimal digits)
2660ccea Poul Sander 2023-09-22 19:25 13635
    // n is the position of the decimal point relative to the start of the buffer.
2660ccea Poul Sander 2023-09-22 19:25 13636
2660ccea Poul Sander 2023-09-22 19:25 13637
    if (k <= n and n <= max_exp)
2660ccea Poul Sander 2023-09-22 19:25 13638
    {
2660ccea Poul Sander 2023-09-22 19:25 13639
        // digits[000]
2660ccea Poul Sander 2023-09-22 19:25 13640
        // len <= max_exp + 2
2660ccea Poul Sander 2023-09-22 19:25 13641
2660ccea Poul Sander 2023-09-22 19:25 13642
        std::memset(buf + k, '0', static_cast<size_t>(n - k));
2660ccea Poul Sander 2023-09-22 19:25 13643
        // Make it look like a floating-point number (#362, #378)
2660ccea Poul Sander 2023-09-22 19:25 13644
        buf[n + 0] = '.';
2660ccea Poul Sander 2023-09-22 19:25 13645
        buf[n + 1] = '0';
2660ccea Poul Sander 2023-09-22 19:25 13646
        return buf + (n + 2);
2660ccea Poul Sander 2023-09-22 19:25 13647
    }
2660ccea Poul Sander 2023-09-22 19:25 13648
2660ccea Poul Sander 2023-09-22 19:25 13649
    if (0 < n and n <= max_exp)
2660ccea Poul Sander 2023-09-22 19:25 13650
    {
2660ccea Poul Sander 2023-09-22 19:25 13651
        // dig.its
2660ccea Poul Sander 2023-09-22 19:25 13652
        // len <= max_digits10 + 1
2660ccea Poul Sander 2023-09-22 19:25 13653
2660ccea Poul Sander 2023-09-22 19:25 13654
        assert(k > n);
2660ccea Poul Sander 2023-09-22 19:25 13655
2660ccea Poul Sander 2023-09-22 19:25 13656
        std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
2660ccea Poul Sander 2023-09-22 19:25 13657
        buf[n] = '.';
2660ccea Poul Sander 2023-09-22 19:25 13658
        return buf + (k + 1);
2660ccea Poul Sander 2023-09-22 19:25 13659
    }
2660ccea Poul Sander 2023-09-22 19:25 13660
2660ccea Poul Sander 2023-09-22 19:25 13661
    if (min_exp < n and n <= 0)
2660ccea Poul Sander 2023-09-22 19:25 13662
    {
2660ccea Poul Sander 2023-09-22 19:25 13663
        // 0.[000]digits
2660ccea Poul Sander 2023-09-22 19:25 13664
        // len <= 2 + (-min_exp - 1) + max_digits10
2660ccea Poul Sander 2023-09-22 19:25 13665
2660ccea Poul Sander 2023-09-22 19:25 13666
        std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
2660ccea Poul Sander 2023-09-22 19:25 13667
        buf[0] = '0';
2660ccea Poul Sander 2023-09-22 19:25 13668
        buf[1] = '.';
2660ccea Poul Sander 2023-09-22 19:25 13669
        std::memset(buf + 2, '0', static_cast<size_t>(-n));
2660ccea Poul Sander 2023-09-22 19:25 13670
        return buf + (2 + (-n) + k);
2660ccea Poul Sander 2023-09-22 19:25 13671
    }
2660ccea Poul Sander 2023-09-22 19:25 13672
2660ccea Poul Sander 2023-09-22 19:25 13673
    if (k == 1)
2660ccea Poul Sander 2023-09-22 19:25 13674
    {
2660ccea Poul Sander 2023-09-22 19:25 13675
        // dE+123
2660ccea Poul Sander 2023-09-22 19:25 13676
        // len <= 1 + 5
2660ccea Poul Sander 2023-09-22 19:25 13677
2660ccea Poul Sander 2023-09-22 19:25 13678
        buf += 1;
2660ccea Poul Sander 2023-09-22 19:25 13679
    }
2660ccea Poul Sander 2023-09-22 19:25 13680
    else
2660ccea Poul Sander 2023-09-22 19:25 13681
    {
2660ccea Poul Sander 2023-09-22 19:25 13682
        // d.igitsE+123
2660ccea Poul Sander 2023-09-22 19:25 13683
        // len <= max_digits10 + 1 + 5
2660ccea Poul Sander 2023-09-22 19:25 13684
2660ccea Poul Sander 2023-09-22 19:25 13685
        std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
2660ccea Poul Sander 2023-09-22 19:25 13686
        buf[1] = '.';
2660ccea Poul Sander 2023-09-22 19:25 13687
        buf += 1 + k;
2660ccea Poul Sander 2023-09-22 19:25 13688
    }
2660ccea Poul Sander 2023-09-22 19:25 13689
2660ccea Poul Sander 2023-09-22 19:25 13690
    *buf++ = 'e';
2660ccea Poul Sander 2023-09-22 19:25 13691
    return append_exponent(buf, n - 1);
2660ccea Poul Sander 2023-09-22 19:25 13692
}
2660ccea Poul Sander 2023-09-22 19:25 13693
2660ccea Poul Sander 2023-09-22 19:25 13694
} // namespace dtoa_impl
2660ccea Poul Sander 2023-09-22 19:25 13695
2660ccea Poul Sander 2023-09-22 19:25 13696
/*!
2660ccea Poul Sander 2023-09-22 19:25 13697
@brief generates a decimal representation of the floating-point number value in [first, last).
2660ccea Poul Sander 2023-09-22 19:25 13698
2660ccea Poul Sander 2023-09-22 19:25 13699
The format of the resulting decimal representation is similar to printf's %g
2660ccea Poul Sander 2023-09-22 19:25 13700
format. Returns an iterator pointing past-the-end of the decimal representation.
2660ccea Poul Sander 2023-09-22 19:25 13701
2660ccea Poul Sander 2023-09-22 19:25 13702
@note The input number must be finite, i.e. NaN's and Inf's are not supported.
2660ccea Poul Sander 2023-09-22 19:25 13703
@note The buffer must be large enough.
2660ccea Poul Sander 2023-09-22 19:25 13704
@note The result is NOT null-terminated.
2660ccea Poul Sander 2023-09-22 19:25 13705
*/
2660ccea Poul Sander 2023-09-22 19:25 13706
template <typename FloatType>
2660ccea Poul Sander 2023-09-22 19:25 13707
JSON_HEDLEY_NON_NULL(1, 2)
2660ccea Poul Sander 2023-09-22 19:25 13708
JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 13709
char* to_chars(char* first, const char* last, FloatType value)
2660ccea Poul Sander 2023-09-22 19:25 13710
{
2660ccea Poul Sander 2023-09-22 19:25 13711
    static_cast<void>(last); // maybe unused - fix warning
2660ccea Poul Sander 2023-09-22 19:25 13712
    assert(std::isfinite(value));
2660ccea Poul Sander 2023-09-22 19:25 13713
2660ccea Poul Sander 2023-09-22 19:25 13714
    // Use signbit(value) instead of (value < 0) since signbit works for -0.
2660ccea Poul Sander 2023-09-22 19:25 13715
    if (std::signbit(value))
2660ccea Poul Sander 2023-09-22 19:25 13716
    {
2660ccea Poul Sander 2023-09-22 19:25 13717
        value = -value;
2660ccea Poul Sander 2023-09-22 19:25 13718
        *first++ = '-';
2660ccea Poul Sander 2023-09-22 19:25 13719
    }
2660ccea Poul Sander 2023-09-22 19:25 13720
2660ccea Poul Sander 2023-09-22 19:25 13721
    if (value == 0) // +-0
2660ccea Poul Sander 2023-09-22 19:25 13722
    {
2660ccea Poul Sander 2023-09-22 19:25 13723
        *first++ = '0';
2660ccea Poul Sander 2023-09-22 19:25 13724
        // Make it look like a floating-point number (#362, #378)
2660ccea Poul Sander 2023-09-22 19:25 13725
        *first++ = '.';
2660ccea Poul Sander 2023-09-22 19:25 13726
        *first++ = '0';
2660ccea Poul Sander 2023-09-22 19:25 13727
        return first;
2660ccea Poul Sander 2023-09-22 19:25 13728
    }
2660ccea Poul Sander 2023-09-22 19:25 13729
2660ccea Poul Sander 2023-09-22 19:25 13730
    assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
2660ccea Poul Sander 2023-09-22 19:25 13731
2660ccea Poul Sander 2023-09-22 19:25 13732
    // Compute v = buffer * 10^decimal_exponent.
2660ccea Poul Sander 2023-09-22 19:25 13733
    // The decimal digits are stored in the buffer, which needs to be interpreted
2660ccea Poul Sander 2023-09-22 19:25 13734
    // as an unsigned decimal integer.
2660ccea Poul Sander 2023-09-22 19:25 13735
    // len is the length of the buffer, i.e. the number of decimal digits.
2660ccea Poul Sander 2023-09-22 19:25 13736
    int len = 0;
2660ccea Poul Sander 2023-09-22 19:25 13737
    int decimal_exponent = 0;
2660ccea Poul Sander 2023-09-22 19:25 13738
    dtoa_impl::grisu2(first, len, decimal_exponent, value);
2660ccea Poul Sander 2023-09-22 19:25 13739
2660ccea Poul Sander 2023-09-22 19:25 13740
    assert(len <= std::numeric_limits<FloatType>::max_digits10);
2660ccea Poul Sander 2023-09-22 19:25 13741
2660ccea Poul Sander 2023-09-22 19:25 13742
    // Format the buffer like printf("%.*g", prec, value)
2660ccea Poul Sander 2023-09-22 19:25 13743
    constexpr int kMinExp = -4;
2660ccea Poul Sander 2023-09-22 19:25 13744
    // Use digits10 here to increase compatibility with version 2.
2660ccea Poul Sander 2023-09-22 19:25 13745
    constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
2660ccea Poul Sander 2023-09-22 19:25 13746
2660ccea Poul Sander 2023-09-22 19:25 13747
    assert(last - first >= kMaxExp + 2);
2660ccea Poul Sander 2023-09-22 19:25 13748
    assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
2660ccea Poul Sander 2023-09-22 19:25 13749
    assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
2660ccea Poul Sander 2023-09-22 19:25 13750
2660ccea Poul Sander 2023-09-22 19:25 13751
    return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
2660ccea Poul Sander 2023-09-22 19:25 13752
}
2660ccea Poul Sander 2023-09-22 19:25 13753
2660ccea Poul Sander 2023-09-22 19:25 13754
} // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 13755
} // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 13756
2660ccea Poul Sander 2023-09-22 19:25 13757
// #include <nlohmann/detail/exceptions.hpp>
2660ccea Poul Sander 2023-09-22 19:25 13758
2660ccea Poul Sander 2023-09-22 19:25 13759
// #include <nlohmann/detail/macro_scope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 13760
2660ccea Poul Sander 2023-09-22 19:25 13761
// #include <nlohmann/detail/meta/cpp_future.hpp>
2660ccea Poul Sander 2023-09-22 19:25 13762
2660ccea Poul Sander 2023-09-22 19:25 13763
// #include <nlohmann/detail/output/binary_writer.hpp>
2660ccea Poul Sander 2023-09-22 19:25 13764
2660ccea Poul Sander 2023-09-22 19:25 13765
// #include <nlohmann/detail/output/output_adapters.hpp>
2660ccea Poul Sander 2023-09-22 19:25 13766
2660ccea Poul Sander 2023-09-22 19:25 13767
// #include <nlohmann/detail/value_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 13768
2660ccea Poul Sander 2023-09-22 19:25 13769
2660ccea Poul Sander 2023-09-22 19:25 13770
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 13771
{
2660ccea Poul Sander 2023-09-22 19:25 13772
namespace detail
2660ccea Poul Sander 2023-09-22 19:25 13773
{
2660ccea Poul Sander 2023-09-22 19:25 13774
///////////////////
2660ccea Poul Sander 2023-09-22 19:25 13775
// serialization //
2660ccea Poul Sander 2023-09-22 19:25 13776
///////////////////
2660ccea Poul Sander 2023-09-22 19:25 13777
2660ccea Poul Sander 2023-09-22 19:25 13778
/// how to treat decoding errors
2660ccea Poul Sander 2023-09-22 19:25 13779
enum class error_handler_t
2660ccea Poul Sander 2023-09-22 19:25 13780
{
2660ccea Poul Sander 2023-09-22 19:25 13781
    strict,  ///< throw a type_error exception in case of invalid UTF-8
2660ccea Poul Sander 2023-09-22 19:25 13782
    replace, ///< replace invalid UTF-8 sequences with U+FFFD
2660ccea Poul Sander 2023-09-22 19:25 13783
    ignore   ///< ignore invalid UTF-8 sequences
2660ccea Poul Sander 2023-09-22 19:25 13784
};
2660ccea Poul Sander 2023-09-22 19:25 13785
2660ccea Poul Sander 2023-09-22 19:25 13786
template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 13787
class serializer
2660ccea Poul Sander 2023-09-22 19:25 13788
{
2660ccea Poul Sander 2023-09-22 19:25 13789
    using string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 13790
    using number_float_t = typename BasicJsonType::number_float_t;
2660ccea Poul Sander 2023-09-22 19:25 13791
    using number_integer_t = typename BasicJsonType::number_integer_t;
2660ccea Poul Sander 2023-09-22 19:25 13792
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2660ccea Poul Sander 2023-09-22 19:25 13793
    static constexpr std::uint8_t UTF8_ACCEPT = 0;
2660ccea Poul Sander 2023-09-22 19:25 13794
    static constexpr std::uint8_t UTF8_REJECT = 1;
2660ccea Poul Sander 2023-09-22 19:25 13795
2660ccea Poul Sander 2023-09-22 19:25 13796
  public:
2660ccea Poul Sander 2023-09-22 19:25 13797
    /*!
2660ccea Poul Sander 2023-09-22 19:25 13798
    @param[in] s  output stream to serialize to
2660ccea Poul Sander 2023-09-22 19:25 13799
    @param[in] ichar  indentation character to use
2660ccea Poul Sander 2023-09-22 19:25 13800
    @param[in] error_handler_  how to react on decoding errors
2660ccea Poul Sander 2023-09-22 19:25 13801
    */
2660ccea Poul Sander 2023-09-22 19:25 13802
    serializer(output_adapter_t<char> s, const char ichar,
2660ccea Poul Sander 2023-09-22 19:25 13803
               error_handler_t error_handler_ = error_handler_t::strict)
2660ccea Poul Sander 2023-09-22 19:25 13804
        : o(std::move(s))
2660ccea Poul Sander 2023-09-22 19:25 13805
        , loc(std::localeconv())
2660ccea Poul Sander 2023-09-22 19:25 13806
        , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
2660ccea Poul Sander 2023-09-22 19:25 13807
        , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
2660ccea Poul Sander 2023-09-22 19:25 13808
        , indent_char(ichar)
2660ccea Poul Sander 2023-09-22 19:25 13809
        , indent_string(512, indent_char)
2660ccea Poul Sander 2023-09-22 19:25 13810
        , error_handler(error_handler_)
2660ccea Poul Sander 2023-09-22 19:25 13811
    {}
2660ccea Poul Sander 2023-09-22 19:25 13812
2660ccea Poul Sander 2023-09-22 19:25 13813
    // delete because of pointer members
2660ccea Poul Sander 2023-09-22 19:25 13814
    serializer(const serializer&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 13815
    serializer& operator=(const serializer&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 13816
    serializer(serializer&&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 13817
    serializer& operator=(serializer&&) = delete;
2660ccea Poul Sander 2023-09-22 19:25 13818
    ~serializer() = default;
2660ccea Poul Sander 2023-09-22 19:25 13819
2660ccea Poul Sander 2023-09-22 19:25 13820
    /*!
2660ccea Poul Sander 2023-09-22 19:25 13821
    @brief internal implementation of the serialization function
2660ccea Poul Sander 2023-09-22 19:25 13822
2660ccea Poul Sander 2023-09-22 19:25 13823
    This function is called by the public member function dump and organizes
2660ccea Poul Sander 2023-09-22 19:25 13824
    the serialization internally. The indentation level is propagated as
2660ccea Poul Sander 2023-09-22 19:25 13825
    additional parameter. In case of arrays and objects, the function is
2660ccea Poul Sander 2023-09-22 19:25 13826
    called recursively.
2660ccea Poul Sander 2023-09-22 19:25 13827
2660ccea Poul Sander 2023-09-22 19:25 13828
    - strings and object keys are escaped using `escape_string()`
2660ccea Poul Sander 2023-09-22 19:25 13829
    - integer numbers are converted implicitly via `operator<<`
2660ccea Poul Sander 2023-09-22 19:25 13830
    - floating-point numbers are converted to a string using `"%g"` format
2660ccea Poul Sander 2023-09-22 19:25 13831
2660ccea Poul Sander 2023-09-22 19:25 13832
    @param[in] val             value to serialize
2660ccea Poul Sander 2023-09-22 19:25 13833
    @param[in] pretty_print    whether the output shall be pretty-printed
2660ccea Poul Sander 2023-09-22 19:25 13834
    @param[in] indent_step     the indent level
2660ccea Poul Sander 2023-09-22 19:25 13835
    @param[in] current_indent  the current indent level (only used internally)
2660ccea Poul Sander 2023-09-22 19:25 13836
    */
2660ccea Poul Sander 2023-09-22 19:25 13837
    void dump(const BasicJsonType& val, const bool pretty_print,
2660ccea Poul Sander 2023-09-22 19:25 13838
              const bool ensure_ascii,
2660ccea Poul Sander 2023-09-22 19:25 13839
              const unsigned int indent_step,
2660ccea Poul Sander 2023-09-22 19:25 13840
              const unsigned int current_indent = 0)
2660ccea Poul Sander 2023-09-22 19:25 13841
    {
2660ccea Poul Sander 2023-09-22 19:25 13842
        switch (val.m_type)
2660ccea Poul Sander 2023-09-22 19:25 13843
        {
2660ccea Poul Sander 2023-09-22 19:25 13844
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 13845
            {
2660ccea Poul Sander 2023-09-22 19:25 13846
                if (val.m_value.object->empty())
2660ccea Poul Sander 2023-09-22 19:25 13847
                {
2660ccea Poul Sander 2023-09-22 19:25 13848
                    o->write_characters("{}", 2);
2660ccea Poul Sander 2023-09-22 19:25 13849
                    return;
2660ccea Poul Sander 2023-09-22 19:25 13850
                }
2660ccea Poul Sander 2023-09-22 19:25 13851
2660ccea Poul Sander 2023-09-22 19:25 13852
                if (pretty_print)
2660ccea Poul Sander 2023-09-22 19:25 13853
                {
2660ccea Poul Sander 2023-09-22 19:25 13854
                    o->write_characters("{\n", 2);
2660ccea Poul Sander 2023-09-22 19:25 13855
2660ccea Poul Sander 2023-09-22 19:25 13856
                    // variable to hold indentation for recursive calls
2660ccea Poul Sander 2023-09-22 19:25 13857
                    const auto new_indent = current_indent + indent_step;
2660ccea Poul Sander 2023-09-22 19:25 13858
                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
2660ccea Poul Sander 2023-09-22 19:25 13859
                    {
2660ccea Poul Sander 2023-09-22 19:25 13860
                        indent_string.resize(indent_string.size() * 2, ' ');
2660ccea Poul Sander 2023-09-22 19:25 13861
                    }
2660ccea Poul Sander 2023-09-22 19:25 13862
2660ccea Poul Sander 2023-09-22 19:25 13863
                    // first n-1 elements
2660ccea Poul Sander 2023-09-22 19:25 13864
                    auto i = val.m_value.object->cbegin();
2660ccea Poul Sander 2023-09-22 19:25 13865
                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
2660ccea Poul Sander 2023-09-22 19:25 13866
                    {
2660ccea Poul Sander 2023-09-22 19:25 13867
                        o->write_characters(indent_string.c_str(), new_indent);
2660ccea Poul Sander 2023-09-22 19:25 13868
                        o->write_character('\"');
2660ccea Poul Sander 2023-09-22 19:25 13869
                        dump_escaped(i->first, ensure_ascii);
2660ccea Poul Sander 2023-09-22 19:25 13870
                        o->write_characters("\": ", 3);
2660ccea Poul Sander 2023-09-22 19:25 13871
                        dump(i->second, true, ensure_ascii, indent_step, new_indent);
2660ccea Poul Sander 2023-09-22 19:25 13872
                        o->write_characters(",\n", 2);
2660ccea Poul Sander 2023-09-22 19:25 13873
                    }
2660ccea Poul Sander 2023-09-22 19:25 13874
2660ccea Poul Sander 2023-09-22 19:25 13875
                    // last element
2660ccea Poul Sander 2023-09-22 19:25 13876
                    assert(i != val.m_value.object->cend());
2660ccea Poul Sander 2023-09-22 19:25 13877
                    assert(std::next(i) == val.m_value.object->cend());
2660ccea Poul Sander 2023-09-22 19:25 13878
                    o->write_characters(indent_string.c_str(), new_indent);
2660ccea Poul Sander 2023-09-22 19:25 13879
                    o->write_character('\"');
2660ccea Poul Sander 2023-09-22 19:25 13880
                    dump_escaped(i->first, ensure_ascii);
2660ccea Poul Sander 2023-09-22 19:25 13881
                    o->write_characters("\": ", 3);
2660ccea Poul Sander 2023-09-22 19:25 13882
                    dump(i->second, true, ensure_ascii, indent_step, new_indent);
2660ccea Poul Sander 2023-09-22 19:25 13883
2660ccea Poul Sander 2023-09-22 19:25 13884
                    o->write_character('\n');
2660ccea Poul Sander 2023-09-22 19:25 13885
                    o->write_characters(indent_string.c_str(), current_indent);
2660ccea Poul Sander 2023-09-22 19:25 13886
                    o->write_character('}');
2660ccea Poul Sander 2023-09-22 19:25 13887
                }
2660ccea Poul Sander 2023-09-22 19:25 13888
                else
2660ccea Poul Sander 2023-09-22 19:25 13889
                {
2660ccea Poul Sander 2023-09-22 19:25 13890
                    o->write_character('{');
2660ccea Poul Sander 2023-09-22 19:25 13891
2660ccea Poul Sander 2023-09-22 19:25 13892
                    // first n-1 elements
2660ccea Poul Sander 2023-09-22 19:25 13893
                    auto i = val.m_value.object->cbegin();
2660ccea Poul Sander 2023-09-22 19:25 13894
                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
2660ccea Poul Sander 2023-09-22 19:25 13895
                    {
2660ccea Poul Sander 2023-09-22 19:25 13896
                        o->write_character('\"');
2660ccea Poul Sander 2023-09-22 19:25 13897
                        dump_escaped(i->first, ensure_ascii);
2660ccea Poul Sander 2023-09-22 19:25 13898
                        o->write_characters("\":", 2);
2660ccea Poul Sander 2023-09-22 19:25 13899
                        dump(i->second, false, ensure_ascii, indent_step, current_indent);
2660ccea Poul Sander 2023-09-22 19:25 13900
                        o->write_character(',');
2660ccea Poul Sander 2023-09-22 19:25 13901
                    }
2660ccea Poul Sander 2023-09-22 19:25 13902
2660ccea Poul Sander 2023-09-22 19:25 13903
                    // last element
2660ccea Poul Sander 2023-09-22 19:25 13904
                    assert(i != val.m_value.object->cend());
2660ccea Poul Sander 2023-09-22 19:25 13905
                    assert(std::next(i) == val.m_value.object->cend());
2660ccea Poul Sander 2023-09-22 19:25 13906
                    o->write_character('\"');
2660ccea Poul Sander 2023-09-22 19:25 13907
                    dump_escaped(i->first, ensure_ascii);
2660ccea Poul Sander 2023-09-22 19:25 13908
                    o->write_characters("\":", 2);
2660ccea Poul Sander 2023-09-22 19:25 13909
                    dump(i->second, false, ensure_ascii, indent_step, current_indent);
2660ccea Poul Sander 2023-09-22 19:25 13910
2660ccea Poul Sander 2023-09-22 19:25 13911
                    o->write_character('}');
2660ccea Poul Sander 2023-09-22 19:25 13912
                }
2660ccea Poul Sander 2023-09-22 19:25 13913
2660ccea Poul Sander 2023-09-22 19:25 13914
                return;
2660ccea Poul Sander 2023-09-22 19:25 13915
            }
2660ccea Poul Sander 2023-09-22 19:25 13916
2660ccea Poul Sander 2023-09-22 19:25 13917
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 13918
            {
2660ccea Poul Sander 2023-09-22 19:25 13919
                if (val.m_value.array->empty())
2660ccea Poul Sander 2023-09-22 19:25 13920
                {
2660ccea Poul Sander 2023-09-22 19:25 13921
                    o->write_characters("[]", 2);
2660ccea Poul Sander 2023-09-22 19:25 13922
                    return;
2660ccea Poul Sander 2023-09-22 19:25 13923
                }
2660ccea Poul Sander 2023-09-22 19:25 13924
2660ccea Poul Sander 2023-09-22 19:25 13925
                if (pretty_print)
2660ccea Poul Sander 2023-09-22 19:25 13926
                {
2660ccea Poul Sander 2023-09-22 19:25 13927
                    o->write_characters("[\n", 2);
2660ccea Poul Sander 2023-09-22 19:25 13928
2660ccea Poul Sander 2023-09-22 19:25 13929
                    // variable to hold indentation for recursive calls
2660ccea Poul Sander 2023-09-22 19:25 13930
                    const auto new_indent = current_indent + indent_step;
2660ccea Poul Sander 2023-09-22 19:25 13931
                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
2660ccea Poul Sander 2023-09-22 19:25 13932
                    {
2660ccea Poul Sander 2023-09-22 19:25 13933
                        indent_string.resize(indent_string.size() * 2, ' ');
2660ccea Poul Sander 2023-09-22 19:25 13934
                    }
2660ccea Poul Sander 2023-09-22 19:25 13935
2660ccea Poul Sander 2023-09-22 19:25 13936
                    // first n-1 elements
2660ccea Poul Sander 2023-09-22 19:25 13937
                    for (auto i = val.m_value.array->cbegin();
2660ccea Poul Sander 2023-09-22 19:25 13938
                            i != val.m_value.array->cend() - 1; ++i)
2660ccea Poul Sander 2023-09-22 19:25 13939
                    {
2660ccea Poul Sander 2023-09-22 19:25 13940
                        o->write_characters(indent_string.c_str(), new_indent);
2660ccea Poul Sander 2023-09-22 19:25 13941
                        dump(*i, true, ensure_ascii, indent_step, new_indent);
2660ccea Poul Sander 2023-09-22 19:25 13942
                        o->write_characters(",\n", 2);
2660ccea Poul Sander 2023-09-22 19:25 13943
                    }
2660ccea Poul Sander 2023-09-22 19:25 13944
2660ccea Poul Sander 2023-09-22 19:25 13945
                    // last element
2660ccea Poul Sander 2023-09-22 19:25 13946
                    assert(not val.m_value.array->empty());
2660ccea Poul Sander 2023-09-22 19:25 13947
                    o->write_characters(indent_string.c_str(), new_indent);
2660ccea Poul Sander 2023-09-22 19:25 13948
                    dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
2660ccea Poul Sander 2023-09-22 19:25 13949
2660ccea Poul Sander 2023-09-22 19:25 13950
                    o->write_character('\n');
2660ccea Poul Sander 2023-09-22 19:25 13951
                    o->write_characters(indent_string.c_str(), current_indent);
2660ccea Poul Sander 2023-09-22 19:25 13952
                    o->write_character(']');
2660ccea Poul Sander 2023-09-22 19:25 13953
                }
2660ccea Poul Sander 2023-09-22 19:25 13954
                else
2660ccea Poul Sander 2023-09-22 19:25 13955
                {
2660ccea Poul Sander 2023-09-22 19:25 13956
                    o->write_character('[');
2660ccea Poul Sander 2023-09-22 19:25 13957
2660ccea Poul Sander 2023-09-22 19:25 13958
                    // first n-1 elements
2660ccea Poul Sander 2023-09-22 19:25 13959
                    for (auto i = val.m_value.array->cbegin();
2660ccea Poul Sander 2023-09-22 19:25 13960
                            i != val.m_value.array->cend() - 1; ++i)
2660ccea Poul Sander 2023-09-22 19:25 13961
                    {
2660ccea Poul Sander 2023-09-22 19:25 13962
                        dump(*i, false, ensure_ascii, indent_step, current_indent);
2660ccea Poul Sander 2023-09-22 19:25 13963
                        o->write_character(',');
2660ccea Poul Sander 2023-09-22 19:25 13964
                    }
2660ccea Poul Sander 2023-09-22 19:25 13965
2660ccea Poul Sander 2023-09-22 19:25 13966
                    // last element
2660ccea Poul Sander 2023-09-22 19:25 13967
                    assert(not val.m_value.array->empty());
2660ccea Poul Sander 2023-09-22 19:25 13968
                    dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
2660ccea Poul Sander 2023-09-22 19:25 13969
2660ccea Poul Sander 2023-09-22 19:25 13970
                    o->write_character(']');
2660ccea Poul Sander 2023-09-22 19:25 13971
                }
2660ccea Poul Sander 2023-09-22 19:25 13972
2660ccea Poul Sander 2023-09-22 19:25 13973
                return;
2660ccea Poul Sander 2023-09-22 19:25 13974
            }
2660ccea Poul Sander 2023-09-22 19:25 13975
2660ccea Poul Sander 2023-09-22 19:25 13976
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 13977
            {
2660ccea Poul Sander 2023-09-22 19:25 13978
                o->write_character('\"');
2660ccea Poul Sander 2023-09-22 19:25 13979
                dump_escaped(*val.m_value.string, ensure_ascii);
2660ccea Poul Sander 2023-09-22 19:25 13980
                o->write_character('\"');
2660ccea Poul Sander 2023-09-22 19:25 13981
                return;
2660ccea Poul Sander 2023-09-22 19:25 13982
            }
2660ccea Poul Sander 2023-09-22 19:25 13983
2660ccea Poul Sander 2023-09-22 19:25 13984
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 13985
            {
2660ccea Poul Sander 2023-09-22 19:25 13986
                if (val.m_value.boolean)
2660ccea Poul Sander 2023-09-22 19:25 13987
                {
2660ccea Poul Sander 2023-09-22 19:25 13988
                    o->write_characters("true", 4);
2660ccea Poul Sander 2023-09-22 19:25 13989
                }
2660ccea Poul Sander 2023-09-22 19:25 13990
                else
2660ccea Poul Sander 2023-09-22 19:25 13991
                {
2660ccea Poul Sander 2023-09-22 19:25 13992
                    o->write_characters("false", 5);
2660ccea Poul Sander 2023-09-22 19:25 13993
                }
2660ccea Poul Sander 2023-09-22 19:25 13994
                return;
2660ccea Poul Sander 2023-09-22 19:25 13995
            }
2660ccea Poul Sander 2023-09-22 19:25 13996
2660ccea Poul Sander 2023-09-22 19:25 13997
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 13998
            {
2660ccea Poul Sander 2023-09-22 19:25 13999
                dump_integer(val.m_value.number_integer);
2660ccea Poul Sander 2023-09-22 19:25 14000
                return;
2660ccea Poul Sander 2023-09-22 19:25 14001
            }
2660ccea Poul Sander 2023-09-22 19:25 14002
2660ccea Poul Sander 2023-09-22 19:25 14003
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 14004
            {
2660ccea Poul Sander 2023-09-22 19:25 14005
                dump_integer(val.m_value.number_unsigned);
2660ccea Poul Sander 2023-09-22 19:25 14006
                return;
2660ccea Poul Sander 2023-09-22 19:25 14007
            }
2660ccea Poul Sander 2023-09-22 19:25 14008
2660ccea Poul Sander 2023-09-22 19:25 14009
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 14010
            {
2660ccea Poul Sander 2023-09-22 19:25 14011
                dump_float(val.m_value.number_float);
2660ccea Poul Sander 2023-09-22 19:25 14012
                return;
2660ccea Poul Sander 2023-09-22 19:25 14013
            }
2660ccea Poul Sander 2023-09-22 19:25 14014
2660ccea Poul Sander 2023-09-22 19:25 14015
            case value_t::discarded:
2660ccea Poul Sander 2023-09-22 19:25 14016
            {
2660ccea Poul Sander 2023-09-22 19:25 14017
                o->write_characters("<discarded>", 11);
2660ccea Poul Sander 2023-09-22 19:25 14018
                return;
2660ccea Poul Sander 2023-09-22 19:25 14019
            }
2660ccea Poul Sander 2023-09-22 19:25 14020
2660ccea Poul Sander 2023-09-22 19:25 14021
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 14022
            {
2660ccea Poul Sander 2023-09-22 19:25 14023
                o->write_characters("null", 4);
2660ccea Poul Sander 2023-09-22 19:25 14024
                return;
2660ccea Poul Sander 2023-09-22 19:25 14025
            }
2660ccea Poul Sander 2023-09-22 19:25 14026
2660ccea Poul Sander 2023-09-22 19:25 14027
            default:            // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 14028
                assert(false);  // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 14029
        }
2660ccea Poul Sander 2023-09-22 19:25 14030
    }
2660ccea Poul Sander 2023-09-22 19:25 14031
2660ccea Poul Sander 2023-09-22 19:25 14032
  private:
2660ccea Poul Sander 2023-09-22 19:25 14033
    /*!
2660ccea Poul Sander 2023-09-22 19:25 14034
    @brief dump escaped string
2660ccea Poul Sander 2023-09-22 19:25 14035
2660ccea Poul Sander 2023-09-22 19:25 14036
    Escape a string by replacing certain special characters by a sequence of an
2660ccea Poul Sander 2023-09-22 19:25 14037
    escape character (backslash) and another character and other control
2660ccea Poul Sander 2023-09-22 19:25 14038
    characters by a sequence of "\u" followed by a four-digit hex
2660ccea Poul Sander 2023-09-22 19:25 14039
    representation. The escaped string is written to output stream @a o.
2660ccea Poul Sander 2023-09-22 19:25 14040
2660ccea Poul Sander 2023-09-22 19:25 14041
    @param[in] s  the string to escape
2660ccea Poul Sander 2023-09-22 19:25 14042
    @param[in] ensure_ascii  whether to escape non-ASCII characters with
2660ccea Poul Sander 2023-09-22 19:25 14043
                             \uXXXX sequences
2660ccea Poul Sander 2023-09-22 19:25 14044
2660ccea Poul Sander 2023-09-22 19:25 14045
    @complexity Linear in the length of string @a s.
2660ccea Poul Sander 2023-09-22 19:25 14046
    */
2660ccea Poul Sander 2023-09-22 19:25 14047
    void dump_escaped(const string_t& s, const bool ensure_ascii)
2660ccea Poul Sander 2023-09-22 19:25 14048
    {
2660ccea Poul Sander 2023-09-22 19:25 14049
        std::uint32_t codepoint;
2660ccea Poul Sander 2023-09-22 19:25 14050
        std::uint8_t state = UTF8_ACCEPT;
2660ccea Poul Sander 2023-09-22 19:25 14051
        std::size_t bytes = 0;  // number of bytes written to string_buffer
2660ccea Poul Sander 2023-09-22 19:25 14052
2660ccea Poul Sander 2023-09-22 19:25 14053
        // number of bytes written at the point of the last valid byte
2660ccea Poul Sander 2023-09-22 19:25 14054
        std::size_t bytes_after_last_accept = 0;
2660ccea Poul Sander 2023-09-22 19:25 14055
        std::size_t undumped_chars = 0;
2660ccea Poul Sander 2023-09-22 19:25 14056
2660ccea Poul Sander 2023-09-22 19:25 14057
        for (std::size_t i = 0; i < s.size(); ++i)
2660ccea Poul Sander 2023-09-22 19:25 14058
        {
2660ccea Poul Sander 2023-09-22 19:25 14059
            const auto byte = static_cast<uint8_t>(s[i]);
2660ccea Poul Sander 2023-09-22 19:25 14060
2660ccea Poul Sander 2023-09-22 19:25 14061
            switch (decode(state, codepoint, byte))
2660ccea Poul Sander 2023-09-22 19:25 14062
            {
2660ccea Poul Sander 2023-09-22 19:25 14063
                case UTF8_ACCEPT:  // decode found a new code point
2660ccea Poul Sander 2023-09-22 19:25 14064
                {
2660ccea Poul Sander 2023-09-22 19:25 14065
                    switch (codepoint)
2660ccea Poul Sander 2023-09-22 19:25 14066
                    {
2660ccea Poul Sander 2023-09-22 19:25 14067
                        case 0x08: // backspace
2660ccea Poul Sander 2023-09-22 19:25 14068
                        {
2660ccea Poul Sander 2023-09-22 19:25 14069
                            string_buffer[bytes++] = '\\';
2660ccea Poul Sander 2023-09-22 19:25 14070
                            string_buffer[bytes++] = 'b';
2660ccea Poul Sander 2023-09-22 19:25 14071
                            break;
2660ccea Poul Sander 2023-09-22 19:25 14072
                        }
2660ccea Poul Sander 2023-09-22 19:25 14073
2660ccea Poul Sander 2023-09-22 19:25 14074
                        case 0x09: // horizontal tab
2660ccea Poul Sander 2023-09-22 19:25 14075
                        {
2660ccea Poul Sander 2023-09-22 19:25 14076
                            string_buffer[bytes++] = '\\';
2660ccea Poul Sander 2023-09-22 19:25 14077
                            string_buffer[bytes++] = 't';
2660ccea Poul Sander 2023-09-22 19:25 14078
                            break;
2660ccea Poul Sander 2023-09-22 19:25 14079
                        }
2660ccea Poul Sander 2023-09-22 19:25 14080
2660ccea Poul Sander 2023-09-22 19:25 14081
                        case 0x0A: // newline
2660ccea Poul Sander 2023-09-22 19:25 14082
                        {
2660ccea Poul Sander 2023-09-22 19:25 14083
                            string_buffer[bytes++] = '\\';
2660ccea Poul Sander 2023-09-22 19:25 14084
                            string_buffer[bytes++] = 'n';
2660ccea Poul Sander 2023-09-22 19:25 14085
                            break;
2660ccea Poul Sander 2023-09-22 19:25 14086
                        }
2660ccea Poul Sander 2023-09-22 19:25 14087
2660ccea Poul Sander 2023-09-22 19:25 14088
                        case 0x0C: // formfeed
2660ccea Poul Sander 2023-09-22 19:25 14089
                        {
2660ccea Poul Sander 2023-09-22 19:25 14090
                            string_buffer[bytes++] = '\\';
2660ccea Poul Sander 2023-09-22 19:25 14091
                            string_buffer[bytes++] = 'f';
2660ccea Poul Sander 2023-09-22 19:25 14092
                            break;
2660ccea Poul Sander 2023-09-22 19:25 14093
                        }
2660ccea Poul Sander 2023-09-22 19:25 14094
2660ccea Poul Sander 2023-09-22 19:25 14095
                        case 0x0D: // carriage return
2660ccea Poul Sander 2023-09-22 19:25 14096
                        {
2660ccea Poul Sander 2023-09-22 19:25 14097
                            string_buffer[bytes++] = '\\';
2660ccea Poul Sander 2023-09-22 19:25 14098
                            string_buffer[bytes++] = 'r';
2660ccea Poul Sander 2023-09-22 19:25 14099
                            break;
2660ccea Poul Sander 2023-09-22 19:25 14100
                        }
2660ccea Poul Sander 2023-09-22 19:25 14101
2660ccea Poul Sander 2023-09-22 19:25 14102
                        case 0x22: // quotation mark
2660ccea Poul Sander 2023-09-22 19:25 14103
                        {
2660ccea Poul Sander 2023-09-22 19:25 14104
                            string_buffer[bytes++] = '\\';
2660ccea Poul Sander 2023-09-22 19:25 14105
                            string_buffer[bytes++] = '\"';
2660ccea Poul Sander 2023-09-22 19:25 14106
                            break;
2660ccea Poul Sander 2023-09-22 19:25 14107
                        }
2660ccea Poul Sander 2023-09-22 19:25 14108
2660ccea Poul Sander 2023-09-22 19:25 14109
                        case 0x5C: // reverse solidus
2660ccea Poul Sander 2023-09-22 19:25 14110
                        {
2660ccea Poul Sander 2023-09-22 19:25 14111
                            string_buffer[bytes++] = '\\';
2660ccea Poul Sander 2023-09-22 19:25 14112
                            string_buffer[bytes++] = '\\';
2660ccea Poul Sander 2023-09-22 19:25 14113
                            break;
2660ccea Poul Sander 2023-09-22 19:25 14114
                        }
2660ccea Poul Sander 2023-09-22 19:25 14115
2660ccea Poul Sander 2023-09-22 19:25 14116
                        default:
2660ccea Poul Sander 2023-09-22 19:25 14117
                        {
2660ccea Poul Sander 2023-09-22 19:25 14118
                            // escape control characters (0x00..0x1F) or, if
2660ccea Poul Sander 2023-09-22 19:25 14119
                            // ensure_ascii parameter is used, non-ASCII characters
2660ccea Poul Sander 2023-09-22 19:25 14120
                            if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
2660ccea Poul Sander 2023-09-22 19:25 14121
                            {
2660ccea Poul Sander 2023-09-22 19:25 14122
                                if (codepoint <= 0xFFFF)
2660ccea Poul Sander 2023-09-22 19:25 14123
                                {
2660ccea Poul Sander 2023-09-22 19:25 14124
                                    (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
2660ccea Poul Sander 2023-09-22 19:25 14125
                                                    static_cast<std::uint16_t>(codepoint));
2660ccea Poul Sander 2023-09-22 19:25 14126
                                    bytes += 6;
2660ccea Poul Sander 2023-09-22 19:25 14127
                                }
2660ccea Poul Sander 2023-09-22 19:25 14128
                                else
2660ccea Poul Sander 2023-09-22 19:25 14129
                                {
2660ccea Poul Sander 2023-09-22 19:25 14130
                                    (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
2660ccea Poul Sander 2023-09-22 19:25 14131
                                                    static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
2660ccea Poul Sander 2023-09-22 19:25 14132
                                                    static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
2660ccea Poul Sander 2023-09-22 19:25 14133
                                    bytes += 12;
2660ccea Poul Sander 2023-09-22 19:25 14134
                                }
2660ccea Poul Sander 2023-09-22 19:25 14135
                            }
2660ccea Poul Sander 2023-09-22 19:25 14136
                            else
2660ccea Poul Sander 2023-09-22 19:25 14137
                            {
2660ccea Poul Sander 2023-09-22 19:25 14138
                                // copy byte to buffer (all previous bytes
2660ccea Poul Sander 2023-09-22 19:25 14139
                                // been copied have in default case above)
2660ccea Poul Sander 2023-09-22 19:25 14140
                                string_buffer[bytes++] = s[i];
2660ccea Poul Sander 2023-09-22 19:25 14141
                            }
2660ccea Poul Sander 2023-09-22 19:25 14142
                            break;
2660ccea Poul Sander 2023-09-22 19:25 14143
                        }
2660ccea Poul Sander 2023-09-22 19:25 14144
                    }
2660ccea Poul Sander 2023-09-22 19:25 14145
2660ccea Poul Sander 2023-09-22 19:25 14146
                    // write buffer and reset index; there must be 13 bytes
2660ccea Poul Sander 2023-09-22 19:25 14147
                    // left, as this is the maximal number of bytes to be
2660ccea Poul Sander 2023-09-22 19:25 14148
                    // written ("\uxxxx\uxxxx\0") for one code point
2660ccea Poul Sander 2023-09-22 19:25 14149
                    if (string_buffer.size() - bytes < 13)
2660ccea Poul Sander 2023-09-22 19:25 14150
                    {
2660ccea Poul Sander 2023-09-22 19:25 14151
                        o->write_characters(string_buffer.data(), bytes);
2660ccea Poul Sander 2023-09-22 19:25 14152
                        bytes = 0;
2660ccea Poul Sander 2023-09-22 19:25 14153
                    }
2660ccea Poul Sander 2023-09-22 19:25 14154
2660ccea Poul Sander 2023-09-22 19:25 14155
                    // remember the byte position of this accept
2660ccea Poul Sander 2023-09-22 19:25 14156
                    bytes_after_last_accept = bytes;
2660ccea Poul Sander 2023-09-22 19:25 14157
                    undumped_chars = 0;
2660ccea Poul Sander 2023-09-22 19:25 14158
                    break;
2660ccea Poul Sander 2023-09-22 19:25 14159
                }
2660ccea Poul Sander 2023-09-22 19:25 14160
2660ccea Poul Sander 2023-09-22 19:25 14161
                case UTF8_REJECT:  // decode found invalid UTF-8 byte
2660ccea Poul Sander 2023-09-22 19:25 14162
                {
2660ccea Poul Sander 2023-09-22 19:25 14163
                    switch (error_handler)
2660ccea Poul Sander 2023-09-22 19:25 14164
                    {
2660ccea Poul Sander 2023-09-22 19:25 14165
                        case error_handler_t::strict:
2660ccea Poul Sander 2023-09-22 19:25 14166
                        {
2660ccea Poul Sander 2023-09-22 19:25 14167
                            std::string sn(3, '\0');
2660ccea Poul Sander 2023-09-22 19:25 14168
                            (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
2660ccea Poul Sander 2023-09-22 19:25 14169
                            JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
2660ccea Poul Sander 2023-09-22 19:25 14170
                        }
2660ccea Poul Sander 2023-09-22 19:25 14171
2660ccea Poul Sander 2023-09-22 19:25 14172
                        case error_handler_t::ignore:
2660ccea Poul Sander 2023-09-22 19:25 14173
                        case error_handler_t::replace:
2660ccea Poul Sander 2023-09-22 19:25 14174
                        {
2660ccea Poul Sander 2023-09-22 19:25 14175
                            // in case we saw this character the first time, we
2660ccea Poul Sander 2023-09-22 19:25 14176
                            // would like to read it again, because the byte
2660ccea Poul Sander 2023-09-22 19:25 14177
                            // may be OK for itself, but just not OK for the
2660ccea Poul Sander 2023-09-22 19:25 14178
                            // previous sequence
2660ccea Poul Sander 2023-09-22 19:25 14179
                            if (undumped_chars > 0)
2660ccea Poul Sander 2023-09-22 19:25 14180
                            {
2660ccea Poul Sander 2023-09-22 19:25 14181
                                --i;
2660ccea Poul Sander 2023-09-22 19:25 14182
                            }
2660ccea Poul Sander 2023-09-22 19:25 14183
2660ccea Poul Sander 2023-09-22 19:25 14184
                            // reset length buffer to the last accepted index;
2660ccea Poul Sander 2023-09-22 19:25 14185
                            // thus removing/ignoring the invalid characters
2660ccea Poul Sander 2023-09-22 19:25 14186
                            bytes = bytes_after_last_accept;
2660ccea Poul Sander 2023-09-22 19:25 14187
2660ccea Poul Sander 2023-09-22 19:25 14188
                            if (error_handler == error_handler_t::replace)
2660ccea Poul Sander 2023-09-22 19:25 14189
                            {
2660ccea Poul Sander 2023-09-22 19:25 14190
                                // add a replacement character
2660ccea Poul Sander 2023-09-22 19:25 14191
                                if (ensure_ascii)
2660ccea Poul Sander 2023-09-22 19:25 14192
                                {
2660ccea Poul Sander 2023-09-22 19:25 14193
                                    string_buffer[bytes++] = '\\';
2660ccea Poul Sander 2023-09-22 19:25 14194
                                    string_buffer[bytes++] = 'u';
2660ccea Poul Sander 2023-09-22 19:25 14195
                                    string_buffer[bytes++] = 'f';
2660ccea Poul Sander 2023-09-22 19:25 14196
                                    string_buffer[bytes++] = 'f';
2660ccea Poul Sander 2023-09-22 19:25 14197
                                    string_buffer[bytes++] = 'f';
2660ccea Poul Sander 2023-09-22 19:25 14198
                                    string_buffer[bytes++] = 'd';
2660ccea Poul Sander 2023-09-22 19:25 14199
                                }
2660ccea Poul Sander 2023-09-22 19:25 14200
                                else
2660ccea Poul Sander 2023-09-22 19:25 14201
                                {
2660ccea Poul Sander 2023-09-22 19:25 14202
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
2660ccea Poul Sander 2023-09-22 19:25 14203
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
2660ccea Poul Sander 2023-09-22 19:25 14204
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
2660ccea Poul Sander 2023-09-22 19:25 14205
                                }
2660ccea Poul Sander 2023-09-22 19:25 14206
2660ccea Poul Sander 2023-09-22 19:25 14207
                                // write buffer and reset index; there must be 13 bytes
2660ccea Poul Sander 2023-09-22 19:25 14208
                                // left, as this is the maximal number of bytes to be
2660ccea Poul Sander 2023-09-22 19:25 14209
                                // written ("\uxxxx\uxxxx\0") for one code point
2660ccea Poul Sander 2023-09-22 19:25 14210
                                if (string_buffer.size() - bytes < 13)
2660ccea Poul Sander 2023-09-22 19:25 14211
                                {
2660ccea Poul Sander 2023-09-22 19:25 14212
                                    o->write_characters(string_buffer.data(), bytes);
2660ccea Poul Sander 2023-09-22 19:25 14213
                                    bytes = 0;
2660ccea Poul Sander 2023-09-22 19:25 14214
                                }
2660ccea Poul Sander 2023-09-22 19:25 14215
2660ccea Poul Sander 2023-09-22 19:25 14216
                                bytes_after_last_accept = bytes;
2660ccea Poul Sander 2023-09-22 19:25 14217
                            }
2660ccea Poul Sander 2023-09-22 19:25 14218
2660ccea Poul Sander 2023-09-22 19:25 14219
                            undumped_chars = 0;
2660ccea Poul Sander 2023-09-22 19:25 14220
2660ccea Poul Sander 2023-09-22 19:25 14221
                            // continue processing the string
2660ccea Poul Sander 2023-09-22 19:25 14222
                            state = UTF8_ACCEPT;
2660ccea Poul Sander 2023-09-22 19:25 14223
                            break;
2660ccea Poul Sander 2023-09-22 19:25 14224
                        }
2660ccea Poul Sander 2023-09-22 19:25 14225
2660ccea Poul Sander 2023-09-22 19:25 14226
                        default:            // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 14227
                            assert(false);  // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 14228
                    }
2660ccea Poul Sander 2023-09-22 19:25 14229
                    break;
2660ccea Poul Sander 2023-09-22 19:25 14230
                }
2660ccea Poul Sander 2023-09-22 19:25 14231
2660ccea Poul Sander 2023-09-22 19:25 14232
                default:  // decode found yet incomplete multi-byte code point
2660ccea Poul Sander 2023-09-22 19:25 14233
                {
2660ccea Poul Sander 2023-09-22 19:25 14234
                    if (not ensure_ascii)
2660ccea Poul Sander 2023-09-22 19:25 14235
                    {
2660ccea Poul Sander 2023-09-22 19:25 14236
                        // code point will not be escaped - copy byte to buffer
2660ccea Poul Sander 2023-09-22 19:25 14237
                        string_buffer[bytes++] = s[i];
2660ccea Poul Sander 2023-09-22 19:25 14238
                    }
2660ccea Poul Sander 2023-09-22 19:25 14239
                    ++undumped_chars;
2660ccea Poul Sander 2023-09-22 19:25 14240
                    break;
2660ccea Poul Sander 2023-09-22 19:25 14241
                }
2660ccea Poul Sander 2023-09-22 19:25 14242
            }
2660ccea Poul Sander 2023-09-22 19:25 14243
        }
2660ccea Poul Sander 2023-09-22 19:25 14244
2660ccea Poul Sander 2023-09-22 19:25 14245
        // we finished processing the string
2660ccea Poul Sander 2023-09-22 19:25 14246
        if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
2660ccea Poul Sander 2023-09-22 19:25 14247
        {
2660ccea Poul Sander 2023-09-22 19:25 14248
            // write buffer
2660ccea Poul Sander 2023-09-22 19:25 14249
            if (bytes > 0)
2660ccea Poul Sander 2023-09-22 19:25 14250
            {
2660ccea Poul Sander 2023-09-22 19:25 14251
                o->write_characters(string_buffer.data(), bytes);
2660ccea Poul Sander 2023-09-22 19:25 14252
            }
2660ccea Poul Sander 2023-09-22 19:25 14253
        }
2660ccea Poul Sander 2023-09-22 19:25 14254
        else
2660ccea Poul Sander 2023-09-22 19:25 14255
        {
2660ccea Poul Sander 2023-09-22 19:25 14256
            // we finish reading, but do not accept: string was incomplete
2660ccea Poul Sander 2023-09-22 19:25 14257
            switch (error_handler)
2660ccea Poul Sander 2023-09-22 19:25 14258
            {
2660ccea Poul Sander 2023-09-22 19:25 14259
                case error_handler_t::strict:
2660ccea Poul Sander 2023-09-22 19:25 14260
                {
2660ccea Poul Sander 2023-09-22 19:25 14261
                    std::string sn(3, '\0');
2660ccea Poul Sander 2023-09-22 19:25 14262
                    (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
2660ccea Poul Sander 2023-09-22 19:25 14263
                    JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
2660ccea Poul Sander 2023-09-22 19:25 14264
                }
2660ccea Poul Sander 2023-09-22 19:25 14265
2660ccea Poul Sander 2023-09-22 19:25 14266
                case error_handler_t::ignore:
2660ccea Poul Sander 2023-09-22 19:25 14267
                {
2660ccea Poul Sander 2023-09-22 19:25 14268
                    // write all accepted bytes
2660ccea Poul Sander 2023-09-22 19:25 14269
                    o->write_characters(string_buffer.data(), bytes_after_last_accept);
2660ccea Poul Sander 2023-09-22 19:25 14270
                    break;
2660ccea Poul Sander 2023-09-22 19:25 14271
                }
2660ccea Poul Sander 2023-09-22 19:25 14272
2660ccea Poul Sander 2023-09-22 19:25 14273
                case error_handler_t::replace:
2660ccea Poul Sander 2023-09-22 19:25 14274
                {
2660ccea Poul Sander 2023-09-22 19:25 14275
                    // write all accepted bytes
2660ccea Poul Sander 2023-09-22 19:25 14276
                    o->write_characters(string_buffer.data(), bytes_after_last_accept);
2660ccea Poul Sander 2023-09-22 19:25 14277
                    // add a replacement character
2660ccea Poul Sander 2023-09-22 19:25 14278
                    if (ensure_ascii)
2660ccea Poul Sander 2023-09-22 19:25 14279
                    {
2660ccea Poul Sander 2023-09-22 19:25 14280
                        o->write_characters("\\ufffd", 6);
2660ccea Poul Sander 2023-09-22 19:25 14281
                    }
2660ccea Poul Sander 2023-09-22 19:25 14282
                    else
2660ccea Poul Sander 2023-09-22 19:25 14283
                    {
2660ccea Poul Sander 2023-09-22 19:25 14284
                        o->write_characters("\xEF\xBF\xBD", 3);
2660ccea Poul Sander 2023-09-22 19:25 14285
                    }
2660ccea Poul Sander 2023-09-22 19:25 14286
                    break;
2660ccea Poul Sander 2023-09-22 19:25 14287
                }
2660ccea Poul Sander 2023-09-22 19:25 14288
2660ccea Poul Sander 2023-09-22 19:25 14289
                default:            // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 14290
                    assert(false);  // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 14291
            }
2660ccea Poul Sander 2023-09-22 19:25 14292
        }
2660ccea Poul Sander 2023-09-22 19:25 14293
    }
2660ccea Poul Sander 2023-09-22 19:25 14294
2660ccea Poul Sander 2023-09-22 19:25 14295
    /*!
2660ccea Poul Sander 2023-09-22 19:25 14296
    @brief count digits
2660ccea Poul Sander 2023-09-22 19:25 14297
2660ccea Poul Sander 2023-09-22 19:25 14298
    Count the number of decimal (base 10) digits for an input unsigned integer.
2660ccea Poul Sander 2023-09-22 19:25 14299
2660ccea Poul Sander 2023-09-22 19:25 14300
    @param[in] x  unsigned integer number to count its digits
2660ccea Poul Sander 2023-09-22 19:25 14301
    @return    number of decimal digits
2660ccea Poul Sander 2023-09-22 19:25 14302
    */
2660ccea Poul Sander 2023-09-22 19:25 14303
    inline unsigned int count_digits(number_unsigned_t x) noexcept
2660ccea Poul Sander 2023-09-22 19:25 14304
    {
2660ccea Poul Sander 2023-09-22 19:25 14305
        unsigned int n_digits = 1;
2660ccea Poul Sander 2023-09-22 19:25 14306
        for (;;)
2660ccea Poul Sander 2023-09-22 19:25 14307
        {
2660ccea Poul Sander 2023-09-22 19:25 14308
            if (x < 10)
2660ccea Poul Sander 2023-09-22 19:25 14309
            {
2660ccea Poul Sander 2023-09-22 19:25 14310
                return n_digits;
2660ccea Poul Sander 2023-09-22 19:25 14311
            }
2660ccea Poul Sander 2023-09-22 19:25 14312
            if (x < 100)
2660ccea Poul Sander 2023-09-22 19:25 14313
            {
2660ccea Poul Sander 2023-09-22 19:25 14314
                return n_digits + 1;
2660ccea Poul Sander 2023-09-22 19:25 14315
            }
2660ccea Poul Sander 2023-09-22 19:25 14316
            if (x < 1000)
2660ccea Poul Sander 2023-09-22 19:25 14317
            {
2660ccea Poul Sander 2023-09-22 19:25 14318
                return n_digits + 2;
2660ccea Poul Sander 2023-09-22 19:25 14319
            }
2660ccea Poul Sander 2023-09-22 19:25 14320
            if (x < 10000)
2660ccea Poul Sander 2023-09-22 19:25 14321
            {
2660ccea Poul Sander 2023-09-22 19:25 14322
                return n_digits + 3;
2660ccea Poul Sander 2023-09-22 19:25 14323
            }
2660ccea Poul Sander 2023-09-22 19:25 14324
            x = x / 10000u;
2660ccea Poul Sander 2023-09-22 19:25 14325
            n_digits += 4;
2660ccea Poul Sander 2023-09-22 19:25 14326
        }
2660ccea Poul Sander 2023-09-22 19:25 14327
    }
2660ccea Poul Sander 2023-09-22 19:25 14328
2660ccea Poul Sander 2023-09-22 19:25 14329
    /*!
2660ccea Poul Sander 2023-09-22 19:25 14330
    @brief dump an integer
2660ccea Poul Sander 2023-09-22 19:25 14331
2660ccea Poul Sander 2023-09-22 19:25 14332
    Dump a given integer to output stream @a o. Works internally with
2660ccea Poul Sander 2023-09-22 19:25 14333
    @a number_buffer.
2660ccea Poul Sander 2023-09-22 19:25 14334
2660ccea Poul Sander 2023-09-22 19:25 14335
    @param[in] x  integer number (signed or unsigned) to dump
2660ccea Poul Sander 2023-09-22 19:25 14336
    @tparam NumberType either @a number_integer_t or @a number_unsigned_t
2660ccea Poul Sander 2023-09-22 19:25 14337
    */
2660ccea Poul Sander 2023-09-22 19:25 14338
    template<typename NumberType, detail::enable_if_t<
2660ccea Poul Sander 2023-09-22 19:25 14339
                 std::is_same<NumberType, number_unsigned_t>::value or
2660ccea Poul Sander 2023-09-22 19:25 14340
                 std::is_same<NumberType, number_integer_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 14341
                 int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 14342
    void dump_integer(NumberType x)
2660ccea Poul Sander 2023-09-22 19:25 14343
    {
2660ccea Poul Sander 2023-09-22 19:25 14344
        static constexpr std::array<std::array<char, 2>, 100> digits_to_99
2660ccea Poul Sander 2023-09-22 19:25 14345
        {
2660ccea Poul Sander 2023-09-22 19:25 14346
            {
2660ccea Poul Sander 2023-09-22 19:25 14347
                {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
2660ccea Poul Sander 2023-09-22 19:25 14348
                {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
2660ccea Poul Sander 2023-09-22 19:25 14349
                {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
2660ccea Poul Sander 2023-09-22 19:25 14350
                {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
2660ccea Poul Sander 2023-09-22 19:25 14351
                {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
2660ccea Poul Sander 2023-09-22 19:25 14352
                {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
2660ccea Poul Sander 2023-09-22 19:25 14353
                {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
2660ccea Poul Sander 2023-09-22 19:25 14354
                {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
2660ccea Poul Sander 2023-09-22 19:25 14355
                {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
2660ccea Poul Sander 2023-09-22 19:25 14356
                {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
2660ccea Poul Sander 2023-09-22 19:25 14357
            }
2660ccea Poul Sander 2023-09-22 19:25 14358
        };
2660ccea Poul Sander 2023-09-22 19:25 14359
2660ccea Poul Sander 2023-09-22 19:25 14360
        // special case for "0"
2660ccea Poul Sander 2023-09-22 19:25 14361
        if (x == 0)
2660ccea Poul Sander 2023-09-22 19:25 14362
        {
2660ccea Poul Sander 2023-09-22 19:25 14363
            o->write_character('0');
2660ccea Poul Sander 2023-09-22 19:25 14364
            return;
2660ccea Poul Sander 2023-09-22 19:25 14365
        }
2660ccea Poul Sander 2023-09-22 19:25 14366
2660ccea Poul Sander 2023-09-22 19:25 14367
        // use a pointer to fill the buffer
2660ccea Poul Sander 2023-09-22 19:25 14368
        auto buffer_ptr = number_buffer.begin();
2660ccea Poul Sander 2023-09-22 19:25 14369
2660ccea Poul Sander 2023-09-22 19:25 14370
        const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755
2660ccea Poul Sander 2023-09-22 19:25 14371
        number_unsigned_t abs_value;
2660ccea Poul Sander 2023-09-22 19:25 14372
2660ccea Poul Sander 2023-09-22 19:25 14373
        unsigned int n_chars;
2660ccea Poul Sander 2023-09-22 19:25 14374
2660ccea Poul Sander 2023-09-22 19:25 14375
        if (is_negative)
2660ccea Poul Sander 2023-09-22 19:25 14376
        {
2660ccea Poul Sander 2023-09-22 19:25 14377
            *buffer_ptr = '-';
2660ccea Poul Sander 2023-09-22 19:25 14378
            abs_value = remove_sign(x);
2660ccea Poul Sander 2023-09-22 19:25 14379
2660ccea Poul Sander 2023-09-22 19:25 14380
            // account one more byte for the minus sign
2660ccea Poul Sander 2023-09-22 19:25 14381
            n_chars = 1 + count_digits(abs_value);
2660ccea Poul Sander 2023-09-22 19:25 14382
        }
2660ccea Poul Sander 2023-09-22 19:25 14383
        else
2660ccea Poul Sander 2023-09-22 19:25 14384
        {
2660ccea Poul Sander 2023-09-22 19:25 14385
            abs_value = static_cast<number_unsigned_t>(x);
2660ccea Poul Sander 2023-09-22 19:25 14386
            n_chars = count_digits(abs_value);
2660ccea Poul Sander 2023-09-22 19:25 14387
        }
2660ccea Poul Sander 2023-09-22 19:25 14388
2660ccea Poul Sander 2023-09-22 19:25 14389
        // spare 1 byte for '\0'
2660ccea Poul Sander 2023-09-22 19:25 14390
        assert(n_chars < number_buffer.size() - 1);
2660ccea Poul Sander 2023-09-22 19:25 14391
2660ccea Poul Sander 2023-09-22 19:25 14392
        // jump to the end to generate the string from backward
2660ccea Poul Sander 2023-09-22 19:25 14393
        // so we later avoid reversing the result
2660ccea Poul Sander 2023-09-22 19:25 14394
        buffer_ptr += n_chars;
2660ccea Poul Sander 2023-09-22 19:25 14395
2660ccea Poul Sander 2023-09-22 19:25 14396
        // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
2660ccea Poul Sander 2023-09-22 19:25 14397
        // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
2660ccea Poul Sander 2023-09-22 19:25 14398
        while (abs_value >= 100)
2660ccea Poul Sander 2023-09-22 19:25 14399
        {
2660ccea Poul Sander 2023-09-22 19:25 14400
            const auto digits_index = static_cast<unsigned>((abs_value % 100));
2660ccea Poul Sander 2023-09-22 19:25 14401
            abs_value /= 100;
2660ccea Poul Sander 2023-09-22 19:25 14402
            *(--buffer_ptr) = digits_to_99[digits_index][1];
2660ccea Poul Sander 2023-09-22 19:25 14403
            *(--buffer_ptr) = digits_to_99[digits_index][0];
2660ccea Poul Sander 2023-09-22 19:25 14404
        }
2660ccea Poul Sander 2023-09-22 19:25 14405
2660ccea Poul Sander 2023-09-22 19:25 14406
        if (abs_value >= 10)
2660ccea Poul Sander 2023-09-22 19:25 14407
        {
2660ccea Poul Sander 2023-09-22 19:25 14408
            const auto digits_index = static_cast<unsigned>(abs_value);
2660ccea Poul Sander 2023-09-22 19:25 14409
            *(--buffer_ptr) = digits_to_99[digits_index][1];
2660ccea Poul Sander 2023-09-22 19:25 14410
            *(--buffer_ptr) = digits_to_99[digits_index][0];
2660ccea Poul Sander 2023-09-22 19:25 14411
        }
2660ccea Poul Sander 2023-09-22 19:25 14412
        else
2660ccea Poul Sander 2023-09-22 19:25 14413
        {
2660ccea Poul Sander 2023-09-22 19:25 14414
            *(--buffer_ptr) = static_cast<char>('0' + abs_value);
2660ccea Poul Sander 2023-09-22 19:25 14415
        }
2660ccea Poul Sander 2023-09-22 19:25 14416
2660ccea Poul Sander 2023-09-22 19:25 14417
        o->write_characters(number_buffer.data(), n_chars);
2660ccea Poul Sander 2023-09-22 19:25 14418
    }
2660ccea Poul Sander 2023-09-22 19:25 14419
2660ccea Poul Sander 2023-09-22 19:25 14420
    /*!
2660ccea Poul Sander 2023-09-22 19:25 14421
    @brief dump a floating-point number
2660ccea Poul Sander 2023-09-22 19:25 14422
2660ccea Poul Sander 2023-09-22 19:25 14423
    Dump a given floating-point number to output stream @a o. Works internally
2660ccea Poul Sander 2023-09-22 19:25 14424
    with @a number_buffer.
2660ccea Poul Sander 2023-09-22 19:25 14425
2660ccea Poul Sander 2023-09-22 19:25 14426
    @param[in] x  floating-point number to dump
2660ccea Poul Sander 2023-09-22 19:25 14427
    */
2660ccea Poul Sander 2023-09-22 19:25 14428
    void dump_float(number_float_t x)
2660ccea Poul Sander 2023-09-22 19:25 14429
    {
2660ccea Poul Sander 2023-09-22 19:25 14430
        // NaN / inf
2660ccea Poul Sander 2023-09-22 19:25 14431
        if (not std::isfinite(x))
2660ccea Poul Sander 2023-09-22 19:25 14432
        {
2660ccea Poul Sander 2023-09-22 19:25 14433
            o->write_characters("null", 4);
2660ccea Poul Sander 2023-09-22 19:25 14434
            return;
2660ccea Poul Sander 2023-09-22 19:25 14435
        }
2660ccea Poul Sander 2023-09-22 19:25 14436
2660ccea Poul Sander 2023-09-22 19:25 14437
        // If number_float_t is an IEEE-754 single or double precision number,
2660ccea Poul Sander 2023-09-22 19:25 14438
        // use the Grisu2 algorithm to produce short numbers which are
2660ccea Poul Sander 2023-09-22 19:25 14439
        // guaranteed to round-trip, using strtof and strtod, resp.
2660ccea Poul Sander 2023-09-22 19:25 14440
        //
2660ccea Poul Sander 2023-09-22 19:25 14441
        // NB: The test below works if <long double> == <double>.
2660ccea Poul Sander 2023-09-22 19:25 14442
        static constexpr bool is_ieee_single_or_double
2660ccea Poul Sander 2023-09-22 19:25 14443
            = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
2660ccea Poul Sander 2023-09-22 19:25 14444
              (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
2660ccea Poul Sander 2023-09-22 19:25 14445
2660ccea Poul Sander 2023-09-22 19:25 14446
        dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
2660ccea Poul Sander 2023-09-22 19:25 14447
    }
2660ccea Poul Sander 2023-09-22 19:25 14448
2660ccea Poul Sander 2023-09-22 19:25 14449
    void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
2660ccea Poul Sander 2023-09-22 19:25 14450
    {
2660ccea Poul Sander 2023-09-22 19:25 14451
        char* begin = number_buffer.data();
2660ccea Poul Sander 2023-09-22 19:25 14452
        char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
2660ccea Poul Sander 2023-09-22 19:25 14453
2660ccea Poul Sander 2023-09-22 19:25 14454
        o->write_characters(begin, static_cast<size_t>(end - begin));
2660ccea Poul Sander 2023-09-22 19:25 14455
    }
2660ccea Poul Sander 2023-09-22 19:25 14456
2660ccea Poul Sander 2023-09-22 19:25 14457
    void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
2660ccea Poul Sander 2023-09-22 19:25 14458
    {
2660ccea Poul Sander 2023-09-22 19:25 14459
        // get number of digits for a float -> text -> float round-trip
2660ccea Poul Sander 2023-09-22 19:25 14460
        static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
2660ccea Poul Sander 2023-09-22 19:25 14461
2660ccea Poul Sander 2023-09-22 19:25 14462
        // the actual conversion
2660ccea Poul Sander 2023-09-22 19:25 14463
        std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
2660ccea Poul Sander 2023-09-22 19:25 14464
2660ccea Poul Sander 2023-09-22 19:25 14465
        // negative value indicates an error
2660ccea Poul Sander 2023-09-22 19:25 14466
        assert(len > 0);
2660ccea Poul Sander 2023-09-22 19:25 14467
        // check if buffer was large enough
2660ccea Poul Sander 2023-09-22 19:25 14468
        assert(static_cast<std::size_t>(len) < number_buffer.size());
2660ccea Poul Sander 2023-09-22 19:25 14469
2660ccea Poul Sander 2023-09-22 19:25 14470
        // erase thousands separator
2660ccea Poul Sander 2023-09-22 19:25 14471
        if (thousands_sep != '\0')
2660ccea Poul Sander 2023-09-22 19:25 14472
        {
2660ccea Poul Sander 2023-09-22 19:25 14473
            const auto end = std::remove(number_buffer.begin(),
2660ccea Poul Sander 2023-09-22 19:25 14474
                                         number_buffer.begin() + len, thousands_sep);
2660ccea Poul Sander 2023-09-22 19:25 14475
            std::fill(end, number_buffer.end(), '\0');
2660ccea Poul Sander 2023-09-22 19:25 14476
            assert((end - number_buffer.begin()) <= len);
2660ccea Poul Sander 2023-09-22 19:25 14477
            len = (end - number_buffer.begin());
2660ccea Poul Sander 2023-09-22 19:25 14478
        }
2660ccea Poul Sander 2023-09-22 19:25 14479
2660ccea Poul Sander 2023-09-22 19:25 14480
        // convert decimal point to '.'
2660ccea Poul Sander 2023-09-22 19:25 14481
        if (decimal_point != '\0' and decimal_point != '.')
2660ccea Poul Sander 2023-09-22 19:25 14482
        {
2660ccea Poul Sander 2023-09-22 19:25 14483
            const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
2660ccea Poul Sander 2023-09-22 19:25 14484
            if (dec_pos != number_buffer.end())
2660ccea Poul Sander 2023-09-22 19:25 14485
            {
2660ccea Poul Sander 2023-09-22 19:25 14486
                *dec_pos = '.';
2660ccea Poul Sander 2023-09-22 19:25 14487
            }
2660ccea Poul Sander 2023-09-22 19:25 14488
        }
2660ccea Poul Sander 2023-09-22 19:25 14489
2660ccea Poul Sander 2023-09-22 19:25 14490
        o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
2660ccea Poul Sander 2023-09-22 19:25 14491
2660ccea Poul Sander 2023-09-22 19:25 14492
        // determine if need to append ".0"
2660ccea Poul Sander 2023-09-22 19:25 14493
        const bool value_is_int_like =
2660ccea Poul Sander 2023-09-22 19:25 14494
            std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
2660ccea Poul Sander 2023-09-22 19:25 14495
                         [](char c)
2660ccea Poul Sander 2023-09-22 19:25 14496
        {
2660ccea Poul Sander 2023-09-22 19:25 14497
            return c == '.' or c == 'e';
2660ccea Poul Sander 2023-09-22 19:25 14498
        });
2660ccea Poul Sander 2023-09-22 19:25 14499
2660ccea Poul Sander 2023-09-22 19:25 14500
        if (value_is_int_like)
2660ccea Poul Sander 2023-09-22 19:25 14501
        {
2660ccea Poul Sander 2023-09-22 19:25 14502
            o->write_characters(".0", 2);
2660ccea Poul Sander 2023-09-22 19:25 14503
        }
2660ccea Poul Sander 2023-09-22 19:25 14504
    }
2660ccea Poul Sander 2023-09-22 19:25 14505
2660ccea Poul Sander 2023-09-22 19:25 14506
    /*!
2660ccea Poul Sander 2023-09-22 19:25 14507
    @brief check whether a string is UTF-8 encoded
2660ccea Poul Sander 2023-09-22 19:25 14508
2660ccea Poul Sander 2023-09-22 19:25 14509
    The function checks each byte of a string whether it is UTF-8 encoded. The
2660ccea Poul Sander 2023-09-22 19:25 14510
    result of the check is stored in the @a state parameter. The function must
2660ccea Poul Sander 2023-09-22 19:25 14511
    be called initially with state 0 (accept). State 1 means the string must
2660ccea Poul Sander 2023-09-22 19:25 14512
    be rejected, because the current byte is not allowed. If the string is
2660ccea Poul Sander 2023-09-22 19:25 14513
    completely processed, but the state is non-zero, the string ended
2660ccea Poul Sander 2023-09-22 19:25 14514
    prematurely; that is, the last byte indicated more bytes should have
2660ccea Poul Sander 2023-09-22 19:25 14515
    followed.
2660ccea Poul Sander 2023-09-22 19:25 14516
2660ccea Poul Sander 2023-09-22 19:25 14517
    @param[in,out] state  the state of the decoding
2660ccea Poul Sander 2023-09-22 19:25 14518
    @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)
2660ccea Poul Sander 2023-09-22 19:25 14519
    @param[in] byte       next byte to decode
2660ccea Poul Sander 2023-09-22 19:25 14520
    @return               new state
2660ccea Poul Sander 2023-09-22 19:25 14521
2660ccea Poul Sander 2023-09-22 19:25 14522
    @note The function has been edited: a std::array is used.
2660ccea Poul Sander 2023-09-22 19:25 14523
2660ccea Poul Sander 2023-09-22 19:25 14524
    @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
2660ccea Poul Sander 2023-09-22 19:25 14525
    @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
2660ccea Poul Sander 2023-09-22 19:25 14526
    */
2660ccea Poul Sander 2023-09-22 19:25 14527
    static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
2660ccea Poul Sander 2023-09-22 19:25 14528
    {
2660ccea Poul Sander 2023-09-22 19:25 14529
        static const std::array<std::uint8_t, 400> utf8d =
2660ccea Poul Sander 2023-09-22 19:25 14530
        {
2660ccea Poul Sander 2023-09-22 19:25 14531
            {
2660ccea Poul Sander 2023-09-22 19:25 14532
                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
2660ccea Poul Sander 2023-09-22 19:25 14533
                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
2660ccea Poul Sander 2023-09-22 19:25 14534
                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
2660ccea Poul Sander 2023-09-22 19:25 14535
                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
2660ccea Poul Sander 2023-09-22 19:25 14536
                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
2660ccea Poul Sander 2023-09-22 19:25 14537
                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
2660ccea Poul Sander 2023-09-22 19:25 14538
                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
2660ccea Poul Sander 2023-09-22 19:25 14539
                0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
2660ccea Poul Sander 2023-09-22 19:25 14540
                0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
2660ccea Poul Sander 2023-09-22 19:25 14541
                0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
2660ccea Poul Sander 2023-09-22 19:25 14542
                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
2660ccea Poul Sander 2023-09-22 19:25 14543
                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
2660ccea Poul Sander 2023-09-22 19:25 14544
                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
2660ccea Poul Sander 2023-09-22 19:25 14545
                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
2660ccea Poul Sander 2023-09-22 19:25 14546
            }
2660ccea Poul Sander 2023-09-22 19:25 14547
        };
2660ccea Poul Sander 2023-09-22 19:25 14548
2660ccea Poul Sander 2023-09-22 19:25 14549
        const std::uint8_t type = utf8d[byte];
2660ccea Poul Sander 2023-09-22 19:25 14550
2660ccea Poul Sander 2023-09-22 19:25 14551
        codep = (state != UTF8_ACCEPT)
2660ccea Poul Sander 2023-09-22 19:25 14552
                ? (byte & 0x3fu) | (codep << 6u)
2660ccea Poul Sander 2023-09-22 19:25 14553
                : (0xFFu >> type) & (byte);
2660ccea Poul Sander 2023-09-22 19:25 14554
2660ccea Poul Sander 2023-09-22 19:25 14555
        state = utf8d[256u + state * 16u + type];
2660ccea Poul Sander 2023-09-22 19:25 14556
        return state;
2660ccea Poul Sander 2023-09-22 19:25 14557
    }
2660ccea Poul Sander 2023-09-22 19:25 14558
2660ccea Poul Sander 2023-09-22 19:25 14559
    /*
2660ccea Poul Sander 2023-09-22 19:25 14560
     * Overload to make the compiler happy while it is instantiating
2660ccea Poul Sander 2023-09-22 19:25 14561
     * dump_integer for number_unsigned_t.
2660ccea Poul Sander 2023-09-22 19:25 14562
     * Must never be called.
2660ccea Poul Sander 2023-09-22 19:25 14563
     */
2660ccea Poul Sander 2023-09-22 19:25 14564
    number_unsigned_t remove_sign(number_unsigned_t x)
2660ccea Poul Sander 2023-09-22 19:25 14565
    {
2660ccea Poul Sander 2023-09-22 19:25 14566
        assert(false); // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 14567
        return x; // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 14568
    }
2660ccea Poul Sander 2023-09-22 19:25 14569
2660ccea Poul Sander 2023-09-22 19:25 14570
    /*
2660ccea Poul Sander 2023-09-22 19:25 14571
     * Helper function for dump_integer
2660ccea Poul Sander 2023-09-22 19:25 14572
     *
2660ccea Poul Sander 2023-09-22 19:25 14573
     * This function takes a negative signed integer and returns its absolute
2660ccea Poul Sander 2023-09-22 19:25 14574
     * value as unsigned integer. The plus/minus shuffling is necessary as we can
2660ccea Poul Sander 2023-09-22 19:25 14575
     * not directly remove the sign of an arbitrary signed integer as the
2660ccea Poul Sander 2023-09-22 19:25 14576
     * absolute values of INT_MIN and INT_MAX are usually not the same. See
2660ccea Poul Sander 2023-09-22 19:25 14577
     * #1708 for details.
2660ccea Poul Sander 2023-09-22 19:25 14578
     */
2660ccea Poul Sander 2023-09-22 19:25 14579
    inline number_unsigned_t remove_sign(number_integer_t x) noexcept
2660ccea Poul Sander 2023-09-22 19:25 14580
    {
2660ccea Poul Sander 2023-09-22 19:25 14581
        assert(x < 0 and x < (std::numeric_limits<number_integer_t>::max)());
2660ccea Poul Sander 2023-09-22 19:25 14582
        return static_cast<number_unsigned_t>(-(x + 1)) + 1;
2660ccea Poul Sander 2023-09-22 19:25 14583
    }
2660ccea Poul Sander 2023-09-22 19:25 14584
2660ccea Poul Sander 2023-09-22 19:25 14585
  private:
2660ccea Poul Sander 2023-09-22 19:25 14586
    /// the output of the serializer
2660ccea Poul Sander 2023-09-22 19:25 14587
    output_adapter_t<char> o = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 14588
2660ccea Poul Sander 2023-09-22 19:25 14589
    /// a (hopefully) large enough character buffer
2660ccea Poul Sander 2023-09-22 19:25 14590
    std::array<char, 64> number_buffer{{}};
2660ccea Poul Sander 2023-09-22 19:25 14591
2660ccea Poul Sander 2023-09-22 19:25 14592
    /// the locale
2660ccea Poul Sander 2023-09-22 19:25 14593
    const std::lconv* loc = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 14594
    /// the locale's thousand separator character
2660ccea Poul Sander 2023-09-22 19:25 14595
    const char thousands_sep = '\0';
2660ccea Poul Sander 2023-09-22 19:25 14596
    /// the locale's decimal point character
2660ccea Poul Sander 2023-09-22 19:25 14597
    const char decimal_point = '\0';
2660ccea Poul Sander 2023-09-22 19:25 14598
2660ccea Poul Sander 2023-09-22 19:25 14599
    /// string buffer
2660ccea Poul Sander 2023-09-22 19:25 14600
    std::array<char, 512> string_buffer{{}};
2660ccea Poul Sander 2023-09-22 19:25 14601
2660ccea Poul Sander 2023-09-22 19:25 14602
    /// the indentation character
2660ccea Poul Sander 2023-09-22 19:25 14603
    const char indent_char;
2660ccea Poul Sander 2023-09-22 19:25 14604
    /// the indentation string
2660ccea Poul Sander 2023-09-22 19:25 14605
    string_t indent_string;
2660ccea Poul Sander 2023-09-22 19:25 14606
2660ccea Poul Sander 2023-09-22 19:25 14607
    /// error_handler how to react on decoding errors
2660ccea Poul Sander 2023-09-22 19:25 14608
    const error_handler_t error_handler;
2660ccea Poul Sander 2023-09-22 19:25 14609
};
2660ccea Poul Sander 2023-09-22 19:25 14610
}  // namespace detail
2660ccea Poul Sander 2023-09-22 19:25 14611
}  // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 14612
2660ccea Poul Sander 2023-09-22 19:25 14613
// #include <nlohmann/detail/value_t.hpp>
2660ccea Poul Sander 2023-09-22 19:25 14614
2660ccea Poul Sander 2023-09-22 19:25 14615
// #include <nlohmann/json_fwd.hpp>
2660ccea Poul Sander 2023-09-22 19:25 14616
2660ccea Poul Sander 2023-09-22 19:25 14617
2660ccea Poul Sander 2023-09-22 19:25 14618
/*!
2660ccea Poul Sander 2023-09-22 19:25 14619
@brief namespace for Niels Lohmann
2660ccea Poul Sander 2023-09-22 19:25 14620
@see https://github.com/nlohmann
2660ccea Poul Sander 2023-09-22 19:25 14621
@since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 14622
*/
2660ccea Poul Sander 2023-09-22 19:25 14623
namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 14624
{
2660ccea Poul Sander 2023-09-22 19:25 14625
2660ccea Poul Sander 2023-09-22 19:25 14626
/*!
2660ccea Poul Sander 2023-09-22 19:25 14627
@brief a class to store JSON values
2660ccea Poul Sander 2023-09-22 19:25 14628
2660ccea Poul Sander 2023-09-22 19:25 14629
@tparam ObjectType type for JSON objects (`std::map` by default; will be used
2660ccea Poul Sander 2023-09-22 19:25 14630
in @ref object_t)
2660ccea Poul Sander 2023-09-22 19:25 14631
@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
2660ccea Poul Sander 2023-09-22 19:25 14632
in @ref array_t)
2660ccea Poul Sander 2023-09-22 19:25 14633
@tparam StringType type for JSON strings and object keys (`std::string` by
2660ccea Poul Sander 2023-09-22 19:25 14634
default; will be used in @ref string_t)
2660ccea Poul Sander 2023-09-22 19:25 14635
@tparam BooleanType type for JSON booleans (`bool` by default; will be used
2660ccea Poul Sander 2023-09-22 19:25 14636
in @ref boolean_t)
2660ccea Poul Sander 2023-09-22 19:25 14637
@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
2660ccea Poul Sander 2023-09-22 19:25 14638
default; will be used in @ref number_integer_t)
2660ccea Poul Sander 2023-09-22 19:25 14639
@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
2660ccea Poul Sander 2023-09-22 19:25 14640
`uint64_t` by default; will be used in @ref number_unsigned_t)
2660ccea Poul Sander 2023-09-22 19:25 14641
@tparam NumberFloatType type for JSON floating-point numbers (`double` by
2660ccea Poul Sander 2023-09-22 19:25 14642
default; will be used in @ref number_float_t)
2660ccea Poul Sander 2023-09-22 19:25 14643
@tparam AllocatorType type of the allocator to use (`std::allocator` by
2660ccea Poul Sander 2023-09-22 19:25 14644
default)
2660ccea Poul Sander 2023-09-22 19:25 14645
@tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
2660ccea Poul Sander 2023-09-22 19:25 14646
and `from_json()` (@ref adl_serializer by default)
2660ccea Poul Sander 2023-09-22 19:25 14647
2660ccea Poul Sander 2023-09-22 19:25 14648
@requirement The class satisfies the following concept requirements:
2660ccea Poul Sander 2023-09-22 19:25 14649
- Basic
2660ccea Poul Sander 2023-09-22 19:25 14650
 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
2660ccea Poul Sander 2023-09-22 19:25 14651
   JSON values can be default constructed. The result will be a JSON null
2660ccea Poul Sander 2023-09-22 19:25 14652
   value.
2660ccea Poul Sander 2023-09-22 19:25 14653
 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
2660ccea Poul Sander 2023-09-22 19:25 14654
   A JSON value can be constructed from an rvalue argument.
2660ccea Poul Sander 2023-09-22 19:25 14655
 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
2660ccea Poul Sander 2023-09-22 19:25 14656
   A JSON value can be copy-constructed from an lvalue expression.
2660ccea Poul Sander 2023-09-22 19:25 14657
 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
2660ccea Poul Sander 2023-09-22 19:25 14658
   A JSON value van be assigned from an rvalue argument.
2660ccea Poul Sander 2023-09-22 19:25 14659
 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
2660ccea Poul Sander 2023-09-22 19:25 14660
   A JSON value can be copy-assigned from an lvalue expression.
2660ccea Poul Sander 2023-09-22 19:25 14661
 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
2660ccea Poul Sander 2023-09-22 19:25 14662
   JSON values can be destructed.
2660ccea Poul Sander 2023-09-22 19:25 14663
- Layout
2660ccea Poul Sander 2023-09-22 19:25 14664
 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
2660ccea Poul Sander 2023-09-22 19:25 14665
   JSON values have
2660ccea Poul Sander 2023-09-22 19:25 14666
   [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
2660ccea Poul Sander 2023-09-22 19:25 14667
   All non-static data members are private and standard layout types, the
2660ccea Poul Sander 2023-09-22 19:25 14668
   class has no virtual functions or (virtual) base classes.
2660ccea Poul Sander 2023-09-22 19:25 14669
- Library-wide
2660ccea Poul Sander 2023-09-22 19:25 14670
 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
2660ccea Poul Sander 2023-09-22 19:25 14671
   JSON values can be compared with `==`, see @ref
2660ccea Poul Sander 2023-09-22 19:25 14672
   operator==(const_reference,const_reference).
2660ccea Poul Sander 2023-09-22 19:25 14673
 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
2660ccea Poul Sander 2023-09-22 19:25 14674
   JSON values can be compared with `<`, see @ref
2660ccea Poul Sander 2023-09-22 19:25 14675
   operator<(const_reference,const_reference).
2660ccea Poul Sander 2023-09-22 19:25 14676
 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
2660ccea Poul Sander 2023-09-22 19:25 14677
   Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
2660ccea Poul Sander 2023-09-22 19:25 14678
   other compatible types, using unqualified function call @ref swap().
2660ccea Poul Sander 2023-09-22 19:25 14679
 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
2660ccea Poul Sander 2023-09-22 19:25 14680
   JSON values can be compared against `std::nullptr_t` objects which are used
2660ccea Poul Sander 2023-09-22 19:25 14681
   to model the `null` value.
2660ccea Poul Sander 2023-09-22 19:25 14682
- Container
2660ccea Poul Sander 2023-09-22 19:25 14683
 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
2660ccea Poul Sander 2023-09-22 19:25 14684
   JSON values can be used like STL containers and provide iterator access.
2660ccea Poul Sander 2023-09-22 19:25 14685
 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
2660ccea Poul Sander 2023-09-22 19:25 14686
   JSON values can be used like STL containers and provide reverse iterator
2660ccea Poul Sander 2023-09-22 19:25 14687
   access.
2660ccea Poul Sander 2023-09-22 19:25 14688
2660ccea Poul Sander 2023-09-22 19:25 14689
@invariant The member variables @a m_value and @a m_type have the following
2660ccea Poul Sander 2023-09-22 19:25 14690
relationship:
2660ccea Poul Sander 2023-09-22 19:25 14691
- If `m_type == value_t::object`, then `m_value.object != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 14692
- If `m_type == value_t::array`, then `m_value.array != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 14693
- If `m_type == value_t::string`, then `m_value.string != nullptr`.
2660ccea Poul Sander 2023-09-22 19:25 14694
The invariants are checked by member function assert_invariant().
2660ccea Poul Sander 2023-09-22 19:25 14695
2660ccea Poul Sander 2023-09-22 19:25 14696
@internal
2660ccea Poul Sander 2023-09-22 19:25 14697
@note ObjectType trick from http://stackoverflow.com/a/9860911
2660ccea Poul Sander 2023-09-22 19:25 14698
@endinternal
2660ccea Poul Sander 2023-09-22 19:25 14699
2660ccea Poul Sander 2023-09-22 19:25 14700
@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
2660ccea Poul Sander 2023-09-22 19:25 14701
Format](http://rfc7159.net/rfc7159)
2660ccea Poul Sander 2023-09-22 19:25 14702
2660ccea Poul Sander 2023-09-22 19:25 14703
@since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 14704
2660ccea Poul Sander 2023-09-22 19:25 14705
@nosubgrouping
2660ccea Poul Sander 2023-09-22 19:25 14706
*/
2660ccea Poul Sander 2023-09-22 19:25 14707
NLOHMANN_BASIC_JSON_TPL_DECLARATION
2660ccea Poul Sander 2023-09-22 19:25 14708
class basic_json
2660ccea Poul Sander 2023-09-22 19:25 14709
{
2660ccea Poul Sander 2023-09-22 19:25 14710
  private:
2660ccea Poul Sander 2023-09-22 19:25 14711
    template<detail::value_t> friend struct detail::external_constructor;
2660ccea Poul Sander 2023-09-22 19:25 14712
    friend ::nlohmann::json_pointer<basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14713
    friend ::nlohmann::detail::parser<basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14714
    friend ::nlohmann::detail::serializer<basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14715
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 14716
    friend class ::nlohmann::detail::iter_impl;
2660ccea Poul Sander 2023-09-22 19:25 14717
    template<typename BasicJsonType, typename CharType>
2660ccea Poul Sander 2023-09-22 19:25 14718
    friend class ::nlohmann::detail::binary_writer;
2660ccea Poul Sander 2023-09-22 19:25 14719
    template<typename BasicJsonType, typename SAX>
2660ccea Poul Sander 2023-09-22 19:25 14720
    friend class ::nlohmann::detail::binary_reader;
2660ccea Poul Sander 2023-09-22 19:25 14721
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 14722
    friend class ::nlohmann::detail::json_sax_dom_parser;
2660ccea Poul Sander 2023-09-22 19:25 14723
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 14724
    friend class ::nlohmann::detail::json_sax_dom_callback_parser;
2660ccea Poul Sander 2023-09-22 19:25 14725
2660ccea Poul Sander 2023-09-22 19:25 14726
    /// workaround type for MSVC
2660ccea Poul Sander 2023-09-22 19:25 14727
    using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
2660ccea Poul Sander 2023-09-22 19:25 14728
2660ccea Poul Sander 2023-09-22 19:25 14729
    // convenience aliases for types residing in namespace detail;
2660ccea Poul Sander 2023-09-22 19:25 14730
    using lexer = ::nlohmann::detail::lexer<basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14731
    using parser = ::nlohmann::detail::parser<basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14732
2660ccea Poul Sander 2023-09-22 19:25 14733
    using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
2660ccea Poul Sander 2023-09-22 19:25 14734
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 14735
    using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
2660ccea Poul Sander 2023-09-22 19:25 14736
    template<typename BasicJsonType>
2660ccea Poul Sander 2023-09-22 19:25 14737
    using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
2660ccea Poul Sander 2023-09-22 19:25 14738
    template<typename Iterator>
2660ccea Poul Sander 2023-09-22 19:25 14739
    using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
2660ccea Poul Sander 2023-09-22 19:25 14740
    template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
2660ccea Poul Sander 2023-09-22 19:25 14741
2660ccea Poul Sander 2023-09-22 19:25 14742
    template<typename CharType>
2660ccea Poul Sander 2023-09-22 19:25 14743
    using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
2660ccea Poul Sander 2023-09-22 19:25 14744
2660ccea Poul Sander 2023-09-22 19:25 14745
    using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14746
    template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
2660ccea Poul Sander 2023-09-22 19:25 14747
2660ccea Poul Sander 2023-09-22 19:25 14748
    using serializer = ::nlohmann::detail::serializer<basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14749
2660ccea Poul Sander 2023-09-22 19:25 14750
  public:
2660ccea Poul Sander 2023-09-22 19:25 14751
    using value_t = detail::value_t;
2660ccea Poul Sander 2023-09-22 19:25 14752
    /// JSON Pointer, see @ref nlohmann::json_pointer
2660ccea Poul Sander 2023-09-22 19:25 14753
    using json_pointer = ::nlohmann::json_pointer<basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14754
    template<typename T, typename SFINAE>
2660ccea Poul Sander 2023-09-22 19:25 14755
    using json_serializer = JSONSerializer<T, SFINAE>;
2660ccea Poul Sander 2023-09-22 19:25 14756
    /// how to treat decoding errors
2660ccea Poul Sander 2023-09-22 19:25 14757
    using error_handler_t = detail::error_handler_t;
2660ccea Poul Sander 2023-09-22 19:25 14758
    /// helper type for initializer lists of basic_json values
2660ccea Poul Sander 2023-09-22 19:25 14759
    using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
2660ccea Poul Sander 2023-09-22 19:25 14760
2660ccea Poul Sander 2023-09-22 19:25 14761
    using input_format_t = detail::input_format_t;
2660ccea Poul Sander 2023-09-22 19:25 14762
    /// SAX interface type, see @ref nlohmann::json_sax
2660ccea Poul Sander 2023-09-22 19:25 14763
    using json_sax_t = json_sax<basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14764
2660ccea Poul Sander 2023-09-22 19:25 14765
    ////////////////
2660ccea Poul Sander 2023-09-22 19:25 14766
    // exceptions //
2660ccea Poul Sander 2023-09-22 19:25 14767
    ////////////////
2660ccea Poul Sander 2023-09-22 19:25 14768
2660ccea Poul Sander 2023-09-22 19:25 14769
    /// @name exceptions
2660ccea Poul Sander 2023-09-22 19:25 14770
    /// Classes to implement user-defined exceptions.
2660ccea Poul Sander 2023-09-22 19:25 14771
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 14772
2660ccea Poul Sander 2023-09-22 19:25 14773
    /// @copydoc detail::exception
2660ccea Poul Sander 2023-09-22 19:25 14774
    using exception = detail::exception;
2660ccea Poul Sander 2023-09-22 19:25 14775
    /// @copydoc detail::parse_error
2660ccea Poul Sander 2023-09-22 19:25 14776
    using parse_error = detail::parse_error;
2660ccea Poul Sander 2023-09-22 19:25 14777
    /// @copydoc detail::invalid_iterator
2660ccea Poul Sander 2023-09-22 19:25 14778
    using invalid_iterator = detail::invalid_iterator;
2660ccea Poul Sander 2023-09-22 19:25 14779
    /// @copydoc detail::type_error
2660ccea Poul Sander 2023-09-22 19:25 14780
    using type_error = detail::type_error;
2660ccea Poul Sander 2023-09-22 19:25 14781
    /// @copydoc detail::out_of_range
2660ccea Poul Sander 2023-09-22 19:25 14782
    using out_of_range = detail::out_of_range;
2660ccea Poul Sander 2023-09-22 19:25 14783
    /// @copydoc detail::other_error
2660ccea Poul Sander 2023-09-22 19:25 14784
    using other_error = detail::other_error;
2660ccea Poul Sander 2023-09-22 19:25 14785
2660ccea Poul Sander 2023-09-22 19:25 14786
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 14787
2660ccea Poul Sander 2023-09-22 19:25 14788
2660ccea Poul Sander 2023-09-22 19:25 14789
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 14790
    // container types //
2660ccea Poul Sander 2023-09-22 19:25 14791
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 14792
2660ccea Poul Sander 2023-09-22 19:25 14793
    /// @name container types
2660ccea Poul Sander 2023-09-22 19:25 14794
    /// The canonic container types to use @ref basic_json like any other STL
2660ccea Poul Sander 2023-09-22 19:25 14795
    /// container.
2660ccea Poul Sander 2023-09-22 19:25 14796
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 14797
2660ccea Poul Sander 2023-09-22 19:25 14798
    /// the type of elements in a basic_json container
2660ccea Poul Sander 2023-09-22 19:25 14799
    using value_type = basic_json;
2660ccea Poul Sander 2023-09-22 19:25 14800
2660ccea Poul Sander 2023-09-22 19:25 14801
    /// the type of an element reference
2660ccea Poul Sander 2023-09-22 19:25 14802
    using reference = value_type&;
2660ccea Poul Sander 2023-09-22 19:25 14803
    /// the type of an element const reference
2660ccea Poul Sander 2023-09-22 19:25 14804
    using const_reference = const value_type&;
2660ccea Poul Sander 2023-09-22 19:25 14805
2660ccea Poul Sander 2023-09-22 19:25 14806
    /// a type to represent differences between iterators
2660ccea Poul Sander 2023-09-22 19:25 14807
    using difference_type = std::ptrdiff_t;
2660ccea Poul Sander 2023-09-22 19:25 14808
    /// a type to represent container sizes
2660ccea Poul Sander 2023-09-22 19:25 14809
    using size_type = std::size_t;
2660ccea Poul Sander 2023-09-22 19:25 14810
2660ccea Poul Sander 2023-09-22 19:25 14811
    /// the allocator type
2660ccea Poul Sander 2023-09-22 19:25 14812
    using allocator_type = AllocatorType<basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14813
2660ccea Poul Sander 2023-09-22 19:25 14814
    /// the type of an element pointer
2660ccea Poul Sander 2023-09-22 19:25 14815
    using pointer = typename std::allocator_traits<allocator_type>::pointer;
2660ccea Poul Sander 2023-09-22 19:25 14816
    /// the type of an element const pointer
2660ccea Poul Sander 2023-09-22 19:25 14817
    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
2660ccea Poul Sander 2023-09-22 19:25 14818
2660ccea Poul Sander 2023-09-22 19:25 14819
    /// an iterator for a basic_json container
2660ccea Poul Sander 2023-09-22 19:25 14820
    using iterator = iter_impl<basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14821
    /// a const iterator for a basic_json container
2660ccea Poul Sander 2023-09-22 19:25 14822
    using const_iterator = iter_impl<const basic_json>;
2660ccea Poul Sander 2023-09-22 19:25 14823
    /// a reverse iterator for a basic_json container
2660ccea Poul Sander 2023-09-22 19:25 14824
    using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
2660ccea Poul Sander 2023-09-22 19:25 14825
    /// a const reverse iterator for a basic_json container
2660ccea Poul Sander 2023-09-22 19:25 14826
    using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
2660ccea Poul Sander 2023-09-22 19:25 14827
2660ccea Poul Sander 2023-09-22 19:25 14828
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 14829
2660ccea Poul Sander 2023-09-22 19:25 14830
2660ccea Poul Sander 2023-09-22 19:25 14831
    /*!
2660ccea Poul Sander 2023-09-22 19:25 14832
    @brief returns the allocator associated with the container
2660ccea Poul Sander 2023-09-22 19:25 14833
    */
2660ccea Poul Sander 2023-09-22 19:25 14834
    static allocator_type get_allocator()
2660ccea Poul Sander 2023-09-22 19:25 14835
    {
2660ccea Poul Sander 2023-09-22 19:25 14836
        return allocator_type();
2660ccea Poul Sander 2023-09-22 19:25 14837
    }
2660ccea Poul Sander 2023-09-22 19:25 14838
2660ccea Poul Sander 2023-09-22 19:25 14839
    /*!
2660ccea Poul Sander 2023-09-22 19:25 14840
    @brief returns version information on the library
2660ccea Poul Sander 2023-09-22 19:25 14841
2660ccea Poul Sander 2023-09-22 19:25 14842
    This function returns a JSON object with information about the library,
2660ccea Poul Sander 2023-09-22 19:25 14843
    including the version number and information on the platform and compiler.
2660ccea Poul Sander 2023-09-22 19:25 14844
2660ccea Poul Sander 2023-09-22 19:25 14845
    @return JSON object holding version information
2660ccea Poul Sander 2023-09-22 19:25 14846
    key         | description
2660ccea Poul Sander 2023-09-22 19:25 14847
    ----------- | ---------------
2660ccea Poul Sander 2023-09-22 19:25 14848
    `compiler`  | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version).
2660ccea Poul Sander 2023-09-22 19:25 14849
    `copyright` | The copyright line for the library as string.
2660ccea Poul Sander 2023-09-22 19:25 14850
    `name`      | The name of the library as string.
2660ccea Poul Sander 2023-09-22 19:25 14851
    `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
2660ccea Poul Sander 2023-09-22 19:25 14852
    `url`       | The URL of the project as string.
2660ccea Poul Sander 2023-09-22 19:25 14853
    `version`   | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string).
2660ccea Poul Sander 2023-09-22 19:25 14854
2660ccea Poul Sander 2023-09-22 19:25 14855
    @liveexample{The following code shows an example output of the `meta()`
2660ccea Poul Sander 2023-09-22 19:25 14856
    function.,meta}
2660ccea Poul Sander 2023-09-22 19:25 14857
2660ccea Poul Sander 2023-09-22 19:25 14858
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 14859
    changes to any JSON value.
2660ccea Poul Sander 2023-09-22 19:25 14860
2660ccea Poul Sander 2023-09-22 19:25 14861
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 14862
2660ccea Poul Sander 2023-09-22 19:25 14863
    @since 2.1.0
2660ccea Poul Sander 2023-09-22 19:25 14864
    */
2660ccea Poul Sander 2023-09-22 19:25 14865
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 14866
    static basic_json meta()
2660ccea Poul Sander 2023-09-22 19:25 14867
    {
2660ccea Poul Sander 2023-09-22 19:25 14868
        basic_json result;
2660ccea Poul Sander 2023-09-22 19:25 14869
2660ccea Poul Sander 2023-09-22 19:25 14870
        result["copyright"] = "(C) 2013-2017 Niels Lohmann";
2660ccea Poul Sander 2023-09-22 19:25 14871
        result["name"] = "JSON for Modern C++";
2660ccea Poul Sander 2023-09-22 19:25 14872
        result["url"] = "https://github.com/nlohmann/json";
2660ccea Poul Sander 2023-09-22 19:25 14873
        result["version"]["string"] =
2660ccea Poul Sander 2023-09-22 19:25 14874
            std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
2660ccea Poul Sander 2023-09-22 19:25 14875
            std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
2660ccea Poul Sander 2023-09-22 19:25 14876
            std::to_string(NLOHMANN_JSON_VERSION_PATCH);
2660ccea Poul Sander 2023-09-22 19:25 14877
        result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
2660ccea Poul Sander 2023-09-22 19:25 14878
        result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
2660ccea Poul Sander 2023-09-22 19:25 14879
        result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
2660ccea Poul Sander 2023-09-22 19:25 14880
2660ccea Poul Sander 2023-09-22 19:25 14881
#ifdef _WIN32
2660ccea Poul Sander 2023-09-22 19:25 14882
        result["platform"] = "win32";
2660ccea Poul Sander 2023-09-22 19:25 14883
#elif defined __linux__
2660ccea Poul Sander 2023-09-22 19:25 14884
        result["platform"] = "linux";
2660ccea Poul Sander 2023-09-22 19:25 14885
#elif defined __APPLE__
2660ccea Poul Sander 2023-09-22 19:25 14886
        result["platform"] = "apple";
2660ccea Poul Sander 2023-09-22 19:25 14887
#elif defined __unix__
2660ccea Poul Sander 2023-09-22 19:25 14888
        result["platform"] = "unix";
2660ccea Poul Sander 2023-09-22 19:25 14889
#else
2660ccea Poul Sander 2023-09-22 19:25 14890
        result["platform"] = "unknown";
2660ccea Poul Sander 2023-09-22 19:25 14891
#endif
2660ccea Poul Sander 2023-09-22 19:25 14892
2660ccea Poul Sander 2023-09-22 19:25 14893
#if defined(__ICC) || defined(__INTEL_COMPILER)
2660ccea Poul Sander 2023-09-22 19:25 14894
        result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
2660ccea Poul Sander 2023-09-22 19:25 14895
#elif defined(__clang__)
2660ccea Poul Sander 2023-09-22 19:25 14896
        result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
2660ccea Poul Sander 2023-09-22 19:25 14897
#elif defined(__GNUC__) || defined(__GNUG__)
2660ccea Poul Sander 2023-09-22 19:25 14898
        result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
2660ccea Poul Sander 2023-09-22 19:25 14899
#elif defined(__HP_cc) || defined(__HP_aCC)
2660ccea Poul Sander 2023-09-22 19:25 14900
        result["compiler"] = "hp"
2660ccea Poul Sander 2023-09-22 19:25 14901
#elif defined(__IBMCPP__)
2660ccea Poul Sander 2023-09-22 19:25 14902
        result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
2660ccea Poul Sander 2023-09-22 19:25 14903
#elif defined(_MSC_VER)
2660ccea Poul Sander 2023-09-22 19:25 14904
        result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
2660ccea Poul Sander 2023-09-22 19:25 14905
#elif defined(__PGI)
2660ccea Poul Sander 2023-09-22 19:25 14906
        result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
2660ccea Poul Sander 2023-09-22 19:25 14907
#elif defined(__SUNPRO_CC)
2660ccea Poul Sander 2023-09-22 19:25 14908
        result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
2660ccea Poul Sander 2023-09-22 19:25 14909
#else
2660ccea Poul Sander 2023-09-22 19:25 14910
        result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
2660ccea Poul Sander 2023-09-22 19:25 14911
#endif
2660ccea Poul Sander 2023-09-22 19:25 14912
2660ccea Poul Sander 2023-09-22 19:25 14913
#ifdef __cplusplus
2660ccea Poul Sander 2023-09-22 19:25 14914
        result["compiler"]["c++"] = std::to_string(__cplusplus);
2660ccea Poul Sander 2023-09-22 19:25 14915
#else
2660ccea Poul Sander 2023-09-22 19:25 14916
        result["compiler"]["c++"] = "unknown";
2660ccea Poul Sander 2023-09-22 19:25 14917
#endif
2660ccea Poul Sander 2023-09-22 19:25 14918
        return result;
2660ccea Poul Sander 2023-09-22 19:25 14919
    }
2660ccea Poul Sander 2023-09-22 19:25 14920
2660ccea Poul Sander 2023-09-22 19:25 14921
2660ccea Poul Sander 2023-09-22 19:25 14922
    ///////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 14923
    // JSON value data types //
2660ccea Poul Sander 2023-09-22 19:25 14924
    ///////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 14925
2660ccea Poul Sander 2023-09-22 19:25 14926
    /// @name JSON value data types
2660ccea Poul Sander 2023-09-22 19:25 14927
    /// The data types to store a JSON value. These types are derived from
2660ccea Poul Sander 2023-09-22 19:25 14928
    /// the template arguments passed to class @ref basic_json.
2660ccea Poul Sander 2023-09-22 19:25 14929
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 14930
2660ccea Poul Sander 2023-09-22 19:25 14931
#if defined(JSON_HAS_CPP_14)
2660ccea Poul Sander 2023-09-22 19:25 14932
    // Use transparent comparator if possible, combined with perfect forwarding
2660ccea Poul Sander 2023-09-22 19:25 14933
    // on find() and count() calls prevents unnecessary string construction.
2660ccea Poul Sander 2023-09-22 19:25 14934
    using object_comparator_t = std::less<>;
2660ccea Poul Sander 2023-09-22 19:25 14935
#else
2660ccea Poul Sander 2023-09-22 19:25 14936
    using object_comparator_t = std::less<StringType>;
2660ccea Poul Sander 2023-09-22 19:25 14937
#endif
2660ccea Poul Sander 2023-09-22 19:25 14938
2660ccea Poul Sander 2023-09-22 19:25 14939
    /*!
2660ccea Poul Sander 2023-09-22 19:25 14940
    @brief a type for an object
2660ccea Poul Sander 2023-09-22 19:25 14941
2660ccea Poul Sander 2023-09-22 19:25 14942
    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
2660ccea Poul Sander 2023-09-22 19:25 14943
    > An object is an unordered collection of zero or more name/value pairs,
2660ccea Poul Sander 2023-09-22 19:25 14944
    > where a name is a string and a value is a string, number, boolean, null,
2660ccea Poul Sander 2023-09-22 19:25 14945
    > object, or array.
2660ccea Poul Sander 2023-09-22 19:25 14946
2660ccea Poul Sander 2023-09-22 19:25 14947
    To store objects in C++, a type is defined by the template parameters
2660ccea Poul Sander 2023-09-22 19:25 14948
    described below.
2660ccea Poul Sander 2023-09-22 19:25 14949
2660ccea Poul Sander 2023-09-22 19:25 14950
    @tparam ObjectType  the container to store objects (e.g., `std::map` or
2660ccea Poul Sander 2023-09-22 19:25 14951
    `std::unordered_map`)
2660ccea Poul Sander 2023-09-22 19:25 14952
    @tparam StringType the type of the keys or names (e.g., `std::string`).
2660ccea Poul Sander 2023-09-22 19:25 14953
    The comparison function `std::less<StringType>` is used to order elements
2660ccea Poul Sander 2023-09-22 19:25 14954
    inside the container.
2660ccea Poul Sander 2023-09-22 19:25 14955
    @tparam AllocatorType the allocator to use for objects (e.g.,
2660ccea Poul Sander 2023-09-22 19:25 14956
    `std::allocator`)
2660ccea Poul Sander 2023-09-22 19:25 14957
2660ccea Poul Sander 2023-09-22 19:25 14958
    #### Default type
2660ccea Poul Sander 2023-09-22 19:25 14959
2660ccea Poul Sander 2023-09-22 19:25 14960
    With the default values for @a ObjectType (`std::map`), @a StringType
2660ccea Poul Sander 2023-09-22 19:25 14961
    (`std::string`), and @a AllocatorType (`std::allocator`), the default
2660ccea Poul Sander 2023-09-22 19:25 14962
    value for @a object_t is:
2660ccea Poul Sander 2023-09-22 19:25 14963
2660ccea Poul Sander 2023-09-22 19:25 14964
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 14965
    std::map<
2660ccea Poul Sander 2023-09-22 19:25 14966
      std::string, // key_type
2660ccea Poul Sander 2023-09-22 19:25 14967
      basic_json, // value_type
2660ccea Poul Sander 2023-09-22 19:25 14968
      std::less<std::string>, // key_compare
2660ccea Poul Sander 2023-09-22 19:25 14969
      std::allocator<std::pair<const std::string, basic_json>> // allocator_type
2660ccea Poul Sander 2023-09-22 19:25 14970
    >
2660ccea Poul Sander 2023-09-22 19:25 14971
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 14972
2660ccea Poul Sander 2023-09-22 19:25 14973
    #### Behavior
2660ccea Poul Sander 2023-09-22 19:25 14974
2660ccea Poul Sander 2023-09-22 19:25 14975
    The choice of @a object_t influences the behavior of the JSON class. With
2660ccea Poul Sander 2023-09-22 19:25 14976
    the default type, objects have the following behavior:
2660ccea Poul Sander 2023-09-22 19:25 14977
2660ccea Poul Sander 2023-09-22 19:25 14978
    - When all names are unique, objects will be interoperable in the sense
2660ccea Poul Sander 2023-09-22 19:25 14979
      that all software implementations receiving that object will agree on
2660ccea Poul Sander 2023-09-22 19:25 14980
      the name-value mappings.
2660ccea Poul Sander 2023-09-22 19:25 14981
    - When the names within an object are not unique, it is unspecified which
2660ccea Poul Sander 2023-09-22 19:25 14982
      one of the values for a given key will be chosen. For instance,
2660ccea Poul Sander 2023-09-22 19:25 14983
      `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
2660ccea Poul Sander 2023-09-22 19:25 14984
      `{"key": 2}`.
2660ccea Poul Sander 2023-09-22 19:25 14985
    - Internally, name/value pairs are stored in lexicographical order of the
2660ccea Poul Sander 2023-09-22 19:25 14986
      names. Objects will also be serialized (see @ref dump) in this order.
2660ccea Poul Sander 2023-09-22 19:25 14987
      For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
2660ccea Poul Sander 2023-09-22 19:25 14988
      and serialized as `{"a": 2, "b": 1}`.
2660ccea Poul Sander 2023-09-22 19:25 14989
    - When comparing objects, the order of the name/value pairs is irrelevant.
2660ccea Poul Sander 2023-09-22 19:25 14990
      This makes objects interoperable in the sense that they will not be
2660ccea Poul Sander 2023-09-22 19:25 14991
      affected by these differences. For instance, `{"b": 1, "a": 2}` and
2660ccea Poul Sander 2023-09-22 19:25 14992
      `{"a": 2, "b": 1}` will be treated as equal.
2660ccea Poul Sander 2023-09-22 19:25 14993
2660ccea Poul Sander 2023-09-22 19:25 14994
    #### Limits
2660ccea Poul Sander 2023-09-22 19:25 14995
2660ccea Poul Sander 2023-09-22 19:25 14996
    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
2660ccea Poul Sander 2023-09-22 19:25 14997
    > An implementation may set limits on the maximum depth of nesting.
2660ccea Poul Sander 2023-09-22 19:25 14998
2660ccea Poul Sander 2023-09-22 19:25 14999
    In this class, the object's limit of nesting is not explicitly constrained.
2660ccea Poul Sander 2023-09-22 19:25 15000
    However, a maximum depth of nesting may be introduced by the compiler or
2660ccea Poul Sander 2023-09-22 19:25 15001
    runtime environment. A theoretical limit can be queried by calling the
2660ccea Poul Sander 2023-09-22 19:25 15002
    @ref max_size function of a JSON object.
2660ccea Poul Sander 2023-09-22 19:25 15003
2660ccea Poul Sander 2023-09-22 19:25 15004
    #### Storage
2660ccea Poul Sander 2023-09-22 19:25 15005
2660ccea Poul Sander 2023-09-22 19:25 15006
    Objects are stored as pointers in a @ref basic_json type. That is, for any
2660ccea Poul Sander 2023-09-22 19:25 15007
    access to object values, a pointer of type `object_t*` must be
2660ccea Poul Sander 2023-09-22 19:25 15008
    dereferenced.
2660ccea Poul Sander 2023-09-22 19:25 15009
2660ccea Poul Sander 2023-09-22 19:25 15010
    @sa @ref array_t -- type for an array value
2660ccea Poul Sander 2023-09-22 19:25 15011
2660ccea Poul Sander 2023-09-22 19:25 15012
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 15013
2660ccea Poul Sander 2023-09-22 19:25 15014
    @note The order name/value pairs are added to the object is *not*
2660ccea Poul Sander 2023-09-22 19:25 15015
    preserved by the library. Therefore, iterating an object may return
2660ccea Poul Sander 2023-09-22 19:25 15016
    name/value pairs in a different order than they were originally stored. In
2660ccea Poul Sander 2023-09-22 19:25 15017
    fact, keys will be traversed in alphabetical order as `std::map` with
2660ccea Poul Sander 2023-09-22 19:25 15018
    `std::less` is used by default. Please note this behavior conforms to [RFC
2660ccea Poul Sander 2023-09-22 19:25 15019
    7159](http://rfc7159.net/rfc7159), because any order implements the
2660ccea Poul Sander 2023-09-22 19:25 15020
    specified "unordered" nature of JSON objects.
2660ccea Poul Sander 2023-09-22 19:25 15021
    */
2660ccea Poul Sander 2023-09-22 19:25 15022
    using object_t = ObjectType<StringType,
2660ccea Poul Sander 2023-09-22 19:25 15023
          basic_json,
2660ccea Poul Sander 2023-09-22 19:25 15024
          object_comparator_t,
2660ccea Poul Sander 2023-09-22 19:25 15025
          AllocatorType<std::pair<const StringType,
2660ccea Poul Sander 2023-09-22 19:25 15026
          basic_json>>>;
2660ccea Poul Sander 2023-09-22 19:25 15027
2660ccea Poul Sander 2023-09-22 19:25 15028
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15029
    @brief a type for an array
2660ccea Poul Sander 2023-09-22 19:25 15030
2660ccea Poul Sander 2023-09-22 19:25 15031
    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
2660ccea Poul Sander 2023-09-22 19:25 15032
    > An array is an ordered sequence of zero or more values.
2660ccea Poul Sander 2023-09-22 19:25 15033
2660ccea Poul Sander 2023-09-22 19:25 15034
    To store objects in C++, a type is defined by the template parameters
2660ccea Poul Sander 2023-09-22 19:25 15035
    explained below.
2660ccea Poul Sander 2023-09-22 19:25 15036
2660ccea Poul Sander 2023-09-22 19:25 15037
    @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
2660ccea Poul Sander 2023-09-22 19:25 15038
    `std::list`)
2660ccea Poul Sander 2023-09-22 19:25 15039
    @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
2660ccea Poul Sander 2023-09-22 19:25 15040
2660ccea Poul Sander 2023-09-22 19:25 15041
    #### Default type
2660ccea Poul Sander 2023-09-22 19:25 15042
2660ccea Poul Sander 2023-09-22 19:25 15043
    With the default values for @a ArrayType (`std::vector`) and @a
2660ccea Poul Sander 2023-09-22 19:25 15044
    AllocatorType (`std::allocator`), the default value for @a array_t is:
2660ccea Poul Sander 2023-09-22 19:25 15045
2660ccea Poul Sander 2023-09-22 19:25 15046
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 15047
    std::vector<
2660ccea Poul Sander 2023-09-22 19:25 15048
      basic_json, // value_type
2660ccea Poul Sander 2023-09-22 19:25 15049
      std::allocator<basic_json> // allocator_type
2660ccea Poul Sander 2023-09-22 19:25 15050
    >
2660ccea Poul Sander 2023-09-22 19:25 15051
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 15052
2660ccea Poul Sander 2023-09-22 19:25 15053
    #### Limits
2660ccea Poul Sander 2023-09-22 19:25 15054
2660ccea Poul Sander 2023-09-22 19:25 15055
    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
2660ccea Poul Sander 2023-09-22 19:25 15056
    > An implementation may set limits on the maximum depth of nesting.
2660ccea Poul Sander 2023-09-22 19:25 15057
2660ccea Poul Sander 2023-09-22 19:25 15058
    In this class, the array's limit of nesting is not explicitly constrained.
2660ccea Poul Sander 2023-09-22 19:25 15059
    However, a maximum depth of nesting may be introduced by the compiler or
2660ccea Poul Sander 2023-09-22 19:25 15060
    runtime environment. A theoretical limit can be queried by calling the
2660ccea Poul Sander 2023-09-22 19:25 15061
    @ref max_size function of a JSON array.
2660ccea Poul Sander 2023-09-22 19:25 15062
2660ccea Poul Sander 2023-09-22 19:25 15063
    #### Storage
2660ccea Poul Sander 2023-09-22 19:25 15064
2660ccea Poul Sander 2023-09-22 19:25 15065
    Arrays are stored as pointers in a @ref basic_json type. That is, for any
2660ccea Poul Sander 2023-09-22 19:25 15066
    access to array values, a pointer of type `array_t*` must be dereferenced.
2660ccea Poul Sander 2023-09-22 19:25 15067
2660ccea Poul Sander 2023-09-22 19:25 15068
    @sa @ref object_t -- type for an object value
2660ccea Poul Sander 2023-09-22 19:25 15069
2660ccea Poul Sander 2023-09-22 19:25 15070
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 15071
    */
2660ccea Poul Sander 2023-09-22 19:25 15072
    using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
2660ccea Poul Sander 2023-09-22 19:25 15073
2660ccea Poul Sander 2023-09-22 19:25 15074
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15075
    @brief a type for a string
2660ccea Poul Sander 2023-09-22 19:25 15076
2660ccea Poul Sander 2023-09-22 19:25 15077
    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
2660ccea Poul Sander 2023-09-22 19:25 15078
    > A string is a sequence of zero or more Unicode characters.
2660ccea Poul Sander 2023-09-22 19:25 15079
2660ccea Poul Sander 2023-09-22 19:25 15080
    To store objects in C++, a type is defined by the template parameter
2660ccea Poul Sander 2023-09-22 19:25 15081
    described below. Unicode values are split by the JSON class into
2660ccea Poul Sander 2023-09-22 19:25 15082
    byte-sized characters during deserialization.
2660ccea Poul Sander 2023-09-22 19:25 15083
2660ccea Poul Sander 2023-09-22 19:25 15084
    @tparam StringType  the container to store strings (e.g., `std::string`).
2660ccea Poul Sander 2023-09-22 19:25 15085
    Note this container is used for keys/names in objects, see @ref object_t.
2660ccea Poul Sander 2023-09-22 19:25 15086
2660ccea Poul Sander 2023-09-22 19:25 15087
    #### Default type
2660ccea Poul Sander 2023-09-22 19:25 15088
2660ccea Poul Sander 2023-09-22 19:25 15089
    With the default values for @a StringType (`std::string`), the default
2660ccea Poul Sander 2023-09-22 19:25 15090
    value for @a string_t is:
2660ccea Poul Sander 2023-09-22 19:25 15091
2660ccea Poul Sander 2023-09-22 19:25 15092
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 15093
    std::string
2660ccea Poul Sander 2023-09-22 19:25 15094
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 15095
2660ccea Poul Sander 2023-09-22 19:25 15096
    #### Encoding
2660ccea Poul Sander 2023-09-22 19:25 15097
2660ccea Poul Sander 2023-09-22 19:25 15098
    Strings are stored in UTF-8 encoding. Therefore, functions like
2660ccea Poul Sander 2023-09-22 19:25 15099
    `std::string::size()` or `std::string::length()` return the number of
2660ccea Poul Sander 2023-09-22 19:25 15100
    bytes in the string rather than the number of characters or glyphs.
2660ccea Poul Sander 2023-09-22 19:25 15101
2660ccea Poul Sander 2023-09-22 19:25 15102
    #### String comparison
2660ccea Poul Sander 2023-09-22 19:25 15103
2660ccea Poul Sander 2023-09-22 19:25 15104
    [RFC 7159](http://rfc7159.net/rfc7159) states:
2660ccea Poul Sander 2023-09-22 19:25 15105
    > Software implementations are typically required to test names of object
2660ccea Poul Sander 2023-09-22 19:25 15106
    > members for equality. Implementations that transform the textual
2660ccea Poul Sander 2023-09-22 19:25 15107
    > representation into sequences of Unicode code units and then perform the
2660ccea Poul Sander 2023-09-22 19:25 15108
    > comparison numerically, code unit by code unit, are interoperable in the
2660ccea Poul Sander 2023-09-22 19:25 15109
    > sense that implementations will agree in all cases on equality or
2660ccea Poul Sander 2023-09-22 19:25 15110
    > inequality of two strings. For example, implementations that compare
2660ccea Poul Sander 2023-09-22 19:25 15111
    > strings with escaped characters unconverted may incorrectly find that
2660ccea Poul Sander 2023-09-22 19:25 15112
    > `"a\\b"` and `"a\u005Cb"` are not equal.
2660ccea Poul Sander 2023-09-22 19:25 15113
2660ccea Poul Sander 2023-09-22 19:25 15114
    This implementation is interoperable as it does compare strings code unit
2660ccea Poul Sander 2023-09-22 19:25 15115
    by code unit.
2660ccea Poul Sander 2023-09-22 19:25 15116
2660ccea Poul Sander 2023-09-22 19:25 15117
    #### Storage
2660ccea Poul Sander 2023-09-22 19:25 15118
2660ccea Poul Sander 2023-09-22 19:25 15119
    String values are stored as pointers in a @ref basic_json type. That is,
2660ccea Poul Sander 2023-09-22 19:25 15120
    for any access to string values, a pointer of type `string_t*` must be
2660ccea Poul Sander 2023-09-22 19:25 15121
    dereferenced.
2660ccea Poul Sander 2023-09-22 19:25 15122
2660ccea Poul Sander 2023-09-22 19:25 15123
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 15124
    */
2660ccea Poul Sander 2023-09-22 19:25 15125
    using string_t = StringType;
2660ccea Poul Sander 2023-09-22 19:25 15126
2660ccea Poul Sander 2023-09-22 19:25 15127
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15128
    @brief a type for a boolean
2660ccea Poul Sander 2023-09-22 19:25 15129
2660ccea Poul Sander 2023-09-22 19:25 15130
    [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
2660ccea Poul Sander 2023-09-22 19:25 15131
    type which differentiates the two literals `true` and `false`.
2660ccea Poul Sander 2023-09-22 19:25 15132
2660ccea Poul Sander 2023-09-22 19:25 15133
    To store objects in C++, a type is defined by the template parameter @a
2660ccea Poul Sander 2023-09-22 19:25 15134
    BooleanType which chooses the type to use.
2660ccea Poul Sander 2023-09-22 19:25 15135
2660ccea Poul Sander 2023-09-22 19:25 15136
    #### Default type
2660ccea Poul Sander 2023-09-22 19:25 15137
2660ccea Poul Sander 2023-09-22 19:25 15138
    With the default values for @a BooleanType (`bool`), the default value for
2660ccea Poul Sander 2023-09-22 19:25 15139
    @a boolean_t is:
2660ccea Poul Sander 2023-09-22 19:25 15140
2660ccea Poul Sander 2023-09-22 19:25 15141
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 15142
    bool
2660ccea Poul Sander 2023-09-22 19:25 15143
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 15144
2660ccea Poul Sander 2023-09-22 19:25 15145
    #### Storage
2660ccea Poul Sander 2023-09-22 19:25 15146
2660ccea Poul Sander 2023-09-22 19:25 15147
    Boolean values are stored directly inside a @ref basic_json type.
2660ccea Poul Sander 2023-09-22 19:25 15148
2660ccea Poul Sander 2023-09-22 19:25 15149
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 15150
    */
2660ccea Poul Sander 2023-09-22 19:25 15151
    using boolean_t = BooleanType;
2660ccea Poul Sander 2023-09-22 19:25 15152
2660ccea Poul Sander 2023-09-22 19:25 15153
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15154
    @brief a type for a number (integer)
2660ccea Poul Sander 2023-09-22 19:25 15155
2660ccea Poul Sander 2023-09-22 19:25 15156
    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
2660ccea Poul Sander 2023-09-22 19:25 15157
    > The representation of numbers is similar to that used in most
2660ccea Poul Sander 2023-09-22 19:25 15158
    > programming languages. A number is represented in base 10 using decimal
2660ccea Poul Sander 2023-09-22 19:25 15159
    > digits. It contains an integer component that may be prefixed with an
2660ccea Poul Sander 2023-09-22 19:25 15160
    > optional minus sign, which may be followed by a fraction part and/or an
2660ccea Poul Sander 2023-09-22 19:25 15161
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
2660ccea Poul Sander 2023-09-22 19:25 15162
    > cannot be represented in the grammar below (such as Infinity and NaN)
2660ccea Poul Sander 2023-09-22 19:25 15163
    > are not permitted.
2660ccea Poul Sander 2023-09-22 19:25 15164
2660ccea Poul Sander 2023-09-22 19:25 15165
    This description includes both integer and floating-point numbers.
2660ccea Poul Sander 2023-09-22 19:25 15166
    However, C++ allows more precise storage if it is known whether the number
2660ccea Poul Sander 2023-09-22 19:25 15167
    is a signed integer, an unsigned integer or a floating-point number.
2660ccea Poul Sander 2023-09-22 19:25 15168
    Therefore, three different types, @ref number_integer_t, @ref
2660ccea Poul Sander 2023-09-22 19:25 15169
    number_unsigned_t and @ref number_float_t are used.
2660ccea Poul Sander 2023-09-22 19:25 15170
2660ccea Poul Sander 2023-09-22 19:25 15171
    To store integer numbers in C++, a type is defined by the template
2660ccea Poul Sander 2023-09-22 19:25 15172
    parameter @a NumberIntegerType which chooses the type to use.
2660ccea Poul Sander 2023-09-22 19:25 15173
2660ccea Poul Sander 2023-09-22 19:25 15174
    #### Default type
2660ccea Poul Sander 2023-09-22 19:25 15175
2660ccea Poul Sander 2023-09-22 19:25 15176
    With the default values for @a NumberIntegerType (`int64_t`), the default
2660ccea Poul Sander 2023-09-22 19:25 15177
    value for @a number_integer_t is:
2660ccea Poul Sander 2023-09-22 19:25 15178
2660ccea Poul Sander 2023-09-22 19:25 15179
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 15180
    int64_t
2660ccea Poul Sander 2023-09-22 19:25 15181
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 15182
2660ccea Poul Sander 2023-09-22 19:25 15183
    #### Default behavior
2660ccea Poul Sander 2023-09-22 19:25 15184
2660ccea Poul Sander 2023-09-22 19:25 15185
    - The restrictions about leading zeros is not enforced in C++. Instead,
2660ccea Poul Sander 2023-09-22 19:25 15186
      leading zeros in integer literals lead to an interpretation as octal
2660ccea Poul Sander 2023-09-22 19:25 15187
      number. Internally, the value will be stored as decimal number. For
2660ccea Poul Sander 2023-09-22 19:25 15188
      instance, the C++ integer literal `010` will be serialized to `8`.
2660ccea Poul Sander 2023-09-22 19:25 15189
      During deserialization, leading zeros yield an error.
2660ccea Poul Sander 2023-09-22 19:25 15190
    - Not-a-number (NaN) values will be serialized to `null`.
2660ccea Poul Sander 2023-09-22 19:25 15191
2660ccea Poul Sander 2023-09-22 19:25 15192
    #### Limits
2660ccea Poul Sander 2023-09-22 19:25 15193
2660ccea Poul Sander 2023-09-22 19:25 15194
    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
2660ccea Poul Sander 2023-09-22 19:25 15195
    > An implementation may set limits on the range and precision of numbers.
2660ccea Poul Sander 2023-09-22 19:25 15196
2660ccea Poul Sander 2023-09-22 19:25 15197
    When the default type is used, the maximal integer number that can be
2660ccea Poul Sander 2023-09-22 19:25 15198
    stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
2660ccea Poul Sander 2023-09-22 19:25 15199
    that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
2660ccea Poul Sander 2023-09-22 19:25 15200
    that are out of range will yield over/underflow when used in a
2660ccea Poul Sander 2023-09-22 19:25 15201
    constructor. During deserialization, too large or small integer numbers
2660ccea Poul Sander 2023-09-22 19:25 15202
    will be automatically be stored as @ref number_unsigned_t or @ref
2660ccea Poul Sander 2023-09-22 19:25 15203
    number_float_t.
2660ccea Poul Sander 2023-09-22 19:25 15204
2660ccea Poul Sander 2023-09-22 19:25 15205
    [RFC 7159](http://rfc7159.net/rfc7159) further states:
2660ccea Poul Sander 2023-09-22 19:25 15206
    > Note that when such software is used, numbers that are integers and are
2660ccea Poul Sander 2023-09-22 19:25 15207
    > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
2660ccea Poul Sander 2023-09-22 19:25 15208
    > that implementations will agree exactly on their numeric values.
2660ccea Poul Sander 2023-09-22 19:25 15209
2660ccea Poul Sander 2023-09-22 19:25 15210
    As this range is a subrange of the exactly supported range [INT64_MIN,
2660ccea Poul Sander 2023-09-22 19:25 15211
    INT64_MAX], this class's integer type is interoperable.
2660ccea Poul Sander 2023-09-22 19:25 15212
2660ccea Poul Sander 2023-09-22 19:25 15213
    #### Storage
2660ccea Poul Sander 2023-09-22 19:25 15214
2660ccea Poul Sander 2023-09-22 19:25 15215
    Integer number values are stored directly inside a @ref basic_json type.
2660ccea Poul Sander 2023-09-22 19:25 15216
2660ccea Poul Sander 2023-09-22 19:25 15217
    @sa @ref number_float_t -- type for number values (floating-point)
2660ccea Poul Sander 2023-09-22 19:25 15218
2660ccea Poul Sander 2023-09-22 19:25 15219
    @sa @ref number_unsigned_t -- type for number values (unsigned integer)
2660ccea Poul Sander 2023-09-22 19:25 15220
2660ccea Poul Sander 2023-09-22 19:25 15221
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 15222
    */
2660ccea Poul Sander 2023-09-22 19:25 15223
    using number_integer_t = NumberIntegerType;
2660ccea Poul Sander 2023-09-22 19:25 15224
2660ccea Poul Sander 2023-09-22 19:25 15225
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15226
    @brief a type for a number (unsigned)
2660ccea Poul Sander 2023-09-22 19:25 15227
2660ccea Poul Sander 2023-09-22 19:25 15228
    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
2660ccea Poul Sander 2023-09-22 19:25 15229
    > The representation of numbers is similar to that used in most
2660ccea Poul Sander 2023-09-22 19:25 15230
    > programming languages. A number is represented in base 10 using decimal
2660ccea Poul Sander 2023-09-22 19:25 15231
    > digits. It contains an integer component that may be prefixed with an
2660ccea Poul Sander 2023-09-22 19:25 15232
    > optional minus sign, which may be followed by a fraction part and/or an
2660ccea Poul Sander 2023-09-22 19:25 15233
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
2660ccea Poul Sander 2023-09-22 19:25 15234
    > cannot be represented in the grammar below (such as Infinity and NaN)
2660ccea Poul Sander 2023-09-22 19:25 15235
    > are not permitted.
2660ccea Poul Sander 2023-09-22 19:25 15236
2660ccea Poul Sander 2023-09-22 19:25 15237
    This description includes both integer and floating-point numbers.
2660ccea Poul Sander 2023-09-22 19:25 15238
    However, C++ allows more precise storage if it is known whether the number
2660ccea Poul Sander 2023-09-22 19:25 15239
    is a signed integer, an unsigned integer or a floating-point number.
2660ccea Poul Sander 2023-09-22 19:25 15240
    Therefore, three different types, @ref number_integer_t, @ref
2660ccea Poul Sander 2023-09-22 19:25 15241
    number_unsigned_t and @ref number_float_t are used.
2660ccea Poul Sander 2023-09-22 19:25 15242
2660ccea Poul Sander 2023-09-22 19:25 15243
    To store unsigned integer numbers in C++, a type is defined by the
2660ccea Poul Sander 2023-09-22 19:25 15244
    template parameter @a NumberUnsignedType which chooses the type to use.
2660ccea Poul Sander 2023-09-22 19:25 15245
2660ccea Poul Sander 2023-09-22 19:25 15246
    #### Default type
2660ccea Poul Sander 2023-09-22 19:25 15247
2660ccea Poul Sander 2023-09-22 19:25 15248
    With the default values for @a NumberUnsignedType (`uint64_t`), the
2660ccea Poul Sander 2023-09-22 19:25 15249
    default value for @a number_unsigned_t is:
2660ccea Poul Sander 2023-09-22 19:25 15250
2660ccea Poul Sander 2023-09-22 19:25 15251
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 15252
    uint64_t
2660ccea Poul Sander 2023-09-22 19:25 15253
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 15254
2660ccea Poul Sander 2023-09-22 19:25 15255
    #### Default behavior
2660ccea Poul Sander 2023-09-22 19:25 15256
2660ccea Poul Sander 2023-09-22 19:25 15257
    - The restrictions about leading zeros is not enforced in C++. Instead,
2660ccea Poul Sander 2023-09-22 19:25 15258
      leading zeros in integer literals lead to an interpretation as octal
2660ccea Poul Sander 2023-09-22 19:25 15259
      number. Internally, the value will be stored as decimal number. For
2660ccea Poul Sander 2023-09-22 19:25 15260
      instance, the C++ integer literal `010` will be serialized to `8`.
2660ccea Poul Sander 2023-09-22 19:25 15261
      During deserialization, leading zeros yield an error.
2660ccea Poul Sander 2023-09-22 19:25 15262
    - Not-a-number (NaN) values will be serialized to `null`.
2660ccea Poul Sander 2023-09-22 19:25 15263
2660ccea Poul Sander 2023-09-22 19:25 15264
    #### Limits
2660ccea Poul Sander 2023-09-22 19:25 15265
2660ccea Poul Sander 2023-09-22 19:25 15266
    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
2660ccea Poul Sander 2023-09-22 19:25 15267
    > An implementation may set limits on the range and precision of numbers.
2660ccea Poul Sander 2023-09-22 19:25 15268
2660ccea Poul Sander 2023-09-22 19:25 15269
    When the default type is used, the maximal integer number that can be
2660ccea Poul Sander 2023-09-22 19:25 15270
    stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
2660ccea Poul Sander 2023-09-22 19:25 15271
    number that can be stored is `0`. Integer numbers that are out of range
2660ccea Poul Sander 2023-09-22 19:25 15272
    will yield over/underflow when used in a constructor. During
2660ccea Poul Sander 2023-09-22 19:25 15273
    deserialization, too large or small integer numbers will be automatically
2660ccea Poul Sander 2023-09-22 19:25 15274
    be stored as @ref number_integer_t or @ref number_float_t.
2660ccea Poul Sander 2023-09-22 19:25 15275
2660ccea Poul Sander 2023-09-22 19:25 15276
    [RFC 7159](http://rfc7159.net/rfc7159) further states:
2660ccea Poul Sander 2023-09-22 19:25 15277
    > Note that when such software is used, numbers that are integers and are
2660ccea Poul Sander 2023-09-22 19:25 15278
    > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
2660ccea Poul Sander 2023-09-22 19:25 15279
    > that implementations will agree exactly on their numeric values.
2660ccea Poul Sander 2023-09-22 19:25 15280
2660ccea Poul Sander 2023-09-22 19:25 15281
    As this range is a subrange (when considered in conjunction with the
2660ccea Poul Sander 2023-09-22 19:25 15282
    number_integer_t type) of the exactly supported range [0, UINT64_MAX],
2660ccea Poul Sander 2023-09-22 19:25 15283
    this class's integer type is interoperable.
2660ccea Poul Sander 2023-09-22 19:25 15284
2660ccea Poul Sander 2023-09-22 19:25 15285
    #### Storage
2660ccea Poul Sander 2023-09-22 19:25 15286
2660ccea Poul Sander 2023-09-22 19:25 15287
    Integer number values are stored directly inside a @ref basic_json type.
2660ccea Poul Sander 2023-09-22 19:25 15288
2660ccea Poul Sander 2023-09-22 19:25 15289
    @sa @ref number_float_t -- type for number values (floating-point)
2660ccea Poul Sander 2023-09-22 19:25 15290
    @sa @ref number_integer_t -- type for number values (integer)
2660ccea Poul Sander 2023-09-22 19:25 15291
2660ccea Poul Sander 2023-09-22 19:25 15292
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 15293
    */
2660ccea Poul Sander 2023-09-22 19:25 15294
    using number_unsigned_t = NumberUnsignedType;
2660ccea Poul Sander 2023-09-22 19:25 15295
2660ccea Poul Sander 2023-09-22 19:25 15296
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15297
    @brief a type for a number (floating-point)
2660ccea Poul Sander 2023-09-22 19:25 15298
2660ccea Poul Sander 2023-09-22 19:25 15299
    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
2660ccea Poul Sander 2023-09-22 19:25 15300
    > The representation of numbers is similar to that used in most
2660ccea Poul Sander 2023-09-22 19:25 15301
    > programming languages. A number is represented in base 10 using decimal
2660ccea Poul Sander 2023-09-22 19:25 15302
    > digits. It contains an integer component that may be prefixed with an
2660ccea Poul Sander 2023-09-22 19:25 15303
    > optional minus sign, which may be followed by a fraction part and/or an
2660ccea Poul Sander 2023-09-22 19:25 15304
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
2660ccea Poul Sander 2023-09-22 19:25 15305
    > cannot be represented in the grammar below (such as Infinity and NaN)
2660ccea Poul Sander 2023-09-22 19:25 15306
    > are not permitted.
2660ccea Poul Sander 2023-09-22 19:25 15307
2660ccea Poul Sander 2023-09-22 19:25 15308
    This description includes both integer and floating-point numbers.
2660ccea Poul Sander 2023-09-22 19:25 15309
    However, C++ allows more precise storage if it is known whether the number
2660ccea Poul Sander 2023-09-22 19:25 15310
    is a signed integer, an unsigned integer or a floating-point number.
2660ccea Poul Sander 2023-09-22 19:25 15311
    Therefore, three different types, @ref number_integer_t, @ref
2660ccea Poul Sander 2023-09-22 19:25 15312
    number_unsigned_t and @ref number_float_t are used.
2660ccea Poul Sander 2023-09-22 19:25 15313
2660ccea Poul Sander 2023-09-22 19:25 15314
    To store floating-point numbers in C++, a type is defined by the template
2660ccea Poul Sander 2023-09-22 19:25 15315
    parameter @a NumberFloatType which chooses the type to use.
2660ccea Poul Sander 2023-09-22 19:25 15316
2660ccea Poul Sander 2023-09-22 19:25 15317
    #### Default type
2660ccea Poul Sander 2023-09-22 19:25 15318
2660ccea Poul Sander 2023-09-22 19:25 15319
    With the default values for @a NumberFloatType (`double`), the default
2660ccea Poul Sander 2023-09-22 19:25 15320
    value for @a number_float_t is:
2660ccea Poul Sander 2023-09-22 19:25 15321
2660ccea Poul Sander 2023-09-22 19:25 15322
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 15323
    double
2660ccea Poul Sander 2023-09-22 19:25 15324
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 15325
2660ccea Poul Sander 2023-09-22 19:25 15326
    #### Default behavior
2660ccea Poul Sander 2023-09-22 19:25 15327
2660ccea Poul Sander 2023-09-22 19:25 15328
    - The restrictions about leading zeros is not enforced in C++. Instead,
2660ccea Poul Sander 2023-09-22 19:25 15329
      leading zeros in floating-point literals will be ignored. Internally,
2660ccea Poul Sander 2023-09-22 19:25 15330
      the value will be stored as decimal number. For instance, the C++
2660ccea Poul Sander 2023-09-22 19:25 15331
      floating-point literal `01.2` will be serialized to `1.2`. During
2660ccea Poul Sander 2023-09-22 19:25 15332
      deserialization, leading zeros yield an error.
2660ccea Poul Sander 2023-09-22 19:25 15333
    - Not-a-number (NaN) values will be serialized to `null`.
2660ccea Poul Sander 2023-09-22 19:25 15334
2660ccea Poul Sander 2023-09-22 19:25 15335
    #### Limits
2660ccea Poul Sander 2023-09-22 19:25 15336
2660ccea Poul Sander 2023-09-22 19:25 15337
    [RFC 7159](http://rfc7159.net/rfc7159) states:
2660ccea Poul Sander 2023-09-22 19:25 15338
    > This specification allows implementations to set limits on the range and
2660ccea Poul Sander 2023-09-22 19:25 15339
    > precision of numbers accepted. Since software that implements IEEE
2660ccea Poul Sander 2023-09-22 19:25 15340
    > 754-2008 binary64 (double precision) numbers is generally available and
2660ccea Poul Sander 2023-09-22 19:25 15341
    > widely used, good interoperability can be achieved by implementations
2660ccea Poul Sander 2023-09-22 19:25 15342
    > that expect no more precision or range than these provide, in the sense
2660ccea Poul Sander 2023-09-22 19:25 15343
    > that implementations will approximate JSON numbers within the expected
2660ccea Poul Sander 2023-09-22 19:25 15344
    > precision.
2660ccea Poul Sander 2023-09-22 19:25 15345
2660ccea Poul Sander 2023-09-22 19:25 15346
    This implementation does exactly follow this approach, as it uses double
2660ccea Poul Sander 2023-09-22 19:25 15347
    precision floating-point numbers. Note values smaller than
2660ccea Poul Sander 2023-09-22 19:25 15348
    `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
2660ccea Poul Sander 2023-09-22 19:25 15349
    will be stored as NaN internally and be serialized to `null`.
2660ccea Poul Sander 2023-09-22 19:25 15350
2660ccea Poul Sander 2023-09-22 19:25 15351
    #### Storage
2660ccea Poul Sander 2023-09-22 19:25 15352
2660ccea Poul Sander 2023-09-22 19:25 15353
    Floating-point number values are stored directly inside a @ref basic_json
2660ccea Poul Sander 2023-09-22 19:25 15354
    type.
2660ccea Poul Sander 2023-09-22 19:25 15355
2660ccea Poul Sander 2023-09-22 19:25 15356
    @sa @ref number_integer_t -- type for number values (integer)
2660ccea Poul Sander 2023-09-22 19:25 15357
2660ccea Poul Sander 2023-09-22 19:25 15358
    @sa @ref number_unsigned_t -- type for number values (unsigned integer)
2660ccea Poul Sander 2023-09-22 19:25 15359
2660ccea Poul Sander 2023-09-22 19:25 15360
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 15361
    */
2660ccea Poul Sander 2023-09-22 19:25 15362
    using number_float_t = NumberFloatType;
2660ccea Poul Sander 2023-09-22 19:25 15363
2660ccea Poul Sander 2023-09-22 19:25 15364
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 15365
2660ccea Poul Sander 2023-09-22 19:25 15366
  private:
2660ccea Poul Sander 2023-09-22 19:25 15367
2660ccea Poul Sander 2023-09-22 19:25 15368
    /// helper for exception-safe object creation
2660ccea Poul Sander 2023-09-22 19:25 15369
    template<typename T, typename... Args>
2660ccea Poul Sander 2023-09-22 19:25 15370
    JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 15371
    static T* create(Args&& ... args)
2660ccea Poul Sander 2023-09-22 19:25 15372
    {
2660ccea Poul Sander 2023-09-22 19:25 15373
        AllocatorType<T> alloc;
2660ccea Poul Sander 2023-09-22 19:25 15374
        using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
2660ccea Poul Sander 2023-09-22 19:25 15375
2660ccea Poul Sander 2023-09-22 19:25 15376
        auto deleter = [&](T * object)
2660ccea Poul Sander 2023-09-22 19:25 15377
        {
2660ccea Poul Sander 2023-09-22 19:25 15378
            AllocatorTraits::deallocate(alloc, object, 1);
2660ccea Poul Sander 2023-09-22 19:25 15379
        };
2660ccea Poul Sander 2023-09-22 19:25 15380
        std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
2660ccea Poul Sander 2023-09-22 19:25 15381
        AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
2660ccea Poul Sander 2023-09-22 19:25 15382
        assert(object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 15383
        return object.release();
2660ccea Poul Sander 2023-09-22 19:25 15384
    }
2660ccea Poul Sander 2023-09-22 19:25 15385
2660ccea Poul Sander 2023-09-22 19:25 15386
    ////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 15387
    // JSON value storage //
2660ccea Poul Sander 2023-09-22 19:25 15388
    ////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 15389
2660ccea Poul Sander 2023-09-22 19:25 15390
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15391
    @brief a JSON value
2660ccea Poul Sander 2023-09-22 19:25 15392
2660ccea Poul Sander 2023-09-22 19:25 15393
    The actual storage for a JSON value of the @ref basic_json class. This
2660ccea Poul Sander 2023-09-22 19:25 15394
    union combines the different storage types for the JSON value types
2660ccea Poul Sander 2023-09-22 19:25 15395
    defined in @ref value_t.
2660ccea Poul Sander 2023-09-22 19:25 15396
2660ccea Poul Sander 2023-09-22 19:25 15397
    JSON type | value_t type    | used type
2660ccea Poul Sander 2023-09-22 19:25 15398
    --------- | --------------- | ------------------------
2660ccea Poul Sander 2023-09-22 19:25 15399
    object    | object          | pointer to @ref object_t
2660ccea Poul Sander 2023-09-22 19:25 15400
    array     | array           | pointer to @ref array_t
2660ccea Poul Sander 2023-09-22 19:25 15401
    string    | string          | pointer to @ref string_t
2660ccea Poul Sander 2023-09-22 19:25 15402
    boolean   | boolean         | @ref boolean_t
2660ccea Poul Sander 2023-09-22 19:25 15403
    number    | number_integer  | @ref number_integer_t
2660ccea Poul Sander 2023-09-22 19:25 15404
    number    | number_unsigned | @ref number_unsigned_t
2660ccea Poul Sander 2023-09-22 19:25 15405
    number    | number_float    | @ref number_float_t
2660ccea Poul Sander 2023-09-22 19:25 15406
    null      | null            | *no value is stored*
2660ccea Poul Sander 2023-09-22 19:25 15407
2660ccea Poul Sander 2023-09-22 19:25 15408
    @note Variable-length types (objects, arrays, and strings) are stored as
2660ccea Poul Sander 2023-09-22 19:25 15409
    pointers. The size of the union should not exceed 64 bits if the default
2660ccea Poul Sander 2023-09-22 19:25 15410
    value types are used.
2660ccea Poul Sander 2023-09-22 19:25 15411
2660ccea Poul Sander 2023-09-22 19:25 15412
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 15413
    */
2660ccea Poul Sander 2023-09-22 19:25 15414
    union json_value
2660ccea Poul Sander 2023-09-22 19:25 15415
    {
2660ccea Poul Sander 2023-09-22 19:25 15416
        /// object (stored with pointer to save storage)
2660ccea Poul Sander 2023-09-22 19:25 15417
        object_t* object;
2660ccea Poul Sander 2023-09-22 19:25 15418
        /// array (stored with pointer to save storage)
2660ccea Poul Sander 2023-09-22 19:25 15419
        array_t* array;
2660ccea Poul Sander 2023-09-22 19:25 15420
        /// string (stored with pointer to save storage)
2660ccea Poul Sander 2023-09-22 19:25 15421
        string_t* string;
2660ccea Poul Sander 2023-09-22 19:25 15422
        /// boolean
2660ccea Poul Sander 2023-09-22 19:25 15423
        boolean_t boolean;
2660ccea Poul Sander 2023-09-22 19:25 15424
        /// number (integer)
2660ccea Poul Sander 2023-09-22 19:25 15425
        number_integer_t number_integer;
2660ccea Poul Sander 2023-09-22 19:25 15426
        /// number (unsigned integer)
2660ccea Poul Sander 2023-09-22 19:25 15427
        number_unsigned_t number_unsigned;
2660ccea Poul Sander 2023-09-22 19:25 15428
        /// number (floating-point)
2660ccea Poul Sander 2023-09-22 19:25 15429
        number_float_t number_float;
2660ccea Poul Sander 2023-09-22 19:25 15430
2660ccea Poul Sander 2023-09-22 19:25 15431
        /// default constructor (for null values)
2660ccea Poul Sander 2023-09-22 19:25 15432
        json_value() = default;
2660ccea Poul Sander 2023-09-22 19:25 15433
        /// constructor for booleans
2660ccea Poul Sander 2023-09-22 19:25 15434
        json_value(boolean_t v) noexcept : boolean(v) {}
2660ccea Poul Sander 2023-09-22 19:25 15435
        /// constructor for numbers (integer)
2660ccea Poul Sander 2023-09-22 19:25 15436
        json_value(number_integer_t v) noexcept : number_integer(v) {}
2660ccea Poul Sander 2023-09-22 19:25 15437
        /// constructor for numbers (unsigned)
2660ccea Poul Sander 2023-09-22 19:25 15438
        json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
2660ccea Poul Sander 2023-09-22 19:25 15439
        /// constructor for numbers (floating-point)
2660ccea Poul Sander 2023-09-22 19:25 15440
        json_value(number_float_t v) noexcept : number_float(v) {}
2660ccea Poul Sander 2023-09-22 19:25 15441
        /// constructor for empty values of a given type
2660ccea Poul Sander 2023-09-22 19:25 15442
        json_value(value_t t)
2660ccea Poul Sander 2023-09-22 19:25 15443
        {
2660ccea Poul Sander 2023-09-22 19:25 15444
            switch (t)
2660ccea Poul Sander 2023-09-22 19:25 15445
            {
2660ccea Poul Sander 2023-09-22 19:25 15446
                case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 15447
                {
2660ccea Poul Sander 2023-09-22 19:25 15448
                    object = create<object_t>();
2660ccea Poul Sander 2023-09-22 19:25 15449
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15450
                }
2660ccea Poul Sander 2023-09-22 19:25 15451
2660ccea Poul Sander 2023-09-22 19:25 15452
                case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 15453
                {
2660ccea Poul Sander 2023-09-22 19:25 15454
                    array = create<array_t>();
2660ccea Poul Sander 2023-09-22 19:25 15455
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15456
                }
2660ccea Poul Sander 2023-09-22 19:25 15457
2660ccea Poul Sander 2023-09-22 19:25 15458
                case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 15459
                {
2660ccea Poul Sander 2023-09-22 19:25 15460
                    string = create<string_t>("");
2660ccea Poul Sander 2023-09-22 19:25 15461
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15462
                }
2660ccea Poul Sander 2023-09-22 19:25 15463
2660ccea Poul Sander 2023-09-22 19:25 15464
                case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 15465
                {
2660ccea Poul Sander 2023-09-22 19:25 15466
                    boolean = boolean_t(false);
2660ccea Poul Sander 2023-09-22 19:25 15467
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15468
                }
2660ccea Poul Sander 2023-09-22 19:25 15469
2660ccea Poul Sander 2023-09-22 19:25 15470
                case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 15471
                {
2660ccea Poul Sander 2023-09-22 19:25 15472
                    number_integer = number_integer_t(0);
2660ccea Poul Sander 2023-09-22 19:25 15473
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15474
                }
2660ccea Poul Sander 2023-09-22 19:25 15475
2660ccea Poul Sander 2023-09-22 19:25 15476
                case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 15477
                {
2660ccea Poul Sander 2023-09-22 19:25 15478
                    number_unsigned = number_unsigned_t(0);
2660ccea Poul Sander 2023-09-22 19:25 15479
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15480
                }
2660ccea Poul Sander 2023-09-22 19:25 15481
2660ccea Poul Sander 2023-09-22 19:25 15482
                case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 15483
                {
2660ccea Poul Sander 2023-09-22 19:25 15484
                    number_float = number_float_t(0.0);
2660ccea Poul Sander 2023-09-22 19:25 15485
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15486
                }
2660ccea Poul Sander 2023-09-22 19:25 15487
2660ccea Poul Sander 2023-09-22 19:25 15488
                case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 15489
                {
2660ccea Poul Sander 2023-09-22 19:25 15490
                    object = nullptr;  // silence warning, see #821
2660ccea Poul Sander 2023-09-22 19:25 15491
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15492
                }
2660ccea Poul Sander 2023-09-22 19:25 15493
2660ccea Poul Sander 2023-09-22 19:25 15494
                default:
2660ccea Poul Sander 2023-09-22 19:25 15495
                {
2660ccea Poul Sander 2023-09-22 19:25 15496
                    object = nullptr;  // silence warning, see #821
2660ccea Poul Sander 2023-09-22 19:25 15497
                    if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
2660ccea Poul Sander 2023-09-22 19:25 15498
                    {
2660ccea Poul Sander 2023-09-22 19:25 15499
                        JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.7.3")); // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 15500
                    }
2660ccea Poul Sander 2023-09-22 19:25 15501
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15502
                }
2660ccea Poul Sander 2023-09-22 19:25 15503
            }
2660ccea Poul Sander 2023-09-22 19:25 15504
        }
2660ccea Poul Sander 2023-09-22 19:25 15505
2660ccea Poul Sander 2023-09-22 19:25 15506
        /// constructor for strings
2660ccea Poul Sander 2023-09-22 19:25 15507
        json_value(const string_t& value)
2660ccea Poul Sander 2023-09-22 19:25 15508
        {
2660ccea Poul Sander 2023-09-22 19:25 15509
            string = create<string_t>(value);
2660ccea Poul Sander 2023-09-22 19:25 15510
        }
2660ccea Poul Sander 2023-09-22 19:25 15511
2660ccea Poul Sander 2023-09-22 19:25 15512
        /// constructor for rvalue strings
2660ccea Poul Sander 2023-09-22 19:25 15513
        json_value(string_t&& value)
2660ccea Poul Sander 2023-09-22 19:25 15514
        {
2660ccea Poul Sander 2023-09-22 19:25 15515
            string = create<string_t>(std::move(value));
2660ccea Poul Sander 2023-09-22 19:25 15516
        }
2660ccea Poul Sander 2023-09-22 19:25 15517
2660ccea Poul Sander 2023-09-22 19:25 15518
        /// constructor for objects
2660ccea Poul Sander 2023-09-22 19:25 15519
        json_value(const object_t& value)
2660ccea Poul Sander 2023-09-22 19:25 15520
        {
2660ccea Poul Sander 2023-09-22 19:25 15521
            object = create<object_t>(value);
2660ccea Poul Sander 2023-09-22 19:25 15522
        }
2660ccea Poul Sander 2023-09-22 19:25 15523
2660ccea Poul Sander 2023-09-22 19:25 15524
        /// constructor for rvalue objects
2660ccea Poul Sander 2023-09-22 19:25 15525
        json_value(object_t&& value)
2660ccea Poul Sander 2023-09-22 19:25 15526
        {
2660ccea Poul Sander 2023-09-22 19:25 15527
            object = create<object_t>(std::move(value));
2660ccea Poul Sander 2023-09-22 19:25 15528
        }
2660ccea Poul Sander 2023-09-22 19:25 15529
2660ccea Poul Sander 2023-09-22 19:25 15530
        /// constructor for arrays
2660ccea Poul Sander 2023-09-22 19:25 15531
        json_value(const array_t& value)
2660ccea Poul Sander 2023-09-22 19:25 15532
        {
2660ccea Poul Sander 2023-09-22 19:25 15533
            array = create<array_t>(value);
2660ccea Poul Sander 2023-09-22 19:25 15534
        }
2660ccea Poul Sander 2023-09-22 19:25 15535
2660ccea Poul Sander 2023-09-22 19:25 15536
        /// constructor for rvalue arrays
2660ccea Poul Sander 2023-09-22 19:25 15537
        json_value(array_t&& value)
2660ccea Poul Sander 2023-09-22 19:25 15538
        {
2660ccea Poul Sander 2023-09-22 19:25 15539
            array = create<array_t>(std::move(value));
2660ccea Poul Sander 2023-09-22 19:25 15540
        }
2660ccea Poul Sander 2023-09-22 19:25 15541
2660ccea Poul Sander 2023-09-22 19:25 15542
        void destroy(value_t t) noexcept
2660ccea Poul Sander 2023-09-22 19:25 15543
        {
2660ccea Poul Sander 2023-09-22 19:25 15544
            // flatten the current json_value to a heap-allocated stack
2660ccea Poul Sander 2023-09-22 19:25 15545
            std::vector<basic_json> stack;
2660ccea Poul Sander 2023-09-22 19:25 15546
2660ccea Poul Sander 2023-09-22 19:25 15547
            // move the top-level items to stack
2660ccea Poul Sander 2023-09-22 19:25 15548
            if (t == value_t::array)
2660ccea Poul Sander 2023-09-22 19:25 15549
            {
2660ccea Poul Sander 2023-09-22 19:25 15550
                stack.reserve(array->size());
2660ccea Poul Sander 2023-09-22 19:25 15551
                std::move(array->begin(), array->end(), std::back_inserter(stack));
2660ccea Poul Sander 2023-09-22 19:25 15552
            }
2660ccea Poul Sander 2023-09-22 19:25 15553
            else if (t == value_t::object)
2660ccea Poul Sander 2023-09-22 19:25 15554
            {
2660ccea Poul Sander 2023-09-22 19:25 15555
                stack.reserve(object->size());
2660ccea Poul Sander 2023-09-22 19:25 15556
                for (auto&& it : *object)
2660ccea Poul Sander 2023-09-22 19:25 15557
                {
2660ccea Poul Sander 2023-09-22 19:25 15558
                    stack.push_back(std::move(it.second));
2660ccea Poul Sander 2023-09-22 19:25 15559
                }
2660ccea Poul Sander 2023-09-22 19:25 15560
            }
2660ccea Poul Sander 2023-09-22 19:25 15561
2660ccea Poul Sander 2023-09-22 19:25 15562
            while (not stack.empty())
2660ccea Poul Sander 2023-09-22 19:25 15563
            {
2660ccea Poul Sander 2023-09-22 19:25 15564
                // move the last item to local variable to be processed
2660ccea Poul Sander 2023-09-22 19:25 15565
                basic_json current_item(std::move(stack.back()));
2660ccea Poul Sander 2023-09-22 19:25 15566
                stack.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 15567
2660ccea Poul Sander 2023-09-22 19:25 15568
                // if current_item is array/object, move
2660ccea Poul Sander 2023-09-22 19:25 15569
                // its children to the stack to be processed later
2660ccea Poul Sander 2023-09-22 19:25 15570
                if (current_item.is_array())
2660ccea Poul Sander 2023-09-22 19:25 15571
                {
2660ccea Poul Sander 2023-09-22 19:25 15572
                    std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
2660ccea Poul Sander 2023-09-22 19:25 15573
                              std::back_inserter(stack));
2660ccea Poul Sander 2023-09-22 19:25 15574
2660ccea Poul Sander 2023-09-22 19:25 15575
                    current_item.m_value.array->clear();
2660ccea Poul Sander 2023-09-22 19:25 15576
                }
2660ccea Poul Sander 2023-09-22 19:25 15577
                else if (current_item.is_object())
2660ccea Poul Sander 2023-09-22 19:25 15578
                {
2660ccea Poul Sander 2023-09-22 19:25 15579
                    for (auto&& it : *current_item.m_value.object)
2660ccea Poul Sander 2023-09-22 19:25 15580
                    {
2660ccea Poul Sander 2023-09-22 19:25 15581
                        stack.push_back(std::move(it.second));
2660ccea Poul Sander 2023-09-22 19:25 15582
                    }
2660ccea Poul Sander 2023-09-22 19:25 15583
2660ccea Poul Sander 2023-09-22 19:25 15584
                    current_item.m_value.object->clear();
2660ccea Poul Sander 2023-09-22 19:25 15585
                }
2660ccea Poul Sander 2023-09-22 19:25 15586
2660ccea Poul Sander 2023-09-22 19:25 15587
                // it's now safe that current_item get destructed
2660ccea Poul Sander 2023-09-22 19:25 15588
                // since it doesn't have any children
2660ccea Poul Sander 2023-09-22 19:25 15589
            }
2660ccea Poul Sander 2023-09-22 19:25 15590
2660ccea Poul Sander 2023-09-22 19:25 15591
            switch (t)
2660ccea Poul Sander 2023-09-22 19:25 15592
            {
2660ccea Poul Sander 2023-09-22 19:25 15593
                case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 15594
                {
2660ccea Poul Sander 2023-09-22 19:25 15595
                    AllocatorType<object_t> alloc;
2660ccea Poul Sander 2023-09-22 19:25 15596
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
2660ccea Poul Sander 2023-09-22 19:25 15597
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
2660ccea Poul Sander 2023-09-22 19:25 15598
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15599
                }
2660ccea Poul Sander 2023-09-22 19:25 15600
2660ccea Poul Sander 2023-09-22 19:25 15601
                case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 15602
                {
2660ccea Poul Sander 2023-09-22 19:25 15603
                    AllocatorType<array_t> alloc;
2660ccea Poul Sander 2023-09-22 19:25 15604
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
2660ccea Poul Sander 2023-09-22 19:25 15605
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
2660ccea Poul Sander 2023-09-22 19:25 15606
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15607
                }
2660ccea Poul Sander 2023-09-22 19:25 15608
2660ccea Poul Sander 2023-09-22 19:25 15609
                case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 15610
                {
2660ccea Poul Sander 2023-09-22 19:25 15611
                    AllocatorType<string_t> alloc;
2660ccea Poul Sander 2023-09-22 19:25 15612
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
2660ccea Poul Sander 2023-09-22 19:25 15613
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
2660ccea Poul Sander 2023-09-22 19:25 15614
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15615
                }
2660ccea Poul Sander 2023-09-22 19:25 15616
2660ccea Poul Sander 2023-09-22 19:25 15617
                default:
2660ccea Poul Sander 2023-09-22 19:25 15618
                {
2660ccea Poul Sander 2023-09-22 19:25 15619
                    break;
2660ccea Poul Sander 2023-09-22 19:25 15620
                }
2660ccea Poul Sander 2023-09-22 19:25 15621
            }
2660ccea Poul Sander 2023-09-22 19:25 15622
        }
2660ccea Poul Sander 2023-09-22 19:25 15623
    };
2660ccea Poul Sander 2023-09-22 19:25 15624
2660ccea Poul Sander 2023-09-22 19:25 15625
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15626
    @brief checks the class invariants
2660ccea Poul Sander 2023-09-22 19:25 15627
2660ccea Poul Sander 2023-09-22 19:25 15628
    This function asserts the class invariants. It needs to be called at the
2660ccea Poul Sander 2023-09-22 19:25 15629
    end of every constructor to make sure that created objects respect the
2660ccea Poul Sander 2023-09-22 19:25 15630
    invariant. Furthermore, it has to be called each time the type of a JSON
2660ccea Poul Sander 2023-09-22 19:25 15631
    value is changed, because the invariant expresses a relationship between
2660ccea Poul Sander 2023-09-22 19:25 15632
    @a m_type and @a m_value.
2660ccea Poul Sander 2023-09-22 19:25 15633
    */
2660ccea Poul Sander 2023-09-22 19:25 15634
    void assert_invariant() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 15635
    {
2660ccea Poul Sander 2023-09-22 19:25 15636
        assert(m_type != value_t::object or m_value.object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 15637
        assert(m_type != value_t::array or m_value.array != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 15638
        assert(m_type != value_t::string or m_value.string != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 15639
    }
2660ccea Poul Sander 2023-09-22 19:25 15640
2660ccea Poul Sander 2023-09-22 19:25 15641
  public:
2660ccea Poul Sander 2023-09-22 19:25 15642
    //////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 15643
    // JSON parser callback //
2660ccea Poul Sander 2023-09-22 19:25 15644
    //////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 15645
2660ccea Poul Sander 2023-09-22 19:25 15646
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15647
    @brief parser event types
2660ccea Poul Sander 2023-09-22 19:25 15648
2660ccea Poul Sander 2023-09-22 19:25 15649
    The parser callback distinguishes the following events:
2660ccea Poul Sander 2023-09-22 19:25 15650
    - `object_start`: the parser read `{` and started to process a JSON object
2660ccea Poul Sander 2023-09-22 19:25 15651
    - `key`: the parser read a key of a value in an object
2660ccea Poul Sander 2023-09-22 19:25 15652
    - `object_end`: the parser read `}` and finished processing a JSON object
2660ccea Poul Sander 2023-09-22 19:25 15653
    - `array_start`: the parser read `[` and started to process a JSON array
2660ccea Poul Sander 2023-09-22 19:25 15654
    - `array_end`: the parser read `]` and finished processing a JSON array
2660ccea Poul Sander 2023-09-22 19:25 15655
    - `value`: the parser finished reading a JSON value
2660ccea Poul Sander 2023-09-22 19:25 15656
2660ccea Poul Sander 2023-09-22 19:25 15657
    @image html callback_events.png "Example when certain parse events are triggered"
2660ccea Poul Sander 2023-09-22 19:25 15658
2660ccea Poul Sander 2023-09-22 19:25 15659
    @sa @ref parser_callback_t for more information and examples
2660ccea Poul Sander 2023-09-22 19:25 15660
    */
2660ccea Poul Sander 2023-09-22 19:25 15661
    using parse_event_t = typename parser::parse_event_t;
2660ccea Poul Sander 2023-09-22 19:25 15662
2660ccea Poul Sander 2023-09-22 19:25 15663
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15664
    @brief per-element parser callback type
2660ccea Poul Sander 2023-09-22 19:25 15665
2660ccea Poul Sander 2023-09-22 19:25 15666
    With a parser callback function, the result of parsing a JSON text can be
2660ccea Poul Sander 2023-09-22 19:25 15667
    influenced. When passed to @ref parse, it is called on certain events
2660ccea Poul Sander 2023-09-22 19:25 15668
    (passed as @ref parse_event_t via parameter @a event) with a set recursion
2660ccea Poul Sander 2023-09-22 19:25 15669
    depth @a depth and context JSON value @a parsed. The return value of the
2660ccea Poul Sander 2023-09-22 19:25 15670
    callback function is a boolean indicating whether the element that emitted
2660ccea Poul Sander 2023-09-22 19:25 15671
    the callback shall be kept or not.
2660ccea Poul Sander 2023-09-22 19:25 15672
2660ccea Poul Sander 2023-09-22 19:25 15673
    We distinguish six scenarios (determined by the event type) in which the
2660ccea Poul Sander 2023-09-22 19:25 15674
    callback function can be called. The following table describes the values
2660ccea Poul Sander 2023-09-22 19:25 15675
    of the parameters @a depth, @a event, and @a parsed.
2660ccea Poul Sander 2023-09-22 19:25 15676
2660ccea Poul Sander 2023-09-22 19:25 15677
    parameter @a event | description | parameter @a depth | parameter @a parsed
2660ccea Poul Sander 2023-09-22 19:25 15678
    ------------------ | ----------- | ------------------ | -------------------
2660ccea Poul Sander 2023-09-22 19:25 15679
    parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
2660ccea Poul Sander 2023-09-22 19:25 15680
    parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
2660ccea Poul Sander 2023-09-22 19:25 15681
    parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
2660ccea Poul Sander 2023-09-22 19:25 15682
    parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
2660ccea Poul Sander 2023-09-22 19:25 15683
    parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
2660ccea Poul Sander 2023-09-22 19:25 15684
    parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
2660ccea Poul Sander 2023-09-22 19:25 15685
2660ccea Poul Sander 2023-09-22 19:25 15686
    @image html callback_events.png "Example when certain parse events are triggered"
2660ccea Poul Sander 2023-09-22 19:25 15687
2660ccea Poul Sander 2023-09-22 19:25 15688
    Discarding a value (i.e., returning `false`) has different effects
2660ccea Poul Sander 2023-09-22 19:25 15689
    depending on the context in which function was called:
2660ccea Poul Sander 2023-09-22 19:25 15690
2660ccea Poul Sander 2023-09-22 19:25 15691
    - Discarded values in structured types are skipped. That is, the parser
2660ccea Poul Sander 2023-09-22 19:25 15692
      will behave as if the discarded value was never read.
2660ccea Poul Sander 2023-09-22 19:25 15693
    - In case a value outside a structured type is skipped, it is replaced
2660ccea Poul Sander 2023-09-22 19:25 15694
      with `null`. This case happens if the top-level element is skipped.
2660ccea Poul Sander 2023-09-22 19:25 15695
2660ccea Poul Sander 2023-09-22 19:25 15696
    @param[in] depth  the depth of the recursion during parsing
2660ccea Poul Sander 2023-09-22 19:25 15697
2660ccea Poul Sander 2023-09-22 19:25 15698
    @param[in] event  an event of type parse_event_t indicating the context in
2660ccea Poul Sander 2023-09-22 19:25 15699
    the callback function has been called
2660ccea Poul Sander 2023-09-22 19:25 15700
2660ccea Poul Sander 2023-09-22 19:25 15701
    @param[in,out] parsed  the current intermediate parse result; note that
2660ccea Poul Sander 2023-09-22 19:25 15702
    writing to this value has no effect for parse_event_t::key events
2660ccea Poul Sander 2023-09-22 19:25 15703
2660ccea Poul Sander 2023-09-22 19:25 15704
    @return Whether the JSON value which called the function during parsing
2660ccea Poul Sander 2023-09-22 19:25 15705
    should be kept (`true`) or not (`false`). In the latter case, it is either
2660ccea Poul Sander 2023-09-22 19:25 15706
    skipped completely or replaced by an empty discarded object.
2660ccea Poul Sander 2023-09-22 19:25 15707
2660ccea Poul Sander 2023-09-22 19:25 15708
    @sa @ref parse for examples
2660ccea Poul Sander 2023-09-22 19:25 15709
2660ccea Poul Sander 2023-09-22 19:25 15710
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 15711
    */
2660ccea Poul Sander 2023-09-22 19:25 15712
    using parser_callback_t = typename parser::parser_callback_t;
2660ccea Poul Sander 2023-09-22 19:25 15713
2660ccea Poul Sander 2023-09-22 19:25 15714
    //////////////////
2660ccea Poul Sander 2023-09-22 19:25 15715
    // constructors //
2660ccea Poul Sander 2023-09-22 19:25 15716
    //////////////////
2660ccea Poul Sander 2023-09-22 19:25 15717
2660ccea Poul Sander 2023-09-22 19:25 15718
    /// @name constructors and destructors
2660ccea Poul Sander 2023-09-22 19:25 15719
    /// Constructors of class @ref basic_json, copy/move constructor, copy
2660ccea Poul Sander 2023-09-22 19:25 15720
    /// assignment, static functions creating objects, and the destructor.
2660ccea Poul Sander 2023-09-22 19:25 15721
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 15722
2660ccea Poul Sander 2023-09-22 19:25 15723
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15724
    @brief create an empty value with a given type
2660ccea Poul Sander 2023-09-22 19:25 15725
2660ccea Poul Sander 2023-09-22 19:25 15726
    Create an empty JSON value with a given type. The value will be default
2660ccea Poul Sander 2023-09-22 19:25 15727
    initialized with an empty value which depends on the type:
2660ccea Poul Sander 2023-09-22 19:25 15728
2660ccea Poul Sander 2023-09-22 19:25 15729
    Value type  | initial value
2660ccea Poul Sander 2023-09-22 19:25 15730
    ----------- | -------------
2660ccea Poul Sander 2023-09-22 19:25 15731
    null        | `null`
2660ccea Poul Sander 2023-09-22 19:25 15732
    boolean     | `false`
2660ccea Poul Sander 2023-09-22 19:25 15733
    string      | `""`
2660ccea Poul Sander 2023-09-22 19:25 15734
    number      | `0`
2660ccea Poul Sander 2023-09-22 19:25 15735
    object      | `{}`
2660ccea Poul Sander 2023-09-22 19:25 15736
    array       | `[]`
2660ccea Poul Sander 2023-09-22 19:25 15737
2660ccea Poul Sander 2023-09-22 19:25 15738
    @param[in] v  the type of the value to create
2660ccea Poul Sander 2023-09-22 19:25 15739
2660ccea Poul Sander 2023-09-22 19:25 15740
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 15741
2660ccea Poul Sander 2023-09-22 19:25 15742
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 15743
    changes to any JSON value.
2660ccea Poul Sander 2023-09-22 19:25 15744
2660ccea Poul Sander 2023-09-22 19:25 15745
    @liveexample{The following code shows the constructor for different @ref
2660ccea Poul Sander 2023-09-22 19:25 15746
    value_t values,basic_json__value_t}
2660ccea Poul Sander 2023-09-22 19:25 15747
2660ccea Poul Sander 2023-09-22 19:25 15748
    @sa @ref clear() -- restores the postcondition of this constructor
2660ccea Poul Sander 2023-09-22 19:25 15749
2660ccea Poul Sander 2023-09-22 19:25 15750
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 15751
    */
2660ccea Poul Sander 2023-09-22 19:25 15752
    basic_json(const value_t v)
2660ccea Poul Sander 2023-09-22 19:25 15753
        : m_type(v), m_value(v)
2660ccea Poul Sander 2023-09-22 19:25 15754
    {
2660ccea Poul Sander 2023-09-22 19:25 15755
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 15756
    }
2660ccea Poul Sander 2023-09-22 19:25 15757
2660ccea Poul Sander 2023-09-22 19:25 15758
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15759
    @brief create a null object
2660ccea Poul Sander 2023-09-22 19:25 15760
2660ccea Poul Sander 2023-09-22 19:25 15761
    Create a `null` JSON value. It either takes a null pointer as parameter
2660ccea Poul Sander 2023-09-22 19:25 15762
    (explicitly creating `null`) or no parameter (implicitly creating `null`).
2660ccea Poul Sander 2023-09-22 19:25 15763
    The passed null pointer itself is not read -- it is only used to choose
2660ccea Poul Sander 2023-09-22 19:25 15764
    the right constructor.
2660ccea Poul Sander 2023-09-22 19:25 15765
2660ccea Poul Sander 2023-09-22 19:25 15766
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 15767
2660ccea Poul Sander 2023-09-22 19:25 15768
    @exceptionsafety No-throw guarantee: this constructor never throws
2660ccea Poul Sander 2023-09-22 19:25 15769
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 15770
2660ccea Poul Sander 2023-09-22 19:25 15771
    @liveexample{The following code shows the constructor with and without a
2660ccea Poul Sander 2023-09-22 19:25 15772
    null pointer parameter.,basic_json__nullptr_t}
2660ccea Poul Sander 2023-09-22 19:25 15773
2660ccea Poul Sander 2023-09-22 19:25 15774
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 15775
    */
2660ccea Poul Sander 2023-09-22 19:25 15776
    basic_json(std::nullptr_t = nullptr) noexcept
2660ccea Poul Sander 2023-09-22 19:25 15777
        : basic_json(value_t::null)
2660ccea Poul Sander 2023-09-22 19:25 15778
    {
2660ccea Poul Sander 2023-09-22 19:25 15779
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 15780
    }
2660ccea Poul Sander 2023-09-22 19:25 15781
2660ccea Poul Sander 2023-09-22 19:25 15782
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15783
    @brief create a JSON value
2660ccea Poul Sander 2023-09-22 19:25 15784
2660ccea Poul Sander 2023-09-22 19:25 15785
    This is a "catch all" constructor for all compatible JSON types; that is,
2660ccea Poul Sander 2023-09-22 19:25 15786
    types for which a `to_json()` method exists. The constructor forwards the
2660ccea Poul Sander 2023-09-22 19:25 15787
    parameter @a val to that method (to `json_serializer<U>::to_json` method
2660ccea Poul Sander 2023-09-22 19:25 15788
    with `U = uncvref_t<CompatibleType>`, to be exact).
2660ccea Poul Sander 2023-09-22 19:25 15789
2660ccea Poul Sander 2023-09-22 19:25 15790
    Template type @a CompatibleType includes, but is not limited to, the
2660ccea Poul Sander 2023-09-22 19:25 15791
    following types:
2660ccea Poul Sander 2023-09-22 19:25 15792
    - **arrays**: @ref array_t and all kinds of compatible containers such as
2660ccea Poul Sander 2023-09-22 19:25 15793
      `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
2660ccea Poul Sander 2023-09-22 19:25 15794
      `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
2660ccea Poul Sander 2023-09-22 19:25 15795
      `std::multiset`, and `std::unordered_multiset` with a `value_type` from
2660ccea Poul Sander 2023-09-22 19:25 15796
      which a @ref basic_json value can be constructed.
2660ccea Poul Sander 2023-09-22 19:25 15797
    - **objects**: @ref object_t and all kinds of compatible associative
2660ccea Poul Sander 2023-09-22 19:25 15798
      containers such as `std::map`, `std::unordered_map`, `std::multimap`,
2660ccea Poul Sander 2023-09-22 19:25 15799
      and `std::unordered_multimap` with a `key_type` compatible to
2660ccea Poul Sander 2023-09-22 19:25 15800
      @ref string_t and a `value_type` from which a @ref basic_json value can
2660ccea Poul Sander 2023-09-22 19:25 15801
      be constructed.
2660ccea Poul Sander 2023-09-22 19:25 15802
    - **strings**: @ref string_t, string literals, and all compatible string
2660ccea Poul Sander 2023-09-22 19:25 15803
      containers can be used.
2660ccea Poul Sander 2023-09-22 19:25 15804
    - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
2660ccea Poul Sander 2023-09-22 19:25 15805
      @ref number_float_t, and all convertible number types such as `int`,
2660ccea Poul Sander 2023-09-22 19:25 15806
      `size_t`, `int64_t`, `float` or `double` can be used.
2660ccea Poul Sander 2023-09-22 19:25 15807
    - **boolean**: @ref boolean_t / `bool` can be used.
2660ccea Poul Sander 2023-09-22 19:25 15808
2660ccea Poul Sander 2023-09-22 19:25 15809
    See the examples below.
2660ccea Poul Sander 2023-09-22 19:25 15810
2660ccea Poul Sander 2023-09-22 19:25 15811
    @tparam CompatibleType a type such that:
2660ccea Poul Sander 2023-09-22 19:25 15812
    - @a CompatibleType is not derived from `std::istream`,
2660ccea Poul Sander 2023-09-22 19:25 15813
    - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
2660ccea Poul Sander 2023-09-22 19:25 15814
         constructors),
2660ccea Poul Sander 2023-09-22 19:25 15815
    - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
2660ccea Poul Sander 2023-09-22 19:25 15816
    - @a CompatibleType is not a @ref basic_json nested type (e.g.,
2660ccea Poul Sander 2023-09-22 19:25 15817
         @ref json_pointer, @ref iterator, etc ...)
2660ccea Poul Sander 2023-09-22 19:25 15818
    - @ref @ref json_serializer<U> has a
2660ccea Poul Sander 2023-09-22 19:25 15819
         `to_json(basic_json_t&, CompatibleType&&)` method
2660ccea Poul Sander 2023-09-22 19:25 15820
2660ccea Poul Sander 2023-09-22 19:25 15821
    @tparam U = `uncvref_t<CompatibleType>`
2660ccea Poul Sander 2023-09-22 19:25 15822
2660ccea Poul Sander 2023-09-22 19:25 15823
    @param[in] val the value to be forwarded to the respective constructor
2660ccea Poul Sander 2023-09-22 19:25 15824
2660ccea Poul Sander 2023-09-22 19:25 15825
    @complexity Usually linear in the size of the passed @a val, also
2660ccea Poul Sander 2023-09-22 19:25 15826
                depending on the implementation of the called `to_json()`
2660ccea Poul Sander 2023-09-22 19:25 15827
                method.
2660ccea Poul Sander 2023-09-22 19:25 15828
2660ccea Poul Sander 2023-09-22 19:25 15829
    @exceptionsafety Depends on the called constructor. For types directly
2660ccea Poul Sander 2023-09-22 19:25 15830
    supported by the library (i.e., all types for which no `to_json()` function
2660ccea Poul Sander 2023-09-22 19:25 15831
    was provided), strong guarantee holds: if an exception is thrown, there are
2660ccea Poul Sander 2023-09-22 19:25 15832
    no changes to any JSON value.
2660ccea Poul Sander 2023-09-22 19:25 15833
2660ccea Poul Sander 2023-09-22 19:25 15834
    @liveexample{The following code shows the constructor with several
2660ccea Poul Sander 2023-09-22 19:25 15835
    compatible types.,basic_json__CompatibleType}
2660ccea Poul Sander 2023-09-22 19:25 15836
2660ccea Poul Sander 2023-09-22 19:25 15837
    @since version 2.1.0
2660ccea Poul Sander 2023-09-22 19:25 15838
    */
2660ccea Poul Sander 2023-09-22 19:25 15839
    template <typename CompatibleType,
2660ccea Poul Sander 2023-09-22 19:25 15840
              typename U = detail::uncvref_t<CompatibleType>,
2660ccea Poul Sander 2023-09-22 19:25 15841
              detail::enable_if_t<
2660ccea Poul Sander 2023-09-22 19:25 15842
                  not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 15843
    basic_json(CompatibleType && val) noexcept(noexcept(
2660ccea Poul Sander 2023-09-22 19:25 15844
                JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
2660ccea Poul Sander 2023-09-22 19:25 15845
                                           std::forward<CompatibleType>(val))))
2660ccea Poul Sander 2023-09-22 19:25 15846
    {
2660ccea Poul Sander 2023-09-22 19:25 15847
        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
2660ccea Poul Sander 2023-09-22 19:25 15848
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 15849
    }
2660ccea Poul Sander 2023-09-22 19:25 15850
2660ccea Poul Sander 2023-09-22 19:25 15851
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15852
    @brief create a JSON value from an existing one
2660ccea Poul Sander 2023-09-22 19:25 15853
2660ccea Poul Sander 2023-09-22 19:25 15854
    This is a constructor for existing @ref basic_json types.
2660ccea Poul Sander 2023-09-22 19:25 15855
    It does not hijack copy/move constructors, since the parameter has different
2660ccea Poul Sander 2023-09-22 19:25 15856
    template arguments than the current ones.
2660ccea Poul Sander 2023-09-22 19:25 15857
2660ccea Poul Sander 2023-09-22 19:25 15858
    The constructor tries to convert the internal @ref m_value of the parameter.
2660ccea Poul Sander 2023-09-22 19:25 15859
2660ccea Poul Sander 2023-09-22 19:25 15860
    @tparam BasicJsonType a type such that:
2660ccea Poul Sander 2023-09-22 19:25 15861
    - @a BasicJsonType is a @ref basic_json type.
2660ccea Poul Sander 2023-09-22 19:25 15862
    - @a BasicJsonType has different template arguments than @ref basic_json_t.
2660ccea Poul Sander 2023-09-22 19:25 15863
2660ccea Poul Sander 2023-09-22 19:25 15864
    @param[in] val the @ref basic_json value to be converted.
2660ccea Poul Sander 2023-09-22 19:25 15865
2660ccea Poul Sander 2023-09-22 19:25 15866
    @complexity Usually linear in the size of the passed @a val, also
2660ccea Poul Sander 2023-09-22 19:25 15867
                depending on the implementation of the called `to_json()`
2660ccea Poul Sander 2023-09-22 19:25 15868
                method.
2660ccea Poul Sander 2023-09-22 19:25 15869
2660ccea Poul Sander 2023-09-22 19:25 15870
    @exceptionsafety Depends on the called constructor. For types directly
2660ccea Poul Sander 2023-09-22 19:25 15871
    supported by the library (i.e., all types for which no `to_json()` function
2660ccea Poul Sander 2023-09-22 19:25 15872
    was provided), strong guarantee holds: if an exception is thrown, there are
2660ccea Poul Sander 2023-09-22 19:25 15873
    no changes to any JSON value.
2660ccea Poul Sander 2023-09-22 19:25 15874
2660ccea Poul Sander 2023-09-22 19:25 15875
    @since version 3.2.0
2660ccea Poul Sander 2023-09-22 19:25 15876
    */
2660ccea Poul Sander 2023-09-22 19:25 15877
    template <typename BasicJsonType,
2660ccea Poul Sander 2023-09-22 19:25 15878
              detail::enable_if_t<
2660ccea Poul Sander 2023-09-22 19:25 15879
                  detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 15880
    basic_json(const BasicJsonType& val)
2660ccea Poul Sander 2023-09-22 19:25 15881
    {
2660ccea Poul Sander 2023-09-22 19:25 15882
        using other_boolean_t = typename BasicJsonType::boolean_t;
2660ccea Poul Sander 2023-09-22 19:25 15883
        using other_number_float_t = typename BasicJsonType::number_float_t;
2660ccea Poul Sander 2023-09-22 19:25 15884
        using other_number_integer_t = typename BasicJsonType::number_integer_t;
2660ccea Poul Sander 2023-09-22 19:25 15885
        using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2660ccea Poul Sander 2023-09-22 19:25 15886
        using other_string_t = typename BasicJsonType::string_t;
2660ccea Poul Sander 2023-09-22 19:25 15887
        using other_object_t = typename BasicJsonType::object_t;
2660ccea Poul Sander 2023-09-22 19:25 15888
        using other_array_t = typename BasicJsonType::array_t;
2660ccea Poul Sander 2023-09-22 19:25 15889
2660ccea Poul Sander 2023-09-22 19:25 15890
        switch (val.type())
2660ccea Poul Sander 2023-09-22 19:25 15891
        {
2660ccea Poul Sander 2023-09-22 19:25 15892
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 15893
                JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
2660ccea Poul Sander 2023-09-22 19:25 15894
                break;
2660ccea Poul Sander 2023-09-22 19:25 15895
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 15896
                JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
2660ccea Poul Sander 2023-09-22 19:25 15897
                break;
2660ccea Poul Sander 2023-09-22 19:25 15898
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 15899
                JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
2660ccea Poul Sander 2023-09-22 19:25 15900
                break;
2660ccea Poul Sander 2023-09-22 19:25 15901
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 15902
                JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
2660ccea Poul Sander 2023-09-22 19:25 15903
                break;
2660ccea Poul Sander 2023-09-22 19:25 15904
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 15905
                JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
2660ccea Poul Sander 2023-09-22 19:25 15906
                break;
2660ccea Poul Sander 2023-09-22 19:25 15907
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 15908
                JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
2660ccea Poul Sander 2023-09-22 19:25 15909
                break;
2660ccea Poul Sander 2023-09-22 19:25 15910
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 15911
                JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
2660ccea Poul Sander 2023-09-22 19:25 15912
                break;
2660ccea Poul Sander 2023-09-22 19:25 15913
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 15914
                *this = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 15915
                break;
2660ccea Poul Sander 2023-09-22 19:25 15916
            case value_t::discarded:
2660ccea Poul Sander 2023-09-22 19:25 15917
                m_type = value_t::discarded;
2660ccea Poul Sander 2023-09-22 19:25 15918
                break;
2660ccea Poul Sander 2023-09-22 19:25 15919
            default:            // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 15920
                assert(false);  // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 15921
        }
2660ccea Poul Sander 2023-09-22 19:25 15922
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 15923
    }
2660ccea Poul Sander 2023-09-22 19:25 15924
2660ccea Poul Sander 2023-09-22 19:25 15925
    /*!
2660ccea Poul Sander 2023-09-22 19:25 15926
    @brief create a container (array or object) from an initializer list
2660ccea Poul Sander 2023-09-22 19:25 15927
2660ccea Poul Sander 2023-09-22 19:25 15928
    Creates a JSON value of type array or object from the passed initializer
2660ccea Poul Sander 2023-09-22 19:25 15929
    list @a init. In case @a type_deduction is `true` (default), the type of
2660ccea Poul Sander 2023-09-22 19:25 15930
    the JSON value to be created is deducted from the initializer list @a init
2660ccea Poul Sander 2023-09-22 19:25 15931
    according to the following rules:
2660ccea Poul Sander 2023-09-22 19:25 15932
2660ccea Poul Sander 2023-09-22 19:25 15933
    1. If the list is empty, an empty JSON object value `{}` is created.
2660ccea Poul Sander 2023-09-22 19:25 15934
    2. If the list consists of pairs whose first element is a string, a JSON
2660ccea Poul Sander 2023-09-22 19:25 15935
       object value is created where the first elements of the pairs are
2660ccea Poul Sander 2023-09-22 19:25 15936
       treated as keys and the second elements are as values.
2660ccea Poul Sander 2023-09-22 19:25 15937
    3. In all other cases, an array is created.
2660ccea Poul Sander 2023-09-22 19:25 15938
2660ccea Poul Sander 2023-09-22 19:25 15939
    The rules aim to create the best fit between a C++ initializer list and
2660ccea Poul Sander 2023-09-22 19:25 15940
    JSON values. The rationale is as follows:
2660ccea Poul Sander 2023-09-22 19:25 15941
2660ccea Poul Sander 2023-09-22 19:25 15942
    1. The empty initializer list is written as `{}` which is exactly an empty
2660ccea Poul Sander 2023-09-22 19:25 15943
       JSON object.
2660ccea Poul Sander 2023-09-22 19:25 15944
    2. C++ has no way of describing mapped types other than to list a list of
2660ccea Poul Sander 2023-09-22 19:25 15945
       pairs. As JSON requires that keys must be of type string, rule 2 is the
2660ccea Poul Sander 2023-09-22 19:25 15946
       weakest constraint one can pose on initializer lists to interpret them
2660ccea Poul Sander 2023-09-22 19:25 15947
       as an object.
2660ccea Poul Sander 2023-09-22 19:25 15948
    3. In all other cases, the initializer list could not be interpreted as
2660ccea Poul Sander 2023-09-22 19:25 15949
       JSON object type, so interpreting it as JSON array type is safe.
2660ccea Poul Sander 2023-09-22 19:25 15950
2660ccea Poul Sander 2023-09-22 19:25 15951
    With the rules described above, the following JSON values cannot be
2660ccea Poul Sander 2023-09-22 19:25 15952
    expressed by an initializer list:
2660ccea Poul Sander 2023-09-22 19:25 15953
2660ccea Poul Sander 2023-09-22 19:25 15954
    - the empty array (`[]`): use @ref array(initializer_list_t)
2660ccea Poul Sander 2023-09-22 19:25 15955
      with an empty initializer list in this case
2660ccea Poul Sander 2023-09-22 19:25 15956
    - arrays whose elements satisfy rule 2: use @ref
2660ccea Poul Sander 2023-09-22 19:25 15957
      array(initializer_list_t) with the same initializer list
2660ccea Poul Sander 2023-09-22 19:25 15958
      in this case
2660ccea Poul Sander 2023-09-22 19:25 15959
2660ccea Poul Sander 2023-09-22 19:25 15960
    @note When used without parentheses around an empty initializer list, @ref
2660ccea Poul Sander 2023-09-22 19:25 15961
    basic_json() is called instead of this function, yielding the JSON null
2660ccea Poul Sander 2023-09-22 19:25 15962
    value.
2660ccea Poul Sander 2023-09-22 19:25 15963
2660ccea Poul Sander 2023-09-22 19:25 15964
    @param[in] init  initializer list with JSON values
2660ccea Poul Sander 2023-09-22 19:25 15965
2660ccea Poul Sander 2023-09-22 19:25 15966
    @param[in] type_deduction internal parameter; when set to `true`, the type
2660ccea Poul Sander 2023-09-22 19:25 15967
    of the JSON value is deducted from the initializer list @a init; when set
2660ccea Poul Sander 2023-09-22 19:25 15968
    to `false`, the type provided via @a manual_type is forced. This mode is
2660ccea Poul Sander 2023-09-22 19:25 15969
    used by the functions @ref array(initializer_list_t) and
2660ccea Poul Sander 2023-09-22 19:25 15970
    @ref object(initializer_list_t).
2660ccea Poul Sander 2023-09-22 19:25 15971
2660ccea Poul Sander 2023-09-22 19:25 15972
    @param[in] manual_type internal parameter; when @a type_deduction is set
2660ccea Poul Sander 2023-09-22 19:25 15973
    to `false`, the created JSON value will use the provided type (only @ref
2660ccea Poul Sander 2023-09-22 19:25 15974
    value_t::array and @ref value_t::object are valid); when @a type_deduction
2660ccea Poul Sander 2023-09-22 19:25 15975
    is set to `true`, this parameter has no effect
2660ccea Poul Sander 2023-09-22 19:25 15976
2660ccea Poul Sander 2023-09-22 19:25 15977
    @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
2660ccea Poul Sander 2023-09-22 19:25 15978
    `value_t::object`, but @a init contains an element which is not a pair
2660ccea Poul Sander 2023-09-22 19:25 15979
    whose first element is a string. In this case, the constructor could not
2660ccea Poul Sander 2023-09-22 19:25 15980
    create an object. If @a type_deduction would have be `true`, an array
2660ccea Poul Sander 2023-09-22 19:25 15981
    would have been created. See @ref object(initializer_list_t)
2660ccea Poul Sander 2023-09-22 19:25 15982
    for an example.
2660ccea Poul Sander 2023-09-22 19:25 15983
2660ccea Poul Sander 2023-09-22 19:25 15984
    @complexity Linear in the size of the initializer list @a init.
2660ccea Poul Sander 2023-09-22 19:25 15985
2660ccea Poul Sander 2023-09-22 19:25 15986
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 15987
    changes to any JSON value.
2660ccea Poul Sander 2023-09-22 19:25 15988
2660ccea Poul Sander 2023-09-22 19:25 15989
    @liveexample{The example below shows how JSON values are created from
2660ccea Poul Sander 2023-09-22 19:25 15990
    initializer lists.,basic_json__list_init_t}
2660ccea Poul Sander 2023-09-22 19:25 15991
2660ccea Poul Sander 2023-09-22 19:25 15992
    @sa @ref array(initializer_list_t) -- create a JSON array
2660ccea Poul Sander 2023-09-22 19:25 15993
    value from an initializer list
2660ccea Poul Sander 2023-09-22 19:25 15994
    @sa @ref object(initializer_list_t) -- create a JSON object
2660ccea Poul Sander 2023-09-22 19:25 15995
    value from an initializer list
2660ccea Poul Sander 2023-09-22 19:25 15996
2660ccea Poul Sander 2023-09-22 19:25 15997
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 15998
    */
2660ccea Poul Sander 2023-09-22 19:25 15999
    basic_json(initializer_list_t init,
2660ccea Poul Sander 2023-09-22 19:25 16000
               bool type_deduction = true,
2660ccea Poul Sander 2023-09-22 19:25 16001
               value_t manual_type = value_t::array)
2660ccea Poul Sander 2023-09-22 19:25 16002
    {
2660ccea Poul Sander 2023-09-22 19:25 16003
        // check if each element is an array with two elements whose first
2660ccea Poul Sander 2023-09-22 19:25 16004
        // element is a string
2660ccea Poul Sander 2023-09-22 19:25 16005
        bool is_an_object = std::all_of(init.begin(), init.end(),
2660ccea Poul Sander 2023-09-22 19:25 16006
                                        [](const detail::json_ref<basic_json>& element_ref)
2660ccea Poul Sander 2023-09-22 19:25 16007
        {
2660ccea Poul Sander 2023-09-22 19:25 16008
            return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
2660ccea Poul Sander 2023-09-22 19:25 16009
        });
2660ccea Poul Sander 2023-09-22 19:25 16010
2660ccea Poul Sander 2023-09-22 19:25 16011
        // adjust type if type deduction is not wanted
2660ccea Poul Sander 2023-09-22 19:25 16012
        if (not type_deduction)
2660ccea Poul Sander 2023-09-22 19:25 16013
        {
2660ccea Poul Sander 2023-09-22 19:25 16014
            // if array is wanted, do not create an object though possible
2660ccea Poul Sander 2023-09-22 19:25 16015
            if (manual_type == value_t::array)
2660ccea Poul Sander 2023-09-22 19:25 16016
            {
2660ccea Poul Sander 2023-09-22 19:25 16017
                is_an_object = false;
2660ccea Poul Sander 2023-09-22 19:25 16018
            }
2660ccea Poul Sander 2023-09-22 19:25 16019
2660ccea Poul Sander 2023-09-22 19:25 16020
            // if object is wanted but impossible, throw an exception
2660ccea Poul Sander 2023-09-22 19:25 16021
            if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object and not is_an_object))
2660ccea Poul Sander 2023-09-22 19:25 16022
            {
2660ccea Poul Sander 2023-09-22 19:25 16023
                JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
2660ccea Poul Sander 2023-09-22 19:25 16024
            }
2660ccea Poul Sander 2023-09-22 19:25 16025
        }
2660ccea Poul Sander 2023-09-22 19:25 16026
2660ccea Poul Sander 2023-09-22 19:25 16027
        if (is_an_object)
2660ccea Poul Sander 2023-09-22 19:25 16028
        {
2660ccea Poul Sander 2023-09-22 19:25 16029
            // the initializer list is a list of pairs -> create object
2660ccea Poul Sander 2023-09-22 19:25 16030
            m_type = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 16031
            m_value = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 16032
2660ccea Poul Sander 2023-09-22 19:25 16033
            std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
2660ccea Poul Sander 2023-09-22 19:25 16034
            {
2660ccea Poul Sander 2023-09-22 19:25 16035
                auto element = element_ref.moved_or_copied();
2660ccea Poul Sander 2023-09-22 19:25 16036
                m_value.object->emplace(
2660ccea Poul Sander 2023-09-22 19:25 16037
                    std::move(*((*element.m_value.array)[0].m_value.string)),
2660ccea Poul Sander 2023-09-22 19:25 16038
                    std::move((*element.m_value.array)[1]));
2660ccea Poul Sander 2023-09-22 19:25 16039
            });
2660ccea Poul Sander 2023-09-22 19:25 16040
        }
2660ccea Poul Sander 2023-09-22 19:25 16041
        else
2660ccea Poul Sander 2023-09-22 19:25 16042
        {
2660ccea Poul Sander 2023-09-22 19:25 16043
            // the initializer list describes an array -> create array
2660ccea Poul Sander 2023-09-22 19:25 16044
            m_type = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 16045
            m_value.array = create<array_t>(init.begin(), init.end());
2660ccea Poul Sander 2023-09-22 19:25 16046
        }
2660ccea Poul Sander 2023-09-22 19:25 16047
2660ccea Poul Sander 2023-09-22 19:25 16048
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 16049
    }
2660ccea Poul Sander 2023-09-22 19:25 16050
2660ccea Poul Sander 2023-09-22 19:25 16051
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16052
    @brief explicitly create an array from an initializer list
2660ccea Poul Sander 2023-09-22 19:25 16053
2660ccea Poul Sander 2023-09-22 19:25 16054
    Creates a JSON array value from a given initializer list. That is, given a
2660ccea Poul Sander 2023-09-22 19:25 16055
    list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
2660ccea Poul Sander 2023-09-22 19:25 16056
    initializer list is empty, the empty array `[]` is created.
2660ccea Poul Sander 2023-09-22 19:25 16057
2660ccea Poul Sander 2023-09-22 19:25 16058
    @note This function is only needed to express two edge cases that cannot
2660ccea Poul Sander 2023-09-22 19:25 16059
    be realized with the initializer list constructor (@ref
2660ccea Poul Sander 2023-09-22 19:25 16060
    basic_json(initializer_list_t, bool, value_t)). These cases
2660ccea Poul Sander 2023-09-22 19:25 16061
    are:
2660ccea Poul Sander 2023-09-22 19:25 16062
    1. creating an array whose elements are all pairs whose first element is a
2660ccea Poul Sander 2023-09-22 19:25 16063
    string -- in this case, the initializer list constructor would create an
2660ccea Poul Sander 2023-09-22 19:25 16064
    object, taking the first elements as keys
2660ccea Poul Sander 2023-09-22 19:25 16065
    2. creating an empty array -- passing the empty initializer list to the
2660ccea Poul Sander 2023-09-22 19:25 16066
    initializer list constructor yields an empty object
2660ccea Poul Sander 2023-09-22 19:25 16067
2660ccea Poul Sander 2023-09-22 19:25 16068
    @param[in] init  initializer list with JSON values to create an array from
2660ccea Poul Sander 2023-09-22 19:25 16069
    (optional)
2660ccea Poul Sander 2023-09-22 19:25 16070
2660ccea Poul Sander 2023-09-22 19:25 16071
    @return JSON array value
2660ccea Poul Sander 2023-09-22 19:25 16072
2660ccea Poul Sander 2023-09-22 19:25 16073
    @complexity Linear in the size of @a init.
2660ccea Poul Sander 2023-09-22 19:25 16074
2660ccea Poul Sander 2023-09-22 19:25 16075
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 16076
    changes to any JSON value.
2660ccea Poul Sander 2023-09-22 19:25 16077
2660ccea Poul Sander 2023-09-22 19:25 16078
    @liveexample{The following code shows an example for the `array`
2660ccea Poul Sander 2023-09-22 19:25 16079
    function.,array}
2660ccea Poul Sander 2023-09-22 19:25 16080
2660ccea Poul Sander 2023-09-22 19:25 16081
    @sa @ref basic_json(initializer_list_t, bool, value_t) --
2660ccea Poul Sander 2023-09-22 19:25 16082
    create a JSON value from an initializer list
2660ccea Poul Sander 2023-09-22 19:25 16083
    @sa @ref object(initializer_list_t) -- create a JSON object
2660ccea Poul Sander 2023-09-22 19:25 16084
    value from an initializer list
2660ccea Poul Sander 2023-09-22 19:25 16085
2660ccea Poul Sander 2023-09-22 19:25 16086
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16087
    */
2660ccea Poul Sander 2023-09-22 19:25 16088
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 16089
    static basic_json array(initializer_list_t init = {})
2660ccea Poul Sander 2023-09-22 19:25 16090
    {
2660ccea Poul Sander 2023-09-22 19:25 16091
        return basic_json(init, false, value_t::array);
2660ccea Poul Sander 2023-09-22 19:25 16092
    }
2660ccea Poul Sander 2023-09-22 19:25 16093
2660ccea Poul Sander 2023-09-22 19:25 16094
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16095
    @brief explicitly create an object from an initializer list
2660ccea Poul Sander 2023-09-22 19:25 16096
2660ccea Poul Sander 2023-09-22 19:25 16097
    Creates a JSON object value from a given initializer list. The initializer
2660ccea Poul Sander 2023-09-22 19:25 16098
    lists elements must be pairs, and their first elements must be strings. If
2660ccea Poul Sander 2023-09-22 19:25 16099
    the initializer list is empty, the empty object `{}` is created.
2660ccea Poul Sander 2023-09-22 19:25 16100
2660ccea Poul Sander 2023-09-22 19:25 16101
    @note This function is only added for symmetry reasons. In contrast to the
2660ccea Poul Sander 2023-09-22 19:25 16102
    related function @ref array(initializer_list_t), there are
2660ccea Poul Sander 2023-09-22 19:25 16103
    no cases which can only be expressed by this function. That is, any
2660ccea Poul Sander 2023-09-22 19:25 16104
    initializer list @a init can also be passed to the initializer list
2660ccea Poul Sander 2023-09-22 19:25 16105
    constructor @ref basic_json(initializer_list_t, bool, value_t).
2660ccea Poul Sander 2023-09-22 19:25 16106
2660ccea Poul Sander 2023-09-22 19:25 16107
    @param[in] init  initializer list to create an object from (optional)
2660ccea Poul Sander 2023-09-22 19:25 16108
2660ccea Poul Sander 2023-09-22 19:25 16109
    @return JSON object value
2660ccea Poul Sander 2023-09-22 19:25 16110
2660ccea Poul Sander 2023-09-22 19:25 16111
    @throw type_error.301 if @a init is not a list of pairs whose first
2660ccea Poul Sander 2023-09-22 19:25 16112
    elements are strings. In this case, no object can be created. When such a
2660ccea Poul Sander 2023-09-22 19:25 16113
    value is passed to @ref basic_json(initializer_list_t, bool, value_t),
2660ccea Poul Sander 2023-09-22 19:25 16114
    an array would have been created from the passed initializer list @a init.
2660ccea Poul Sander 2023-09-22 19:25 16115
    See example below.
2660ccea Poul Sander 2023-09-22 19:25 16116
2660ccea Poul Sander 2023-09-22 19:25 16117
    @complexity Linear in the size of @a init.
2660ccea Poul Sander 2023-09-22 19:25 16118
2660ccea Poul Sander 2023-09-22 19:25 16119
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 16120
    changes to any JSON value.
2660ccea Poul Sander 2023-09-22 19:25 16121
2660ccea Poul Sander 2023-09-22 19:25 16122
    @liveexample{The following code shows an example for the `object`
2660ccea Poul Sander 2023-09-22 19:25 16123
    function.,object}
2660ccea Poul Sander 2023-09-22 19:25 16124
2660ccea Poul Sander 2023-09-22 19:25 16125
    @sa @ref basic_json(initializer_list_t, bool, value_t) --
2660ccea Poul Sander 2023-09-22 19:25 16126
    create a JSON value from an initializer list
2660ccea Poul Sander 2023-09-22 19:25 16127
    @sa @ref array(initializer_list_t) -- create a JSON array
2660ccea Poul Sander 2023-09-22 19:25 16128
    value from an initializer list
2660ccea Poul Sander 2023-09-22 19:25 16129
2660ccea Poul Sander 2023-09-22 19:25 16130
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16131
    */
2660ccea Poul Sander 2023-09-22 19:25 16132
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 16133
    static basic_json object(initializer_list_t init = {})
2660ccea Poul Sander 2023-09-22 19:25 16134
    {
2660ccea Poul Sander 2023-09-22 19:25 16135
        return basic_json(init, false, value_t::object);
2660ccea Poul Sander 2023-09-22 19:25 16136
    }
2660ccea Poul Sander 2023-09-22 19:25 16137
2660ccea Poul Sander 2023-09-22 19:25 16138
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16139
    @brief construct an array with count copies of given value
2660ccea Poul Sander 2023-09-22 19:25 16140
2660ccea Poul Sander 2023-09-22 19:25 16141
    Constructs a JSON array value by creating @a cnt copies of a passed value.
2660ccea Poul Sander 2023-09-22 19:25 16142
    In case @a cnt is `0`, an empty array is created.
2660ccea Poul Sander 2023-09-22 19:25 16143
2660ccea Poul Sander 2023-09-22 19:25 16144
    @param[in] cnt  the number of JSON copies of @a val to create
2660ccea Poul Sander 2023-09-22 19:25 16145
    @param[in] val  the JSON value to copy
2660ccea Poul Sander 2023-09-22 19:25 16146
2660ccea Poul Sander 2023-09-22 19:25 16147
    @post `std::distance(begin(),end()) == cnt` holds.
2660ccea Poul Sander 2023-09-22 19:25 16148
2660ccea Poul Sander 2023-09-22 19:25 16149
    @complexity Linear in @a cnt.
2660ccea Poul Sander 2023-09-22 19:25 16150
2660ccea Poul Sander 2023-09-22 19:25 16151
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 16152
    changes to any JSON value.
2660ccea Poul Sander 2023-09-22 19:25 16153
2660ccea Poul Sander 2023-09-22 19:25 16154
    @liveexample{The following code shows examples for the @ref
2660ccea Poul Sander 2023-09-22 19:25 16155
    basic_json(size_type\, const basic_json&)
2660ccea Poul Sander 2023-09-22 19:25 16156
    constructor.,basic_json__size_type_basic_json}
2660ccea Poul Sander 2023-09-22 19:25 16157
2660ccea Poul Sander 2023-09-22 19:25 16158
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16159
    */
2660ccea Poul Sander 2023-09-22 19:25 16160
    basic_json(size_type cnt, const basic_json& val)
2660ccea Poul Sander 2023-09-22 19:25 16161
        : m_type(value_t::array)
2660ccea Poul Sander 2023-09-22 19:25 16162
    {
2660ccea Poul Sander 2023-09-22 19:25 16163
        m_value.array = create<array_t>(cnt, val);
2660ccea Poul Sander 2023-09-22 19:25 16164
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 16165
    }
2660ccea Poul Sander 2023-09-22 19:25 16166
2660ccea Poul Sander 2023-09-22 19:25 16167
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16168
    @brief construct a JSON container given an iterator range
2660ccea Poul Sander 2023-09-22 19:25 16169
2660ccea Poul Sander 2023-09-22 19:25 16170
    Constructs the JSON value with the contents of the range `[first, last)`.
2660ccea Poul Sander 2023-09-22 19:25 16171
    The semantics depends on the different types a JSON value can have:
2660ccea Poul Sander 2023-09-22 19:25 16172
    - In case of a null type, invalid_iterator.206 is thrown.
2660ccea Poul Sander 2023-09-22 19:25 16173
    - In case of other primitive types (number, boolean, or string), @a first
2660ccea Poul Sander 2023-09-22 19:25 16174
      must be `begin()` and @a last must be `end()`. In this case, the value is
2660ccea Poul Sander 2023-09-22 19:25 16175
      copied. Otherwise, invalid_iterator.204 is thrown.
2660ccea Poul Sander 2023-09-22 19:25 16176
    - In case of structured types (array, object), the constructor behaves as
2660ccea Poul Sander 2023-09-22 19:25 16177
      similar versions for `std::vector` or `std::map`; that is, a JSON array
2660ccea Poul Sander 2023-09-22 19:25 16178
      or object is constructed from the values in the range.
2660ccea Poul Sander 2023-09-22 19:25 16179
2660ccea Poul Sander 2023-09-22 19:25 16180
    @tparam InputIT an input iterator type (@ref iterator or @ref
2660ccea Poul Sander 2023-09-22 19:25 16181
    const_iterator)
2660ccea Poul Sander 2023-09-22 19:25 16182
2660ccea Poul Sander 2023-09-22 19:25 16183
    @param[in] first begin of the range to copy from (included)
2660ccea Poul Sander 2023-09-22 19:25 16184
    @param[in] last end of the range to copy from (excluded)
2660ccea Poul Sander 2023-09-22 19:25 16185
2660ccea Poul Sander 2023-09-22 19:25 16186
    @pre Iterators @a first and @a last must be initialized. **This
2660ccea Poul Sander 2023-09-22 19:25 16187
         precondition is enforced with an assertion (see warning).** If
2660ccea Poul Sander 2023-09-22 19:25 16188
         assertions are switched off, a violation of this precondition yields
2660ccea Poul Sander 2023-09-22 19:25 16189
         undefined behavior.
2660ccea Poul Sander 2023-09-22 19:25 16190
2660ccea Poul Sander 2023-09-22 19:25 16191
    @pre Range `[first, last)` is valid. Usually, this precondition cannot be
2660ccea Poul Sander 2023-09-22 19:25 16192
         checked efficiently. Only certain edge cases are detected; see the
2660ccea Poul Sander 2023-09-22 19:25 16193
         description of the exceptions below. A violation of this precondition
2660ccea Poul Sander 2023-09-22 19:25 16194
         yields undefined behavior.
2660ccea Poul Sander 2023-09-22 19:25 16195
2660ccea Poul Sander 2023-09-22 19:25 16196
    @warning A precondition is enforced with a runtime assertion that will
2660ccea Poul Sander 2023-09-22 19:25 16197
             result in calling `std::abort` if this precondition is not met.
2660ccea Poul Sander 2023-09-22 19:25 16198
             Assertions can be disabled by defining `NDEBUG` at compile time.
2660ccea Poul Sander 2023-09-22 19:25 16199
             See https://en.cppreference.com/w/cpp/error/assert for more
2660ccea Poul Sander 2023-09-22 19:25 16200
             information.
2660ccea Poul Sander 2023-09-22 19:25 16201
2660ccea Poul Sander 2023-09-22 19:25 16202
    @throw invalid_iterator.201 if iterators @a first and @a last are not
2660ccea Poul Sander 2023-09-22 19:25 16203
    compatible (i.e., do not belong to the same JSON value). In this case,
2660ccea Poul Sander 2023-09-22 19:25 16204
    the range `[first, last)` is undefined.
2660ccea Poul Sander 2023-09-22 19:25 16205
    @throw invalid_iterator.204 if iterators @a first and @a last belong to a
2660ccea Poul Sander 2023-09-22 19:25 16206
    primitive type (number, boolean, or string), but @a first does not point
2660ccea Poul Sander 2023-09-22 19:25 16207
    to the first element any more. In this case, the range `[first, last)` is
2660ccea Poul Sander 2023-09-22 19:25 16208
    undefined. See example code below.
2660ccea Poul Sander 2023-09-22 19:25 16209
    @throw invalid_iterator.206 if iterators @a first and @a last belong to a
2660ccea Poul Sander 2023-09-22 19:25 16210
    null value. In this case, the range `[first, last)` is undefined.
2660ccea Poul Sander 2023-09-22 19:25 16211
2660ccea Poul Sander 2023-09-22 19:25 16212
    @complexity Linear in distance between @a first and @a last.
2660ccea Poul Sander 2023-09-22 19:25 16213
2660ccea Poul Sander 2023-09-22 19:25 16214
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 16215
    changes to any JSON value.
2660ccea Poul Sander 2023-09-22 19:25 16216
2660ccea Poul Sander 2023-09-22 19:25 16217
    @liveexample{The example below shows several ways to create JSON values by
2660ccea Poul Sander 2023-09-22 19:25 16218
    specifying a subrange with iterators.,basic_json__InputIt_InputIt}
2660ccea Poul Sander 2023-09-22 19:25 16219
2660ccea Poul Sander 2023-09-22 19:25 16220
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16221
    */
2660ccea Poul Sander 2023-09-22 19:25 16222
    template<class InputIT, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 16223
                 std::is_same<InputIT, typename basic_json_t::iterator>::value or
2660ccea Poul Sander 2023-09-22 19:25 16224
                 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 16225
    basic_json(InputIT first, InputIT last)
2660ccea Poul Sander 2023-09-22 19:25 16226
    {
2660ccea Poul Sander 2023-09-22 19:25 16227
        assert(first.m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 16228
        assert(last.m_object != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 16229
2660ccea Poul Sander 2023-09-22 19:25 16230
        // make sure iterator fits the current value
2660ccea Poul Sander 2023-09-22 19:25 16231
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
2660ccea Poul Sander 2023-09-22 19:25 16232
        {
2660ccea Poul Sander 2023-09-22 19:25 16233
            JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
2660ccea Poul Sander 2023-09-22 19:25 16234
        }
2660ccea Poul Sander 2023-09-22 19:25 16235
2660ccea Poul Sander 2023-09-22 19:25 16236
        // copy type from first iterator
2660ccea Poul Sander 2023-09-22 19:25 16237
        m_type = first.m_object->m_type;
2660ccea Poul Sander 2023-09-22 19:25 16238
2660ccea Poul Sander 2023-09-22 19:25 16239
        // check if iterator range is complete for primitive values
2660ccea Poul Sander 2023-09-22 19:25 16240
        switch (m_type)
2660ccea Poul Sander 2023-09-22 19:25 16241
        {
2660ccea Poul Sander 2023-09-22 19:25 16242
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 16243
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 16244
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 16245
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 16246
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 16247
            {
2660ccea Poul Sander 2023-09-22 19:25 16248
                if (JSON_HEDLEY_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
2660ccea Poul Sander 2023-09-22 19:25 16249
                                         or not last.m_it.primitive_iterator.is_end()))
2660ccea Poul Sander 2023-09-22 19:25 16250
                {
2660ccea Poul Sander 2023-09-22 19:25 16251
                    JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
2660ccea Poul Sander 2023-09-22 19:25 16252
                }
2660ccea Poul Sander 2023-09-22 19:25 16253
                break;
2660ccea Poul Sander 2023-09-22 19:25 16254
            }
2660ccea Poul Sander 2023-09-22 19:25 16255
2660ccea Poul Sander 2023-09-22 19:25 16256
            default:
2660ccea Poul Sander 2023-09-22 19:25 16257
                break;
2660ccea Poul Sander 2023-09-22 19:25 16258
        }
2660ccea Poul Sander 2023-09-22 19:25 16259
2660ccea Poul Sander 2023-09-22 19:25 16260
        switch (m_type)
2660ccea Poul Sander 2023-09-22 19:25 16261
        {
2660ccea Poul Sander 2023-09-22 19:25 16262
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 16263
            {
2660ccea Poul Sander 2023-09-22 19:25 16264
                m_value.number_integer = first.m_object->m_value.number_integer;
2660ccea Poul Sander 2023-09-22 19:25 16265
                break;
2660ccea Poul Sander 2023-09-22 19:25 16266
            }
2660ccea Poul Sander 2023-09-22 19:25 16267
2660ccea Poul Sander 2023-09-22 19:25 16268
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 16269
            {
2660ccea Poul Sander 2023-09-22 19:25 16270
                m_value.number_unsigned = first.m_object->m_value.number_unsigned;
2660ccea Poul Sander 2023-09-22 19:25 16271
                break;
2660ccea Poul Sander 2023-09-22 19:25 16272
            }
2660ccea Poul Sander 2023-09-22 19:25 16273
2660ccea Poul Sander 2023-09-22 19:25 16274
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 16275
            {
2660ccea Poul Sander 2023-09-22 19:25 16276
                m_value.number_float = first.m_object->m_value.number_float;
2660ccea Poul Sander 2023-09-22 19:25 16277
                break;
2660ccea Poul Sander 2023-09-22 19:25 16278
            }
2660ccea Poul Sander 2023-09-22 19:25 16279
2660ccea Poul Sander 2023-09-22 19:25 16280
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 16281
            {
2660ccea Poul Sander 2023-09-22 19:25 16282
                m_value.boolean = first.m_object->m_value.boolean;
2660ccea Poul Sander 2023-09-22 19:25 16283
                break;
2660ccea Poul Sander 2023-09-22 19:25 16284
            }
2660ccea Poul Sander 2023-09-22 19:25 16285
2660ccea Poul Sander 2023-09-22 19:25 16286
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 16287
            {
2660ccea Poul Sander 2023-09-22 19:25 16288
                m_value = *first.m_object->m_value.string;
2660ccea Poul Sander 2023-09-22 19:25 16289
                break;
2660ccea Poul Sander 2023-09-22 19:25 16290
            }
2660ccea Poul Sander 2023-09-22 19:25 16291
2660ccea Poul Sander 2023-09-22 19:25 16292
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 16293
            {
2660ccea Poul Sander 2023-09-22 19:25 16294
                m_value.object = create<object_t>(first.m_it.object_iterator,
2660ccea Poul Sander 2023-09-22 19:25 16295
                                                  last.m_it.object_iterator);
2660ccea Poul Sander 2023-09-22 19:25 16296
                break;
2660ccea Poul Sander 2023-09-22 19:25 16297
            }
2660ccea Poul Sander 2023-09-22 19:25 16298
2660ccea Poul Sander 2023-09-22 19:25 16299
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 16300
            {
2660ccea Poul Sander 2023-09-22 19:25 16301
                m_value.array = create<array_t>(first.m_it.array_iterator,
2660ccea Poul Sander 2023-09-22 19:25 16302
                                                last.m_it.array_iterator);
2660ccea Poul Sander 2023-09-22 19:25 16303
                break;
2660ccea Poul Sander 2023-09-22 19:25 16304
            }
2660ccea Poul Sander 2023-09-22 19:25 16305
2660ccea Poul Sander 2023-09-22 19:25 16306
            default:
2660ccea Poul Sander 2023-09-22 19:25 16307
                JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
2660ccea Poul Sander 2023-09-22 19:25 16308
                                                    std::string(first.m_object->type_name())));
2660ccea Poul Sander 2023-09-22 19:25 16309
        }
2660ccea Poul Sander 2023-09-22 19:25 16310
2660ccea Poul Sander 2023-09-22 19:25 16311
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 16312
    }
2660ccea Poul Sander 2023-09-22 19:25 16313
2660ccea Poul Sander 2023-09-22 19:25 16314
2660ccea Poul Sander 2023-09-22 19:25 16315
    ///////////////////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 16316
    // other constructors and destructor //
2660ccea Poul Sander 2023-09-22 19:25 16317
    ///////////////////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 16318
2660ccea Poul Sander 2023-09-22 19:25 16319
    /// @private
2660ccea Poul Sander 2023-09-22 19:25 16320
    basic_json(const detail::json_ref<basic_json>& ref)
2660ccea Poul Sander 2023-09-22 19:25 16321
        : basic_json(ref.moved_or_copied())
2660ccea Poul Sander 2023-09-22 19:25 16322
    {}
2660ccea Poul Sander 2023-09-22 19:25 16323
2660ccea Poul Sander 2023-09-22 19:25 16324
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16325
    @brief copy constructor
2660ccea Poul Sander 2023-09-22 19:25 16326
2660ccea Poul Sander 2023-09-22 19:25 16327
    Creates a copy of a given JSON value.
2660ccea Poul Sander 2023-09-22 19:25 16328
2660ccea Poul Sander 2023-09-22 19:25 16329
    @param[in] other  the JSON value to copy
2660ccea Poul Sander 2023-09-22 19:25 16330
2660ccea Poul Sander 2023-09-22 19:25 16331
    @post `*this == other`
2660ccea Poul Sander 2023-09-22 19:25 16332
2660ccea Poul Sander 2023-09-22 19:25 16333
    @complexity Linear in the size of @a other.
2660ccea Poul Sander 2023-09-22 19:25 16334
2660ccea Poul Sander 2023-09-22 19:25 16335
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 16336
    changes to any JSON value.
2660ccea Poul Sander 2023-09-22 19:25 16337
2660ccea Poul Sander 2023-09-22 19:25 16338
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 16339
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2660ccea Poul Sander 2023-09-22 19:25 16340
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 16341
    - The complexity is linear.
2660ccea Poul Sander 2023-09-22 19:25 16342
    - As postcondition, it holds: `other == basic_json(other)`.
2660ccea Poul Sander 2023-09-22 19:25 16343
2660ccea Poul Sander 2023-09-22 19:25 16344
    @liveexample{The following code shows an example for the copy
2660ccea Poul Sander 2023-09-22 19:25 16345
    constructor.,basic_json__basic_json}
2660ccea Poul Sander 2023-09-22 19:25 16346
2660ccea Poul Sander 2023-09-22 19:25 16347
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16348
    */
2660ccea Poul Sander 2023-09-22 19:25 16349
    basic_json(const basic_json& other)
2660ccea Poul Sander 2023-09-22 19:25 16350
        : m_type(other.m_type)
2660ccea Poul Sander 2023-09-22 19:25 16351
    {
2660ccea Poul Sander 2023-09-22 19:25 16352
        // check of passed value is valid
2660ccea Poul Sander 2023-09-22 19:25 16353
        other.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 16354
2660ccea Poul Sander 2023-09-22 19:25 16355
        switch (m_type)
2660ccea Poul Sander 2023-09-22 19:25 16356
        {
2660ccea Poul Sander 2023-09-22 19:25 16357
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 16358
            {
2660ccea Poul Sander 2023-09-22 19:25 16359
                m_value = *other.m_value.object;
2660ccea Poul Sander 2023-09-22 19:25 16360
                break;
2660ccea Poul Sander 2023-09-22 19:25 16361
            }
2660ccea Poul Sander 2023-09-22 19:25 16362
2660ccea Poul Sander 2023-09-22 19:25 16363
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 16364
            {
2660ccea Poul Sander 2023-09-22 19:25 16365
                m_value = *other.m_value.array;
2660ccea Poul Sander 2023-09-22 19:25 16366
                break;
2660ccea Poul Sander 2023-09-22 19:25 16367
            }
2660ccea Poul Sander 2023-09-22 19:25 16368
2660ccea Poul Sander 2023-09-22 19:25 16369
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 16370
            {
2660ccea Poul Sander 2023-09-22 19:25 16371
                m_value = *other.m_value.string;
2660ccea Poul Sander 2023-09-22 19:25 16372
                break;
2660ccea Poul Sander 2023-09-22 19:25 16373
            }
2660ccea Poul Sander 2023-09-22 19:25 16374
2660ccea Poul Sander 2023-09-22 19:25 16375
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 16376
            {
2660ccea Poul Sander 2023-09-22 19:25 16377
                m_value = other.m_value.boolean;
2660ccea Poul Sander 2023-09-22 19:25 16378
                break;
2660ccea Poul Sander 2023-09-22 19:25 16379
            }
2660ccea Poul Sander 2023-09-22 19:25 16380
2660ccea Poul Sander 2023-09-22 19:25 16381
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 16382
            {
2660ccea Poul Sander 2023-09-22 19:25 16383
                m_value = other.m_value.number_integer;
2660ccea Poul Sander 2023-09-22 19:25 16384
                break;
2660ccea Poul Sander 2023-09-22 19:25 16385
            }
2660ccea Poul Sander 2023-09-22 19:25 16386
2660ccea Poul Sander 2023-09-22 19:25 16387
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 16388
            {
2660ccea Poul Sander 2023-09-22 19:25 16389
                m_value = other.m_value.number_unsigned;
2660ccea Poul Sander 2023-09-22 19:25 16390
                break;
2660ccea Poul Sander 2023-09-22 19:25 16391
            }
2660ccea Poul Sander 2023-09-22 19:25 16392
2660ccea Poul Sander 2023-09-22 19:25 16393
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 16394
            {
2660ccea Poul Sander 2023-09-22 19:25 16395
                m_value = other.m_value.number_float;
2660ccea Poul Sander 2023-09-22 19:25 16396
                break;
2660ccea Poul Sander 2023-09-22 19:25 16397
            }
2660ccea Poul Sander 2023-09-22 19:25 16398
2660ccea Poul Sander 2023-09-22 19:25 16399
            default:
2660ccea Poul Sander 2023-09-22 19:25 16400
                break;
2660ccea Poul Sander 2023-09-22 19:25 16401
        }
2660ccea Poul Sander 2023-09-22 19:25 16402
2660ccea Poul Sander 2023-09-22 19:25 16403
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 16404
    }
2660ccea Poul Sander 2023-09-22 19:25 16405
2660ccea Poul Sander 2023-09-22 19:25 16406
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16407
    @brief move constructor
2660ccea Poul Sander 2023-09-22 19:25 16408
2660ccea Poul Sander 2023-09-22 19:25 16409
    Move constructor. Constructs a JSON value with the contents of the given
2660ccea Poul Sander 2023-09-22 19:25 16410
    value @a other using move semantics. It "steals" the resources from @a
2660ccea Poul Sander 2023-09-22 19:25 16411
    other and leaves it as JSON null value.
2660ccea Poul Sander 2023-09-22 19:25 16412
2660ccea Poul Sander 2023-09-22 19:25 16413
    @param[in,out] other  value to move to this object
2660ccea Poul Sander 2023-09-22 19:25 16414
2660ccea Poul Sander 2023-09-22 19:25 16415
    @post `*this` has the same value as @a other before the call.
2660ccea Poul Sander 2023-09-22 19:25 16416
    @post @a other is a JSON null value.
2660ccea Poul Sander 2023-09-22 19:25 16417
2660ccea Poul Sander 2023-09-22 19:25 16418
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16419
2660ccea Poul Sander 2023-09-22 19:25 16420
    @exceptionsafety No-throw guarantee: this constructor never throws
2660ccea Poul Sander 2023-09-22 19:25 16421
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16422
2660ccea Poul Sander 2023-09-22 19:25 16423
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 16424
    [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
2660ccea Poul Sander 2023-09-22 19:25 16425
    requirements.
2660ccea Poul Sander 2023-09-22 19:25 16426
2660ccea Poul Sander 2023-09-22 19:25 16427
    @liveexample{The code below shows the move constructor explicitly called
2660ccea Poul Sander 2023-09-22 19:25 16428
    via std::move.,basic_json__moveconstructor}
2660ccea Poul Sander 2023-09-22 19:25 16429
2660ccea Poul Sander 2023-09-22 19:25 16430
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16431
    */
2660ccea Poul Sander 2023-09-22 19:25 16432
    basic_json(basic_json&& other) noexcept
2660ccea Poul Sander 2023-09-22 19:25 16433
        : m_type(std::move(other.m_type)),
2660ccea Poul Sander 2023-09-22 19:25 16434
          m_value(std::move(other.m_value))
2660ccea Poul Sander 2023-09-22 19:25 16435
    {
2660ccea Poul Sander 2023-09-22 19:25 16436
        // check that passed value is valid
2660ccea Poul Sander 2023-09-22 19:25 16437
        other.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 16438
2660ccea Poul Sander 2023-09-22 19:25 16439
        // invalidate payload
2660ccea Poul Sander 2023-09-22 19:25 16440
        other.m_type = value_t::null;
2660ccea Poul Sander 2023-09-22 19:25 16441
        other.m_value = {};
2660ccea Poul Sander 2023-09-22 19:25 16442
2660ccea Poul Sander 2023-09-22 19:25 16443
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 16444
    }
2660ccea Poul Sander 2023-09-22 19:25 16445
2660ccea Poul Sander 2023-09-22 19:25 16446
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16447
    @brief copy assignment
2660ccea Poul Sander 2023-09-22 19:25 16448
2660ccea Poul Sander 2023-09-22 19:25 16449
    Copy assignment operator. Copies a JSON value via the "copy and swap"
2660ccea Poul Sander 2023-09-22 19:25 16450
    strategy: It is expressed in terms of the copy constructor, destructor,
2660ccea Poul Sander 2023-09-22 19:25 16451
    and the `swap()` member function.
2660ccea Poul Sander 2023-09-22 19:25 16452
2660ccea Poul Sander 2023-09-22 19:25 16453
    @param[in] other  value to copy from
2660ccea Poul Sander 2023-09-22 19:25 16454
2660ccea Poul Sander 2023-09-22 19:25 16455
    @complexity Linear.
2660ccea Poul Sander 2023-09-22 19:25 16456
2660ccea Poul Sander 2023-09-22 19:25 16457
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 16458
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2660ccea Poul Sander 2023-09-22 19:25 16459
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 16460
    - The complexity is linear.
2660ccea Poul Sander 2023-09-22 19:25 16461
2660ccea Poul Sander 2023-09-22 19:25 16462
    @liveexample{The code below shows and example for the copy assignment. It
2660ccea Poul Sander 2023-09-22 19:25 16463
    creates a copy of value `a` which is then swapped with `b`. Finally\, the
2660ccea Poul Sander 2023-09-22 19:25 16464
    copy of `a` (which is the null value after the swap) is
2660ccea Poul Sander 2023-09-22 19:25 16465
    destroyed.,basic_json__copyassignment}
2660ccea Poul Sander 2023-09-22 19:25 16466
2660ccea Poul Sander 2023-09-22 19:25 16467
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16468
    */
2660ccea Poul Sander 2023-09-22 19:25 16469
    basic_json& operator=(basic_json other) noexcept (
2660ccea Poul Sander 2023-09-22 19:25 16470
        std::is_nothrow_move_constructible<value_t>::value and
2660ccea Poul Sander 2023-09-22 19:25 16471
        std::is_nothrow_move_assignable<value_t>::value and
2660ccea Poul Sander 2023-09-22 19:25 16472
        std::is_nothrow_move_constructible<json_value>::value and
2660ccea Poul Sander 2023-09-22 19:25 16473
        std::is_nothrow_move_assignable<json_value>::value
2660ccea Poul Sander 2023-09-22 19:25 16474
    )
2660ccea Poul Sander 2023-09-22 19:25 16475
    {
2660ccea Poul Sander 2023-09-22 19:25 16476
        // check that passed value is valid
2660ccea Poul Sander 2023-09-22 19:25 16477
        other.assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 16478
2660ccea Poul Sander 2023-09-22 19:25 16479
        using std::swap;
2660ccea Poul Sander 2023-09-22 19:25 16480
        swap(m_type, other.m_type);
2660ccea Poul Sander 2023-09-22 19:25 16481
        swap(m_value, other.m_value);
2660ccea Poul Sander 2023-09-22 19:25 16482
2660ccea Poul Sander 2023-09-22 19:25 16483
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 16484
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 16485
    }
2660ccea Poul Sander 2023-09-22 19:25 16486
2660ccea Poul Sander 2023-09-22 19:25 16487
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16488
    @brief destructor
2660ccea Poul Sander 2023-09-22 19:25 16489
2660ccea Poul Sander 2023-09-22 19:25 16490
    Destroys the JSON value and frees all allocated memory.
2660ccea Poul Sander 2023-09-22 19:25 16491
2660ccea Poul Sander 2023-09-22 19:25 16492
    @complexity Linear.
2660ccea Poul Sander 2023-09-22 19:25 16493
2660ccea Poul Sander 2023-09-22 19:25 16494
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 16495
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2660ccea Poul Sander 2023-09-22 19:25 16496
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 16497
    - The complexity is linear.
2660ccea Poul Sander 2023-09-22 19:25 16498
    - All stored elements are destroyed and all memory is freed.
2660ccea Poul Sander 2023-09-22 19:25 16499
2660ccea Poul Sander 2023-09-22 19:25 16500
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16501
    */
2660ccea Poul Sander 2023-09-22 19:25 16502
    ~basic_json() noexcept
2660ccea Poul Sander 2023-09-22 19:25 16503
    {
2660ccea Poul Sander 2023-09-22 19:25 16504
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 16505
        m_value.destroy(m_type);
2660ccea Poul Sander 2023-09-22 19:25 16506
    }
2660ccea Poul Sander 2023-09-22 19:25 16507
2660ccea Poul Sander 2023-09-22 19:25 16508
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 16509
2660ccea Poul Sander 2023-09-22 19:25 16510
  public:
2660ccea Poul Sander 2023-09-22 19:25 16511
    ///////////////////////
2660ccea Poul Sander 2023-09-22 19:25 16512
    // object inspection //
2660ccea Poul Sander 2023-09-22 19:25 16513
    ///////////////////////
2660ccea Poul Sander 2023-09-22 19:25 16514
2660ccea Poul Sander 2023-09-22 19:25 16515
    /// @name object inspection
2660ccea Poul Sander 2023-09-22 19:25 16516
    /// Functions to inspect the type of a JSON value.
2660ccea Poul Sander 2023-09-22 19:25 16517
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 16518
2660ccea Poul Sander 2023-09-22 19:25 16519
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16520
    @brief serialization
2660ccea Poul Sander 2023-09-22 19:25 16521
2660ccea Poul Sander 2023-09-22 19:25 16522
    Serialization function for JSON values. The function tries to mimic
2660ccea Poul Sander 2023-09-22 19:25 16523
    Python's `json.dumps()` function, and currently supports its @a indent
2660ccea Poul Sander 2023-09-22 19:25 16524
    and @a ensure_ascii parameters.
2660ccea Poul Sander 2023-09-22 19:25 16525
2660ccea Poul Sander 2023-09-22 19:25 16526
    @param[in] indent If indent is nonnegative, then array elements and object
2660ccea Poul Sander 2023-09-22 19:25 16527
    members will be pretty-printed with that indent level. An indent level of
2660ccea Poul Sander 2023-09-22 19:25 16528
    `0` will only insert newlines. `-1` (the default) selects the most compact
2660ccea Poul Sander 2023-09-22 19:25 16529
    representation.
2660ccea Poul Sander 2023-09-22 19:25 16530
    @param[in] indent_char The character to use for indentation if @a indent is
2660ccea Poul Sander 2023-09-22 19:25 16531
    greater than `0`. The default is ` ` (space).
2660ccea Poul Sander 2023-09-22 19:25 16532
    @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
2660ccea Poul Sander 2023-09-22 19:25 16533
    in the output are escaped with `\uXXXX` sequences, and the result consists
2660ccea Poul Sander 2023-09-22 19:25 16534
    of ASCII characters only.
2660ccea Poul Sander 2023-09-22 19:25 16535
    @param[in] error_handler  how to react on decoding errors; there are three
2660ccea Poul Sander 2023-09-22 19:25 16536
    possible values: `strict` (throws and exception in case a decoding error
2660ccea Poul Sander 2023-09-22 19:25 16537
    occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
2660ccea Poul Sander 2023-09-22 19:25 16538
    and `ignore` (ignore invalid UTF-8 sequences during serialization).
2660ccea Poul Sander 2023-09-22 19:25 16539
2660ccea Poul Sander 2023-09-22 19:25 16540
    @return string containing the serialization of the JSON value
2660ccea Poul Sander 2023-09-22 19:25 16541
2660ccea Poul Sander 2023-09-22 19:25 16542
    @throw type_error.316 if a string stored inside the JSON value is not
2660ccea Poul Sander 2023-09-22 19:25 16543
                          UTF-8 encoded
2660ccea Poul Sander 2023-09-22 19:25 16544
2660ccea Poul Sander 2023-09-22 19:25 16545
    @complexity Linear.
2660ccea Poul Sander 2023-09-22 19:25 16546
2660ccea Poul Sander 2023-09-22 19:25 16547
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 16548
    changes in the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 16549
2660ccea Poul Sander 2023-09-22 19:25 16550
    @liveexample{The following example shows the effect of different @a indent\,
2660ccea Poul Sander 2023-09-22 19:25 16551
    @a indent_char\, and @a ensure_ascii parameters to the result of the
2660ccea Poul Sander 2023-09-22 19:25 16552
    serialization.,dump}
2660ccea Poul Sander 2023-09-22 19:25 16553
2660ccea Poul Sander 2023-09-22 19:25 16554
    @see https://docs.python.org/2/library/json.html#json.dump
2660ccea Poul Sander 2023-09-22 19:25 16555
2660ccea Poul Sander 2023-09-22 19:25 16556
    @since version 1.0.0; indentation character @a indent_char, option
2660ccea Poul Sander 2023-09-22 19:25 16557
           @a ensure_ascii and exceptions added in version 3.0.0; error
2660ccea Poul Sander 2023-09-22 19:25 16558
           handlers added in version 3.4.0.
2660ccea Poul Sander 2023-09-22 19:25 16559
    */
2660ccea Poul Sander 2023-09-22 19:25 16560
    string_t dump(const int indent = -1,
2660ccea Poul Sander 2023-09-22 19:25 16561
                  const char indent_char = ' ',
2660ccea Poul Sander 2023-09-22 19:25 16562
                  const bool ensure_ascii = false,
2660ccea Poul Sander 2023-09-22 19:25 16563
                  const error_handler_t error_handler = error_handler_t::strict) const
2660ccea Poul Sander 2023-09-22 19:25 16564
    {
2660ccea Poul Sander 2023-09-22 19:25 16565
        string_t result;
2660ccea Poul Sander 2023-09-22 19:25 16566
        serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
2660ccea Poul Sander 2023-09-22 19:25 16567
2660ccea Poul Sander 2023-09-22 19:25 16568
        if (indent >= 0)
2660ccea Poul Sander 2023-09-22 19:25 16569
        {
2660ccea Poul Sander 2023-09-22 19:25 16570
            s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
2660ccea Poul Sander 2023-09-22 19:25 16571
        }
2660ccea Poul Sander 2023-09-22 19:25 16572
        else
2660ccea Poul Sander 2023-09-22 19:25 16573
        {
2660ccea Poul Sander 2023-09-22 19:25 16574
            s.dump(*this, false, ensure_ascii, 0);
2660ccea Poul Sander 2023-09-22 19:25 16575
        }
2660ccea Poul Sander 2023-09-22 19:25 16576
2660ccea Poul Sander 2023-09-22 19:25 16577
        return result;
2660ccea Poul Sander 2023-09-22 19:25 16578
    }
2660ccea Poul Sander 2023-09-22 19:25 16579
2660ccea Poul Sander 2023-09-22 19:25 16580
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16581
    @brief return the type of the JSON value (explicit)
2660ccea Poul Sander 2023-09-22 19:25 16582
2660ccea Poul Sander 2023-09-22 19:25 16583
    Return the type of the JSON value as a value from the @ref value_t
2660ccea Poul Sander 2023-09-22 19:25 16584
    enumeration.
2660ccea Poul Sander 2023-09-22 19:25 16585
2660ccea Poul Sander 2023-09-22 19:25 16586
    @return the type of the JSON value
2660ccea Poul Sander 2023-09-22 19:25 16587
            Value type                | return value
2660ccea Poul Sander 2023-09-22 19:25 16588
            ------------------------- | -------------------------
2660ccea Poul Sander 2023-09-22 19:25 16589
            null                      | value_t::null
2660ccea Poul Sander 2023-09-22 19:25 16590
            boolean                   | value_t::boolean
2660ccea Poul Sander 2023-09-22 19:25 16591
            string                    | value_t::string
2660ccea Poul Sander 2023-09-22 19:25 16592
            number (integer)          | value_t::number_integer
2660ccea Poul Sander 2023-09-22 19:25 16593
            number (unsigned integer) | value_t::number_unsigned
2660ccea Poul Sander 2023-09-22 19:25 16594
            number (floating-point)   | value_t::number_float
2660ccea Poul Sander 2023-09-22 19:25 16595
            object                    | value_t::object
2660ccea Poul Sander 2023-09-22 19:25 16596
            array                     | value_t::array
2660ccea Poul Sander 2023-09-22 19:25 16597
            discarded                 | value_t::discarded
2660ccea Poul Sander 2023-09-22 19:25 16598
2660ccea Poul Sander 2023-09-22 19:25 16599
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16600
2660ccea Poul Sander 2023-09-22 19:25 16601
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16602
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16603
2660ccea Poul Sander 2023-09-22 19:25 16604
    @liveexample{The following code exemplifies `type()` for all JSON
2660ccea Poul Sander 2023-09-22 19:25 16605
    types.,type}
2660ccea Poul Sander 2023-09-22 19:25 16606
2660ccea Poul Sander 2023-09-22 19:25 16607
    @sa @ref operator value_t() -- return the type of the JSON value (implicit)
2660ccea Poul Sander 2023-09-22 19:25 16608
    @sa @ref type_name() -- return the type as string
2660ccea Poul Sander 2023-09-22 19:25 16609
2660ccea Poul Sander 2023-09-22 19:25 16610
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16611
    */
2660ccea Poul Sander 2023-09-22 19:25 16612
    constexpr value_t type() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16613
    {
2660ccea Poul Sander 2023-09-22 19:25 16614
        return m_type;
2660ccea Poul Sander 2023-09-22 19:25 16615
    }
2660ccea Poul Sander 2023-09-22 19:25 16616
2660ccea Poul Sander 2023-09-22 19:25 16617
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16618
    @brief return whether type is primitive
2660ccea Poul Sander 2023-09-22 19:25 16619
2660ccea Poul Sander 2023-09-22 19:25 16620
    This function returns true if and only if the JSON type is primitive
2660ccea Poul Sander 2023-09-22 19:25 16621
    (string, number, boolean, or null).
2660ccea Poul Sander 2023-09-22 19:25 16622
2660ccea Poul Sander 2023-09-22 19:25 16623
    @return `true` if type is primitive (string, number, boolean, or null),
2660ccea Poul Sander 2023-09-22 19:25 16624
    `false` otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16625
2660ccea Poul Sander 2023-09-22 19:25 16626
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16627
2660ccea Poul Sander 2023-09-22 19:25 16628
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16629
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16630
2660ccea Poul Sander 2023-09-22 19:25 16631
    @liveexample{The following code exemplifies `is_primitive()` for all JSON
2660ccea Poul Sander 2023-09-22 19:25 16632
    types.,is_primitive}
2660ccea Poul Sander 2023-09-22 19:25 16633
2660ccea Poul Sander 2023-09-22 19:25 16634
    @sa @ref is_structured() -- returns whether JSON value is structured
2660ccea Poul Sander 2023-09-22 19:25 16635
    @sa @ref is_null() -- returns whether JSON value is `null`
2660ccea Poul Sander 2023-09-22 19:25 16636
    @sa @ref is_string() -- returns whether JSON value is a string
2660ccea Poul Sander 2023-09-22 19:25 16637
    @sa @ref is_boolean() -- returns whether JSON value is a boolean
2660ccea Poul Sander 2023-09-22 19:25 16638
    @sa @ref is_number() -- returns whether JSON value is a number
2660ccea Poul Sander 2023-09-22 19:25 16639
2660ccea Poul Sander 2023-09-22 19:25 16640
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16641
    */
2660ccea Poul Sander 2023-09-22 19:25 16642
    constexpr bool is_primitive() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16643
    {
2660ccea Poul Sander 2023-09-22 19:25 16644
        return is_null() or is_string() or is_boolean() or is_number();
2660ccea Poul Sander 2023-09-22 19:25 16645
    }
2660ccea Poul Sander 2023-09-22 19:25 16646
2660ccea Poul Sander 2023-09-22 19:25 16647
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16648
    @brief return whether type is structured
2660ccea Poul Sander 2023-09-22 19:25 16649
2660ccea Poul Sander 2023-09-22 19:25 16650
    This function returns true if and only if the JSON type is structured
2660ccea Poul Sander 2023-09-22 19:25 16651
    (array or object).
2660ccea Poul Sander 2023-09-22 19:25 16652
2660ccea Poul Sander 2023-09-22 19:25 16653
    @return `true` if type is structured (array or object), `false` otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16654
2660ccea Poul Sander 2023-09-22 19:25 16655
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16656
2660ccea Poul Sander 2023-09-22 19:25 16657
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16658
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16659
2660ccea Poul Sander 2023-09-22 19:25 16660
    @liveexample{The following code exemplifies `is_structured()` for all JSON
2660ccea Poul Sander 2023-09-22 19:25 16661
    types.,is_structured}
2660ccea Poul Sander 2023-09-22 19:25 16662
2660ccea Poul Sander 2023-09-22 19:25 16663
    @sa @ref is_primitive() -- returns whether value is primitive
2660ccea Poul Sander 2023-09-22 19:25 16664
    @sa @ref is_array() -- returns whether value is an array
2660ccea Poul Sander 2023-09-22 19:25 16665
    @sa @ref is_object() -- returns whether value is an object
2660ccea Poul Sander 2023-09-22 19:25 16666
2660ccea Poul Sander 2023-09-22 19:25 16667
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16668
    */
2660ccea Poul Sander 2023-09-22 19:25 16669
    constexpr bool is_structured() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16670
    {
2660ccea Poul Sander 2023-09-22 19:25 16671
        return is_array() or is_object();
2660ccea Poul Sander 2023-09-22 19:25 16672
    }
2660ccea Poul Sander 2023-09-22 19:25 16673
2660ccea Poul Sander 2023-09-22 19:25 16674
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16675
    @brief return whether value is null
2660ccea Poul Sander 2023-09-22 19:25 16676
2660ccea Poul Sander 2023-09-22 19:25 16677
    This function returns true if and only if the JSON value is null.
2660ccea Poul Sander 2023-09-22 19:25 16678
2660ccea Poul Sander 2023-09-22 19:25 16679
    @return `true` if type is null, `false` otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16680
2660ccea Poul Sander 2023-09-22 19:25 16681
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16682
2660ccea Poul Sander 2023-09-22 19:25 16683
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16684
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16685
2660ccea Poul Sander 2023-09-22 19:25 16686
    @liveexample{The following code exemplifies `is_null()` for all JSON
2660ccea Poul Sander 2023-09-22 19:25 16687
    types.,is_null}
2660ccea Poul Sander 2023-09-22 19:25 16688
2660ccea Poul Sander 2023-09-22 19:25 16689
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16690
    */
2660ccea Poul Sander 2023-09-22 19:25 16691
    constexpr bool is_null() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16692
    {
2660ccea Poul Sander 2023-09-22 19:25 16693
        return m_type == value_t::null;
2660ccea Poul Sander 2023-09-22 19:25 16694
    }
2660ccea Poul Sander 2023-09-22 19:25 16695
2660ccea Poul Sander 2023-09-22 19:25 16696
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16697
    @brief return whether value is a boolean
2660ccea Poul Sander 2023-09-22 19:25 16698
2660ccea Poul Sander 2023-09-22 19:25 16699
    This function returns true if and only if the JSON value is a boolean.
2660ccea Poul Sander 2023-09-22 19:25 16700
2660ccea Poul Sander 2023-09-22 19:25 16701
    @return `true` if type is boolean, `false` otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16702
2660ccea Poul Sander 2023-09-22 19:25 16703
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16704
2660ccea Poul Sander 2023-09-22 19:25 16705
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16706
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16707
2660ccea Poul Sander 2023-09-22 19:25 16708
    @liveexample{The following code exemplifies `is_boolean()` for all JSON
2660ccea Poul Sander 2023-09-22 19:25 16709
    types.,is_boolean}
2660ccea Poul Sander 2023-09-22 19:25 16710
2660ccea Poul Sander 2023-09-22 19:25 16711
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16712
    */
2660ccea Poul Sander 2023-09-22 19:25 16713
    constexpr bool is_boolean() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16714
    {
2660ccea Poul Sander 2023-09-22 19:25 16715
        return m_type == value_t::boolean;
2660ccea Poul Sander 2023-09-22 19:25 16716
    }
2660ccea Poul Sander 2023-09-22 19:25 16717
2660ccea Poul Sander 2023-09-22 19:25 16718
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16719
    @brief return whether value is a number
2660ccea Poul Sander 2023-09-22 19:25 16720
2660ccea Poul Sander 2023-09-22 19:25 16721
    This function returns true if and only if the JSON value is a number. This
2660ccea Poul Sander 2023-09-22 19:25 16722
    includes both integer (signed and unsigned) and floating-point values.
2660ccea Poul Sander 2023-09-22 19:25 16723
2660ccea Poul Sander 2023-09-22 19:25 16724
    @return `true` if type is number (regardless whether integer, unsigned
2660ccea Poul Sander 2023-09-22 19:25 16725
    integer or floating-type), `false` otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16726
2660ccea Poul Sander 2023-09-22 19:25 16727
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16728
2660ccea Poul Sander 2023-09-22 19:25 16729
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16730
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16731
2660ccea Poul Sander 2023-09-22 19:25 16732
    @liveexample{The following code exemplifies `is_number()` for all JSON
2660ccea Poul Sander 2023-09-22 19:25 16733
    types.,is_number}
2660ccea Poul Sander 2023-09-22 19:25 16734
2660ccea Poul Sander 2023-09-22 19:25 16735
    @sa @ref is_number_integer() -- check if value is an integer or unsigned
2660ccea Poul Sander 2023-09-22 19:25 16736
    integer number
2660ccea Poul Sander 2023-09-22 19:25 16737
    @sa @ref is_number_unsigned() -- check if value is an unsigned integer
2660ccea Poul Sander 2023-09-22 19:25 16738
    number
2660ccea Poul Sander 2023-09-22 19:25 16739
    @sa @ref is_number_float() -- check if value is a floating-point number
2660ccea Poul Sander 2023-09-22 19:25 16740
2660ccea Poul Sander 2023-09-22 19:25 16741
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16742
    */
2660ccea Poul Sander 2023-09-22 19:25 16743
    constexpr bool is_number() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16744
    {
2660ccea Poul Sander 2023-09-22 19:25 16745
        return is_number_integer() or is_number_float();
2660ccea Poul Sander 2023-09-22 19:25 16746
    }
2660ccea Poul Sander 2023-09-22 19:25 16747
2660ccea Poul Sander 2023-09-22 19:25 16748
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16749
    @brief return whether value is an integer number
2660ccea Poul Sander 2023-09-22 19:25 16750
2660ccea Poul Sander 2023-09-22 19:25 16751
    This function returns true if and only if the JSON value is a signed or
2660ccea Poul Sander 2023-09-22 19:25 16752
    unsigned integer number. This excludes floating-point values.
2660ccea Poul Sander 2023-09-22 19:25 16753
2660ccea Poul Sander 2023-09-22 19:25 16754
    @return `true` if type is an integer or unsigned integer number, `false`
2660ccea Poul Sander 2023-09-22 19:25 16755
    otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16756
2660ccea Poul Sander 2023-09-22 19:25 16757
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16758
2660ccea Poul Sander 2023-09-22 19:25 16759
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16760
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16761
2660ccea Poul Sander 2023-09-22 19:25 16762
    @liveexample{The following code exemplifies `is_number_integer()` for all
2660ccea Poul Sander 2023-09-22 19:25 16763
    JSON types.,is_number_integer}
2660ccea Poul Sander 2023-09-22 19:25 16764
2660ccea Poul Sander 2023-09-22 19:25 16765
    @sa @ref is_number() -- check if value is a number
2660ccea Poul Sander 2023-09-22 19:25 16766
    @sa @ref is_number_unsigned() -- check if value is an unsigned integer
2660ccea Poul Sander 2023-09-22 19:25 16767
    number
2660ccea Poul Sander 2023-09-22 19:25 16768
    @sa @ref is_number_float() -- check if value is a floating-point number
2660ccea Poul Sander 2023-09-22 19:25 16769
2660ccea Poul Sander 2023-09-22 19:25 16770
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16771
    */
2660ccea Poul Sander 2023-09-22 19:25 16772
    constexpr bool is_number_integer() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16773
    {
2660ccea Poul Sander 2023-09-22 19:25 16774
        return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
2660ccea Poul Sander 2023-09-22 19:25 16775
    }
2660ccea Poul Sander 2023-09-22 19:25 16776
2660ccea Poul Sander 2023-09-22 19:25 16777
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16778
    @brief return whether value is an unsigned integer number
2660ccea Poul Sander 2023-09-22 19:25 16779
2660ccea Poul Sander 2023-09-22 19:25 16780
    This function returns true if and only if the JSON value is an unsigned
2660ccea Poul Sander 2023-09-22 19:25 16781
    integer number. This excludes floating-point and signed integer values.
2660ccea Poul Sander 2023-09-22 19:25 16782
2660ccea Poul Sander 2023-09-22 19:25 16783
    @return `true` if type is an unsigned integer number, `false` otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16784
2660ccea Poul Sander 2023-09-22 19:25 16785
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16786
2660ccea Poul Sander 2023-09-22 19:25 16787
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16788
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16789
2660ccea Poul Sander 2023-09-22 19:25 16790
    @liveexample{The following code exemplifies `is_number_unsigned()` for all
2660ccea Poul Sander 2023-09-22 19:25 16791
    JSON types.,is_number_unsigned}
2660ccea Poul Sander 2023-09-22 19:25 16792
2660ccea Poul Sander 2023-09-22 19:25 16793
    @sa @ref is_number() -- check if value is a number
2660ccea Poul Sander 2023-09-22 19:25 16794
    @sa @ref is_number_integer() -- check if value is an integer or unsigned
2660ccea Poul Sander 2023-09-22 19:25 16795
    integer number
2660ccea Poul Sander 2023-09-22 19:25 16796
    @sa @ref is_number_float() -- check if value is a floating-point number
2660ccea Poul Sander 2023-09-22 19:25 16797
2660ccea Poul Sander 2023-09-22 19:25 16798
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 16799
    */
2660ccea Poul Sander 2023-09-22 19:25 16800
    constexpr bool is_number_unsigned() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16801
    {
2660ccea Poul Sander 2023-09-22 19:25 16802
        return m_type == value_t::number_unsigned;
2660ccea Poul Sander 2023-09-22 19:25 16803
    }
2660ccea Poul Sander 2023-09-22 19:25 16804
2660ccea Poul Sander 2023-09-22 19:25 16805
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16806
    @brief return whether value is a floating-point number
2660ccea Poul Sander 2023-09-22 19:25 16807
2660ccea Poul Sander 2023-09-22 19:25 16808
    This function returns true if and only if the JSON value is a
2660ccea Poul Sander 2023-09-22 19:25 16809
    floating-point number. This excludes signed and unsigned integer values.
2660ccea Poul Sander 2023-09-22 19:25 16810
2660ccea Poul Sander 2023-09-22 19:25 16811
    @return `true` if type is a floating-point number, `false` otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16812
2660ccea Poul Sander 2023-09-22 19:25 16813
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16814
2660ccea Poul Sander 2023-09-22 19:25 16815
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16816
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16817
2660ccea Poul Sander 2023-09-22 19:25 16818
    @liveexample{The following code exemplifies `is_number_float()` for all
2660ccea Poul Sander 2023-09-22 19:25 16819
    JSON types.,is_number_float}
2660ccea Poul Sander 2023-09-22 19:25 16820
2660ccea Poul Sander 2023-09-22 19:25 16821
    @sa @ref is_number() -- check if value is number
2660ccea Poul Sander 2023-09-22 19:25 16822
    @sa @ref is_number_integer() -- check if value is an integer number
2660ccea Poul Sander 2023-09-22 19:25 16823
    @sa @ref is_number_unsigned() -- check if value is an unsigned integer
2660ccea Poul Sander 2023-09-22 19:25 16824
    number
2660ccea Poul Sander 2023-09-22 19:25 16825
2660ccea Poul Sander 2023-09-22 19:25 16826
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16827
    */
2660ccea Poul Sander 2023-09-22 19:25 16828
    constexpr bool is_number_float() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16829
    {
2660ccea Poul Sander 2023-09-22 19:25 16830
        return m_type == value_t::number_float;
2660ccea Poul Sander 2023-09-22 19:25 16831
    }
2660ccea Poul Sander 2023-09-22 19:25 16832
2660ccea Poul Sander 2023-09-22 19:25 16833
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16834
    @brief return whether value is an object
2660ccea Poul Sander 2023-09-22 19:25 16835
2660ccea Poul Sander 2023-09-22 19:25 16836
    This function returns true if and only if the JSON value is an object.
2660ccea Poul Sander 2023-09-22 19:25 16837
2660ccea Poul Sander 2023-09-22 19:25 16838
    @return `true` if type is object, `false` otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16839
2660ccea Poul Sander 2023-09-22 19:25 16840
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16841
2660ccea Poul Sander 2023-09-22 19:25 16842
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16843
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16844
2660ccea Poul Sander 2023-09-22 19:25 16845
    @liveexample{The following code exemplifies `is_object()` for all JSON
2660ccea Poul Sander 2023-09-22 19:25 16846
    types.,is_object}
2660ccea Poul Sander 2023-09-22 19:25 16847
2660ccea Poul Sander 2023-09-22 19:25 16848
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16849
    */
2660ccea Poul Sander 2023-09-22 19:25 16850
    constexpr bool is_object() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16851
    {
2660ccea Poul Sander 2023-09-22 19:25 16852
        return m_type == value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 16853
    }
2660ccea Poul Sander 2023-09-22 19:25 16854
2660ccea Poul Sander 2023-09-22 19:25 16855
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16856
    @brief return whether value is an array
2660ccea Poul Sander 2023-09-22 19:25 16857
2660ccea Poul Sander 2023-09-22 19:25 16858
    This function returns true if and only if the JSON value is an array.
2660ccea Poul Sander 2023-09-22 19:25 16859
2660ccea Poul Sander 2023-09-22 19:25 16860
    @return `true` if type is array, `false` otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16861
2660ccea Poul Sander 2023-09-22 19:25 16862
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16863
2660ccea Poul Sander 2023-09-22 19:25 16864
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16865
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16866
2660ccea Poul Sander 2023-09-22 19:25 16867
    @liveexample{The following code exemplifies `is_array()` for all JSON
2660ccea Poul Sander 2023-09-22 19:25 16868
    types.,is_array}
2660ccea Poul Sander 2023-09-22 19:25 16869
2660ccea Poul Sander 2023-09-22 19:25 16870
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16871
    */
2660ccea Poul Sander 2023-09-22 19:25 16872
    constexpr bool is_array() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16873
    {
2660ccea Poul Sander 2023-09-22 19:25 16874
        return m_type == value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 16875
    }
2660ccea Poul Sander 2023-09-22 19:25 16876
2660ccea Poul Sander 2023-09-22 19:25 16877
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16878
    @brief return whether value is a string
2660ccea Poul Sander 2023-09-22 19:25 16879
2660ccea Poul Sander 2023-09-22 19:25 16880
    This function returns true if and only if the JSON value is a string.
2660ccea Poul Sander 2023-09-22 19:25 16881
2660ccea Poul Sander 2023-09-22 19:25 16882
    @return `true` if type is string, `false` otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16883
2660ccea Poul Sander 2023-09-22 19:25 16884
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16885
2660ccea Poul Sander 2023-09-22 19:25 16886
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16887
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16888
2660ccea Poul Sander 2023-09-22 19:25 16889
    @liveexample{The following code exemplifies `is_string()` for all JSON
2660ccea Poul Sander 2023-09-22 19:25 16890
    types.,is_string}
2660ccea Poul Sander 2023-09-22 19:25 16891
2660ccea Poul Sander 2023-09-22 19:25 16892
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16893
    */
2660ccea Poul Sander 2023-09-22 19:25 16894
    constexpr bool is_string() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16895
    {
2660ccea Poul Sander 2023-09-22 19:25 16896
        return m_type == value_t::string;
2660ccea Poul Sander 2023-09-22 19:25 16897
    }
2660ccea Poul Sander 2023-09-22 19:25 16898
2660ccea Poul Sander 2023-09-22 19:25 16899
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16900
    @brief return whether value is discarded
2660ccea Poul Sander 2023-09-22 19:25 16901
2660ccea Poul Sander 2023-09-22 19:25 16902
    This function returns true if and only if the JSON value was discarded
2660ccea Poul Sander 2023-09-22 19:25 16903
    during parsing with a callback function (see @ref parser_callback_t).
2660ccea Poul Sander 2023-09-22 19:25 16904
2660ccea Poul Sander 2023-09-22 19:25 16905
    @note This function will always be `false` for JSON values after parsing.
2660ccea Poul Sander 2023-09-22 19:25 16906
    That is, discarded values can only occur during parsing, but will be
2660ccea Poul Sander 2023-09-22 19:25 16907
    removed when inside a structured value or replaced by null in other cases.
2660ccea Poul Sander 2023-09-22 19:25 16908
2660ccea Poul Sander 2023-09-22 19:25 16909
    @return `true` if type is discarded, `false` otherwise.
2660ccea Poul Sander 2023-09-22 19:25 16910
2660ccea Poul Sander 2023-09-22 19:25 16911
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16912
2660ccea Poul Sander 2023-09-22 19:25 16913
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16914
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16915
2660ccea Poul Sander 2023-09-22 19:25 16916
    @liveexample{The following code exemplifies `is_discarded()` for all JSON
2660ccea Poul Sander 2023-09-22 19:25 16917
    types.,is_discarded}
2660ccea Poul Sander 2023-09-22 19:25 16918
2660ccea Poul Sander 2023-09-22 19:25 16919
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16920
    */
2660ccea Poul Sander 2023-09-22 19:25 16921
    constexpr bool is_discarded() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16922
    {
2660ccea Poul Sander 2023-09-22 19:25 16923
        return m_type == value_t::discarded;
2660ccea Poul Sander 2023-09-22 19:25 16924
    }
2660ccea Poul Sander 2023-09-22 19:25 16925
2660ccea Poul Sander 2023-09-22 19:25 16926
    /*!
2660ccea Poul Sander 2023-09-22 19:25 16927
    @brief return the type of the JSON value (implicit)
2660ccea Poul Sander 2023-09-22 19:25 16928
2660ccea Poul Sander 2023-09-22 19:25 16929
    Implicitly return the type of the JSON value as a value from the @ref
2660ccea Poul Sander 2023-09-22 19:25 16930
    value_t enumeration.
2660ccea Poul Sander 2023-09-22 19:25 16931
2660ccea Poul Sander 2023-09-22 19:25 16932
    @return the type of the JSON value
2660ccea Poul Sander 2023-09-22 19:25 16933
2660ccea Poul Sander 2023-09-22 19:25 16934
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 16935
2660ccea Poul Sander 2023-09-22 19:25 16936
    @exceptionsafety No-throw guarantee: this member function never throws
2660ccea Poul Sander 2023-09-22 19:25 16937
    exceptions.
2660ccea Poul Sander 2023-09-22 19:25 16938
2660ccea Poul Sander 2023-09-22 19:25 16939
    @liveexample{The following code exemplifies the @ref value_t operator for
2660ccea Poul Sander 2023-09-22 19:25 16940
    all JSON types.,operator__value_t}
2660ccea Poul Sander 2023-09-22 19:25 16941
2660ccea Poul Sander 2023-09-22 19:25 16942
    @sa @ref type() -- return the type of the JSON value (explicit)
2660ccea Poul Sander 2023-09-22 19:25 16943
    @sa @ref type_name() -- return the type as string
2660ccea Poul Sander 2023-09-22 19:25 16944
2660ccea Poul Sander 2023-09-22 19:25 16945
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 16946
    */
2660ccea Poul Sander 2023-09-22 19:25 16947
    constexpr operator value_t() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16948
    {
2660ccea Poul Sander 2023-09-22 19:25 16949
        return m_type;
2660ccea Poul Sander 2023-09-22 19:25 16950
    }
2660ccea Poul Sander 2023-09-22 19:25 16951
2660ccea Poul Sander 2023-09-22 19:25 16952
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 16953
2660ccea Poul Sander 2023-09-22 19:25 16954
  private:
2660ccea Poul Sander 2023-09-22 19:25 16955
    //////////////////
2660ccea Poul Sander 2023-09-22 19:25 16956
    // value access //
2660ccea Poul Sander 2023-09-22 19:25 16957
    //////////////////
2660ccea Poul Sander 2023-09-22 19:25 16958
2660ccea Poul Sander 2023-09-22 19:25 16959
    /// get a boolean (explicit)
2660ccea Poul Sander 2023-09-22 19:25 16960
    boolean_t get_impl(boolean_t* /*unused*/) const
2660ccea Poul Sander 2023-09-22 19:25 16961
    {
2660ccea Poul Sander 2023-09-22 19:25 16962
        if (JSON_HEDLEY_LIKELY(is_boolean()))
2660ccea Poul Sander 2023-09-22 19:25 16963
        {
2660ccea Poul Sander 2023-09-22 19:25 16964
            return m_value.boolean;
2660ccea Poul Sander 2023-09-22 19:25 16965
        }
2660ccea Poul Sander 2023-09-22 19:25 16966
2660ccea Poul Sander 2023-09-22 19:25 16967
        JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 16968
    }
2660ccea Poul Sander 2023-09-22 19:25 16969
2660ccea Poul Sander 2023-09-22 19:25 16970
    /// get a pointer to the value (object)
2660ccea Poul Sander 2023-09-22 19:25 16971
    object_t* get_impl_ptr(object_t* /*unused*/) noexcept
2660ccea Poul Sander 2023-09-22 19:25 16972
    {
2660ccea Poul Sander 2023-09-22 19:25 16973
        return is_object() ? m_value.object : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 16974
    }
2660ccea Poul Sander 2023-09-22 19:25 16975
2660ccea Poul Sander 2023-09-22 19:25 16976
    /// get a pointer to the value (object)
2660ccea Poul Sander 2023-09-22 19:25 16977
    constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16978
    {
2660ccea Poul Sander 2023-09-22 19:25 16979
        return is_object() ? m_value.object : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 16980
    }
2660ccea Poul Sander 2023-09-22 19:25 16981
2660ccea Poul Sander 2023-09-22 19:25 16982
    /// get a pointer to the value (array)
2660ccea Poul Sander 2023-09-22 19:25 16983
    array_t* get_impl_ptr(array_t* /*unused*/) noexcept
2660ccea Poul Sander 2023-09-22 19:25 16984
    {
2660ccea Poul Sander 2023-09-22 19:25 16985
        return is_array() ? m_value.array : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 16986
    }
2660ccea Poul Sander 2023-09-22 19:25 16987
2660ccea Poul Sander 2023-09-22 19:25 16988
    /// get a pointer to the value (array)
2660ccea Poul Sander 2023-09-22 19:25 16989
    constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
2660ccea Poul Sander 2023-09-22 19:25 16990
    {
2660ccea Poul Sander 2023-09-22 19:25 16991
        return is_array() ? m_value.array : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 16992
    }
2660ccea Poul Sander 2023-09-22 19:25 16993
2660ccea Poul Sander 2023-09-22 19:25 16994
    /// get a pointer to the value (string)
2660ccea Poul Sander 2023-09-22 19:25 16995
    string_t* get_impl_ptr(string_t* /*unused*/) noexcept
2660ccea Poul Sander 2023-09-22 19:25 16996
    {
2660ccea Poul Sander 2023-09-22 19:25 16997
        return is_string() ? m_value.string : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 16998
    }
2660ccea Poul Sander 2023-09-22 19:25 16999
2660ccea Poul Sander 2023-09-22 19:25 17000
    /// get a pointer to the value (string)
2660ccea Poul Sander 2023-09-22 19:25 17001
    constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
2660ccea Poul Sander 2023-09-22 19:25 17002
    {
2660ccea Poul Sander 2023-09-22 19:25 17003
        return is_string() ? m_value.string : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 17004
    }
2660ccea Poul Sander 2023-09-22 19:25 17005
2660ccea Poul Sander 2023-09-22 19:25 17006
    /// get a pointer to the value (boolean)
2660ccea Poul Sander 2023-09-22 19:25 17007
    boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
2660ccea Poul Sander 2023-09-22 19:25 17008
    {
2660ccea Poul Sander 2023-09-22 19:25 17009
        return is_boolean() ? &m_value.boolean : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 17010
    }
2660ccea Poul Sander 2023-09-22 19:25 17011
2660ccea Poul Sander 2023-09-22 19:25 17012
    /// get a pointer to the value (boolean)
2660ccea Poul Sander 2023-09-22 19:25 17013
    constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
2660ccea Poul Sander 2023-09-22 19:25 17014
    {
2660ccea Poul Sander 2023-09-22 19:25 17015
        return is_boolean() ? &m_value.boolean : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 17016
    }
2660ccea Poul Sander 2023-09-22 19:25 17017
2660ccea Poul Sander 2023-09-22 19:25 17018
    /// get a pointer to the value (integer number)
2660ccea Poul Sander 2023-09-22 19:25 17019
    number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
2660ccea Poul Sander 2023-09-22 19:25 17020
    {
2660ccea Poul Sander 2023-09-22 19:25 17021
        return is_number_integer() ? &m_value.number_integer : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 17022
    }
2660ccea Poul Sander 2023-09-22 19:25 17023
2660ccea Poul Sander 2023-09-22 19:25 17024
    /// get a pointer to the value (integer number)
2660ccea Poul Sander 2023-09-22 19:25 17025
    constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
2660ccea Poul Sander 2023-09-22 19:25 17026
    {
2660ccea Poul Sander 2023-09-22 19:25 17027
        return is_number_integer() ? &m_value.number_integer : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 17028
    }
2660ccea Poul Sander 2023-09-22 19:25 17029
2660ccea Poul Sander 2023-09-22 19:25 17030
    /// get a pointer to the value (unsigned number)
2660ccea Poul Sander 2023-09-22 19:25 17031
    number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
2660ccea Poul Sander 2023-09-22 19:25 17032
    {
2660ccea Poul Sander 2023-09-22 19:25 17033
        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 17034
    }
2660ccea Poul Sander 2023-09-22 19:25 17035
2660ccea Poul Sander 2023-09-22 19:25 17036
    /// get a pointer to the value (unsigned number)
2660ccea Poul Sander 2023-09-22 19:25 17037
    constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
2660ccea Poul Sander 2023-09-22 19:25 17038
    {
2660ccea Poul Sander 2023-09-22 19:25 17039
        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 17040
    }
2660ccea Poul Sander 2023-09-22 19:25 17041
2660ccea Poul Sander 2023-09-22 19:25 17042
    /// get a pointer to the value (floating-point number)
2660ccea Poul Sander 2023-09-22 19:25 17043
    number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
2660ccea Poul Sander 2023-09-22 19:25 17044
    {
2660ccea Poul Sander 2023-09-22 19:25 17045
        return is_number_float() ? &m_value.number_float : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 17046
    }
2660ccea Poul Sander 2023-09-22 19:25 17047
2660ccea Poul Sander 2023-09-22 19:25 17048
    /// get a pointer to the value (floating-point number)
2660ccea Poul Sander 2023-09-22 19:25 17049
    constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
2660ccea Poul Sander 2023-09-22 19:25 17050
    {
2660ccea Poul Sander 2023-09-22 19:25 17051
        return is_number_float() ? &m_value.number_float : nullptr;
2660ccea Poul Sander 2023-09-22 19:25 17052
    }
2660ccea Poul Sander 2023-09-22 19:25 17053
2660ccea Poul Sander 2023-09-22 19:25 17054
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17055
    @brief helper function to implement get_ref()
2660ccea Poul Sander 2023-09-22 19:25 17056
2660ccea Poul Sander 2023-09-22 19:25 17057
    This function helps to implement get_ref() without code duplication for
2660ccea Poul Sander 2023-09-22 19:25 17058
    const and non-const overloads
2660ccea Poul Sander 2023-09-22 19:25 17059
2660ccea Poul Sander 2023-09-22 19:25 17060
    @tparam ThisType will be deduced as `basic_json` or `const basic_json`
2660ccea Poul Sander 2023-09-22 19:25 17061
2660ccea Poul Sander 2023-09-22 19:25 17062
    @throw type_error.303 if ReferenceType does not match underlying value
2660ccea Poul Sander 2023-09-22 19:25 17063
    type of the current JSON
2660ccea Poul Sander 2023-09-22 19:25 17064
    */
2660ccea Poul Sander 2023-09-22 19:25 17065
    template<typename ReferenceType, typename ThisType>
2660ccea Poul Sander 2023-09-22 19:25 17066
    static ReferenceType get_ref_impl(ThisType& obj)
2660ccea Poul Sander 2023-09-22 19:25 17067
    {
2660ccea Poul Sander 2023-09-22 19:25 17068
        // delegate the call to get_ptr<>()
2660ccea Poul Sander 2023-09-22 19:25 17069
        auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
2660ccea Poul Sander 2023-09-22 19:25 17070
2660ccea Poul Sander 2023-09-22 19:25 17071
        if (JSON_HEDLEY_LIKELY(ptr != nullptr))
2660ccea Poul Sander 2023-09-22 19:25 17072
        {
2660ccea Poul Sander 2023-09-22 19:25 17073
            return *ptr;
2660ccea Poul Sander 2023-09-22 19:25 17074
        }
2660ccea Poul Sander 2023-09-22 19:25 17075
2660ccea Poul Sander 2023-09-22 19:25 17076
        JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 17077
    }
2660ccea Poul Sander 2023-09-22 19:25 17078
2660ccea Poul Sander 2023-09-22 19:25 17079
  public:
2660ccea Poul Sander 2023-09-22 19:25 17080
    /// @name value access
2660ccea Poul Sander 2023-09-22 19:25 17081
    /// Direct access to the stored value of a JSON value.
2660ccea Poul Sander 2023-09-22 19:25 17082
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 17083
2660ccea Poul Sander 2023-09-22 19:25 17084
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17085
    @brief get special-case overload
2660ccea Poul Sander 2023-09-22 19:25 17086
2660ccea Poul Sander 2023-09-22 19:25 17087
    This overloads avoids a lot of template boilerplate, it can be seen as the
2660ccea Poul Sander 2023-09-22 19:25 17088
    identity method
2660ccea Poul Sander 2023-09-22 19:25 17089
2660ccea Poul Sander 2023-09-22 19:25 17090
    @tparam BasicJsonType == @ref basic_json
2660ccea Poul Sander 2023-09-22 19:25 17091
2660ccea Poul Sander 2023-09-22 19:25 17092
    @return a copy of *this
2660ccea Poul Sander 2023-09-22 19:25 17093
2660ccea Poul Sander 2023-09-22 19:25 17094
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 17095
2660ccea Poul Sander 2023-09-22 19:25 17096
    @since version 2.1.0
2660ccea Poul Sander 2023-09-22 19:25 17097
    */
2660ccea Poul Sander 2023-09-22 19:25 17098
    template<typename BasicJsonType, detail::enable_if_t<
2660ccea Poul Sander 2023-09-22 19:25 17099
                 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
2660ccea Poul Sander 2023-09-22 19:25 17100
                 int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 17101
    basic_json get() const
2660ccea Poul Sander 2023-09-22 19:25 17102
    {
2660ccea Poul Sander 2023-09-22 19:25 17103
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 17104
    }
2660ccea Poul Sander 2023-09-22 19:25 17105
2660ccea Poul Sander 2023-09-22 19:25 17106
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17107
    @brief get special-case overload
2660ccea Poul Sander 2023-09-22 19:25 17108
2660ccea Poul Sander 2023-09-22 19:25 17109
    This overloads converts the current @ref basic_json in a different
2660ccea Poul Sander 2023-09-22 19:25 17110
    @ref basic_json type
2660ccea Poul Sander 2023-09-22 19:25 17111
2660ccea Poul Sander 2023-09-22 19:25 17112
    @tparam BasicJsonType == @ref basic_json
2660ccea Poul Sander 2023-09-22 19:25 17113
2660ccea Poul Sander 2023-09-22 19:25 17114
    @return a copy of *this, converted into @tparam BasicJsonType
2660ccea Poul Sander 2023-09-22 19:25 17115
2660ccea Poul Sander 2023-09-22 19:25 17116
    @complexity Depending on the implementation of the called `from_json()`
2660ccea Poul Sander 2023-09-22 19:25 17117
                method.
2660ccea Poul Sander 2023-09-22 19:25 17118
2660ccea Poul Sander 2023-09-22 19:25 17119
    @since version 3.2.0
2660ccea Poul Sander 2023-09-22 19:25 17120
    */
2660ccea Poul Sander 2023-09-22 19:25 17121
    template<typename BasicJsonType, detail::enable_if_t<
2660ccea Poul Sander 2023-09-22 19:25 17122
                 not std::is_same<BasicJsonType, basic_json>::value and
2660ccea Poul Sander 2023-09-22 19:25 17123
                 detail::is_basic_json<BasicJsonType>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 17124
    BasicJsonType get() const
2660ccea Poul Sander 2023-09-22 19:25 17125
    {
2660ccea Poul Sander 2023-09-22 19:25 17126
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 17127
    }
2660ccea Poul Sander 2023-09-22 19:25 17128
2660ccea Poul Sander 2023-09-22 19:25 17129
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17130
    @brief get a value (explicit)
2660ccea Poul Sander 2023-09-22 19:25 17131
2660ccea Poul Sander 2023-09-22 19:25 17132
    Explicit type conversion between the JSON value and a compatible value
2660ccea Poul Sander 2023-09-22 19:25 17133
    which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
2660ccea Poul Sander 2023-09-22 19:25 17134
    and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
2660ccea Poul Sander 2023-09-22 19:25 17135
    The value is converted by calling the @ref json_serializer<ValueType>
2660ccea Poul Sander 2023-09-22 19:25 17136
    `from_json()` method.
2660ccea Poul Sander 2023-09-22 19:25 17137
2660ccea Poul Sander 2023-09-22 19:25 17138
    The function is equivalent to executing
2660ccea Poul Sander 2023-09-22 19:25 17139
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 17140
    ValueType ret;
2660ccea Poul Sander 2023-09-22 19:25 17141
    JSONSerializer<ValueType>::from_json(*this, ret);
2660ccea Poul Sander 2023-09-22 19:25 17142
    return ret;
2660ccea Poul Sander 2023-09-22 19:25 17143
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 17144
2660ccea Poul Sander 2023-09-22 19:25 17145
    This overloads is chosen if:
2660ccea Poul Sander 2023-09-22 19:25 17146
    - @a ValueType is not @ref basic_json,
2660ccea Poul Sander 2023-09-22 19:25 17147
    - @ref json_serializer<ValueType> has a `from_json()` method of the form
2660ccea Poul Sander 2023-09-22 19:25 17148
      `void from_json(const basic_json&, ValueType&)`, and
2660ccea Poul Sander 2023-09-22 19:25 17149
    - @ref json_serializer<ValueType> does not have a `from_json()` method of
2660ccea Poul Sander 2023-09-22 19:25 17150
      the form `ValueType from_json(const basic_json&)`
2660ccea Poul Sander 2023-09-22 19:25 17151
2660ccea Poul Sander 2023-09-22 19:25 17152
    @tparam ValueTypeCV the provided value type
2660ccea Poul Sander 2023-09-22 19:25 17153
    @tparam ValueType the returned value type
2660ccea Poul Sander 2023-09-22 19:25 17154
2660ccea Poul Sander 2023-09-22 19:25 17155
    @return copy of the JSON value, converted to @a ValueType
2660ccea Poul Sander 2023-09-22 19:25 17156
2660ccea Poul Sander 2023-09-22 19:25 17157
    @throw what @ref json_serializer<ValueType> `from_json()` method throws
2660ccea Poul Sander 2023-09-22 19:25 17158
2660ccea Poul Sander 2023-09-22 19:25 17159
    @liveexample{The example below shows several conversions from JSON values
2660ccea Poul Sander 2023-09-22 19:25 17160
    to other types. There a few things to note: (1) Floating-point numbers can
2660ccea Poul Sander 2023-09-22 19:25 17161
    be converted to integers\, (2) A JSON array can be converted to a standard
2660ccea Poul Sander 2023-09-22 19:25 17162
    `std::vector<short>`\, (3) A JSON object can be converted to C++
2660ccea Poul Sander 2023-09-22 19:25 17163
    associative containers such as `std::unordered_map<std::string\,
2660ccea Poul Sander 2023-09-22 19:25 17164
    json>`.,get__ValueType_const}
2660ccea Poul Sander 2023-09-22 19:25 17165
2660ccea Poul Sander 2023-09-22 19:25 17166
    @since version 2.1.0
2660ccea Poul Sander 2023-09-22 19:25 17167
    */
2660ccea Poul Sander 2023-09-22 19:25 17168
    template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
2660ccea Poul Sander 2023-09-22 19:25 17169
             detail::enable_if_t <
2660ccea Poul Sander 2023-09-22 19:25 17170
                 not detail::is_basic_json<ValueType>::value and
2660ccea Poul Sander 2023-09-22 19:25 17171
                 detail::has_from_json<basic_json_t, ValueType>::value and
2660ccea Poul Sander 2023-09-22 19:25 17172
                 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
2660ccea Poul Sander 2023-09-22 19:25 17173
                 int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 17174
    ValueType get() const noexcept(noexcept(
2660ccea Poul Sander 2023-09-22 19:25 17175
                                       JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
2660ccea Poul Sander 2023-09-22 19:25 17176
    {
2660ccea Poul Sander 2023-09-22 19:25 17177
        // we cannot static_assert on ValueTypeCV being non-const, because
2660ccea Poul Sander 2023-09-22 19:25 17178
        // there is support for get<const basic_json_t>(), which is why we
2660ccea Poul Sander 2023-09-22 19:25 17179
        // still need the uncvref
2660ccea Poul Sander 2023-09-22 19:25 17180
        static_assert(not std::is_reference<ValueTypeCV>::value,
2660ccea Poul Sander 2023-09-22 19:25 17181
                      "get() cannot be used with reference types, you might want to use get_ref()");
2660ccea Poul Sander 2023-09-22 19:25 17182
        static_assert(std::is_default_constructible<ValueType>::value,
2660ccea Poul Sander 2023-09-22 19:25 17183
                      "types must be DefaultConstructible when used with get()");
2660ccea Poul Sander 2023-09-22 19:25 17184
2660ccea Poul Sander 2023-09-22 19:25 17185
        ValueType ret;
2660ccea Poul Sander 2023-09-22 19:25 17186
        JSONSerializer<ValueType>::from_json(*this, ret);
2660ccea Poul Sander 2023-09-22 19:25 17187
        return ret;
2660ccea Poul Sander 2023-09-22 19:25 17188
    }
2660ccea Poul Sander 2023-09-22 19:25 17189
2660ccea Poul Sander 2023-09-22 19:25 17190
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17191
    @brief get a value (explicit); special case
2660ccea Poul Sander 2023-09-22 19:25 17192
2660ccea Poul Sander 2023-09-22 19:25 17193
    Explicit type conversion between the JSON value and a compatible value
2660ccea Poul Sander 2023-09-22 19:25 17194
    which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
2660ccea Poul Sander 2023-09-22 19:25 17195
    and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
2660ccea Poul Sander 2023-09-22 19:25 17196
    The value is converted by calling the @ref json_serializer<ValueType>
2660ccea Poul Sander 2023-09-22 19:25 17197
    `from_json()` method.
2660ccea Poul Sander 2023-09-22 19:25 17198
2660ccea Poul Sander 2023-09-22 19:25 17199
    The function is equivalent to executing
2660ccea Poul Sander 2023-09-22 19:25 17200
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 17201
    return JSONSerializer<ValueTypeCV>::from_json(*this);
2660ccea Poul Sander 2023-09-22 19:25 17202
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 17203
2660ccea Poul Sander 2023-09-22 19:25 17204
    This overloads is chosen if:
2660ccea Poul Sander 2023-09-22 19:25 17205
    - @a ValueType is not @ref basic_json and
2660ccea Poul Sander 2023-09-22 19:25 17206
    - @ref json_serializer<ValueType> has a `from_json()` method of the form
2660ccea Poul Sander 2023-09-22 19:25 17207
      `ValueType from_json(const basic_json&)`
2660ccea Poul Sander 2023-09-22 19:25 17208
2660ccea Poul Sander 2023-09-22 19:25 17209
    @note If @ref json_serializer<ValueType> has both overloads of
2660ccea Poul Sander 2023-09-22 19:25 17210
    `from_json()`, this one is chosen.
2660ccea Poul Sander 2023-09-22 19:25 17211
2660ccea Poul Sander 2023-09-22 19:25 17212
    @tparam ValueTypeCV the provided value type
2660ccea Poul Sander 2023-09-22 19:25 17213
    @tparam ValueType the returned value type
2660ccea Poul Sander 2023-09-22 19:25 17214
2660ccea Poul Sander 2023-09-22 19:25 17215
    @return copy of the JSON value, converted to @a ValueType
2660ccea Poul Sander 2023-09-22 19:25 17216
2660ccea Poul Sander 2023-09-22 19:25 17217
    @throw what @ref json_serializer<ValueType> `from_json()` method throws
2660ccea Poul Sander 2023-09-22 19:25 17218
2660ccea Poul Sander 2023-09-22 19:25 17219
    @since version 2.1.0
2660ccea Poul Sander 2023-09-22 19:25 17220
    */
2660ccea Poul Sander 2023-09-22 19:25 17221
    template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
2660ccea Poul Sander 2023-09-22 19:25 17222
             detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
2660ccea Poul Sander 2023-09-22 19:25 17223
                                 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
2660ccea Poul Sander 2023-09-22 19:25 17224
                                 int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 17225
    ValueType get() const noexcept(noexcept(
2660ccea Poul Sander 2023-09-22 19:25 17226
                                       JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
2660ccea Poul Sander 2023-09-22 19:25 17227
    {
2660ccea Poul Sander 2023-09-22 19:25 17228
        static_assert(not std::is_reference<ValueTypeCV>::value,
2660ccea Poul Sander 2023-09-22 19:25 17229
                      "get() cannot be used with reference types, you might want to use get_ref()");
2660ccea Poul Sander 2023-09-22 19:25 17230
        return JSONSerializer<ValueType>::from_json(*this);
2660ccea Poul Sander 2023-09-22 19:25 17231
    }
2660ccea Poul Sander 2023-09-22 19:25 17232
2660ccea Poul Sander 2023-09-22 19:25 17233
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17234
    @brief get a value (explicit)
2660ccea Poul Sander 2023-09-22 19:25 17235
2660ccea Poul Sander 2023-09-22 19:25 17236
    Explicit type conversion between the JSON value and a compatible value.
2660ccea Poul Sander 2023-09-22 19:25 17237
    The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
2660ccea Poul Sander 2023-09-22 19:25 17238
    `from_json()` method.
2660ccea Poul Sander 2023-09-22 19:25 17239
2660ccea Poul Sander 2023-09-22 19:25 17240
    The function is equivalent to executing
2660ccea Poul Sander 2023-09-22 19:25 17241
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 17242
    ValueType v;
2660ccea Poul Sander 2023-09-22 19:25 17243
    JSONSerializer<ValueType>::from_json(*this, v);
2660ccea Poul Sander 2023-09-22 19:25 17244
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 17245
2660ccea Poul Sander 2023-09-22 19:25 17246
    This overloads is chosen if:
2660ccea Poul Sander 2023-09-22 19:25 17247
    - @a ValueType is not @ref basic_json,
2660ccea Poul Sander 2023-09-22 19:25 17248
    - @ref json_serializer<ValueType> has a `from_json()` method of the form
2660ccea Poul Sander 2023-09-22 19:25 17249
      `void from_json(const basic_json&, ValueType&)`, and
2660ccea Poul Sander 2023-09-22 19:25 17250
2660ccea Poul Sander 2023-09-22 19:25 17251
    @tparam ValueType the input parameter type.
2660ccea Poul Sander 2023-09-22 19:25 17252
2660ccea Poul Sander 2023-09-22 19:25 17253
    @return the input parameter, allowing chaining calls.
2660ccea Poul Sander 2023-09-22 19:25 17254
2660ccea Poul Sander 2023-09-22 19:25 17255
    @throw what @ref json_serializer<ValueType> `from_json()` method throws
2660ccea Poul Sander 2023-09-22 19:25 17256
2660ccea Poul Sander 2023-09-22 19:25 17257
    @liveexample{The example below shows several conversions from JSON values
2660ccea Poul Sander 2023-09-22 19:25 17258
    to other types. There a few things to note: (1) Floating-point numbers can
2660ccea Poul Sander 2023-09-22 19:25 17259
    be converted to integers\, (2) A JSON array can be converted to a standard
2660ccea Poul Sander 2023-09-22 19:25 17260
    `std::vector<short>`\, (3) A JSON object can be converted to C++
2660ccea Poul Sander 2023-09-22 19:25 17261
    associative containers such as `std::unordered_map<std::string\,
2660ccea Poul Sander 2023-09-22 19:25 17262
    json>`.,get_to}
2660ccea Poul Sander 2023-09-22 19:25 17263
2660ccea Poul Sander 2023-09-22 19:25 17264
    @since version 3.3.0
2660ccea Poul Sander 2023-09-22 19:25 17265
    */
2660ccea Poul Sander 2023-09-22 19:25 17266
    template<typename ValueType,
2660ccea Poul Sander 2023-09-22 19:25 17267
             detail::enable_if_t <
2660ccea Poul Sander 2023-09-22 19:25 17268
                 not detail::is_basic_json<ValueType>::value and
2660ccea Poul Sander 2023-09-22 19:25 17269
                 detail::has_from_json<basic_json_t, ValueType>::value,
2660ccea Poul Sander 2023-09-22 19:25 17270
                 int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 17271
    ValueType & get_to(ValueType& v) const noexcept(noexcept(
2660ccea Poul Sander 2023-09-22 19:25 17272
                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
2660ccea Poul Sander 2023-09-22 19:25 17273
    {
2660ccea Poul Sander 2023-09-22 19:25 17274
        JSONSerializer<ValueType>::from_json(*this, v);
2660ccea Poul Sander 2023-09-22 19:25 17275
        return v;
2660ccea Poul Sander 2023-09-22 19:25 17276
    }
2660ccea Poul Sander 2023-09-22 19:25 17277
2660ccea Poul Sander 2023-09-22 19:25 17278
    template <
2660ccea Poul Sander 2023-09-22 19:25 17279
        typename T, std::size_t N,
2660ccea Poul Sander 2023-09-22 19:25 17280
        typename Array = T (&)[N],
2660ccea Poul Sander 2023-09-22 19:25 17281
        detail::enable_if_t <
2660ccea Poul Sander 2023-09-22 19:25 17282
            detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
2660ccea Poul Sander 2023-09-22 19:25 17283
    Array get_to(T (&v)[N]) const
2660ccea Poul Sander 2023-09-22 19:25 17284
    noexcept(noexcept(JSONSerializer<Array>::from_json(
2660ccea Poul Sander 2023-09-22 19:25 17285
                          std::declval<const basic_json_t&>(), v)))
2660ccea Poul Sander 2023-09-22 19:25 17286
    {
2660ccea Poul Sander 2023-09-22 19:25 17287
        JSONSerializer<Array>::from_json(*this, v);
2660ccea Poul Sander 2023-09-22 19:25 17288
        return v;
2660ccea Poul Sander 2023-09-22 19:25 17289
    }
2660ccea Poul Sander 2023-09-22 19:25 17290
2660ccea Poul Sander 2023-09-22 19:25 17291
2660ccea Poul Sander 2023-09-22 19:25 17292
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17293
    @brief get a pointer value (implicit)
2660ccea Poul Sander 2023-09-22 19:25 17294
2660ccea Poul Sander 2023-09-22 19:25 17295
    Implicit pointer access to the internally stored JSON value. No copies are
2660ccea Poul Sander 2023-09-22 19:25 17296
    made.
2660ccea Poul Sander 2023-09-22 19:25 17297
2660ccea Poul Sander 2023-09-22 19:25 17298
    @warning Writing data to the pointee of the result yields an undefined
2660ccea Poul Sander 2023-09-22 19:25 17299
    state.
2660ccea Poul Sander 2023-09-22 19:25 17300
2660ccea Poul Sander 2023-09-22 19:25 17301
    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
2660ccea Poul Sander 2023-09-22 19:25 17302
    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
2660ccea Poul Sander 2023-09-22 19:25 17303
    @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
2660ccea Poul Sander 2023-09-22 19:25 17304
    assertion.
2660ccea Poul Sander 2023-09-22 19:25 17305
2660ccea Poul Sander 2023-09-22 19:25 17306
    @return pointer to the internally stored JSON value if the requested
2660ccea Poul Sander 2023-09-22 19:25 17307
    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
2660ccea Poul Sander 2023-09-22 19:25 17308
2660ccea Poul Sander 2023-09-22 19:25 17309
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 17310
2660ccea Poul Sander 2023-09-22 19:25 17311
    @liveexample{The example below shows how pointers to internal values of a
2660ccea Poul Sander 2023-09-22 19:25 17312
    JSON value can be requested. Note that no type conversions are made and a
2660ccea Poul Sander 2023-09-22 19:25 17313
    `nullptr` is returned if the value and the requested pointer type does not
2660ccea Poul Sander 2023-09-22 19:25 17314
    match.,get_ptr}
2660ccea Poul Sander 2023-09-22 19:25 17315
2660ccea Poul Sander 2023-09-22 19:25 17316
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 17317
    */
2660ccea Poul Sander 2023-09-22 19:25 17318
    template<typename PointerType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 17319
                 std::is_pointer<PointerType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 17320
    auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
2660ccea Poul Sander 2023-09-22 19:25 17321
    {
2660ccea Poul Sander 2023-09-22 19:25 17322
        // delegate the call to get_impl_ptr<>()
2660ccea Poul Sander 2023-09-22 19:25 17323
        return get_impl_ptr(static_cast<PointerType>(nullptr));
2660ccea Poul Sander 2023-09-22 19:25 17324
    }
2660ccea Poul Sander 2023-09-22 19:25 17325
2660ccea Poul Sander 2023-09-22 19:25 17326
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17327
    @brief get a pointer value (implicit)
2660ccea Poul Sander 2023-09-22 19:25 17328
    @copydoc get_ptr()
2660ccea Poul Sander 2023-09-22 19:25 17329
    */
2660ccea Poul Sander 2023-09-22 19:25 17330
    template<typename PointerType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 17331
                 std::is_pointer<PointerType>::value and
2660ccea Poul Sander 2023-09-22 19:25 17332
                 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 17333
    constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
2660ccea Poul Sander 2023-09-22 19:25 17334
    {
2660ccea Poul Sander 2023-09-22 19:25 17335
        // delegate the call to get_impl_ptr<>() const
2660ccea Poul Sander 2023-09-22 19:25 17336
        return get_impl_ptr(static_cast<PointerType>(nullptr));
2660ccea Poul Sander 2023-09-22 19:25 17337
    }
2660ccea Poul Sander 2023-09-22 19:25 17338
2660ccea Poul Sander 2023-09-22 19:25 17339
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17340
    @brief get a pointer value (explicit)
2660ccea Poul Sander 2023-09-22 19:25 17341
2660ccea Poul Sander 2023-09-22 19:25 17342
    Explicit pointer access to the internally stored JSON value. No copies are
2660ccea Poul Sander 2023-09-22 19:25 17343
    made.
2660ccea Poul Sander 2023-09-22 19:25 17344
2660ccea Poul Sander 2023-09-22 19:25 17345
    @warning The pointer becomes invalid if the underlying JSON object
2660ccea Poul Sander 2023-09-22 19:25 17346
    changes.
2660ccea Poul Sander 2023-09-22 19:25 17347
2660ccea Poul Sander 2023-09-22 19:25 17348
    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
2660ccea Poul Sander 2023-09-22 19:25 17349
    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
2660ccea Poul Sander 2023-09-22 19:25 17350
    @ref number_unsigned_t, or @ref number_float_t.
2660ccea Poul Sander 2023-09-22 19:25 17351
2660ccea Poul Sander 2023-09-22 19:25 17352
    @return pointer to the internally stored JSON value if the requested
2660ccea Poul Sander 2023-09-22 19:25 17353
    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
2660ccea Poul Sander 2023-09-22 19:25 17354
2660ccea Poul Sander 2023-09-22 19:25 17355
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 17356
2660ccea Poul Sander 2023-09-22 19:25 17357
    @liveexample{The example below shows how pointers to internal values of a
2660ccea Poul Sander 2023-09-22 19:25 17358
    JSON value can be requested. Note that no type conversions are made and a
2660ccea Poul Sander 2023-09-22 19:25 17359
    `nullptr` is returned if the value and the requested pointer type does not
2660ccea Poul Sander 2023-09-22 19:25 17360
    match.,get__PointerType}
2660ccea Poul Sander 2023-09-22 19:25 17361
2660ccea Poul Sander 2023-09-22 19:25 17362
    @sa @ref get_ptr() for explicit pointer-member access
2660ccea Poul Sander 2023-09-22 19:25 17363
2660ccea Poul Sander 2023-09-22 19:25 17364
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 17365
    */
2660ccea Poul Sander 2023-09-22 19:25 17366
    template<typename PointerType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 17367
                 std::is_pointer<PointerType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 17368
    auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
2660ccea Poul Sander 2023-09-22 19:25 17369
    {
2660ccea Poul Sander 2023-09-22 19:25 17370
        // delegate the call to get_ptr
2660ccea Poul Sander 2023-09-22 19:25 17371
        return get_ptr<PointerType>();
2660ccea Poul Sander 2023-09-22 19:25 17372
    }
2660ccea Poul Sander 2023-09-22 19:25 17373
2660ccea Poul Sander 2023-09-22 19:25 17374
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17375
    @brief get a pointer value (explicit)
2660ccea Poul Sander 2023-09-22 19:25 17376
    @copydoc get()
2660ccea Poul Sander 2023-09-22 19:25 17377
    */
2660ccea Poul Sander 2023-09-22 19:25 17378
    template<typename PointerType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 17379
                 std::is_pointer<PointerType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 17380
    constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
2660ccea Poul Sander 2023-09-22 19:25 17381
    {
2660ccea Poul Sander 2023-09-22 19:25 17382
        // delegate the call to get_ptr
2660ccea Poul Sander 2023-09-22 19:25 17383
        return get_ptr<PointerType>();
2660ccea Poul Sander 2023-09-22 19:25 17384
    }
2660ccea Poul Sander 2023-09-22 19:25 17385
2660ccea Poul Sander 2023-09-22 19:25 17386
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17387
    @brief get a reference value (implicit)
2660ccea Poul Sander 2023-09-22 19:25 17388
2660ccea Poul Sander 2023-09-22 19:25 17389
    Implicit reference access to the internally stored JSON value. No copies
2660ccea Poul Sander 2023-09-22 19:25 17390
    are made.
2660ccea Poul Sander 2023-09-22 19:25 17391
2660ccea Poul Sander 2023-09-22 19:25 17392
    @warning Writing data to the referee of the result yields an undefined
2660ccea Poul Sander 2023-09-22 19:25 17393
    state.
2660ccea Poul Sander 2023-09-22 19:25 17394
2660ccea Poul Sander 2023-09-22 19:25 17395
    @tparam ReferenceType reference type; must be a reference to @ref array_t,
2660ccea Poul Sander 2023-09-22 19:25 17396
    @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
2660ccea Poul Sander 2023-09-22 19:25 17397
    @ref number_float_t. Enforced by static assertion.
2660ccea Poul Sander 2023-09-22 19:25 17398
2660ccea Poul Sander 2023-09-22 19:25 17399
    @return reference to the internally stored JSON value if the requested
2660ccea Poul Sander 2023-09-22 19:25 17400
    reference type @a ReferenceType fits to the JSON value; throws
2660ccea Poul Sander 2023-09-22 19:25 17401
    type_error.303 otherwise
2660ccea Poul Sander 2023-09-22 19:25 17402
2660ccea Poul Sander 2023-09-22 19:25 17403
    @throw type_error.303 in case passed type @a ReferenceType is incompatible
2660ccea Poul Sander 2023-09-22 19:25 17404
    with the stored JSON value; see example below
2660ccea Poul Sander 2023-09-22 19:25 17405
2660ccea Poul Sander 2023-09-22 19:25 17406
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 17407
2660ccea Poul Sander 2023-09-22 19:25 17408
    @liveexample{The example shows several calls to `get_ref()`.,get_ref}
2660ccea Poul Sander 2023-09-22 19:25 17409
2660ccea Poul Sander 2023-09-22 19:25 17410
    @since version 1.1.0
2660ccea Poul Sander 2023-09-22 19:25 17411
    */
2660ccea Poul Sander 2023-09-22 19:25 17412
    template<typename ReferenceType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 17413
                 std::is_reference<ReferenceType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 17414
    ReferenceType get_ref()
2660ccea Poul Sander 2023-09-22 19:25 17415
    {
2660ccea Poul Sander 2023-09-22 19:25 17416
        // delegate call to get_ref_impl
2660ccea Poul Sander 2023-09-22 19:25 17417
        return get_ref_impl<ReferenceType>(*this);
2660ccea Poul Sander 2023-09-22 19:25 17418
    }
2660ccea Poul Sander 2023-09-22 19:25 17419
2660ccea Poul Sander 2023-09-22 19:25 17420
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17421
    @brief get a reference value (implicit)
2660ccea Poul Sander 2023-09-22 19:25 17422
    @copydoc get_ref()
2660ccea Poul Sander 2023-09-22 19:25 17423
    */
2660ccea Poul Sander 2023-09-22 19:25 17424
    template<typename ReferenceType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 17425
                 std::is_reference<ReferenceType>::value and
2660ccea Poul Sander 2023-09-22 19:25 17426
                 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 17427
    ReferenceType get_ref() const
2660ccea Poul Sander 2023-09-22 19:25 17428
    {
2660ccea Poul Sander 2023-09-22 19:25 17429
        // delegate call to get_ref_impl
2660ccea Poul Sander 2023-09-22 19:25 17430
        return get_ref_impl<ReferenceType>(*this);
2660ccea Poul Sander 2023-09-22 19:25 17431
    }
2660ccea Poul Sander 2023-09-22 19:25 17432
2660ccea Poul Sander 2023-09-22 19:25 17433
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17434
    @brief get a value (implicit)
2660ccea Poul Sander 2023-09-22 19:25 17435
2660ccea Poul Sander 2023-09-22 19:25 17436
    Implicit type conversion between the JSON value and a compatible value.
2660ccea Poul Sander 2023-09-22 19:25 17437
    The call is realized by calling @ref get() const.
2660ccea Poul Sander 2023-09-22 19:25 17438
2660ccea Poul Sander 2023-09-22 19:25 17439
    @tparam ValueType non-pointer type compatible to the JSON value, for
2660ccea Poul Sander 2023-09-22 19:25 17440
    instance `int` for JSON integer numbers, `bool` for JSON booleans, or
2660ccea Poul Sander 2023-09-22 19:25 17441
    `std::vector` types for JSON arrays. The character type of @ref string_t
2660ccea Poul Sander 2023-09-22 19:25 17442
    as well as an initializer list of this type is excluded to avoid
2660ccea Poul Sander 2023-09-22 19:25 17443
    ambiguities as these types implicitly convert to `std::string`.
2660ccea Poul Sander 2023-09-22 19:25 17444
2660ccea Poul Sander 2023-09-22 19:25 17445
    @return copy of the JSON value, converted to type @a ValueType
2660ccea Poul Sander 2023-09-22 19:25 17446
2660ccea Poul Sander 2023-09-22 19:25 17447
    @throw type_error.302 in case passed type @a ValueType is incompatible
2660ccea Poul Sander 2023-09-22 19:25 17448
    to the JSON value type (e.g., the JSON value is of type boolean, but a
2660ccea Poul Sander 2023-09-22 19:25 17449
    string is requested); see example below
2660ccea Poul Sander 2023-09-22 19:25 17450
2660ccea Poul Sander 2023-09-22 19:25 17451
    @complexity Linear in the size of the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 17452
2660ccea Poul Sander 2023-09-22 19:25 17453
    @liveexample{The example below shows several conversions from JSON values
2660ccea Poul Sander 2023-09-22 19:25 17454
    to other types. There a few things to note: (1) Floating-point numbers can
2660ccea Poul Sander 2023-09-22 19:25 17455
    be converted to integers\, (2) A JSON array can be converted to a standard
2660ccea Poul Sander 2023-09-22 19:25 17456
    `std::vector<short>`\, (3) A JSON object can be converted to C++
2660ccea Poul Sander 2023-09-22 19:25 17457
    associative containers such as `std::unordered_map<std::string\,
2660ccea Poul Sander 2023-09-22 19:25 17458
    json>`.,operator__ValueType}
2660ccea Poul Sander 2023-09-22 19:25 17459
2660ccea Poul Sander 2023-09-22 19:25 17460
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 17461
    */
2660ccea Poul Sander 2023-09-22 19:25 17462
    template < typename ValueType, typename std::enable_if <
2660ccea Poul Sander 2023-09-22 19:25 17463
                   not std::is_pointer<ValueType>::value and
2660ccea Poul Sander 2023-09-22 19:25 17464
                   not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
2660ccea Poul Sander 2023-09-22 19:25 17465
                   not std::is_same<ValueType, typename string_t::value_type>::value and
2660ccea Poul Sander 2023-09-22 19:25 17466
                   not detail::is_basic_json<ValueType>::value
2660ccea Poul Sander 2023-09-22 19:25 17467
2660ccea Poul Sander 2023-09-22 19:25 17468
#ifndef _MSC_VER  // fix for issue #167 operator<< ambiguity under VS2015
2660ccea Poul Sander 2023-09-22 19:25 17469
                   and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2660ccea Poul Sander 2023-09-22 19:25 17470
#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
2660ccea Poul Sander 2023-09-22 19:25 17471
                   and not std::is_same<ValueType, typename std::string_view>::value
2660ccea Poul Sander 2023-09-22 19:25 17472
#endif
2660ccea Poul Sander 2023-09-22 19:25 17473
#endif
2660ccea Poul Sander 2023-09-22 19:25 17474
                   and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
2660ccea Poul Sander 2023-09-22 19:25 17475
                   , int >::type = 0 >
2660ccea Poul Sander 2023-09-22 19:25 17476
    operator ValueType() const
2660ccea Poul Sander 2023-09-22 19:25 17477
    {
2660ccea Poul Sander 2023-09-22 19:25 17478
        // delegate the call to get<>() const
2660ccea Poul Sander 2023-09-22 19:25 17479
        return get<ValueType>();
2660ccea Poul Sander 2023-09-22 19:25 17480
    }
2660ccea Poul Sander 2023-09-22 19:25 17481
2660ccea Poul Sander 2023-09-22 19:25 17482
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 17483
2660ccea Poul Sander 2023-09-22 19:25 17484
2660ccea Poul Sander 2023-09-22 19:25 17485
    ////////////////////
2660ccea Poul Sander 2023-09-22 19:25 17486
    // element access //
2660ccea Poul Sander 2023-09-22 19:25 17487
    ////////////////////
2660ccea Poul Sander 2023-09-22 19:25 17488
2660ccea Poul Sander 2023-09-22 19:25 17489
    /// @name element access
2660ccea Poul Sander 2023-09-22 19:25 17490
    /// Access to the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 17491
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 17492
2660ccea Poul Sander 2023-09-22 19:25 17493
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17494
    @brief access specified array element with bounds checking
2660ccea Poul Sander 2023-09-22 19:25 17495
2660ccea Poul Sander 2023-09-22 19:25 17496
    Returns a reference to the element at specified location @a idx, with
2660ccea Poul Sander 2023-09-22 19:25 17497
    bounds checking.
2660ccea Poul Sander 2023-09-22 19:25 17498
2660ccea Poul Sander 2023-09-22 19:25 17499
    @param[in] idx  index of the element to access
2660ccea Poul Sander 2023-09-22 19:25 17500
2660ccea Poul Sander 2023-09-22 19:25 17501
    @return reference to the element at index @a idx
2660ccea Poul Sander 2023-09-22 19:25 17502
2660ccea Poul Sander 2023-09-22 19:25 17503
    @throw type_error.304 if the JSON value is not an array; in this case,
2660ccea Poul Sander 2023-09-22 19:25 17504
    calling `at` with an index makes no sense. See example below.
2660ccea Poul Sander 2023-09-22 19:25 17505
    @throw out_of_range.401 if the index @a idx is out of range of the array;
2660ccea Poul Sander 2023-09-22 19:25 17506
    that is, `idx >= size()`. See example below.
2660ccea Poul Sander 2023-09-22 19:25 17507
2660ccea Poul Sander 2023-09-22 19:25 17508
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 17509
    changes in the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 17510
2660ccea Poul Sander 2023-09-22 19:25 17511
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 17512
2660ccea Poul Sander 2023-09-22 19:25 17513
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 17514
2660ccea Poul Sander 2023-09-22 19:25 17515
    @liveexample{The example below shows how array elements can be read and
2660ccea Poul Sander 2023-09-22 19:25 17516
    written using `at()`. It also demonstrates the different exceptions that
2660ccea Poul Sander 2023-09-22 19:25 17517
    can be thrown.,at__size_type}
2660ccea Poul Sander 2023-09-22 19:25 17518
    */
2660ccea Poul Sander 2023-09-22 19:25 17519
    reference at(size_type idx)
2660ccea Poul Sander 2023-09-22 19:25 17520
    {
2660ccea Poul Sander 2023-09-22 19:25 17521
        // at only works for arrays
2660ccea Poul Sander 2023-09-22 19:25 17522
        if (JSON_HEDLEY_LIKELY(is_array()))
2660ccea Poul Sander 2023-09-22 19:25 17523
        {
2660ccea Poul Sander 2023-09-22 19:25 17524
            JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 17525
            {
2660ccea Poul Sander 2023-09-22 19:25 17526
                return m_value.array->at(idx);
2660ccea Poul Sander 2023-09-22 19:25 17527
            }
2660ccea Poul Sander 2023-09-22 19:25 17528
            JSON_CATCH (std::out_of_range&)
2660ccea Poul Sander 2023-09-22 19:25 17529
            {
2660ccea Poul Sander 2023-09-22 19:25 17530
                // create better exception explanation
2660ccea Poul Sander 2023-09-22 19:25 17531
                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
2660ccea Poul Sander 2023-09-22 19:25 17532
            }
2660ccea Poul Sander 2023-09-22 19:25 17533
        }
2660ccea Poul Sander 2023-09-22 19:25 17534
        else
2660ccea Poul Sander 2023-09-22 19:25 17535
        {
2660ccea Poul Sander 2023-09-22 19:25 17536
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 17537
        }
2660ccea Poul Sander 2023-09-22 19:25 17538
    }
2660ccea Poul Sander 2023-09-22 19:25 17539
2660ccea Poul Sander 2023-09-22 19:25 17540
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17541
    @brief access specified array element with bounds checking
2660ccea Poul Sander 2023-09-22 19:25 17542
2660ccea Poul Sander 2023-09-22 19:25 17543
    Returns a const reference to the element at specified location @a idx,
2660ccea Poul Sander 2023-09-22 19:25 17544
    with bounds checking.
2660ccea Poul Sander 2023-09-22 19:25 17545
2660ccea Poul Sander 2023-09-22 19:25 17546
    @param[in] idx  index of the element to access
2660ccea Poul Sander 2023-09-22 19:25 17547
2660ccea Poul Sander 2023-09-22 19:25 17548
    @return const reference to the element at index @a idx
2660ccea Poul Sander 2023-09-22 19:25 17549
2660ccea Poul Sander 2023-09-22 19:25 17550
    @throw type_error.304 if the JSON value is not an array; in this case,
2660ccea Poul Sander 2023-09-22 19:25 17551
    calling `at` with an index makes no sense. See example below.
2660ccea Poul Sander 2023-09-22 19:25 17552
    @throw out_of_range.401 if the index @a idx is out of range of the array;
2660ccea Poul Sander 2023-09-22 19:25 17553
    that is, `idx >= size()`. See example below.
2660ccea Poul Sander 2023-09-22 19:25 17554
2660ccea Poul Sander 2023-09-22 19:25 17555
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 17556
    changes in the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 17557
2660ccea Poul Sander 2023-09-22 19:25 17558
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 17559
2660ccea Poul Sander 2023-09-22 19:25 17560
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 17561
2660ccea Poul Sander 2023-09-22 19:25 17562
    @liveexample{The example below shows how array elements can be read using
2660ccea Poul Sander 2023-09-22 19:25 17563
    `at()`. It also demonstrates the different exceptions that can be thrown.,
2660ccea Poul Sander 2023-09-22 19:25 17564
    at__size_type_const}
2660ccea Poul Sander 2023-09-22 19:25 17565
    */
2660ccea Poul Sander 2023-09-22 19:25 17566
    const_reference at(size_type idx) const
2660ccea Poul Sander 2023-09-22 19:25 17567
    {
2660ccea Poul Sander 2023-09-22 19:25 17568
        // at only works for arrays
2660ccea Poul Sander 2023-09-22 19:25 17569
        if (JSON_HEDLEY_LIKELY(is_array()))
2660ccea Poul Sander 2023-09-22 19:25 17570
        {
2660ccea Poul Sander 2023-09-22 19:25 17571
            JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 17572
            {
2660ccea Poul Sander 2023-09-22 19:25 17573
                return m_value.array->at(idx);
2660ccea Poul Sander 2023-09-22 19:25 17574
            }
2660ccea Poul Sander 2023-09-22 19:25 17575
            JSON_CATCH (std::out_of_range&)
2660ccea Poul Sander 2023-09-22 19:25 17576
            {
2660ccea Poul Sander 2023-09-22 19:25 17577
                // create better exception explanation
2660ccea Poul Sander 2023-09-22 19:25 17578
                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
2660ccea Poul Sander 2023-09-22 19:25 17579
            }
2660ccea Poul Sander 2023-09-22 19:25 17580
        }
2660ccea Poul Sander 2023-09-22 19:25 17581
        else
2660ccea Poul Sander 2023-09-22 19:25 17582
        {
2660ccea Poul Sander 2023-09-22 19:25 17583
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 17584
        }
2660ccea Poul Sander 2023-09-22 19:25 17585
    }
2660ccea Poul Sander 2023-09-22 19:25 17586
2660ccea Poul Sander 2023-09-22 19:25 17587
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17588
    @brief access specified object element with bounds checking
2660ccea Poul Sander 2023-09-22 19:25 17589
2660ccea Poul Sander 2023-09-22 19:25 17590
    Returns a reference to the element at with specified key @a key, with
2660ccea Poul Sander 2023-09-22 19:25 17591
    bounds checking.
2660ccea Poul Sander 2023-09-22 19:25 17592
2660ccea Poul Sander 2023-09-22 19:25 17593
    @param[in] key  key of the element to access
2660ccea Poul Sander 2023-09-22 19:25 17594
2660ccea Poul Sander 2023-09-22 19:25 17595
    @return reference to the element at key @a key
2660ccea Poul Sander 2023-09-22 19:25 17596
2660ccea Poul Sander 2023-09-22 19:25 17597
    @throw type_error.304 if the JSON value is not an object; in this case,
2660ccea Poul Sander 2023-09-22 19:25 17598
    calling `at` with a key makes no sense. See example below.
2660ccea Poul Sander 2023-09-22 19:25 17599
    @throw out_of_range.403 if the key @a key is is not stored in the object;
2660ccea Poul Sander 2023-09-22 19:25 17600
    that is, `find(key) == end()`. See example below.
2660ccea Poul Sander 2023-09-22 19:25 17601
2660ccea Poul Sander 2023-09-22 19:25 17602
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 17603
    changes in the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 17604
2660ccea Poul Sander 2023-09-22 19:25 17605
    @complexity Logarithmic in the size of the container.
2660ccea Poul Sander 2023-09-22 19:25 17606
2660ccea Poul Sander 2023-09-22 19:25 17607
    @sa @ref operator[](const typename object_t::key_type&) for unchecked
2660ccea Poul Sander 2023-09-22 19:25 17608
    access by reference
2660ccea Poul Sander 2023-09-22 19:25 17609
    @sa @ref value() for access by value with a default value
2660ccea Poul Sander 2023-09-22 19:25 17610
2660ccea Poul Sander 2023-09-22 19:25 17611
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 17612
2660ccea Poul Sander 2023-09-22 19:25 17613
    @liveexample{The example below shows how object elements can be read and
2660ccea Poul Sander 2023-09-22 19:25 17614
    written using `at()`. It also demonstrates the different exceptions that
2660ccea Poul Sander 2023-09-22 19:25 17615
    can be thrown.,at__object_t_key_type}
2660ccea Poul Sander 2023-09-22 19:25 17616
    */
2660ccea Poul Sander 2023-09-22 19:25 17617
    reference at(const typename object_t::key_type& key)
2660ccea Poul Sander 2023-09-22 19:25 17618
    {
2660ccea Poul Sander 2023-09-22 19:25 17619
        // at only works for objects
2660ccea Poul Sander 2023-09-22 19:25 17620
        if (JSON_HEDLEY_LIKELY(is_object()))
2660ccea Poul Sander 2023-09-22 19:25 17621
        {
2660ccea Poul Sander 2023-09-22 19:25 17622
            JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 17623
            {
2660ccea Poul Sander 2023-09-22 19:25 17624
                return m_value.object->at(key);
2660ccea Poul Sander 2023-09-22 19:25 17625
            }
2660ccea Poul Sander 2023-09-22 19:25 17626
            JSON_CATCH (std::out_of_range&)
2660ccea Poul Sander 2023-09-22 19:25 17627
            {
2660ccea Poul Sander 2023-09-22 19:25 17628
                // create better exception explanation
2660ccea Poul Sander 2023-09-22 19:25 17629
                JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
2660ccea Poul Sander 2023-09-22 19:25 17630
            }
2660ccea Poul Sander 2023-09-22 19:25 17631
        }
2660ccea Poul Sander 2023-09-22 19:25 17632
        else
2660ccea Poul Sander 2023-09-22 19:25 17633
        {
2660ccea Poul Sander 2023-09-22 19:25 17634
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 17635
        }
2660ccea Poul Sander 2023-09-22 19:25 17636
    }
2660ccea Poul Sander 2023-09-22 19:25 17637
2660ccea Poul Sander 2023-09-22 19:25 17638
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17639
    @brief access specified object element with bounds checking
2660ccea Poul Sander 2023-09-22 19:25 17640
2660ccea Poul Sander 2023-09-22 19:25 17641
    Returns a const reference to the element at with specified key @a key,
2660ccea Poul Sander 2023-09-22 19:25 17642
    with bounds checking.
2660ccea Poul Sander 2023-09-22 19:25 17643
2660ccea Poul Sander 2023-09-22 19:25 17644
    @param[in] key  key of the element to access
2660ccea Poul Sander 2023-09-22 19:25 17645
2660ccea Poul Sander 2023-09-22 19:25 17646
    @return const reference to the element at key @a key
2660ccea Poul Sander 2023-09-22 19:25 17647
2660ccea Poul Sander 2023-09-22 19:25 17648
    @throw type_error.304 if the JSON value is not an object; in this case,
2660ccea Poul Sander 2023-09-22 19:25 17649
    calling `at` with a key makes no sense. See example below.
2660ccea Poul Sander 2023-09-22 19:25 17650
    @throw out_of_range.403 if the key @a key is is not stored in the object;
2660ccea Poul Sander 2023-09-22 19:25 17651
    that is, `find(key) == end()`. See example below.
2660ccea Poul Sander 2023-09-22 19:25 17652
2660ccea Poul Sander 2023-09-22 19:25 17653
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 17654
    changes in the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 17655
2660ccea Poul Sander 2023-09-22 19:25 17656
    @complexity Logarithmic in the size of the container.
2660ccea Poul Sander 2023-09-22 19:25 17657
2660ccea Poul Sander 2023-09-22 19:25 17658
    @sa @ref operator[](const typename object_t::key_type&) for unchecked
2660ccea Poul Sander 2023-09-22 19:25 17659
    access by reference
2660ccea Poul Sander 2023-09-22 19:25 17660
    @sa @ref value() for access by value with a default value
2660ccea Poul Sander 2023-09-22 19:25 17661
2660ccea Poul Sander 2023-09-22 19:25 17662
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 17663
2660ccea Poul Sander 2023-09-22 19:25 17664
    @liveexample{The example below shows how object elements can be read using
2660ccea Poul Sander 2023-09-22 19:25 17665
    `at()`. It also demonstrates the different exceptions that can be thrown.,
2660ccea Poul Sander 2023-09-22 19:25 17666
    at__object_t_key_type_const}
2660ccea Poul Sander 2023-09-22 19:25 17667
    */
2660ccea Poul Sander 2023-09-22 19:25 17668
    const_reference at(const typename object_t::key_type& key) const
2660ccea Poul Sander 2023-09-22 19:25 17669
    {
2660ccea Poul Sander 2023-09-22 19:25 17670
        // at only works for objects
2660ccea Poul Sander 2023-09-22 19:25 17671
        if (JSON_HEDLEY_LIKELY(is_object()))
2660ccea Poul Sander 2023-09-22 19:25 17672
        {
2660ccea Poul Sander 2023-09-22 19:25 17673
            JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 17674
            {
2660ccea Poul Sander 2023-09-22 19:25 17675
                return m_value.object->at(key);
2660ccea Poul Sander 2023-09-22 19:25 17676
            }
2660ccea Poul Sander 2023-09-22 19:25 17677
            JSON_CATCH (std::out_of_range&)
2660ccea Poul Sander 2023-09-22 19:25 17678
            {
2660ccea Poul Sander 2023-09-22 19:25 17679
                // create better exception explanation
2660ccea Poul Sander 2023-09-22 19:25 17680
                JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
2660ccea Poul Sander 2023-09-22 19:25 17681
            }
2660ccea Poul Sander 2023-09-22 19:25 17682
        }
2660ccea Poul Sander 2023-09-22 19:25 17683
        else
2660ccea Poul Sander 2023-09-22 19:25 17684
        {
2660ccea Poul Sander 2023-09-22 19:25 17685
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 17686
        }
2660ccea Poul Sander 2023-09-22 19:25 17687
    }
2660ccea Poul Sander 2023-09-22 19:25 17688
2660ccea Poul Sander 2023-09-22 19:25 17689
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17690
    @brief access specified array element
2660ccea Poul Sander 2023-09-22 19:25 17691
2660ccea Poul Sander 2023-09-22 19:25 17692
    Returns a reference to the element at specified location @a idx.
2660ccea Poul Sander 2023-09-22 19:25 17693
2660ccea Poul Sander 2023-09-22 19:25 17694
    @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
2660ccea Poul Sander 2023-09-22 19:25 17695
    then the array is silently filled up with `null` values to make `idx` a
2660ccea Poul Sander 2023-09-22 19:25 17696
    valid reference to the last stored element.
2660ccea Poul Sander 2023-09-22 19:25 17697
2660ccea Poul Sander 2023-09-22 19:25 17698
    @param[in] idx  index of the element to access
2660ccea Poul Sander 2023-09-22 19:25 17699
2660ccea Poul Sander 2023-09-22 19:25 17700
    @return reference to the element at index @a idx
2660ccea Poul Sander 2023-09-22 19:25 17701
2660ccea Poul Sander 2023-09-22 19:25 17702
    @throw type_error.305 if the JSON value is not an array or null; in that
2660ccea Poul Sander 2023-09-22 19:25 17703
    cases, using the [] operator with an index makes no sense.
2660ccea Poul Sander 2023-09-22 19:25 17704
2660ccea Poul Sander 2023-09-22 19:25 17705
    @complexity Constant if @a idx is in the range of the array. Otherwise
2660ccea Poul Sander 2023-09-22 19:25 17706
    linear in `idx - size()`.
2660ccea Poul Sander 2023-09-22 19:25 17707
2660ccea Poul Sander 2023-09-22 19:25 17708
    @liveexample{The example below shows how array elements can be read and
2660ccea Poul Sander 2023-09-22 19:25 17709
    written using `[]` operator. Note the addition of `null`
2660ccea Poul Sander 2023-09-22 19:25 17710
    values.,operatorarray__size_type}
2660ccea Poul Sander 2023-09-22 19:25 17711
2660ccea Poul Sander 2023-09-22 19:25 17712
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 17713
    */
2660ccea Poul Sander 2023-09-22 19:25 17714
    reference operator[](size_type idx)
2660ccea Poul Sander 2023-09-22 19:25 17715
    {
2660ccea Poul Sander 2023-09-22 19:25 17716
        // implicitly convert null value to an empty array
2660ccea Poul Sander 2023-09-22 19:25 17717
        if (is_null())
2660ccea Poul Sander 2023-09-22 19:25 17718
        {
2660ccea Poul Sander 2023-09-22 19:25 17719
            m_type = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 17720
            m_value.array = create<array_t>();
2660ccea Poul Sander 2023-09-22 19:25 17721
            assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 17722
        }
2660ccea Poul Sander 2023-09-22 19:25 17723
2660ccea Poul Sander 2023-09-22 19:25 17724
        // operator[] only works for arrays
2660ccea Poul Sander 2023-09-22 19:25 17725
        if (JSON_HEDLEY_LIKELY(is_array()))
2660ccea Poul Sander 2023-09-22 19:25 17726
        {
2660ccea Poul Sander 2023-09-22 19:25 17727
            // fill up array with null values if given idx is outside range
2660ccea Poul Sander 2023-09-22 19:25 17728
            if (idx >= m_value.array->size())
2660ccea Poul Sander 2023-09-22 19:25 17729
            {
2660ccea Poul Sander 2023-09-22 19:25 17730
                m_value.array->insert(m_value.array->end(),
2660ccea Poul Sander 2023-09-22 19:25 17731
                                      idx - m_value.array->size() + 1,
2660ccea Poul Sander 2023-09-22 19:25 17732
                                      basic_json());
2660ccea Poul Sander 2023-09-22 19:25 17733
            }
2660ccea Poul Sander 2023-09-22 19:25 17734
2660ccea Poul Sander 2023-09-22 19:25 17735
            return m_value.array->operator[](idx);
2660ccea Poul Sander 2023-09-22 19:25 17736
        }
2660ccea Poul Sander 2023-09-22 19:25 17737
2660ccea Poul Sander 2023-09-22 19:25 17738
        JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 17739
    }
2660ccea Poul Sander 2023-09-22 19:25 17740
2660ccea Poul Sander 2023-09-22 19:25 17741
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17742
    @brief access specified array element
2660ccea Poul Sander 2023-09-22 19:25 17743
2660ccea Poul Sander 2023-09-22 19:25 17744
    Returns a const reference to the element at specified location @a idx.
2660ccea Poul Sander 2023-09-22 19:25 17745
2660ccea Poul Sander 2023-09-22 19:25 17746
    @param[in] idx  index of the element to access
2660ccea Poul Sander 2023-09-22 19:25 17747
2660ccea Poul Sander 2023-09-22 19:25 17748
    @return const reference to the element at index @a idx
2660ccea Poul Sander 2023-09-22 19:25 17749
2660ccea Poul Sander 2023-09-22 19:25 17750
    @throw type_error.305 if the JSON value is not an array; in that case,
2660ccea Poul Sander 2023-09-22 19:25 17751
    using the [] operator with an index makes no sense.
2660ccea Poul Sander 2023-09-22 19:25 17752
2660ccea Poul Sander 2023-09-22 19:25 17753
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 17754
2660ccea Poul Sander 2023-09-22 19:25 17755
    @liveexample{The example below shows how array elements can be read using
2660ccea Poul Sander 2023-09-22 19:25 17756
    the `[]` operator.,operatorarray__size_type_const}
2660ccea Poul Sander 2023-09-22 19:25 17757
2660ccea Poul Sander 2023-09-22 19:25 17758
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 17759
    */
2660ccea Poul Sander 2023-09-22 19:25 17760
    const_reference operator[](size_type idx) const
2660ccea Poul Sander 2023-09-22 19:25 17761
    {
2660ccea Poul Sander 2023-09-22 19:25 17762
        // const operator[] only works for arrays
2660ccea Poul Sander 2023-09-22 19:25 17763
        if (JSON_HEDLEY_LIKELY(is_array()))
2660ccea Poul Sander 2023-09-22 19:25 17764
        {
2660ccea Poul Sander 2023-09-22 19:25 17765
            return m_value.array->operator[](idx);
2660ccea Poul Sander 2023-09-22 19:25 17766
        }
2660ccea Poul Sander 2023-09-22 19:25 17767
2660ccea Poul Sander 2023-09-22 19:25 17768
        JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 17769
    }
2660ccea Poul Sander 2023-09-22 19:25 17770
2660ccea Poul Sander 2023-09-22 19:25 17771
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17772
    @brief access specified object element
2660ccea Poul Sander 2023-09-22 19:25 17773
2660ccea Poul Sander 2023-09-22 19:25 17774
    Returns a reference to the element at with specified key @a key.
2660ccea Poul Sander 2023-09-22 19:25 17775
2660ccea Poul Sander 2023-09-22 19:25 17776
    @note If @a key is not found in the object, then it is silently added to
2660ccea Poul Sander 2023-09-22 19:25 17777
    the object and filled with a `null` value to make `key` a valid reference.
2660ccea Poul Sander 2023-09-22 19:25 17778
    In case the value was `null` before, it is converted to an object.
2660ccea Poul Sander 2023-09-22 19:25 17779
2660ccea Poul Sander 2023-09-22 19:25 17780
    @param[in] key  key of the element to access
2660ccea Poul Sander 2023-09-22 19:25 17781
2660ccea Poul Sander 2023-09-22 19:25 17782
    @return reference to the element at key @a key
2660ccea Poul Sander 2023-09-22 19:25 17783
2660ccea Poul Sander 2023-09-22 19:25 17784
    @throw type_error.305 if the JSON value is not an object or null; in that
2660ccea Poul Sander 2023-09-22 19:25 17785
    cases, using the [] operator with a key makes no sense.
2660ccea Poul Sander 2023-09-22 19:25 17786
2660ccea Poul Sander 2023-09-22 19:25 17787
    @complexity Logarithmic in the size of the container.
2660ccea Poul Sander 2023-09-22 19:25 17788
2660ccea Poul Sander 2023-09-22 19:25 17789
    @liveexample{The example below shows how object elements can be read and
2660ccea Poul Sander 2023-09-22 19:25 17790
    written using the `[]` operator.,operatorarray__key_type}
2660ccea Poul Sander 2023-09-22 19:25 17791
2660ccea Poul Sander 2023-09-22 19:25 17792
    @sa @ref at(const typename object_t::key_type&) for access by reference
2660ccea Poul Sander 2023-09-22 19:25 17793
    with range checking
2660ccea Poul Sander 2023-09-22 19:25 17794
    @sa @ref value() for access by value with a default value
2660ccea Poul Sander 2023-09-22 19:25 17795
2660ccea Poul Sander 2023-09-22 19:25 17796
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 17797
    */
2660ccea Poul Sander 2023-09-22 19:25 17798
    reference operator[](const typename object_t::key_type& key)
2660ccea Poul Sander 2023-09-22 19:25 17799
    {
2660ccea Poul Sander 2023-09-22 19:25 17800
        // implicitly convert null value to an empty object
2660ccea Poul Sander 2023-09-22 19:25 17801
        if (is_null())
2660ccea Poul Sander 2023-09-22 19:25 17802
        {
2660ccea Poul Sander 2023-09-22 19:25 17803
            m_type = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 17804
            m_value.object = create<object_t>();
2660ccea Poul Sander 2023-09-22 19:25 17805
            assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 17806
        }
2660ccea Poul Sander 2023-09-22 19:25 17807
2660ccea Poul Sander 2023-09-22 19:25 17808
        // operator[] only works for objects
2660ccea Poul Sander 2023-09-22 19:25 17809
        if (JSON_HEDLEY_LIKELY(is_object()))
2660ccea Poul Sander 2023-09-22 19:25 17810
        {
2660ccea Poul Sander 2023-09-22 19:25 17811
            return m_value.object->operator[](key);
2660ccea Poul Sander 2023-09-22 19:25 17812
        }
2660ccea Poul Sander 2023-09-22 19:25 17813
2660ccea Poul Sander 2023-09-22 19:25 17814
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 17815
    }
2660ccea Poul Sander 2023-09-22 19:25 17816
2660ccea Poul Sander 2023-09-22 19:25 17817
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17818
    @brief read-only access specified object element
2660ccea Poul Sander 2023-09-22 19:25 17819
2660ccea Poul Sander 2023-09-22 19:25 17820
    Returns a const reference to the element at with specified key @a key. No
2660ccea Poul Sander 2023-09-22 19:25 17821
    bounds checking is performed.
2660ccea Poul Sander 2023-09-22 19:25 17822
2660ccea Poul Sander 2023-09-22 19:25 17823
    @warning If the element with key @a key does not exist, the behavior is
2660ccea Poul Sander 2023-09-22 19:25 17824
    undefined.
2660ccea Poul Sander 2023-09-22 19:25 17825
2660ccea Poul Sander 2023-09-22 19:25 17826
    @param[in] key  key of the element to access
2660ccea Poul Sander 2023-09-22 19:25 17827
2660ccea Poul Sander 2023-09-22 19:25 17828
    @return const reference to the element at key @a key
2660ccea Poul Sander 2023-09-22 19:25 17829
2660ccea Poul Sander 2023-09-22 19:25 17830
    @pre The element with key @a key must exist. **This precondition is
2660ccea Poul Sander 2023-09-22 19:25 17831
         enforced with an assertion.**
2660ccea Poul Sander 2023-09-22 19:25 17832
2660ccea Poul Sander 2023-09-22 19:25 17833
    @throw type_error.305 if the JSON value is not an object; in that case,
2660ccea Poul Sander 2023-09-22 19:25 17834
    using the [] operator with a key makes no sense.
2660ccea Poul Sander 2023-09-22 19:25 17835
2660ccea Poul Sander 2023-09-22 19:25 17836
    @complexity Logarithmic in the size of the container.
2660ccea Poul Sander 2023-09-22 19:25 17837
2660ccea Poul Sander 2023-09-22 19:25 17838
    @liveexample{The example below shows how object elements can be read using
2660ccea Poul Sander 2023-09-22 19:25 17839
    the `[]` operator.,operatorarray__key_type_const}
2660ccea Poul Sander 2023-09-22 19:25 17840
2660ccea Poul Sander 2023-09-22 19:25 17841
    @sa @ref at(const typename object_t::key_type&) for access by reference
2660ccea Poul Sander 2023-09-22 19:25 17842
    with range checking
2660ccea Poul Sander 2023-09-22 19:25 17843
    @sa @ref value() for access by value with a default value
2660ccea Poul Sander 2023-09-22 19:25 17844
2660ccea Poul Sander 2023-09-22 19:25 17845
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 17846
    */
2660ccea Poul Sander 2023-09-22 19:25 17847
    const_reference operator[](const typename object_t::key_type& key) const
2660ccea Poul Sander 2023-09-22 19:25 17848
    {
2660ccea Poul Sander 2023-09-22 19:25 17849
        // const operator[] only works for objects
2660ccea Poul Sander 2023-09-22 19:25 17850
        if (JSON_HEDLEY_LIKELY(is_object()))
2660ccea Poul Sander 2023-09-22 19:25 17851
        {
2660ccea Poul Sander 2023-09-22 19:25 17852
            assert(m_value.object->find(key) != m_value.object->end());
2660ccea Poul Sander 2023-09-22 19:25 17853
            return m_value.object->find(key)->second;
2660ccea Poul Sander 2023-09-22 19:25 17854
        }
2660ccea Poul Sander 2023-09-22 19:25 17855
2660ccea Poul Sander 2023-09-22 19:25 17856
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 17857
    }
2660ccea Poul Sander 2023-09-22 19:25 17858
2660ccea Poul Sander 2023-09-22 19:25 17859
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17860
    @brief access specified object element
2660ccea Poul Sander 2023-09-22 19:25 17861
2660ccea Poul Sander 2023-09-22 19:25 17862
    Returns a reference to the element at with specified key @a key.
2660ccea Poul Sander 2023-09-22 19:25 17863
2660ccea Poul Sander 2023-09-22 19:25 17864
    @note If @a key is not found in the object, then it is silently added to
2660ccea Poul Sander 2023-09-22 19:25 17865
    the object and filled with a `null` value to make `key` a valid reference.
2660ccea Poul Sander 2023-09-22 19:25 17866
    In case the value was `null` before, it is converted to an object.
2660ccea Poul Sander 2023-09-22 19:25 17867
2660ccea Poul Sander 2023-09-22 19:25 17868
    @param[in] key  key of the element to access
2660ccea Poul Sander 2023-09-22 19:25 17869
2660ccea Poul Sander 2023-09-22 19:25 17870
    @return reference to the element at key @a key
2660ccea Poul Sander 2023-09-22 19:25 17871
2660ccea Poul Sander 2023-09-22 19:25 17872
    @throw type_error.305 if the JSON value is not an object or null; in that
2660ccea Poul Sander 2023-09-22 19:25 17873
    cases, using the [] operator with a key makes no sense.
2660ccea Poul Sander 2023-09-22 19:25 17874
2660ccea Poul Sander 2023-09-22 19:25 17875
    @complexity Logarithmic in the size of the container.
2660ccea Poul Sander 2023-09-22 19:25 17876
2660ccea Poul Sander 2023-09-22 19:25 17877
    @liveexample{The example below shows how object elements can be read and
2660ccea Poul Sander 2023-09-22 19:25 17878
    written using the `[]` operator.,operatorarray__key_type}
2660ccea Poul Sander 2023-09-22 19:25 17879
2660ccea Poul Sander 2023-09-22 19:25 17880
    @sa @ref at(const typename object_t::key_type&) for access by reference
2660ccea Poul Sander 2023-09-22 19:25 17881
    with range checking
2660ccea Poul Sander 2023-09-22 19:25 17882
    @sa @ref value() for access by value with a default value
2660ccea Poul Sander 2023-09-22 19:25 17883
2660ccea Poul Sander 2023-09-22 19:25 17884
    @since version 1.1.0
2660ccea Poul Sander 2023-09-22 19:25 17885
    */
2660ccea Poul Sander 2023-09-22 19:25 17886
    template<typename T>
2660ccea Poul Sander 2023-09-22 19:25 17887
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 17888
    reference operator[](T* key)
2660ccea Poul Sander 2023-09-22 19:25 17889
    {
2660ccea Poul Sander 2023-09-22 19:25 17890
        // implicitly convert null to object
2660ccea Poul Sander 2023-09-22 19:25 17891
        if (is_null())
2660ccea Poul Sander 2023-09-22 19:25 17892
        {
2660ccea Poul Sander 2023-09-22 19:25 17893
            m_type = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 17894
            m_value = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 17895
            assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 17896
        }
2660ccea Poul Sander 2023-09-22 19:25 17897
2660ccea Poul Sander 2023-09-22 19:25 17898
        // at only works for objects
2660ccea Poul Sander 2023-09-22 19:25 17899
        if (JSON_HEDLEY_LIKELY(is_object()))
2660ccea Poul Sander 2023-09-22 19:25 17900
        {
2660ccea Poul Sander 2023-09-22 19:25 17901
            return m_value.object->operator[](key);
2660ccea Poul Sander 2023-09-22 19:25 17902
        }
2660ccea Poul Sander 2023-09-22 19:25 17903
2660ccea Poul Sander 2023-09-22 19:25 17904
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 17905
    }
2660ccea Poul Sander 2023-09-22 19:25 17906
2660ccea Poul Sander 2023-09-22 19:25 17907
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17908
    @brief read-only access specified object element
2660ccea Poul Sander 2023-09-22 19:25 17909
2660ccea Poul Sander 2023-09-22 19:25 17910
    Returns a const reference to the element at with specified key @a key. No
2660ccea Poul Sander 2023-09-22 19:25 17911
    bounds checking is performed.
2660ccea Poul Sander 2023-09-22 19:25 17912
2660ccea Poul Sander 2023-09-22 19:25 17913
    @warning If the element with key @a key does not exist, the behavior is
2660ccea Poul Sander 2023-09-22 19:25 17914
    undefined.
2660ccea Poul Sander 2023-09-22 19:25 17915
2660ccea Poul Sander 2023-09-22 19:25 17916
    @param[in] key  key of the element to access
2660ccea Poul Sander 2023-09-22 19:25 17917
2660ccea Poul Sander 2023-09-22 19:25 17918
    @return const reference to the element at key @a key
2660ccea Poul Sander 2023-09-22 19:25 17919
2660ccea Poul Sander 2023-09-22 19:25 17920
    @pre The element with key @a key must exist. **This precondition is
2660ccea Poul Sander 2023-09-22 19:25 17921
         enforced with an assertion.**
2660ccea Poul Sander 2023-09-22 19:25 17922
2660ccea Poul Sander 2023-09-22 19:25 17923
    @throw type_error.305 if the JSON value is not an object; in that case,
2660ccea Poul Sander 2023-09-22 19:25 17924
    using the [] operator with a key makes no sense.
2660ccea Poul Sander 2023-09-22 19:25 17925
2660ccea Poul Sander 2023-09-22 19:25 17926
    @complexity Logarithmic in the size of the container.
2660ccea Poul Sander 2023-09-22 19:25 17927
2660ccea Poul Sander 2023-09-22 19:25 17928
    @liveexample{The example below shows how object elements can be read using
2660ccea Poul Sander 2023-09-22 19:25 17929
    the `[]` operator.,operatorarray__key_type_const}
2660ccea Poul Sander 2023-09-22 19:25 17930
2660ccea Poul Sander 2023-09-22 19:25 17931
    @sa @ref at(const typename object_t::key_type&) for access by reference
2660ccea Poul Sander 2023-09-22 19:25 17932
    with range checking
2660ccea Poul Sander 2023-09-22 19:25 17933
    @sa @ref value() for access by value with a default value
2660ccea Poul Sander 2023-09-22 19:25 17934
2660ccea Poul Sander 2023-09-22 19:25 17935
    @since version 1.1.0
2660ccea Poul Sander 2023-09-22 19:25 17936
    */
2660ccea Poul Sander 2023-09-22 19:25 17937
    template<typename T>
2660ccea Poul Sander 2023-09-22 19:25 17938
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 17939
    const_reference operator[](T* key) const
2660ccea Poul Sander 2023-09-22 19:25 17940
    {
2660ccea Poul Sander 2023-09-22 19:25 17941
        // at only works for objects
2660ccea Poul Sander 2023-09-22 19:25 17942
        if (JSON_HEDLEY_LIKELY(is_object()))
2660ccea Poul Sander 2023-09-22 19:25 17943
        {
2660ccea Poul Sander 2023-09-22 19:25 17944
            assert(m_value.object->find(key) != m_value.object->end());
2660ccea Poul Sander 2023-09-22 19:25 17945
            return m_value.object->find(key)->second;
2660ccea Poul Sander 2023-09-22 19:25 17946
        }
2660ccea Poul Sander 2023-09-22 19:25 17947
2660ccea Poul Sander 2023-09-22 19:25 17948
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 17949
    }
2660ccea Poul Sander 2023-09-22 19:25 17950
2660ccea Poul Sander 2023-09-22 19:25 17951
    /*!
2660ccea Poul Sander 2023-09-22 19:25 17952
    @brief access specified object element with default value
2660ccea Poul Sander 2023-09-22 19:25 17953
2660ccea Poul Sander 2023-09-22 19:25 17954
    Returns either a copy of an object's element at the specified key @a key
2660ccea Poul Sander 2023-09-22 19:25 17955
    or a given default value if no element with key @a key exists.
2660ccea Poul Sander 2023-09-22 19:25 17956
2660ccea Poul Sander 2023-09-22 19:25 17957
    The function is basically equivalent to executing
2660ccea Poul Sander 2023-09-22 19:25 17958
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 17959
    try {
2660ccea Poul Sander 2023-09-22 19:25 17960
        return at(key);
2660ccea Poul Sander 2023-09-22 19:25 17961
    } catch(out_of_range) {
2660ccea Poul Sander 2023-09-22 19:25 17962
        return default_value;
2660ccea Poul Sander 2023-09-22 19:25 17963
    }
2660ccea Poul Sander 2023-09-22 19:25 17964
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 17965
2660ccea Poul Sander 2023-09-22 19:25 17966
    @note Unlike @ref at(const typename object_t::key_type&), this function
2660ccea Poul Sander 2023-09-22 19:25 17967
    does not throw if the given key @a key was not found.
2660ccea Poul Sander 2023-09-22 19:25 17968
2660ccea Poul Sander 2023-09-22 19:25 17969
    @note Unlike @ref operator[](const typename object_t::key_type& key), this
2660ccea Poul Sander 2023-09-22 19:25 17970
    function does not implicitly add an element to the position defined by @a
2660ccea Poul Sander 2023-09-22 19:25 17971
    key. This function is furthermore also applicable to const objects.
2660ccea Poul Sander 2023-09-22 19:25 17972
2660ccea Poul Sander 2023-09-22 19:25 17973
    @param[in] key  key of the element to access
2660ccea Poul Sander 2023-09-22 19:25 17974
    @param[in] default_value  the value to return if @a key is not found
2660ccea Poul Sander 2023-09-22 19:25 17975
2660ccea Poul Sander 2023-09-22 19:25 17976
    @tparam ValueType type compatible to JSON values, for instance `int` for
2660ccea Poul Sander 2023-09-22 19:25 17977
    JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
2660ccea Poul Sander 2023-09-22 19:25 17978
    JSON arrays. Note the type of the expected value at @a key and the default
2660ccea Poul Sander 2023-09-22 19:25 17979
    value @a default_value must be compatible.
2660ccea Poul Sander 2023-09-22 19:25 17980
2660ccea Poul Sander 2023-09-22 19:25 17981
    @return copy of the element at key @a key or @a default_value if @a key
2660ccea Poul Sander 2023-09-22 19:25 17982
    is not found
2660ccea Poul Sander 2023-09-22 19:25 17983
2660ccea Poul Sander 2023-09-22 19:25 17984
    @throw type_error.302 if @a default_value does not match the type of the
2660ccea Poul Sander 2023-09-22 19:25 17985
    value at @a key
2660ccea Poul Sander 2023-09-22 19:25 17986
    @throw type_error.306 if the JSON value is not an object; in that case,
2660ccea Poul Sander 2023-09-22 19:25 17987
    using `value()` with a key makes no sense.
2660ccea Poul Sander 2023-09-22 19:25 17988
2660ccea Poul Sander 2023-09-22 19:25 17989
    @complexity Logarithmic in the size of the container.
2660ccea Poul Sander 2023-09-22 19:25 17990
2660ccea Poul Sander 2023-09-22 19:25 17991
    @liveexample{The example below shows how object elements can be queried
2660ccea Poul Sander 2023-09-22 19:25 17992
    with a default value.,basic_json__value}
2660ccea Poul Sander 2023-09-22 19:25 17993
2660ccea Poul Sander 2023-09-22 19:25 17994
    @sa @ref at(const typename object_t::key_type&) for access by reference
2660ccea Poul Sander 2023-09-22 19:25 17995
    with range checking
2660ccea Poul Sander 2023-09-22 19:25 17996
    @sa @ref operator[](const typename object_t::key_type&) for unchecked
2660ccea Poul Sander 2023-09-22 19:25 17997
    access by reference
2660ccea Poul Sander 2023-09-22 19:25 17998
2660ccea Poul Sander 2023-09-22 19:25 17999
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18000
    */
2660ccea Poul Sander 2023-09-22 19:25 18001
    template<class ValueType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 18002
                 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 18003
    ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
2660ccea Poul Sander 2023-09-22 19:25 18004
    {
2660ccea Poul Sander 2023-09-22 19:25 18005
        // at only works for objects
2660ccea Poul Sander 2023-09-22 19:25 18006
        if (JSON_HEDLEY_LIKELY(is_object()))
2660ccea Poul Sander 2023-09-22 19:25 18007
        {
2660ccea Poul Sander 2023-09-22 19:25 18008
            // if key is found, return value and given default value otherwise
2660ccea Poul Sander 2023-09-22 19:25 18009
            const auto it = find(key);
2660ccea Poul Sander 2023-09-22 19:25 18010
            if (it != end())
2660ccea Poul Sander 2023-09-22 19:25 18011
            {
2660ccea Poul Sander 2023-09-22 19:25 18012
                return *it;
2660ccea Poul Sander 2023-09-22 19:25 18013
            }
2660ccea Poul Sander 2023-09-22 19:25 18014
2660ccea Poul Sander 2023-09-22 19:25 18015
            return default_value;
2660ccea Poul Sander 2023-09-22 19:25 18016
        }
2660ccea Poul Sander 2023-09-22 19:25 18017
2660ccea Poul Sander 2023-09-22 19:25 18018
        JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 18019
    }
2660ccea Poul Sander 2023-09-22 19:25 18020
2660ccea Poul Sander 2023-09-22 19:25 18021
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18022
    @brief overload for a default value of type const char*
2660ccea Poul Sander 2023-09-22 19:25 18023
    @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
2660ccea Poul Sander 2023-09-22 19:25 18024
    */
2660ccea Poul Sander 2023-09-22 19:25 18025
    string_t value(const typename object_t::key_type& key, const char* default_value) const
2660ccea Poul Sander 2023-09-22 19:25 18026
    {
2660ccea Poul Sander 2023-09-22 19:25 18027
        return value(key, string_t(default_value));
2660ccea Poul Sander 2023-09-22 19:25 18028
    }
2660ccea Poul Sander 2023-09-22 19:25 18029
2660ccea Poul Sander 2023-09-22 19:25 18030
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18031
    @brief access specified object element via JSON Pointer with default value
2660ccea Poul Sander 2023-09-22 19:25 18032
2660ccea Poul Sander 2023-09-22 19:25 18033
    Returns either a copy of an object's element at the specified key @a key
2660ccea Poul Sander 2023-09-22 19:25 18034
    or a given default value if no element with key @a key exists.
2660ccea Poul Sander 2023-09-22 19:25 18035
2660ccea Poul Sander 2023-09-22 19:25 18036
    The function is basically equivalent to executing
2660ccea Poul Sander 2023-09-22 19:25 18037
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 18038
    try {
2660ccea Poul Sander 2023-09-22 19:25 18039
        return at(ptr);
2660ccea Poul Sander 2023-09-22 19:25 18040
    } catch(out_of_range) {
2660ccea Poul Sander 2023-09-22 19:25 18041
        return default_value;
2660ccea Poul Sander 2023-09-22 19:25 18042
    }
2660ccea Poul Sander 2023-09-22 19:25 18043
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 18044
2660ccea Poul Sander 2023-09-22 19:25 18045
    @note Unlike @ref at(const json_pointer&), this function does not throw
2660ccea Poul Sander 2023-09-22 19:25 18046
    if the given key @a key was not found.
2660ccea Poul Sander 2023-09-22 19:25 18047
2660ccea Poul Sander 2023-09-22 19:25 18048
    @param[in] ptr  a JSON pointer to the element to access
2660ccea Poul Sander 2023-09-22 19:25 18049
    @param[in] default_value  the value to return if @a ptr found no value
2660ccea Poul Sander 2023-09-22 19:25 18050
2660ccea Poul Sander 2023-09-22 19:25 18051
    @tparam ValueType type compatible to JSON values, for instance `int` for
2660ccea Poul Sander 2023-09-22 19:25 18052
    JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
2660ccea Poul Sander 2023-09-22 19:25 18053
    JSON arrays. Note the type of the expected value at @a key and the default
2660ccea Poul Sander 2023-09-22 19:25 18054
    value @a default_value must be compatible.
2660ccea Poul Sander 2023-09-22 19:25 18055
2660ccea Poul Sander 2023-09-22 19:25 18056
    @return copy of the element at key @a key or @a default_value if @a key
2660ccea Poul Sander 2023-09-22 19:25 18057
    is not found
2660ccea Poul Sander 2023-09-22 19:25 18058
2660ccea Poul Sander 2023-09-22 19:25 18059
    @throw type_error.302 if @a default_value does not match the type of the
2660ccea Poul Sander 2023-09-22 19:25 18060
    value at @a ptr
2660ccea Poul Sander 2023-09-22 19:25 18061
    @throw type_error.306 if the JSON value is not an object; in that case,
2660ccea Poul Sander 2023-09-22 19:25 18062
    using `value()` with a key makes no sense.
2660ccea Poul Sander 2023-09-22 19:25 18063
2660ccea Poul Sander 2023-09-22 19:25 18064
    @complexity Logarithmic in the size of the container.
2660ccea Poul Sander 2023-09-22 19:25 18065
2660ccea Poul Sander 2023-09-22 19:25 18066
    @liveexample{The example below shows how object elements can be queried
2660ccea Poul Sander 2023-09-22 19:25 18067
    with a default value.,basic_json__value_ptr}
2660ccea Poul Sander 2023-09-22 19:25 18068
2660ccea Poul Sander 2023-09-22 19:25 18069
    @sa @ref operator[](const json_pointer&) for unchecked access by reference
2660ccea Poul Sander 2023-09-22 19:25 18070
2660ccea Poul Sander 2023-09-22 19:25 18071
    @since version 2.0.2
2660ccea Poul Sander 2023-09-22 19:25 18072
    */
2660ccea Poul Sander 2023-09-22 19:25 18073
    template<class ValueType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 18074
                 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 18075
    ValueType value(const json_pointer& ptr, const ValueType& default_value) const
2660ccea Poul Sander 2023-09-22 19:25 18076
    {
2660ccea Poul Sander 2023-09-22 19:25 18077
        // at only works for objects
2660ccea Poul Sander 2023-09-22 19:25 18078
        if (JSON_HEDLEY_LIKELY(is_object()))
2660ccea Poul Sander 2023-09-22 19:25 18079
        {
2660ccea Poul Sander 2023-09-22 19:25 18080
            // if pointer resolves a value, return it or use default value
2660ccea Poul Sander 2023-09-22 19:25 18081
            JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 18082
            {
2660ccea Poul Sander 2023-09-22 19:25 18083
                return ptr.get_checked(this);
2660ccea Poul Sander 2023-09-22 19:25 18084
            }
2660ccea Poul Sander 2023-09-22 19:25 18085
            JSON_INTERNAL_CATCH (out_of_range&)
2660ccea Poul Sander 2023-09-22 19:25 18086
            {
2660ccea Poul Sander 2023-09-22 19:25 18087
                return default_value;
2660ccea Poul Sander 2023-09-22 19:25 18088
            }
2660ccea Poul Sander 2023-09-22 19:25 18089
        }
2660ccea Poul Sander 2023-09-22 19:25 18090
2660ccea Poul Sander 2023-09-22 19:25 18091
        JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 18092
    }
2660ccea Poul Sander 2023-09-22 19:25 18093
2660ccea Poul Sander 2023-09-22 19:25 18094
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18095
    @brief overload for a default value of type const char*
2660ccea Poul Sander 2023-09-22 19:25 18096
    @copydoc basic_json::value(const json_pointer&, ValueType) const
2660ccea Poul Sander 2023-09-22 19:25 18097
    */
2660ccea Poul Sander 2023-09-22 19:25 18098
    JSON_HEDLEY_NON_NULL(3)
2660ccea Poul Sander 2023-09-22 19:25 18099
    string_t value(const json_pointer& ptr, const char* default_value) const
2660ccea Poul Sander 2023-09-22 19:25 18100
    {
2660ccea Poul Sander 2023-09-22 19:25 18101
        return value(ptr, string_t(default_value));
2660ccea Poul Sander 2023-09-22 19:25 18102
    }
2660ccea Poul Sander 2023-09-22 19:25 18103
2660ccea Poul Sander 2023-09-22 19:25 18104
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18105
    @brief access the first element
2660ccea Poul Sander 2023-09-22 19:25 18106
2660ccea Poul Sander 2023-09-22 19:25 18107
    Returns a reference to the first element in the container. For a JSON
2660ccea Poul Sander 2023-09-22 19:25 18108
    container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
2660ccea Poul Sander 2023-09-22 19:25 18109
2660ccea Poul Sander 2023-09-22 19:25 18110
    @return In case of a structured type (array or object), a reference to the
2660ccea Poul Sander 2023-09-22 19:25 18111
    first element is returned. In case of number, string, or boolean values, a
2660ccea Poul Sander 2023-09-22 19:25 18112
    reference to the value is returned.
2660ccea Poul Sander 2023-09-22 19:25 18113
2660ccea Poul Sander 2023-09-22 19:25 18114
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 18115
2660ccea Poul Sander 2023-09-22 19:25 18116
    @pre The JSON value must not be `null` (would throw `std::out_of_range`)
2660ccea Poul Sander 2023-09-22 19:25 18117
    or an empty array or object (undefined behavior, **guarded by
2660ccea Poul Sander 2023-09-22 19:25 18118
    assertions**).
2660ccea Poul Sander 2023-09-22 19:25 18119
    @post The JSON value remains unchanged.
2660ccea Poul Sander 2023-09-22 19:25 18120
2660ccea Poul Sander 2023-09-22 19:25 18121
    @throw invalid_iterator.214 when called on `null` value
2660ccea Poul Sander 2023-09-22 19:25 18122
2660ccea Poul Sander 2023-09-22 19:25 18123
    @liveexample{The following code shows an example for `front()`.,front}
2660ccea Poul Sander 2023-09-22 19:25 18124
2660ccea Poul Sander 2023-09-22 19:25 18125
    @sa @ref back() -- access the last element
2660ccea Poul Sander 2023-09-22 19:25 18126
2660ccea Poul Sander 2023-09-22 19:25 18127
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18128
    */
2660ccea Poul Sander 2023-09-22 19:25 18129
    reference front()
2660ccea Poul Sander 2023-09-22 19:25 18130
    {
2660ccea Poul Sander 2023-09-22 19:25 18131
        return *begin();
2660ccea Poul Sander 2023-09-22 19:25 18132
    }
2660ccea Poul Sander 2023-09-22 19:25 18133
2660ccea Poul Sander 2023-09-22 19:25 18134
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18135
    @copydoc basic_json::front()
2660ccea Poul Sander 2023-09-22 19:25 18136
    */
2660ccea Poul Sander 2023-09-22 19:25 18137
    const_reference front() const
2660ccea Poul Sander 2023-09-22 19:25 18138
    {
2660ccea Poul Sander 2023-09-22 19:25 18139
        return *cbegin();
2660ccea Poul Sander 2023-09-22 19:25 18140
    }
2660ccea Poul Sander 2023-09-22 19:25 18141
2660ccea Poul Sander 2023-09-22 19:25 18142
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18143
    @brief access the last element
2660ccea Poul Sander 2023-09-22 19:25 18144
2660ccea Poul Sander 2023-09-22 19:25 18145
    Returns a reference to the last element in the container. For a JSON
2660ccea Poul Sander 2023-09-22 19:25 18146
    container `c`, the expression `c.back()` is equivalent to
2660ccea Poul Sander 2023-09-22 19:25 18147
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 18148
    auto tmp = c.end();
2660ccea Poul Sander 2023-09-22 19:25 18149
    --tmp;
2660ccea Poul Sander 2023-09-22 19:25 18150
    return *tmp;
2660ccea Poul Sander 2023-09-22 19:25 18151
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 18152
2660ccea Poul Sander 2023-09-22 19:25 18153
    @return In case of a structured type (array or object), a reference to the
2660ccea Poul Sander 2023-09-22 19:25 18154
    last element is returned. In case of number, string, or boolean values, a
2660ccea Poul Sander 2023-09-22 19:25 18155
    reference to the value is returned.
2660ccea Poul Sander 2023-09-22 19:25 18156
2660ccea Poul Sander 2023-09-22 19:25 18157
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 18158
2660ccea Poul Sander 2023-09-22 19:25 18159
    @pre The JSON value must not be `null` (would throw `std::out_of_range`)
2660ccea Poul Sander 2023-09-22 19:25 18160
    or an empty array or object (undefined behavior, **guarded by
2660ccea Poul Sander 2023-09-22 19:25 18161
    assertions**).
2660ccea Poul Sander 2023-09-22 19:25 18162
    @post The JSON value remains unchanged.
2660ccea Poul Sander 2023-09-22 19:25 18163
2660ccea Poul Sander 2023-09-22 19:25 18164
    @throw invalid_iterator.214 when called on a `null` value. See example
2660ccea Poul Sander 2023-09-22 19:25 18165
    below.
2660ccea Poul Sander 2023-09-22 19:25 18166
2660ccea Poul Sander 2023-09-22 19:25 18167
    @liveexample{The following code shows an example for `back()`.,back}
2660ccea Poul Sander 2023-09-22 19:25 18168
2660ccea Poul Sander 2023-09-22 19:25 18169
    @sa @ref front() -- access the first element
2660ccea Poul Sander 2023-09-22 19:25 18170
2660ccea Poul Sander 2023-09-22 19:25 18171
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18172
    */
2660ccea Poul Sander 2023-09-22 19:25 18173
    reference back()
2660ccea Poul Sander 2023-09-22 19:25 18174
    {
2660ccea Poul Sander 2023-09-22 19:25 18175
        auto tmp = end();
2660ccea Poul Sander 2023-09-22 19:25 18176
        --tmp;
2660ccea Poul Sander 2023-09-22 19:25 18177
        return *tmp;
2660ccea Poul Sander 2023-09-22 19:25 18178
    }
2660ccea Poul Sander 2023-09-22 19:25 18179
2660ccea Poul Sander 2023-09-22 19:25 18180
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18181
    @copydoc basic_json::back()
2660ccea Poul Sander 2023-09-22 19:25 18182
    */
2660ccea Poul Sander 2023-09-22 19:25 18183
    const_reference back() const
2660ccea Poul Sander 2023-09-22 19:25 18184
    {
2660ccea Poul Sander 2023-09-22 19:25 18185
        auto tmp = cend();
2660ccea Poul Sander 2023-09-22 19:25 18186
        --tmp;
2660ccea Poul Sander 2023-09-22 19:25 18187
        return *tmp;
2660ccea Poul Sander 2023-09-22 19:25 18188
    }
2660ccea Poul Sander 2023-09-22 19:25 18189
2660ccea Poul Sander 2023-09-22 19:25 18190
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18191
    @brief remove element given an iterator
2660ccea Poul Sander 2023-09-22 19:25 18192
2660ccea Poul Sander 2023-09-22 19:25 18193
    Removes the element specified by iterator @a pos. The iterator @a pos must
2660ccea Poul Sander 2023-09-22 19:25 18194
    be valid and dereferenceable. Thus the `end()` iterator (which is valid,
2660ccea Poul Sander 2023-09-22 19:25 18195
    but is not dereferenceable) cannot be used as a value for @a pos.
2660ccea Poul Sander 2023-09-22 19:25 18196
2660ccea Poul Sander 2023-09-22 19:25 18197
    If called on a primitive type other than `null`, the resulting JSON value
2660ccea Poul Sander 2023-09-22 19:25 18198
    will be `null`.
2660ccea Poul Sander 2023-09-22 19:25 18199
2660ccea Poul Sander 2023-09-22 19:25 18200
    @param[in] pos iterator to the element to remove
2660ccea Poul Sander 2023-09-22 19:25 18201
    @return Iterator following the last removed element. If the iterator @a
2660ccea Poul Sander 2023-09-22 19:25 18202
    pos refers to the last element, the `end()` iterator is returned.
2660ccea Poul Sander 2023-09-22 19:25 18203
2660ccea Poul Sander 2023-09-22 19:25 18204
    @tparam IteratorType an @ref iterator or @ref const_iterator
2660ccea Poul Sander 2023-09-22 19:25 18205
2660ccea Poul Sander 2023-09-22 19:25 18206
    @post Invalidates iterators and references at or after the point of the
2660ccea Poul Sander 2023-09-22 19:25 18207
    erase, including the `end()` iterator.
2660ccea Poul Sander 2023-09-22 19:25 18208
2660ccea Poul Sander 2023-09-22 19:25 18209
    @throw type_error.307 if called on a `null` value; example: `"cannot use
2660ccea Poul Sander 2023-09-22 19:25 18210
    erase() with null"`
2660ccea Poul Sander 2023-09-22 19:25 18211
    @throw invalid_iterator.202 if called on an iterator which does not belong
2660ccea Poul Sander 2023-09-22 19:25 18212
    to the current JSON value; example: `"iterator does not fit current
2660ccea Poul Sander 2023-09-22 19:25 18213
    value"`
2660ccea Poul Sander 2023-09-22 19:25 18214
    @throw invalid_iterator.205 if called on a primitive type with invalid
2660ccea Poul Sander 2023-09-22 19:25 18215
    iterator (i.e., any iterator which is not `begin()`); example: `"iterator
2660ccea Poul Sander 2023-09-22 19:25 18216
    out of range"`
2660ccea Poul Sander 2023-09-22 19:25 18217
2660ccea Poul Sander 2023-09-22 19:25 18218
    @complexity The complexity depends on the type:
2660ccea Poul Sander 2023-09-22 19:25 18219
    - objects: amortized constant
2660ccea Poul Sander 2023-09-22 19:25 18220
    - arrays: linear in distance between @a pos and the end of the container
2660ccea Poul Sander 2023-09-22 19:25 18221
    - strings: linear in the length of the string
2660ccea Poul Sander 2023-09-22 19:25 18222
    - other types: constant
2660ccea Poul Sander 2023-09-22 19:25 18223
2660ccea Poul Sander 2023-09-22 19:25 18224
    @liveexample{The example shows the result of `erase()` for different JSON
2660ccea Poul Sander 2023-09-22 19:25 18225
    types.,erase__IteratorType}
2660ccea Poul Sander 2023-09-22 19:25 18226
2660ccea Poul Sander 2023-09-22 19:25 18227
    @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
2660ccea Poul Sander 2023-09-22 19:25 18228
    the given range
2660ccea Poul Sander 2023-09-22 19:25 18229
    @sa @ref erase(const typename object_t::key_type&) -- removes the element
2660ccea Poul Sander 2023-09-22 19:25 18230
    from an object at the given key
2660ccea Poul Sander 2023-09-22 19:25 18231
    @sa @ref erase(const size_type) -- removes the element from an array at
2660ccea Poul Sander 2023-09-22 19:25 18232
    the given index
2660ccea Poul Sander 2023-09-22 19:25 18233
2660ccea Poul Sander 2023-09-22 19:25 18234
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18235
    */
2660ccea Poul Sander 2023-09-22 19:25 18236
    template<class IteratorType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 18237
                 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
2660ccea Poul Sander 2023-09-22 19:25 18238
                 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
2660ccea Poul Sander 2023-09-22 19:25 18239
             = 0>
2660ccea Poul Sander 2023-09-22 19:25 18240
    IteratorType erase(IteratorType pos)
2660ccea Poul Sander 2023-09-22 19:25 18241
    {
2660ccea Poul Sander 2023-09-22 19:25 18242
        // make sure iterator fits the current value
2660ccea Poul Sander 2023-09-22 19:25 18243
        if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
2660ccea Poul Sander 2023-09-22 19:25 18244
        {
2660ccea Poul Sander 2023-09-22 19:25 18245
            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
2660ccea Poul Sander 2023-09-22 19:25 18246
        }
2660ccea Poul Sander 2023-09-22 19:25 18247
2660ccea Poul Sander 2023-09-22 19:25 18248
        IteratorType result = end();
2660ccea Poul Sander 2023-09-22 19:25 18249
2660ccea Poul Sander 2023-09-22 19:25 18250
        switch (m_type)
2660ccea Poul Sander 2023-09-22 19:25 18251
        {
2660ccea Poul Sander 2023-09-22 19:25 18252
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 18253
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 18254
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 18255
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 18256
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 18257
            {
2660ccea Poul Sander 2023-09-22 19:25 18258
                if (JSON_HEDLEY_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
2660ccea Poul Sander 2023-09-22 19:25 18259
                {
2660ccea Poul Sander 2023-09-22 19:25 18260
                    JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
2660ccea Poul Sander 2023-09-22 19:25 18261
                }
2660ccea Poul Sander 2023-09-22 19:25 18262
2660ccea Poul Sander 2023-09-22 19:25 18263
                if (is_string())
2660ccea Poul Sander 2023-09-22 19:25 18264
                {
2660ccea Poul Sander 2023-09-22 19:25 18265
                    AllocatorType<string_t> alloc;
2660ccea Poul Sander 2023-09-22 19:25 18266
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
2660ccea Poul Sander 2023-09-22 19:25 18267
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
2660ccea Poul Sander 2023-09-22 19:25 18268
                    m_value.string = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 18269
                }
2660ccea Poul Sander 2023-09-22 19:25 18270
2660ccea Poul Sander 2023-09-22 19:25 18271
                m_type = value_t::null;
2660ccea Poul Sander 2023-09-22 19:25 18272
                assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 18273
                break;
2660ccea Poul Sander 2023-09-22 19:25 18274
            }
2660ccea Poul Sander 2023-09-22 19:25 18275
2660ccea Poul Sander 2023-09-22 19:25 18276
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 18277
            {
2660ccea Poul Sander 2023-09-22 19:25 18278
                result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
2660ccea Poul Sander 2023-09-22 19:25 18279
                break;
2660ccea Poul Sander 2023-09-22 19:25 18280
            }
2660ccea Poul Sander 2023-09-22 19:25 18281
2660ccea Poul Sander 2023-09-22 19:25 18282
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 18283
            {
2660ccea Poul Sander 2023-09-22 19:25 18284
                result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
2660ccea Poul Sander 2023-09-22 19:25 18285
                break;
2660ccea Poul Sander 2023-09-22 19:25 18286
            }
2660ccea Poul Sander 2023-09-22 19:25 18287
2660ccea Poul Sander 2023-09-22 19:25 18288
            default:
2660ccea Poul Sander 2023-09-22 19:25 18289
                JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 18290
        }
2660ccea Poul Sander 2023-09-22 19:25 18291
2660ccea Poul Sander 2023-09-22 19:25 18292
        return result;
2660ccea Poul Sander 2023-09-22 19:25 18293
    }
2660ccea Poul Sander 2023-09-22 19:25 18294
2660ccea Poul Sander 2023-09-22 19:25 18295
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18296
    @brief remove elements given an iterator range
2660ccea Poul Sander 2023-09-22 19:25 18297
2660ccea Poul Sander 2023-09-22 19:25 18298
    Removes the element specified by the range `[first; last)`. The iterator
2660ccea Poul Sander 2023-09-22 19:25 18299
    @a first does not need to be dereferenceable if `first == last`: erasing
2660ccea Poul Sander 2023-09-22 19:25 18300
    an empty range is a no-op.
2660ccea Poul Sander 2023-09-22 19:25 18301
2660ccea Poul Sander 2023-09-22 19:25 18302
    If called on a primitive type other than `null`, the resulting JSON value
2660ccea Poul Sander 2023-09-22 19:25 18303
    will be `null`.
2660ccea Poul Sander 2023-09-22 19:25 18304
2660ccea Poul Sander 2023-09-22 19:25 18305
    @param[in] first iterator to the beginning of the range to remove
2660ccea Poul Sander 2023-09-22 19:25 18306
    @param[in] last iterator past the end of the range to remove
2660ccea Poul Sander 2023-09-22 19:25 18307
    @return Iterator following the last removed element. If the iterator @a
2660ccea Poul Sander 2023-09-22 19:25 18308
    second refers to the last element, the `end()` iterator is returned.
2660ccea Poul Sander 2023-09-22 19:25 18309
2660ccea Poul Sander 2023-09-22 19:25 18310
    @tparam IteratorType an @ref iterator or @ref const_iterator
2660ccea Poul Sander 2023-09-22 19:25 18311
2660ccea Poul Sander 2023-09-22 19:25 18312
    @post Invalidates iterators and references at or after the point of the
2660ccea Poul Sander 2023-09-22 19:25 18313
    erase, including the `end()` iterator.
2660ccea Poul Sander 2023-09-22 19:25 18314
2660ccea Poul Sander 2023-09-22 19:25 18315
    @throw type_error.307 if called on a `null` value; example: `"cannot use
2660ccea Poul Sander 2023-09-22 19:25 18316
    erase() with null"`
2660ccea Poul Sander 2023-09-22 19:25 18317
    @throw invalid_iterator.203 if called on iterators which does not belong
2660ccea Poul Sander 2023-09-22 19:25 18318
    to the current JSON value; example: `"iterators do not fit current value"`
2660ccea Poul Sander 2023-09-22 19:25 18319
    @throw invalid_iterator.204 if called on a primitive type with invalid
2660ccea Poul Sander 2023-09-22 19:25 18320
    iterators (i.e., if `first != begin()` and `last != end()`); example:
2660ccea Poul Sander 2023-09-22 19:25 18321
    `"iterators out of range"`
2660ccea Poul Sander 2023-09-22 19:25 18322
2660ccea Poul Sander 2023-09-22 19:25 18323
    @complexity The complexity depends on the type:
2660ccea Poul Sander 2023-09-22 19:25 18324
    - objects: `log(size()) + std::distance(first, last)`
2660ccea Poul Sander 2023-09-22 19:25 18325
    - arrays: linear in the distance between @a first and @a last, plus linear
2660ccea Poul Sander 2023-09-22 19:25 18326
      in the distance between @a last and end of the container
2660ccea Poul Sander 2023-09-22 19:25 18327
    - strings: linear in the length of the string
2660ccea Poul Sander 2023-09-22 19:25 18328
    - other types: constant
2660ccea Poul Sander 2023-09-22 19:25 18329
2660ccea Poul Sander 2023-09-22 19:25 18330
    @liveexample{The example shows the result of `erase()` for different JSON
2660ccea Poul Sander 2023-09-22 19:25 18331
    types.,erase__IteratorType_IteratorType}
2660ccea Poul Sander 2023-09-22 19:25 18332
2660ccea Poul Sander 2023-09-22 19:25 18333
    @sa @ref erase(IteratorType) -- removes the element at a given position
2660ccea Poul Sander 2023-09-22 19:25 18334
    @sa @ref erase(const typename object_t::key_type&) -- removes the element
2660ccea Poul Sander 2023-09-22 19:25 18335
    from an object at the given key
2660ccea Poul Sander 2023-09-22 19:25 18336
    @sa @ref erase(const size_type) -- removes the element from an array at
2660ccea Poul Sander 2023-09-22 19:25 18337
    the given index
2660ccea Poul Sander 2023-09-22 19:25 18338
2660ccea Poul Sander 2023-09-22 19:25 18339
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18340
    */
2660ccea Poul Sander 2023-09-22 19:25 18341
    template<class IteratorType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 18342
                 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
2660ccea Poul Sander 2023-09-22 19:25 18343
                 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
2660ccea Poul Sander 2023-09-22 19:25 18344
             = 0>
2660ccea Poul Sander 2023-09-22 19:25 18345
    IteratorType erase(IteratorType first, IteratorType last)
2660ccea Poul Sander 2023-09-22 19:25 18346
    {
2660ccea Poul Sander 2023-09-22 19:25 18347
        // make sure iterator fits the current value
2660ccea Poul Sander 2023-09-22 19:25 18348
        if (JSON_HEDLEY_UNLIKELY(this != first.m_object or this != last.m_object))
2660ccea Poul Sander 2023-09-22 19:25 18349
        {
2660ccea Poul Sander 2023-09-22 19:25 18350
            JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
2660ccea Poul Sander 2023-09-22 19:25 18351
        }
2660ccea Poul Sander 2023-09-22 19:25 18352
2660ccea Poul Sander 2023-09-22 19:25 18353
        IteratorType result = end();
2660ccea Poul Sander 2023-09-22 19:25 18354
2660ccea Poul Sander 2023-09-22 19:25 18355
        switch (m_type)
2660ccea Poul Sander 2023-09-22 19:25 18356
        {
2660ccea Poul Sander 2023-09-22 19:25 18357
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 18358
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 18359
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 18360
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 18361
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 18362
            {
2660ccea Poul Sander 2023-09-22 19:25 18363
                if (JSON_HEDLEY_LIKELY(not first.m_it.primitive_iterator.is_begin()
2660ccea Poul Sander 2023-09-22 19:25 18364
                                       or not last.m_it.primitive_iterator.is_end()))
2660ccea Poul Sander 2023-09-22 19:25 18365
                {
2660ccea Poul Sander 2023-09-22 19:25 18366
                    JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
2660ccea Poul Sander 2023-09-22 19:25 18367
                }
2660ccea Poul Sander 2023-09-22 19:25 18368
2660ccea Poul Sander 2023-09-22 19:25 18369
                if (is_string())
2660ccea Poul Sander 2023-09-22 19:25 18370
                {
2660ccea Poul Sander 2023-09-22 19:25 18371
                    AllocatorType<string_t> alloc;
2660ccea Poul Sander 2023-09-22 19:25 18372
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
2660ccea Poul Sander 2023-09-22 19:25 18373
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
2660ccea Poul Sander 2023-09-22 19:25 18374
                    m_value.string = nullptr;
2660ccea Poul Sander 2023-09-22 19:25 18375
                }
2660ccea Poul Sander 2023-09-22 19:25 18376
2660ccea Poul Sander 2023-09-22 19:25 18377
                m_type = value_t::null;
2660ccea Poul Sander 2023-09-22 19:25 18378
                assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 18379
                break;
2660ccea Poul Sander 2023-09-22 19:25 18380
            }
2660ccea Poul Sander 2023-09-22 19:25 18381
2660ccea Poul Sander 2023-09-22 19:25 18382
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 18383
            {
2660ccea Poul Sander 2023-09-22 19:25 18384
                result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
2660ccea Poul Sander 2023-09-22 19:25 18385
                                              last.m_it.object_iterator);
2660ccea Poul Sander 2023-09-22 19:25 18386
                break;
2660ccea Poul Sander 2023-09-22 19:25 18387
            }
2660ccea Poul Sander 2023-09-22 19:25 18388
2660ccea Poul Sander 2023-09-22 19:25 18389
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 18390
            {
2660ccea Poul Sander 2023-09-22 19:25 18391
                result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
2660ccea Poul Sander 2023-09-22 19:25 18392
                                             last.m_it.array_iterator);
2660ccea Poul Sander 2023-09-22 19:25 18393
                break;
2660ccea Poul Sander 2023-09-22 19:25 18394
            }
2660ccea Poul Sander 2023-09-22 19:25 18395
2660ccea Poul Sander 2023-09-22 19:25 18396
            default:
2660ccea Poul Sander 2023-09-22 19:25 18397
                JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 18398
        }
2660ccea Poul Sander 2023-09-22 19:25 18399
2660ccea Poul Sander 2023-09-22 19:25 18400
        return result;
2660ccea Poul Sander 2023-09-22 19:25 18401
    }
2660ccea Poul Sander 2023-09-22 19:25 18402
2660ccea Poul Sander 2023-09-22 19:25 18403
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18404
    @brief remove element from a JSON object given a key
2660ccea Poul Sander 2023-09-22 19:25 18405
2660ccea Poul Sander 2023-09-22 19:25 18406
    Removes elements from a JSON object with the key value @a key.
2660ccea Poul Sander 2023-09-22 19:25 18407
2660ccea Poul Sander 2023-09-22 19:25 18408
    @param[in] key value of the elements to remove
2660ccea Poul Sander 2023-09-22 19:25 18409
2660ccea Poul Sander 2023-09-22 19:25 18410
    @return Number of elements removed. If @a ObjectType is the default
2660ccea Poul Sander 2023-09-22 19:25 18411
    `std::map` type, the return value will always be `0` (@a key was not
2660ccea Poul Sander 2023-09-22 19:25 18412
    found) or `1` (@a key was found).
2660ccea Poul Sander 2023-09-22 19:25 18413
2660ccea Poul Sander 2023-09-22 19:25 18414
    @post References and iterators to the erased elements are invalidated.
2660ccea Poul Sander 2023-09-22 19:25 18415
    Other references and iterators are not affected.
2660ccea Poul Sander 2023-09-22 19:25 18416
2660ccea Poul Sander 2023-09-22 19:25 18417
    @throw type_error.307 when called on a type other than JSON object;
2660ccea Poul Sander 2023-09-22 19:25 18418
    example: `"cannot use erase() with null"`
2660ccea Poul Sander 2023-09-22 19:25 18419
2660ccea Poul Sander 2023-09-22 19:25 18420
    @complexity `log(size()) + count(key)`
2660ccea Poul Sander 2023-09-22 19:25 18421
2660ccea Poul Sander 2023-09-22 19:25 18422
    @liveexample{The example shows the effect of `erase()`.,erase__key_type}
2660ccea Poul Sander 2023-09-22 19:25 18423
2660ccea Poul Sander 2023-09-22 19:25 18424
    @sa @ref erase(IteratorType) -- removes the element at a given position
2660ccea Poul Sander 2023-09-22 19:25 18425
    @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
2660ccea Poul Sander 2023-09-22 19:25 18426
    the given range
2660ccea Poul Sander 2023-09-22 19:25 18427
    @sa @ref erase(const size_type) -- removes the element from an array at
2660ccea Poul Sander 2023-09-22 19:25 18428
    the given index
2660ccea Poul Sander 2023-09-22 19:25 18429
2660ccea Poul Sander 2023-09-22 19:25 18430
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18431
    */
2660ccea Poul Sander 2023-09-22 19:25 18432
    size_type erase(const typename object_t::key_type& key)
2660ccea Poul Sander 2023-09-22 19:25 18433
    {
2660ccea Poul Sander 2023-09-22 19:25 18434
        // this erase only works for objects
2660ccea Poul Sander 2023-09-22 19:25 18435
        if (JSON_HEDLEY_LIKELY(is_object()))
2660ccea Poul Sander 2023-09-22 19:25 18436
        {
2660ccea Poul Sander 2023-09-22 19:25 18437
            return m_value.object->erase(key);
2660ccea Poul Sander 2023-09-22 19:25 18438
        }
2660ccea Poul Sander 2023-09-22 19:25 18439
2660ccea Poul Sander 2023-09-22 19:25 18440
        JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 18441
    }
2660ccea Poul Sander 2023-09-22 19:25 18442
2660ccea Poul Sander 2023-09-22 19:25 18443
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18444
    @brief remove element from a JSON array given an index
2660ccea Poul Sander 2023-09-22 19:25 18445
2660ccea Poul Sander 2023-09-22 19:25 18446
    Removes element from a JSON array at the index @a idx.
2660ccea Poul Sander 2023-09-22 19:25 18447
2660ccea Poul Sander 2023-09-22 19:25 18448
    @param[in] idx index of the element to remove
2660ccea Poul Sander 2023-09-22 19:25 18449
2660ccea Poul Sander 2023-09-22 19:25 18450
    @throw type_error.307 when called on a type other than JSON object;
2660ccea Poul Sander 2023-09-22 19:25 18451
    example: `"cannot use erase() with null"`
2660ccea Poul Sander 2023-09-22 19:25 18452
    @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
2660ccea Poul Sander 2023-09-22 19:25 18453
    is out of range"`
2660ccea Poul Sander 2023-09-22 19:25 18454
2660ccea Poul Sander 2023-09-22 19:25 18455
    @complexity Linear in distance between @a idx and the end of the container.
2660ccea Poul Sander 2023-09-22 19:25 18456
2660ccea Poul Sander 2023-09-22 19:25 18457
    @liveexample{The example shows the effect of `erase()`.,erase__size_type}
2660ccea Poul Sander 2023-09-22 19:25 18458
2660ccea Poul Sander 2023-09-22 19:25 18459
    @sa @ref erase(IteratorType) -- removes the element at a given position
2660ccea Poul Sander 2023-09-22 19:25 18460
    @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
2660ccea Poul Sander 2023-09-22 19:25 18461
    the given range
2660ccea Poul Sander 2023-09-22 19:25 18462
    @sa @ref erase(const typename object_t::key_type&) -- removes the element
2660ccea Poul Sander 2023-09-22 19:25 18463
    from an object at the given key
2660ccea Poul Sander 2023-09-22 19:25 18464
2660ccea Poul Sander 2023-09-22 19:25 18465
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18466
    */
2660ccea Poul Sander 2023-09-22 19:25 18467
    void erase(const size_type idx)
2660ccea Poul Sander 2023-09-22 19:25 18468
    {
2660ccea Poul Sander 2023-09-22 19:25 18469
        // this erase only works for arrays
2660ccea Poul Sander 2023-09-22 19:25 18470
        if (JSON_HEDLEY_LIKELY(is_array()))
2660ccea Poul Sander 2023-09-22 19:25 18471
        {
2660ccea Poul Sander 2023-09-22 19:25 18472
            if (JSON_HEDLEY_UNLIKELY(idx >= size()))
2660ccea Poul Sander 2023-09-22 19:25 18473
            {
2660ccea Poul Sander 2023-09-22 19:25 18474
                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
2660ccea Poul Sander 2023-09-22 19:25 18475
            }
2660ccea Poul Sander 2023-09-22 19:25 18476
2660ccea Poul Sander 2023-09-22 19:25 18477
            m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
2660ccea Poul Sander 2023-09-22 19:25 18478
        }
2660ccea Poul Sander 2023-09-22 19:25 18479
        else
2660ccea Poul Sander 2023-09-22 19:25 18480
        {
2660ccea Poul Sander 2023-09-22 19:25 18481
            JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 18482
        }
2660ccea Poul Sander 2023-09-22 19:25 18483
    }
2660ccea Poul Sander 2023-09-22 19:25 18484
2660ccea Poul Sander 2023-09-22 19:25 18485
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 18486
2660ccea Poul Sander 2023-09-22 19:25 18487
2660ccea Poul Sander 2023-09-22 19:25 18488
    ////////////
2660ccea Poul Sander 2023-09-22 19:25 18489
    // lookup //
2660ccea Poul Sander 2023-09-22 19:25 18490
    ////////////
2660ccea Poul Sander 2023-09-22 19:25 18491
2660ccea Poul Sander 2023-09-22 19:25 18492
    /// @name lookup
2660ccea Poul Sander 2023-09-22 19:25 18493
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 18494
2660ccea Poul Sander 2023-09-22 19:25 18495
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18496
    @brief find an element in a JSON object
2660ccea Poul Sander 2023-09-22 19:25 18497
2660ccea Poul Sander 2023-09-22 19:25 18498
    Finds an element in a JSON object with key equivalent to @a key. If the
2660ccea Poul Sander 2023-09-22 19:25 18499
    element is not found or the JSON value is not an object, end() is
2660ccea Poul Sander 2023-09-22 19:25 18500
    returned.
2660ccea Poul Sander 2023-09-22 19:25 18501
2660ccea Poul Sander 2023-09-22 19:25 18502
    @note This method always returns @ref end() when executed on a JSON type
2660ccea Poul Sander 2023-09-22 19:25 18503
          that is not an object.
2660ccea Poul Sander 2023-09-22 19:25 18504
2660ccea Poul Sander 2023-09-22 19:25 18505
    @param[in] key key value of the element to search for.
2660ccea Poul Sander 2023-09-22 19:25 18506
2660ccea Poul Sander 2023-09-22 19:25 18507
    @return Iterator to an element with key equivalent to @a key. If no such
2660ccea Poul Sander 2023-09-22 19:25 18508
    element is found or the JSON value is not an object, past-the-end (see
2660ccea Poul Sander 2023-09-22 19:25 18509
    @ref end()) iterator is returned.
2660ccea Poul Sander 2023-09-22 19:25 18510
2660ccea Poul Sander 2023-09-22 19:25 18511
    @complexity Logarithmic in the size of the JSON object.
2660ccea Poul Sander 2023-09-22 19:25 18512
2660ccea Poul Sander 2023-09-22 19:25 18513
    @liveexample{The example shows how `find()` is used.,find__key_type}
2660ccea Poul Sander 2023-09-22 19:25 18514
2660ccea Poul Sander 2023-09-22 19:25 18515
    @sa @ref contains(KeyT&&) const -- checks whether a key exists
2660ccea Poul Sander 2023-09-22 19:25 18516
2660ccea Poul Sander 2023-09-22 19:25 18517
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18518
    */
2660ccea Poul Sander 2023-09-22 19:25 18519
    template<typename KeyT>
2660ccea Poul Sander 2023-09-22 19:25 18520
    iterator find(KeyT&& key)
2660ccea Poul Sander 2023-09-22 19:25 18521
    {
2660ccea Poul Sander 2023-09-22 19:25 18522
        auto result = end();
2660ccea Poul Sander 2023-09-22 19:25 18523
2660ccea Poul Sander 2023-09-22 19:25 18524
        if (is_object())
2660ccea Poul Sander 2023-09-22 19:25 18525
        {
2660ccea Poul Sander 2023-09-22 19:25 18526
            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
2660ccea Poul Sander 2023-09-22 19:25 18527
        }
2660ccea Poul Sander 2023-09-22 19:25 18528
2660ccea Poul Sander 2023-09-22 19:25 18529
        return result;
2660ccea Poul Sander 2023-09-22 19:25 18530
    }
2660ccea Poul Sander 2023-09-22 19:25 18531
2660ccea Poul Sander 2023-09-22 19:25 18532
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18533
    @brief find an element in a JSON object
2660ccea Poul Sander 2023-09-22 19:25 18534
    @copydoc find(KeyT&&)
2660ccea Poul Sander 2023-09-22 19:25 18535
    */
2660ccea Poul Sander 2023-09-22 19:25 18536
    template<typename KeyT>
2660ccea Poul Sander 2023-09-22 19:25 18537
    const_iterator find(KeyT&& key) const
2660ccea Poul Sander 2023-09-22 19:25 18538
    {
2660ccea Poul Sander 2023-09-22 19:25 18539
        auto result = cend();
2660ccea Poul Sander 2023-09-22 19:25 18540
2660ccea Poul Sander 2023-09-22 19:25 18541
        if (is_object())
2660ccea Poul Sander 2023-09-22 19:25 18542
        {
2660ccea Poul Sander 2023-09-22 19:25 18543
            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
2660ccea Poul Sander 2023-09-22 19:25 18544
        }
2660ccea Poul Sander 2023-09-22 19:25 18545
2660ccea Poul Sander 2023-09-22 19:25 18546
        return result;
2660ccea Poul Sander 2023-09-22 19:25 18547
    }
2660ccea Poul Sander 2023-09-22 19:25 18548
2660ccea Poul Sander 2023-09-22 19:25 18549
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18550
    @brief returns the number of occurrences of a key in a JSON object
2660ccea Poul Sander 2023-09-22 19:25 18551
2660ccea Poul Sander 2023-09-22 19:25 18552
    Returns the number of elements with key @a key. If ObjectType is the
2660ccea Poul Sander 2023-09-22 19:25 18553
    default `std::map` type, the return value will always be `0` (@a key was
2660ccea Poul Sander 2023-09-22 19:25 18554
    not found) or `1` (@a key was found).
2660ccea Poul Sander 2023-09-22 19:25 18555
2660ccea Poul Sander 2023-09-22 19:25 18556
    @note This method always returns `0` when executed on a JSON type that is
2660ccea Poul Sander 2023-09-22 19:25 18557
          not an object.
2660ccea Poul Sander 2023-09-22 19:25 18558
2660ccea Poul Sander 2023-09-22 19:25 18559
    @param[in] key key value of the element to count
2660ccea Poul Sander 2023-09-22 19:25 18560
2660ccea Poul Sander 2023-09-22 19:25 18561
    @return Number of elements with key @a key. If the JSON value is not an
2660ccea Poul Sander 2023-09-22 19:25 18562
    object, the return value will be `0`.
2660ccea Poul Sander 2023-09-22 19:25 18563
2660ccea Poul Sander 2023-09-22 19:25 18564
    @complexity Logarithmic in the size of the JSON object.
2660ccea Poul Sander 2023-09-22 19:25 18565
2660ccea Poul Sander 2023-09-22 19:25 18566
    @liveexample{The example shows how `count()` is used.,count}
2660ccea Poul Sander 2023-09-22 19:25 18567
2660ccea Poul Sander 2023-09-22 19:25 18568
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18569
    */
2660ccea Poul Sander 2023-09-22 19:25 18570
    template<typename KeyT>
2660ccea Poul Sander 2023-09-22 19:25 18571
    size_type count(KeyT&& key) const
2660ccea Poul Sander 2023-09-22 19:25 18572
    {
2660ccea Poul Sander 2023-09-22 19:25 18573
        // return 0 for all nonobject types
2660ccea Poul Sander 2023-09-22 19:25 18574
        return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
2660ccea Poul Sander 2023-09-22 19:25 18575
    }
2660ccea Poul Sander 2023-09-22 19:25 18576
2660ccea Poul Sander 2023-09-22 19:25 18577
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18578
    @brief check the existence of an element in a JSON object
2660ccea Poul Sander 2023-09-22 19:25 18579
2660ccea Poul Sander 2023-09-22 19:25 18580
    Check whether an element exists in a JSON object with key equivalent to
2660ccea Poul Sander 2023-09-22 19:25 18581
    @a key. If the element is not found or the JSON value is not an object,
2660ccea Poul Sander 2023-09-22 19:25 18582
    false is returned.
2660ccea Poul Sander 2023-09-22 19:25 18583
2660ccea Poul Sander 2023-09-22 19:25 18584
    @note This method always returns false when executed on a JSON type
2660ccea Poul Sander 2023-09-22 19:25 18585
          that is not an object.
2660ccea Poul Sander 2023-09-22 19:25 18586
2660ccea Poul Sander 2023-09-22 19:25 18587
    @param[in] key key value to check its existence.
2660ccea Poul Sander 2023-09-22 19:25 18588
2660ccea Poul Sander 2023-09-22 19:25 18589
    @return true if an element with specified @a key exists. If no such
2660ccea Poul Sander 2023-09-22 19:25 18590
    element with such key is found or the JSON value is not an object,
2660ccea Poul Sander 2023-09-22 19:25 18591
    false is returned.
2660ccea Poul Sander 2023-09-22 19:25 18592
2660ccea Poul Sander 2023-09-22 19:25 18593
    @complexity Logarithmic in the size of the JSON object.
2660ccea Poul Sander 2023-09-22 19:25 18594
2660ccea Poul Sander 2023-09-22 19:25 18595
    @liveexample{The following code shows an example for `contains()`.,contains}
2660ccea Poul Sander 2023-09-22 19:25 18596
2660ccea Poul Sander 2023-09-22 19:25 18597
    @sa @ref find(KeyT&&) -- returns an iterator to an object element
2660ccea Poul Sander 2023-09-22 19:25 18598
    @sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 18599
2660ccea Poul Sander 2023-09-22 19:25 18600
    @since version 3.6.0
2660ccea Poul Sander 2023-09-22 19:25 18601
    */
2660ccea Poul Sander 2023-09-22 19:25 18602
    template<typename KeyT, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 18603
                 not std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 18604
    bool contains(KeyT && key) const
2660ccea Poul Sander 2023-09-22 19:25 18605
    {
2660ccea Poul Sander 2023-09-22 19:25 18606
        return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
2660ccea Poul Sander 2023-09-22 19:25 18607
    }
2660ccea Poul Sander 2023-09-22 19:25 18608
2660ccea Poul Sander 2023-09-22 19:25 18609
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18610
    @brief check the existence of an element in a JSON object given a JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 18611
2660ccea Poul Sander 2023-09-22 19:25 18612
    Check whether the given JSON pointer @a ptr can be resolved in the current
2660ccea Poul Sander 2023-09-22 19:25 18613
    JSON value.
2660ccea Poul Sander 2023-09-22 19:25 18614
2660ccea Poul Sander 2023-09-22 19:25 18615
    @note This method can be executed on any JSON value type.
2660ccea Poul Sander 2023-09-22 19:25 18616
2660ccea Poul Sander 2023-09-22 19:25 18617
    @param[in] ptr JSON pointer to check its existence.
2660ccea Poul Sander 2023-09-22 19:25 18618
2660ccea Poul Sander 2023-09-22 19:25 18619
    @return true if the JSON pointer can be resolved to a stored value, false
2660ccea Poul Sander 2023-09-22 19:25 18620
    otherwise.
2660ccea Poul Sander 2023-09-22 19:25 18621
2660ccea Poul Sander 2023-09-22 19:25 18622
    @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
2660ccea Poul Sander 2023-09-22 19:25 18623
2660ccea Poul Sander 2023-09-22 19:25 18624
    @throw parse_error.106   if an array index begins with '0'
2660ccea Poul Sander 2023-09-22 19:25 18625
    @throw parse_error.109   if an array index was not a number
2660ccea Poul Sander 2023-09-22 19:25 18626
2660ccea Poul Sander 2023-09-22 19:25 18627
    @complexity Logarithmic in the size of the JSON object.
2660ccea Poul Sander 2023-09-22 19:25 18628
2660ccea Poul Sander 2023-09-22 19:25 18629
    @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
2660ccea Poul Sander 2023-09-22 19:25 18630
2660ccea Poul Sander 2023-09-22 19:25 18631
    @sa @ref contains(KeyT &&) const -- checks the existence of a key
2660ccea Poul Sander 2023-09-22 19:25 18632
2660ccea Poul Sander 2023-09-22 19:25 18633
    @since version 3.7.0
2660ccea Poul Sander 2023-09-22 19:25 18634
    */
2660ccea Poul Sander 2023-09-22 19:25 18635
    bool contains(const json_pointer& ptr) const
2660ccea Poul Sander 2023-09-22 19:25 18636
    {
2660ccea Poul Sander 2023-09-22 19:25 18637
        return ptr.contains(this);
2660ccea Poul Sander 2023-09-22 19:25 18638
    }
2660ccea Poul Sander 2023-09-22 19:25 18639
2660ccea Poul Sander 2023-09-22 19:25 18640
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 18641
2660ccea Poul Sander 2023-09-22 19:25 18642
2660ccea Poul Sander 2023-09-22 19:25 18643
    ///////////////
2660ccea Poul Sander 2023-09-22 19:25 18644
    // iterators //
2660ccea Poul Sander 2023-09-22 19:25 18645
    ///////////////
2660ccea Poul Sander 2023-09-22 19:25 18646
2660ccea Poul Sander 2023-09-22 19:25 18647
    /// @name iterators
2660ccea Poul Sander 2023-09-22 19:25 18648
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 18649
2660ccea Poul Sander 2023-09-22 19:25 18650
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18651
    @brief returns an iterator to the first element
2660ccea Poul Sander 2023-09-22 19:25 18652
2660ccea Poul Sander 2023-09-22 19:25 18653
    Returns an iterator to the first element.
2660ccea Poul Sander 2023-09-22 19:25 18654
2660ccea Poul Sander 2023-09-22 19:25 18655
    @image html range-begin-end.svg "Illustration from cppreference.com"
2660ccea Poul Sander 2023-09-22 19:25 18656
2660ccea Poul Sander 2023-09-22 19:25 18657
    @return iterator to the first element
2660ccea Poul Sander 2023-09-22 19:25 18658
2660ccea Poul Sander 2023-09-22 19:25 18659
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 18660
2660ccea Poul Sander 2023-09-22 19:25 18661
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 18662
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2660ccea Poul Sander 2023-09-22 19:25 18663
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 18664
    - The complexity is constant.
2660ccea Poul Sander 2023-09-22 19:25 18665
2660ccea Poul Sander 2023-09-22 19:25 18666
    @liveexample{The following code shows an example for `begin()`.,begin}
2660ccea Poul Sander 2023-09-22 19:25 18667
2660ccea Poul Sander 2023-09-22 19:25 18668
    @sa @ref cbegin() -- returns a const iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18669
    @sa @ref end() -- returns an iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18670
    @sa @ref cend() -- returns a const iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18671
2660ccea Poul Sander 2023-09-22 19:25 18672
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18673
    */
2660ccea Poul Sander 2023-09-22 19:25 18674
    iterator begin() noexcept
2660ccea Poul Sander 2023-09-22 19:25 18675
    {
2660ccea Poul Sander 2023-09-22 19:25 18676
        iterator result(this);
2660ccea Poul Sander 2023-09-22 19:25 18677
        result.set_begin();
2660ccea Poul Sander 2023-09-22 19:25 18678
        return result;
2660ccea Poul Sander 2023-09-22 19:25 18679
    }
2660ccea Poul Sander 2023-09-22 19:25 18680
2660ccea Poul Sander 2023-09-22 19:25 18681
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18682
    @copydoc basic_json::cbegin()
2660ccea Poul Sander 2023-09-22 19:25 18683
    */
2660ccea Poul Sander 2023-09-22 19:25 18684
    const_iterator begin() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 18685
    {
2660ccea Poul Sander 2023-09-22 19:25 18686
        return cbegin();
2660ccea Poul Sander 2023-09-22 19:25 18687
    }
2660ccea Poul Sander 2023-09-22 19:25 18688
2660ccea Poul Sander 2023-09-22 19:25 18689
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18690
    @brief returns a const iterator to the first element
2660ccea Poul Sander 2023-09-22 19:25 18691
2660ccea Poul Sander 2023-09-22 19:25 18692
    Returns a const iterator to the first element.
2660ccea Poul Sander 2023-09-22 19:25 18693
2660ccea Poul Sander 2023-09-22 19:25 18694
    @image html range-begin-end.svg "Illustration from cppreference.com"
2660ccea Poul Sander 2023-09-22 19:25 18695
2660ccea Poul Sander 2023-09-22 19:25 18696
    @return const iterator to the first element
2660ccea Poul Sander 2023-09-22 19:25 18697
2660ccea Poul Sander 2023-09-22 19:25 18698
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 18699
2660ccea Poul Sander 2023-09-22 19:25 18700
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 18701
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2660ccea Poul Sander 2023-09-22 19:25 18702
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 18703
    - The complexity is constant.
2660ccea Poul Sander 2023-09-22 19:25 18704
    - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
2660ccea Poul Sander 2023-09-22 19:25 18705
2660ccea Poul Sander 2023-09-22 19:25 18706
    @liveexample{The following code shows an example for `cbegin()`.,cbegin}
2660ccea Poul Sander 2023-09-22 19:25 18707
2660ccea Poul Sander 2023-09-22 19:25 18708
    @sa @ref begin() -- returns an iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18709
    @sa @ref end() -- returns an iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18710
    @sa @ref cend() -- returns a const iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18711
2660ccea Poul Sander 2023-09-22 19:25 18712
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18713
    */
2660ccea Poul Sander 2023-09-22 19:25 18714
    const_iterator cbegin() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 18715
    {
2660ccea Poul Sander 2023-09-22 19:25 18716
        const_iterator result(this);
2660ccea Poul Sander 2023-09-22 19:25 18717
        result.set_begin();
2660ccea Poul Sander 2023-09-22 19:25 18718
        return result;
2660ccea Poul Sander 2023-09-22 19:25 18719
    }
2660ccea Poul Sander 2023-09-22 19:25 18720
2660ccea Poul Sander 2023-09-22 19:25 18721
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18722
    @brief returns an iterator to one past the last element
2660ccea Poul Sander 2023-09-22 19:25 18723
2660ccea Poul Sander 2023-09-22 19:25 18724
    Returns an iterator to one past the last element.
2660ccea Poul Sander 2023-09-22 19:25 18725
2660ccea Poul Sander 2023-09-22 19:25 18726
    @image html range-begin-end.svg "Illustration from cppreference.com"
2660ccea Poul Sander 2023-09-22 19:25 18727
2660ccea Poul Sander 2023-09-22 19:25 18728
    @return iterator one past the last element
2660ccea Poul Sander 2023-09-22 19:25 18729
2660ccea Poul Sander 2023-09-22 19:25 18730
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 18731
2660ccea Poul Sander 2023-09-22 19:25 18732
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 18733
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2660ccea Poul Sander 2023-09-22 19:25 18734
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 18735
    - The complexity is constant.
2660ccea Poul Sander 2023-09-22 19:25 18736
2660ccea Poul Sander 2023-09-22 19:25 18737
    @liveexample{The following code shows an example for `end()`.,end}
2660ccea Poul Sander 2023-09-22 19:25 18738
2660ccea Poul Sander 2023-09-22 19:25 18739
    @sa @ref cend() -- returns a const iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18740
    @sa @ref begin() -- returns an iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18741
    @sa @ref cbegin() -- returns a const iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18742
2660ccea Poul Sander 2023-09-22 19:25 18743
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18744
    */
2660ccea Poul Sander 2023-09-22 19:25 18745
    iterator end() noexcept
2660ccea Poul Sander 2023-09-22 19:25 18746
    {
2660ccea Poul Sander 2023-09-22 19:25 18747
        iterator result(this);
2660ccea Poul Sander 2023-09-22 19:25 18748
        result.set_end();
2660ccea Poul Sander 2023-09-22 19:25 18749
        return result;
2660ccea Poul Sander 2023-09-22 19:25 18750
    }
2660ccea Poul Sander 2023-09-22 19:25 18751
2660ccea Poul Sander 2023-09-22 19:25 18752
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18753
    @copydoc basic_json::cend()
2660ccea Poul Sander 2023-09-22 19:25 18754
    */
2660ccea Poul Sander 2023-09-22 19:25 18755
    const_iterator end() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 18756
    {
2660ccea Poul Sander 2023-09-22 19:25 18757
        return cend();
2660ccea Poul Sander 2023-09-22 19:25 18758
    }
2660ccea Poul Sander 2023-09-22 19:25 18759
2660ccea Poul Sander 2023-09-22 19:25 18760
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18761
    @brief returns a const iterator to one past the last element
2660ccea Poul Sander 2023-09-22 19:25 18762
2660ccea Poul Sander 2023-09-22 19:25 18763
    Returns a const iterator to one past the last element.
2660ccea Poul Sander 2023-09-22 19:25 18764
2660ccea Poul Sander 2023-09-22 19:25 18765
    @image html range-begin-end.svg "Illustration from cppreference.com"
2660ccea Poul Sander 2023-09-22 19:25 18766
2660ccea Poul Sander 2023-09-22 19:25 18767
    @return const iterator one past the last element
2660ccea Poul Sander 2023-09-22 19:25 18768
2660ccea Poul Sander 2023-09-22 19:25 18769
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 18770
2660ccea Poul Sander 2023-09-22 19:25 18771
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 18772
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2660ccea Poul Sander 2023-09-22 19:25 18773
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 18774
    - The complexity is constant.
2660ccea Poul Sander 2023-09-22 19:25 18775
    - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
2660ccea Poul Sander 2023-09-22 19:25 18776
2660ccea Poul Sander 2023-09-22 19:25 18777
    @liveexample{The following code shows an example for `cend()`.,cend}
2660ccea Poul Sander 2023-09-22 19:25 18778
2660ccea Poul Sander 2023-09-22 19:25 18779
    @sa @ref end() -- returns an iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18780
    @sa @ref begin() -- returns an iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18781
    @sa @ref cbegin() -- returns a const iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18782
2660ccea Poul Sander 2023-09-22 19:25 18783
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18784
    */
2660ccea Poul Sander 2023-09-22 19:25 18785
    const_iterator cend() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 18786
    {
2660ccea Poul Sander 2023-09-22 19:25 18787
        const_iterator result(this);
2660ccea Poul Sander 2023-09-22 19:25 18788
        result.set_end();
2660ccea Poul Sander 2023-09-22 19:25 18789
        return result;
2660ccea Poul Sander 2023-09-22 19:25 18790
    }
2660ccea Poul Sander 2023-09-22 19:25 18791
2660ccea Poul Sander 2023-09-22 19:25 18792
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18793
    @brief returns an iterator to the reverse-beginning
2660ccea Poul Sander 2023-09-22 19:25 18794
2660ccea Poul Sander 2023-09-22 19:25 18795
    Returns an iterator to the reverse-beginning; that is, the last element.
2660ccea Poul Sander 2023-09-22 19:25 18796
2660ccea Poul Sander 2023-09-22 19:25 18797
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
2660ccea Poul Sander 2023-09-22 19:25 18798
2660ccea Poul Sander 2023-09-22 19:25 18799
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 18800
2660ccea Poul Sander 2023-09-22 19:25 18801
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 18802
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
2660ccea Poul Sander 2023-09-22 19:25 18803
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 18804
    - The complexity is constant.
2660ccea Poul Sander 2023-09-22 19:25 18805
    - Has the semantics of `reverse_iterator(end())`.
2660ccea Poul Sander 2023-09-22 19:25 18806
2660ccea Poul Sander 2023-09-22 19:25 18807
    @liveexample{The following code shows an example for `rbegin()`.,rbegin}
2660ccea Poul Sander 2023-09-22 19:25 18808
2660ccea Poul Sander 2023-09-22 19:25 18809
    @sa @ref crbegin() -- returns a const reverse iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18810
    @sa @ref rend() -- returns a reverse iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18811
    @sa @ref crend() -- returns a const reverse iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18812
2660ccea Poul Sander 2023-09-22 19:25 18813
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18814
    */
2660ccea Poul Sander 2023-09-22 19:25 18815
    reverse_iterator rbegin() noexcept
2660ccea Poul Sander 2023-09-22 19:25 18816
    {
2660ccea Poul Sander 2023-09-22 19:25 18817
        return reverse_iterator(end());
2660ccea Poul Sander 2023-09-22 19:25 18818
    }
2660ccea Poul Sander 2023-09-22 19:25 18819
2660ccea Poul Sander 2023-09-22 19:25 18820
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18821
    @copydoc basic_json::crbegin()
2660ccea Poul Sander 2023-09-22 19:25 18822
    */
2660ccea Poul Sander 2023-09-22 19:25 18823
    const_reverse_iterator rbegin() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 18824
    {
2660ccea Poul Sander 2023-09-22 19:25 18825
        return crbegin();
2660ccea Poul Sander 2023-09-22 19:25 18826
    }
2660ccea Poul Sander 2023-09-22 19:25 18827
2660ccea Poul Sander 2023-09-22 19:25 18828
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18829
    @brief returns an iterator to the reverse-end
2660ccea Poul Sander 2023-09-22 19:25 18830
2660ccea Poul Sander 2023-09-22 19:25 18831
    Returns an iterator to the reverse-end; that is, one before the first
2660ccea Poul Sander 2023-09-22 19:25 18832
    element.
2660ccea Poul Sander 2023-09-22 19:25 18833
2660ccea Poul Sander 2023-09-22 19:25 18834
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
2660ccea Poul Sander 2023-09-22 19:25 18835
2660ccea Poul Sander 2023-09-22 19:25 18836
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 18837
2660ccea Poul Sander 2023-09-22 19:25 18838
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 18839
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
2660ccea Poul Sander 2023-09-22 19:25 18840
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 18841
    - The complexity is constant.
2660ccea Poul Sander 2023-09-22 19:25 18842
    - Has the semantics of `reverse_iterator(begin())`.
2660ccea Poul Sander 2023-09-22 19:25 18843
2660ccea Poul Sander 2023-09-22 19:25 18844
    @liveexample{The following code shows an example for `rend()`.,rend}
2660ccea Poul Sander 2023-09-22 19:25 18845
2660ccea Poul Sander 2023-09-22 19:25 18846
    @sa @ref crend() -- returns a const reverse iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18847
    @sa @ref rbegin() -- returns a reverse iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18848
    @sa @ref crbegin() -- returns a const reverse iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18849
2660ccea Poul Sander 2023-09-22 19:25 18850
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18851
    */
2660ccea Poul Sander 2023-09-22 19:25 18852
    reverse_iterator rend() noexcept
2660ccea Poul Sander 2023-09-22 19:25 18853
    {
2660ccea Poul Sander 2023-09-22 19:25 18854
        return reverse_iterator(begin());
2660ccea Poul Sander 2023-09-22 19:25 18855
    }
2660ccea Poul Sander 2023-09-22 19:25 18856
2660ccea Poul Sander 2023-09-22 19:25 18857
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18858
    @copydoc basic_json::crend()
2660ccea Poul Sander 2023-09-22 19:25 18859
    */
2660ccea Poul Sander 2023-09-22 19:25 18860
    const_reverse_iterator rend() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 18861
    {
2660ccea Poul Sander 2023-09-22 19:25 18862
        return crend();
2660ccea Poul Sander 2023-09-22 19:25 18863
    }
2660ccea Poul Sander 2023-09-22 19:25 18864
2660ccea Poul Sander 2023-09-22 19:25 18865
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18866
    @brief returns a const reverse iterator to the last element
2660ccea Poul Sander 2023-09-22 19:25 18867
2660ccea Poul Sander 2023-09-22 19:25 18868
    Returns a const iterator to the reverse-beginning; that is, the last
2660ccea Poul Sander 2023-09-22 19:25 18869
    element.
2660ccea Poul Sander 2023-09-22 19:25 18870
2660ccea Poul Sander 2023-09-22 19:25 18871
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
2660ccea Poul Sander 2023-09-22 19:25 18872
2660ccea Poul Sander 2023-09-22 19:25 18873
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 18874
2660ccea Poul Sander 2023-09-22 19:25 18875
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 18876
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
2660ccea Poul Sander 2023-09-22 19:25 18877
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 18878
    - The complexity is constant.
2660ccea Poul Sander 2023-09-22 19:25 18879
    - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
2660ccea Poul Sander 2023-09-22 19:25 18880
2660ccea Poul Sander 2023-09-22 19:25 18881
    @liveexample{The following code shows an example for `crbegin()`.,crbegin}
2660ccea Poul Sander 2023-09-22 19:25 18882
2660ccea Poul Sander 2023-09-22 19:25 18883
    @sa @ref rbegin() -- returns a reverse iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18884
    @sa @ref rend() -- returns a reverse iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18885
    @sa @ref crend() -- returns a const reverse iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18886
2660ccea Poul Sander 2023-09-22 19:25 18887
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18888
    */
2660ccea Poul Sander 2023-09-22 19:25 18889
    const_reverse_iterator crbegin() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 18890
    {
2660ccea Poul Sander 2023-09-22 19:25 18891
        return const_reverse_iterator(cend());
2660ccea Poul Sander 2023-09-22 19:25 18892
    }
2660ccea Poul Sander 2023-09-22 19:25 18893
2660ccea Poul Sander 2023-09-22 19:25 18894
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18895
    @brief returns a const reverse iterator to one before the first
2660ccea Poul Sander 2023-09-22 19:25 18896
2660ccea Poul Sander 2023-09-22 19:25 18897
    Returns a const reverse iterator to the reverse-end; that is, one before
2660ccea Poul Sander 2023-09-22 19:25 18898
    the first element.
2660ccea Poul Sander 2023-09-22 19:25 18899
2660ccea Poul Sander 2023-09-22 19:25 18900
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
2660ccea Poul Sander 2023-09-22 19:25 18901
2660ccea Poul Sander 2023-09-22 19:25 18902
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 18903
2660ccea Poul Sander 2023-09-22 19:25 18904
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 18905
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
2660ccea Poul Sander 2023-09-22 19:25 18906
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 18907
    - The complexity is constant.
2660ccea Poul Sander 2023-09-22 19:25 18908
    - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
2660ccea Poul Sander 2023-09-22 19:25 18909
2660ccea Poul Sander 2023-09-22 19:25 18910
    @liveexample{The following code shows an example for `crend()`.,crend}
2660ccea Poul Sander 2023-09-22 19:25 18911
2660ccea Poul Sander 2023-09-22 19:25 18912
    @sa @ref rend() -- returns a reverse iterator to the end
2660ccea Poul Sander 2023-09-22 19:25 18913
    @sa @ref rbegin() -- returns a reverse iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18914
    @sa @ref crbegin() -- returns a const reverse iterator to the beginning
2660ccea Poul Sander 2023-09-22 19:25 18915
2660ccea Poul Sander 2023-09-22 19:25 18916
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 18917
    */
2660ccea Poul Sander 2023-09-22 19:25 18918
    const_reverse_iterator crend() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 18919
    {
2660ccea Poul Sander 2023-09-22 19:25 18920
        return const_reverse_iterator(cbegin());
2660ccea Poul Sander 2023-09-22 19:25 18921
    }
2660ccea Poul Sander 2023-09-22 19:25 18922
2660ccea Poul Sander 2023-09-22 19:25 18923
  public:
2660ccea Poul Sander 2023-09-22 19:25 18924
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18925
    @brief wrapper to access iterator member functions in range-based for
2660ccea Poul Sander 2023-09-22 19:25 18926
2660ccea Poul Sander 2023-09-22 19:25 18927
    This function allows to access @ref iterator::key() and @ref
2660ccea Poul Sander 2023-09-22 19:25 18928
    iterator::value() during range-based for loops. In these loops, a
2660ccea Poul Sander 2023-09-22 19:25 18929
    reference to the JSON values is returned, so there is no access to the
2660ccea Poul Sander 2023-09-22 19:25 18930
    underlying iterator.
2660ccea Poul Sander 2023-09-22 19:25 18931
2660ccea Poul Sander 2023-09-22 19:25 18932
    For loop without iterator_wrapper:
2660ccea Poul Sander 2023-09-22 19:25 18933
2660ccea Poul Sander 2023-09-22 19:25 18934
    @code{cpp}
2660ccea Poul Sander 2023-09-22 19:25 18935
    for (auto it = j_object.begin(); it != j_object.end(); ++it)
2660ccea Poul Sander 2023-09-22 19:25 18936
    {
2660ccea Poul Sander 2023-09-22 19:25 18937
        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
2660ccea Poul Sander 2023-09-22 19:25 18938
    }
2660ccea Poul Sander 2023-09-22 19:25 18939
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 18940
2660ccea Poul Sander 2023-09-22 19:25 18941
    Range-based for loop without iterator proxy:
2660ccea Poul Sander 2023-09-22 19:25 18942
2660ccea Poul Sander 2023-09-22 19:25 18943
    @code{cpp}
2660ccea Poul Sander 2023-09-22 19:25 18944
    for (auto it : j_object)
2660ccea Poul Sander 2023-09-22 19:25 18945
    {
2660ccea Poul Sander 2023-09-22 19:25 18946
        // "it" is of type json::reference and has no key() member
2660ccea Poul Sander 2023-09-22 19:25 18947
        std::cout << "value: " << it << '\n';
2660ccea Poul Sander 2023-09-22 19:25 18948
    }
2660ccea Poul Sander 2023-09-22 19:25 18949
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 18950
2660ccea Poul Sander 2023-09-22 19:25 18951
    Range-based for loop with iterator proxy:
2660ccea Poul Sander 2023-09-22 19:25 18952
2660ccea Poul Sander 2023-09-22 19:25 18953
    @code{cpp}
2660ccea Poul Sander 2023-09-22 19:25 18954
    for (auto it : json::iterator_wrapper(j_object))
2660ccea Poul Sander 2023-09-22 19:25 18955
    {
2660ccea Poul Sander 2023-09-22 19:25 18956
        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
2660ccea Poul Sander 2023-09-22 19:25 18957
    }
2660ccea Poul Sander 2023-09-22 19:25 18958
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 18959
2660ccea Poul Sander 2023-09-22 19:25 18960
    @note When iterating over an array, `key()` will return the index of the
2660ccea Poul Sander 2023-09-22 19:25 18961
          element as string (see example).
2660ccea Poul Sander 2023-09-22 19:25 18962
2660ccea Poul Sander 2023-09-22 19:25 18963
    @param[in] ref  reference to a JSON value
2660ccea Poul Sander 2023-09-22 19:25 18964
    @return iteration proxy object wrapping @a ref with an interface to use in
2660ccea Poul Sander 2023-09-22 19:25 18965
            range-based for loops
2660ccea Poul Sander 2023-09-22 19:25 18966
2660ccea Poul Sander 2023-09-22 19:25 18967
    @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
2660ccea Poul Sander 2023-09-22 19:25 18968
2660ccea Poul Sander 2023-09-22 19:25 18969
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 18970
    changes in the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 18971
2660ccea Poul Sander 2023-09-22 19:25 18972
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 18973
2660ccea Poul Sander 2023-09-22 19:25 18974
    @note The name of this function is not yet final and may change in the
2660ccea Poul Sander 2023-09-22 19:25 18975
    future.
2660ccea Poul Sander 2023-09-22 19:25 18976
2660ccea Poul Sander 2023-09-22 19:25 18977
    @deprecated This stream operator is deprecated and will be removed in
2660ccea Poul Sander 2023-09-22 19:25 18978
                future 4.0.0 of the library. Please use @ref items() instead;
2660ccea Poul Sander 2023-09-22 19:25 18979
                that is, replace `json::iterator_wrapper(j)` with `j.items()`.
2660ccea Poul Sander 2023-09-22 19:25 18980
    */
2660ccea Poul Sander 2023-09-22 19:25 18981
    JSON_HEDLEY_DEPRECATED(3.1.0)
2660ccea Poul Sander 2023-09-22 19:25 18982
    static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
2660ccea Poul Sander 2023-09-22 19:25 18983
    {
2660ccea Poul Sander 2023-09-22 19:25 18984
        return ref.items();
2660ccea Poul Sander 2023-09-22 19:25 18985
    }
2660ccea Poul Sander 2023-09-22 19:25 18986
2660ccea Poul Sander 2023-09-22 19:25 18987
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18988
    @copydoc iterator_wrapper(reference)
2660ccea Poul Sander 2023-09-22 19:25 18989
    */
2660ccea Poul Sander 2023-09-22 19:25 18990
    JSON_HEDLEY_DEPRECATED(3.1.0)
2660ccea Poul Sander 2023-09-22 19:25 18991
    static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
2660ccea Poul Sander 2023-09-22 19:25 18992
    {
2660ccea Poul Sander 2023-09-22 19:25 18993
        return ref.items();
2660ccea Poul Sander 2023-09-22 19:25 18994
    }
2660ccea Poul Sander 2023-09-22 19:25 18995
2660ccea Poul Sander 2023-09-22 19:25 18996
    /*!
2660ccea Poul Sander 2023-09-22 19:25 18997
    @brief helper to access iterator member functions in range-based for
2660ccea Poul Sander 2023-09-22 19:25 18998
2660ccea Poul Sander 2023-09-22 19:25 18999
    This function allows to access @ref iterator::key() and @ref
2660ccea Poul Sander 2023-09-22 19:25 19000
    iterator::value() during range-based for loops. In these loops, a
2660ccea Poul Sander 2023-09-22 19:25 19001
    reference to the JSON values is returned, so there is no access to the
2660ccea Poul Sander 2023-09-22 19:25 19002
    underlying iterator.
2660ccea Poul Sander 2023-09-22 19:25 19003
2660ccea Poul Sander 2023-09-22 19:25 19004
    For loop without `items()` function:
2660ccea Poul Sander 2023-09-22 19:25 19005
2660ccea Poul Sander 2023-09-22 19:25 19006
    @code{cpp}
2660ccea Poul Sander 2023-09-22 19:25 19007
    for (auto it = j_object.begin(); it != j_object.end(); ++it)
2660ccea Poul Sander 2023-09-22 19:25 19008
    {
2660ccea Poul Sander 2023-09-22 19:25 19009
        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
2660ccea Poul Sander 2023-09-22 19:25 19010
    }
2660ccea Poul Sander 2023-09-22 19:25 19011
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 19012
2660ccea Poul Sander 2023-09-22 19:25 19013
    Range-based for loop without `items()` function:
2660ccea Poul Sander 2023-09-22 19:25 19014
2660ccea Poul Sander 2023-09-22 19:25 19015
    @code{cpp}
2660ccea Poul Sander 2023-09-22 19:25 19016
    for (auto it : j_object)
2660ccea Poul Sander 2023-09-22 19:25 19017
    {
2660ccea Poul Sander 2023-09-22 19:25 19018
        // "it" is of type json::reference and has no key() member
2660ccea Poul Sander 2023-09-22 19:25 19019
        std::cout << "value: " << it << '\n';
2660ccea Poul Sander 2023-09-22 19:25 19020
    }
2660ccea Poul Sander 2023-09-22 19:25 19021
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 19022
2660ccea Poul Sander 2023-09-22 19:25 19023
    Range-based for loop with `items()` function:
2660ccea Poul Sander 2023-09-22 19:25 19024
2660ccea Poul Sander 2023-09-22 19:25 19025
    @code{cpp}
2660ccea Poul Sander 2023-09-22 19:25 19026
    for (auto& el : j_object.items())
2660ccea Poul Sander 2023-09-22 19:25 19027
    {
2660ccea Poul Sander 2023-09-22 19:25 19028
        std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
2660ccea Poul Sander 2023-09-22 19:25 19029
    }
2660ccea Poul Sander 2023-09-22 19:25 19030
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 19031
2660ccea Poul Sander 2023-09-22 19:25 19032
    The `items()` function also allows to use
2660ccea Poul Sander 2023-09-22 19:25 19033
    [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
2660ccea Poul Sander 2023-09-22 19:25 19034
    (C++17):
2660ccea Poul Sander 2023-09-22 19:25 19035
2660ccea Poul Sander 2023-09-22 19:25 19036
    @code{cpp}
2660ccea Poul Sander 2023-09-22 19:25 19037
    for (auto& [key, val] : j_object.items())
2660ccea Poul Sander 2023-09-22 19:25 19038
    {
2660ccea Poul Sander 2023-09-22 19:25 19039
        std::cout << "key: " << key << ", value:" << val << '\n';
2660ccea Poul Sander 2023-09-22 19:25 19040
    }
2660ccea Poul Sander 2023-09-22 19:25 19041
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 19042
2660ccea Poul Sander 2023-09-22 19:25 19043
    @note When iterating over an array, `key()` will return the index of the
2660ccea Poul Sander 2023-09-22 19:25 19044
          element as string (see example). For primitive types (e.g., numbers),
2660ccea Poul Sander 2023-09-22 19:25 19045
          `key()` returns an empty string.
2660ccea Poul Sander 2023-09-22 19:25 19046
2660ccea Poul Sander 2023-09-22 19:25 19047
    @return iteration proxy object wrapping @a ref with an interface to use in
2660ccea Poul Sander 2023-09-22 19:25 19048
            range-based for loops
2660ccea Poul Sander 2023-09-22 19:25 19049
2660ccea Poul Sander 2023-09-22 19:25 19050
    @liveexample{The following code shows how the function is used.,items}
2660ccea Poul Sander 2023-09-22 19:25 19051
2660ccea Poul Sander 2023-09-22 19:25 19052
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 19053
    changes in the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 19054
2660ccea Poul Sander 2023-09-22 19:25 19055
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 19056
2660ccea Poul Sander 2023-09-22 19:25 19057
    @since version 3.1.0, structured bindings support since 3.5.0.
2660ccea Poul Sander 2023-09-22 19:25 19058
    */
2660ccea Poul Sander 2023-09-22 19:25 19059
    iteration_proxy<iterator> items() noexcept
2660ccea Poul Sander 2023-09-22 19:25 19060
    {
2660ccea Poul Sander 2023-09-22 19:25 19061
        return iteration_proxy<iterator>(*this);
2660ccea Poul Sander 2023-09-22 19:25 19062
    }
2660ccea Poul Sander 2023-09-22 19:25 19063
2660ccea Poul Sander 2023-09-22 19:25 19064
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19065
    @copydoc items()
2660ccea Poul Sander 2023-09-22 19:25 19066
    */
2660ccea Poul Sander 2023-09-22 19:25 19067
    iteration_proxy<const_iterator> items() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 19068
    {
2660ccea Poul Sander 2023-09-22 19:25 19069
        return iteration_proxy<const_iterator>(*this);
2660ccea Poul Sander 2023-09-22 19:25 19070
    }
2660ccea Poul Sander 2023-09-22 19:25 19071
2660ccea Poul Sander 2023-09-22 19:25 19072
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 19073
2660ccea Poul Sander 2023-09-22 19:25 19074
2660ccea Poul Sander 2023-09-22 19:25 19075
    //////////////
2660ccea Poul Sander 2023-09-22 19:25 19076
    // capacity //
2660ccea Poul Sander 2023-09-22 19:25 19077
    //////////////
2660ccea Poul Sander 2023-09-22 19:25 19078
2660ccea Poul Sander 2023-09-22 19:25 19079
    /// @name capacity
2660ccea Poul Sander 2023-09-22 19:25 19080
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 19081
2660ccea Poul Sander 2023-09-22 19:25 19082
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19083
    @brief checks whether the container is empty.
2660ccea Poul Sander 2023-09-22 19:25 19084
2660ccea Poul Sander 2023-09-22 19:25 19085
    Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
2660ccea Poul Sander 2023-09-22 19:25 19086
2660ccea Poul Sander 2023-09-22 19:25 19087
    @return The return value depends on the different types and is
2660ccea Poul Sander 2023-09-22 19:25 19088
            defined as follows:
2660ccea Poul Sander 2023-09-22 19:25 19089
            Value type  | return value
2660ccea Poul Sander 2023-09-22 19:25 19090
            ----------- | -------------
2660ccea Poul Sander 2023-09-22 19:25 19091
            null        | `true`
2660ccea Poul Sander 2023-09-22 19:25 19092
            boolean     | `false`
2660ccea Poul Sander 2023-09-22 19:25 19093
            string      | `false`
2660ccea Poul Sander 2023-09-22 19:25 19094
            number      | `false`
2660ccea Poul Sander 2023-09-22 19:25 19095
            object      | result of function `object_t::empty()`
2660ccea Poul Sander 2023-09-22 19:25 19096
            array       | result of function `array_t::empty()`
2660ccea Poul Sander 2023-09-22 19:25 19097
2660ccea Poul Sander 2023-09-22 19:25 19098
    @liveexample{The following code uses `empty()` to check if a JSON
2660ccea Poul Sander 2023-09-22 19:25 19099
    object contains any elements.,empty}
2660ccea Poul Sander 2023-09-22 19:25 19100
2660ccea Poul Sander 2023-09-22 19:25 19101
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
2660ccea Poul Sander 2023-09-22 19:25 19102
    the Container concept; that is, their `empty()` functions have constant
2660ccea Poul Sander 2023-09-22 19:25 19103
    complexity.
2660ccea Poul Sander 2023-09-22 19:25 19104
2660ccea Poul Sander 2023-09-22 19:25 19105
    @iterators No changes.
2660ccea Poul Sander 2023-09-22 19:25 19106
2660ccea Poul Sander 2023-09-22 19:25 19107
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 19108
2660ccea Poul Sander 2023-09-22 19:25 19109
    @note This function does not return whether a string stored as JSON value
2660ccea Poul Sander 2023-09-22 19:25 19110
    is empty - it returns whether the JSON container itself is empty which is
2660ccea Poul Sander 2023-09-22 19:25 19111
    false in the case of a string.
2660ccea Poul Sander 2023-09-22 19:25 19112
2660ccea Poul Sander 2023-09-22 19:25 19113
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 19114
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2660ccea Poul Sander 2023-09-22 19:25 19115
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 19116
    - The complexity is constant.
2660ccea Poul Sander 2023-09-22 19:25 19117
    - Has the semantics of `begin() == end()`.
2660ccea Poul Sander 2023-09-22 19:25 19118
2660ccea Poul Sander 2023-09-22 19:25 19119
    @sa @ref size() -- returns the number of elements
2660ccea Poul Sander 2023-09-22 19:25 19120
2660ccea Poul Sander 2023-09-22 19:25 19121
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 19122
    */
2660ccea Poul Sander 2023-09-22 19:25 19123
    bool empty() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 19124
    {
2660ccea Poul Sander 2023-09-22 19:25 19125
        switch (m_type)
2660ccea Poul Sander 2023-09-22 19:25 19126
        {
2660ccea Poul Sander 2023-09-22 19:25 19127
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 19128
            {
2660ccea Poul Sander 2023-09-22 19:25 19129
                // null values are empty
2660ccea Poul Sander 2023-09-22 19:25 19130
                return true;
2660ccea Poul Sander 2023-09-22 19:25 19131
            }
2660ccea Poul Sander 2023-09-22 19:25 19132
2660ccea Poul Sander 2023-09-22 19:25 19133
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 19134
            {
2660ccea Poul Sander 2023-09-22 19:25 19135
                // delegate call to array_t::empty()
2660ccea Poul Sander 2023-09-22 19:25 19136
                return m_value.array->empty();
2660ccea Poul Sander 2023-09-22 19:25 19137
            }
2660ccea Poul Sander 2023-09-22 19:25 19138
2660ccea Poul Sander 2023-09-22 19:25 19139
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 19140
            {
2660ccea Poul Sander 2023-09-22 19:25 19141
                // delegate call to object_t::empty()
2660ccea Poul Sander 2023-09-22 19:25 19142
                return m_value.object->empty();
2660ccea Poul Sander 2023-09-22 19:25 19143
            }
2660ccea Poul Sander 2023-09-22 19:25 19144
2660ccea Poul Sander 2023-09-22 19:25 19145
            default:
2660ccea Poul Sander 2023-09-22 19:25 19146
            {
2660ccea Poul Sander 2023-09-22 19:25 19147
                // all other types are nonempty
2660ccea Poul Sander 2023-09-22 19:25 19148
                return false;
2660ccea Poul Sander 2023-09-22 19:25 19149
            }
2660ccea Poul Sander 2023-09-22 19:25 19150
        }
2660ccea Poul Sander 2023-09-22 19:25 19151
    }
2660ccea Poul Sander 2023-09-22 19:25 19152
2660ccea Poul Sander 2023-09-22 19:25 19153
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19154
    @brief returns the number of elements
2660ccea Poul Sander 2023-09-22 19:25 19155
2660ccea Poul Sander 2023-09-22 19:25 19156
    Returns the number of elements in a JSON value.
2660ccea Poul Sander 2023-09-22 19:25 19157
2660ccea Poul Sander 2023-09-22 19:25 19158
    @return The return value depends on the different types and is
2660ccea Poul Sander 2023-09-22 19:25 19159
            defined as follows:
2660ccea Poul Sander 2023-09-22 19:25 19160
            Value type  | return value
2660ccea Poul Sander 2023-09-22 19:25 19161
            ----------- | -------------
2660ccea Poul Sander 2023-09-22 19:25 19162
            null        | `0`
2660ccea Poul Sander 2023-09-22 19:25 19163
            boolean     | `1`
2660ccea Poul Sander 2023-09-22 19:25 19164
            string      | `1`
2660ccea Poul Sander 2023-09-22 19:25 19165
            number      | `1`
2660ccea Poul Sander 2023-09-22 19:25 19166
            object      | result of function object_t::size()
2660ccea Poul Sander 2023-09-22 19:25 19167
            array       | result of function array_t::size()
2660ccea Poul Sander 2023-09-22 19:25 19168
2660ccea Poul Sander 2023-09-22 19:25 19169
    @liveexample{The following code calls `size()` on the different value
2660ccea Poul Sander 2023-09-22 19:25 19170
    types.,size}
2660ccea Poul Sander 2023-09-22 19:25 19171
2660ccea Poul Sander 2023-09-22 19:25 19172
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
2660ccea Poul Sander 2023-09-22 19:25 19173
    the Container concept; that is, their size() functions have constant
2660ccea Poul Sander 2023-09-22 19:25 19174
    complexity.
2660ccea Poul Sander 2023-09-22 19:25 19175
2660ccea Poul Sander 2023-09-22 19:25 19176
    @iterators No changes.
2660ccea Poul Sander 2023-09-22 19:25 19177
2660ccea Poul Sander 2023-09-22 19:25 19178
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 19179
2660ccea Poul Sander 2023-09-22 19:25 19180
    @note This function does not return the length of a string stored as JSON
2660ccea Poul Sander 2023-09-22 19:25 19181
    value - it returns the number of elements in the JSON value which is 1 in
2660ccea Poul Sander 2023-09-22 19:25 19182
    the case of a string.
2660ccea Poul Sander 2023-09-22 19:25 19183
2660ccea Poul Sander 2023-09-22 19:25 19184
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 19185
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2660ccea Poul Sander 2023-09-22 19:25 19186
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 19187
    - The complexity is constant.
2660ccea Poul Sander 2023-09-22 19:25 19188
    - Has the semantics of `std::distance(begin(), end())`.
2660ccea Poul Sander 2023-09-22 19:25 19189
2660ccea Poul Sander 2023-09-22 19:25 19190
    @sa @ref empty() -- checks whether the container is empty
2660ccea Poul Sander 2023-09-22 19:25 19191
    @sa @ref max_size() -- returns the maximal number of elements
2660ccea Poul Sander 2023-09-22 19:25 19192
2660ccea Poul Sander 2023-09-22 19:25 19193
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 19194
    */
2660ccea Poul Sander 2023-09-22 19:25 19195
    size_type size() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 19196
    {
2660ccea Poul Sander 2023-09-22 19:25 19197
        switch (m_type)
2660ccea Poul Sander 2023-09-22 19:25 19198
        {
2660ccea Poul Sander 2023-09-22 19:25 19199
            case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 19200
            {
2660ccea Poul Sander 2023-09-22 19:25 19201
                // null values are empty
2660ccea Poul Sander 2023-09-22 19:25 19202
                return 0;
2660ccea Poul Sander 2023-09-22 19:25 19203
            }
2660ccea Poul Sander 2023-09-22 19:25 19204
2660ccea Poul Sander 2023-09-22 19:25 19205
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 19206
            {
2660ccea Poul Sander 2023-09-22 19:25 19207
                // delegate call to array_t::size()
2660ccea Poul Sander 2023-09-22 19:25 19208
                return m_value.array->size();
2660ccea Poul Sander 2023-09-22 19:25 19209
            }
2660ccea Poul Sander 2023-09-22 19:25 19210
2660ccea Poul Sander 2023-09-22 19:25 19211
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 19212
            {
2660ccea Poul Sander 2023-09-22 19:25 19213
                // delegate call to object_t::size()
2660ccea Poul Sander 2023-09-22 19:25 19214
                return m_value.object->size();
2660ccea Poul Sander 2023-09-22 19:25 19215
            }
2660ccea Poul Sander 2023-09-22 19:25 19216
2660ccea Poul Sander 2023-09-22 19:25 19217
            default:
2660ccea Poul Sander 2023-09-22 19:25 19218
            {
2660ccea Poul Sander 2023-09-22 19:25 19219
                // all other types have size 1
2660ccea Poul Sander 2023-09-22 19:25 19220
                return 1;
2660ccea Poul Sander 2023-09-22 19:25 19221
            }
2660ccea Poul Sander 2023-09-22 19:25 19222
        }
2660ccea Poul Sander 2023-09-22 19:25 19223
    }
2660ccea Poul Sander 2023-09-22 19:25 19224
2660ccea Poul Sander 2023-09-22 19:25 19225
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19226
    @brief returns the maximum possible number of elements
2660ccea Poul Sander 2023-09-22 19:25 19227
2660ccea Poul Sander 2023-09-22 19:25 19228
    Returns the maximum number of elements a JSON value is able to hold due to
2660ccea Poul Sander 2023-09-22 19:25 19229
    system or library implementation limitations, i.e. `std::distance(begin(),
2660ccea Poul Sander 2023-09-22 19:25 19230
    end())` for the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 19231
2660ccea Poul Sander 2023-09-22 19:25 19232
    @return The return value depends on the different types and is
2660ccea Poul Sander 2023-09-22 19:25 19233
            defined as follows:
2660ccea Poul Sander 2023-09-22 19:25 19234
            Value type  | return value
2660ccea Poul Sander 2023-09-22 19:25 19235
            ----------- | -------------
2660ccea Poul Sander 2023-09-22 19:25 19236
            null        | `0` (same as `size()`)
2660ccea Poul Sander 2023-09-22 19:25 19237
            boolean     | `1` (same as `size()`)
2660ccea Poul Sander 2023-09-22 19:25 19238
            string      | `1` (same as `size()`)
2660ccea Poul Sander 2023-09-22 19:25 19239
            number      | `1` (same as `size()`)
2660ccea Poul Sander 2023-09-22 19:25 19240
            object      | result of function `object_t::max_size()`
2660ccea Poul Sander 2023-09-22 19:25 19241
            array       | result of function `array_t::max_size()`
2660ccea Poul Sander 2023-09-22 19:25 19242
2660ccea Poul Sander 2023-09-22 19:25 19243
    @liveexample{The following code calls `max_size()` on the different value
2660ccea Poul Sander 2023-09-22 19:25 19244
    types. Note the output is implementation specific.,max_size}
2660ccea Poul Sander 2023-09-22 19:25 19245
2660ccea Poul Sander 2023-09-22 19:25 19246
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
2660ccea Poul Sander 2023-09-22 19:25 19247
    the Container concept; that is, their `max_size()` functions have constant
2660ccea Poul Sander 2023-09-22 19:25 19248
    complexity.
2660ccea Poul Sander 2023-09-22 19:25 19249
2660ccea Poul Sander 2023-09-22 19:25 19250
    @iterators No changes.
2660ccea Poul Sander 2023-09-22 19:25 19251
2660ccea Poul Sander 2023-09-22 19:25 19252
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 19253
2660ccea Poul Sander 2023-09-22 19:25 19254
    @requirement This function helps `basic_json` satisfying the
2660ccea Poul Sander 2023-09-22 19:25 19255
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2660ccea Poul Sander 2023-09-22 19:25 19256
    requirements:
2660ccea Poul Sander 2023-09-22 19:25 19257
    - The complexity is constant.
2660ccea Poul Sander 2023-09-22 19:25 19258
    - Has the semantics of returning `b.size()` where `b` is the largest
2660ccea Poul Sander 2023-09-22 19:25 19259
      possible JSON value.
2660ccea Poul Sander 2023-09-22 19:25 19260
2660ccea Poul Sander 2023-09-22 19:25 19261
    @sa @ref size() -- returns the number of elements
2660ccea Poul Sander 2023-09-22 19:25 19262
2660ccea Poul Sander 2023-09-22 19:25 19263
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 19264
    */
2660ccea Poul Sander 2023-09-22 19:25 19265
    size_type max_size() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 19266
    {
2660ccea Poul Sander 2023-09-22 19:25 19267
        switch (m_type)
2660ccea Poul Sander 2023-09-22 19:25 19268
        {
2660ccea Poul Sander 2023-09-22 19:25 19269
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 19270
            {
2660ccea Poul Sander 2023-09-22 19:25 19271
                // delegate call to array_t::max_size()
2660ccea Poul Sander 2023-09-22 19:25 19272
                return m_value.array->max_size();
2660ccea Poul Sander 2023-09-22 19:25 19273
            }
2660ccea Poul Sander 2023-09-22 19:25 19274
2660ccea Poul Sander 2023-09-22 19:25 19275
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 19276
            {
2660ccea Poul Sander 2023-09-22 19:25 19277
                // delegate call to object_t::max_size()
2660ccea Poul Sander 2023-09-22 19:25 19278
                return m_value.object->max_size();
2660ccea Poul Sander 2023-09-22 19:25 19279
            }
2660ccea Poul Sander 2023-09-22 19:25 19280
2660ccea Poul Sander 2023-09-22 19:25 19281
            default:
2660ccea Poul Sander 2023-09-22 19:25 19282
            {
2660ccea Poul Sander 2023-09-22 19:25 19283
                // all other types have max_size() == size()
2660ccea Poul Sander 2023-09-22 19:25 19284
                return size();
2660ccea Poul Sander 2023-09-22 19:25 19285
            }
2660ccea Poul Sander 2023-09-22 19:25 19286
        }
2660ccea Poul Sander 2023-09-22 19:25 19287
    }
2660ccea Poul Sander 2023-09-22 19:25 19288
2660ccea Poul Sander 2023-09-22 19:25 19289
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 19290
2660ccea Poul Sander 2023-09-22 19:25 19291
2660ccea Poul Sander 2023-09-22 19:25 19292
    ///////////////
2660ccea Poul Sander 2023-09-22 19:25 19293
    // modifiers //
2660ccea Poul Sander 2023-09-22 19:25 19294
    ///////////////
2660ccea Poul Sander 2023-09-22 19:25 19295
2660ccea Poul Sander 2023-09-22 19:25 19296
    /// @name modifiers
2660ccea Poul Sander 2023-09-22 19:25 19297
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 19298
2660ccea Poul Sander 2023-09-22 19:25 19299
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19300
    @brief clears the contents
2660ccea Poul Sander 2023-09-22 19:25 19301
2660ccea Poul Sander 2023-09-22 19:25 19302
    Clears the content of a JSON value and resets it to the default value as
2660ccea Poul Sander 2023-09-22 19:25 19303
    if @ref basic_json(value_t) would have been called with the current value
2660ccea Poul Sander 2023-09-22 19:25 19304
    type from @ref type():
2660ccea Poul Sander 2023-09-22 19:25 19305
2660ccea Poul Sander 2023-09-22 19:25 19306
    Value type  | initial value
2660ccea Poul Sander 2023-09-22 19:25 19307
    ----------- | -------------
2660ccea Poul Sander 2023-09-22 19:25 19308
    null        | `null`
2660ccea Poul Sander 2023-09-22 19:25 19309
    boolean     | `false`
2660ccea Poul Sander 2023-09-22 19:25 19310
    string      | `""`
2660ccea Poul Sander 2023-09-22 19:25 19311
    number      | `0`
2660ccea Poul Sander 2023-09-22 19:25 19312
    object      | `{}`
2660ccea Poul Sander 2023-09-22 19:25 19313
    array       | `[]`
2660ccea Poul Sander 2023-09-22 19:25 19314
2660ccea Poul Sander 2023-09-22 19:25 19315
    @post Has the same effect as calling
2660ccea Poul Sander 2023-09-22 19:25 19316
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 19317
    *this = basic_json(type());
2660ccea Poul Sander 2023-09-22 19:25 19318
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 19319
2660ccea Poul Sander 2023-09-22 19:25 19320
    @liveexample{The example below shows the effect of `clear()` to different
2660ccea Poul Sander 2023-09-22 19:25 19321
    JSON types.,clear}
2660ccea Poul Sander 2023-09-22 19:25 19322
2660ccea Poul Sander 2023-09-22 19:25 19323
    @complexity Linear in the size of the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 19324
2660ccea Poul Sander 2023-09-22 19:25 19325
    @iterators All iterators, pointers and references related to this container
2660ccea Poul Sander 2023-09-22 19:25 19326
               are invalidated.
2660ccea Poul Sander 2023-09-22 19:25 19327
2660ccea Poul Sander 2023-09-22 19:25 19328
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 19329
2660ccea Poul Sander 2023-09-22 19:25 19330
    @sa @ref basic_json(value_t) -- constructor that creates an object with the
2660ccea Poul Sander 2023-09-22 19:25 19331
        same value than calling `clear()`
2660ccea Poul Sander 2023-09-22 19:25 19332
2660ccea Poul Sander 2023-09-22 19:25 19333
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 19334
    */
2660ccea Poul Sander 2023-09-22 19:25 19335
    void clear() noexcept
2660ccea Poul Sander 2023-09-22 19:25 19336
    {
2660ccea Poul Sander 2023-09-22 19:25 19337
        switch (m_type)
2660ccea Poul Sander 2023-09-22 19:25 19338
        {
2660ccea Poul Sander 2023-09-22 19:25 19339
            case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 19340
            {
2660ccea Poul Sander 2023-09-22 19:25 19341
                m_value.number_integer = 0;
2660ccea Poul Sander 2023-09-22 19:25 19342
                break;
2660ccea Poul Sander 2023-09-22 19:25 19343
            }
2660ccea Poul Sander 2023-09-22 19:25 19344
2660ccea Poul Sander 2023-09-22 19:25 19345
            case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 19346
            {
2660ccea Poul Sander 2023-09-22 19:25 19347
                m_value.number_unsigned = 0;
2660ccea Poul Sander 2023-09-22 19:25 19348
                break;
2660ccea Poul Sander 2023-09-22 19:25 19349
            }
2660ccea Poul Sander 2023-09-22 19:25 19350
2660ccea Poul Sander 2023-09-22 19:25 19351
            case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 19352
            {
2660ccea Poul Sander 2023-09-22 19:25 19353
                m_value.number_float = 0.0;
2660ccea Poul Sander 2023-09-22 19:25 19354
                break;
2660ccea Poul Sander 2023-09-22 19:25 19355
            }
2660ccea Poul Sander 2023-09-22 19:25 19356
2660ccea Poul Sander 2023-09-22 19:25 19357
            case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 19358
            {
2660ccea Poul Sander 2023-09-22 19:25 19359
                m_value.boolean = false;
2660ccea Poul Sander 2023-09-22 19:25 19360
                break;
2660ccea Poul Sander 2023-09-22 19:25 19361
            }
2660ccea Poul Sander 2023-09-22 19:25 19362
2660ccea Poul Sander 2023-09-22 19:25 19363
            case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 19364
            {
2660ccea Poul Sander 2023-09-22 19:25 19365
                m_value.string->clear();
2660ccea Poul Sander 2023-09-22 19:25 19366
                break;
2660ccea Poul Sander 2023-09-22 19:25 19367
            }
2660ccea Poul Sander 2023-09-22 19:25 19368
2660ccea Poul Sander 2023-09-22 19:25 19369
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 19370
            {
2660ccea Poul Sander 2023-09-22 19:25 19371
                m_value.array->clear();
2660ccea Poul Sander 2023-09-22 19:25 19372
                break;
2660ccea Poul Sander 2023-09-22 19:25 19373
            }
2660ccea Poul Sander 2023-09-22 19:25 19374
2660ccea Poul Sander 2023-09-22 19:25 19375
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 19376
            {
2660ccea Poul Sander 2023-09-22 19:25 19377
                m_value.object->clear();
2660ccea Poul Sander 2023-09-22 19:25 19378
                break;
2660ccea Poul Sander 2023-09-22 19:25 19379
            }
2660ccea Poul Sander 2023-09-22 19:25 19380
2660ccea Poul Sander 2023-09-22 19:25 19381
            default:
2660ccea Poul Sander 2023-09-22 19:25 19382
                break;
2660ccea Poul Sander 2023-09-22 19:25 19383
        }
2660ccea Poul Sander 2023-09-22 19:25 19384
    }
2660ccea Poul Sander 2023-09-22 19:25 19385
2660ccea Poul Sander 2023-09-22 19:25 19386
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19387
    @brief add an object to an array
2660ccea Poul Sander 2023-09-22 19:25 19388
2660ccea Poul Sander 2023-09-22 19:25 19389
    Appends the given element @a val to the end of the JSON value. If the
2660ccea Poul Sander 2023-09-22 19:25 19390
    function is called on a JSON null value, an empty array is created before
2660ccea Poul Sander 2023-09-22 19:25 19391
    appending @a val.
2660ccea Poul Sander 2023-09-22 19:25 19392
2660ccea Poul Sander 2023-09-22 19:25 19393
    @param[in] val the value to add to the JSON array
2660ccea Poul Sander 2023-09-22 19:25 19394
2660ccea Poul Sander 2023-09-22 19:25 19395
    @throw type_error.308 when called on a type other than JSON array or
2660ccea Poul Sander 2023-09-22 19:25 19396
    null; example: `"cannot use push_back() with number"`
2660ccea Poul Sander 2023-09-22 19:25 19397
2660ccea Poul Sander 2023-09-22 19:25 19398
    @complexity Amortized constant.
2660ccea Poul Sander 2023-09-22 19:25 19399
2660ccea Poul Sander 2023-09-22 19:25 19400
    @liveexample{The example shows how `push_back()` and `+=` can be used to
2660ccea Poul Sander 2023-09-22 19:25 19401
    add elements to a JSON array. Note how the `null` value was silently
2660ccea Poul Sander 2023-09-22 19:25 19402
    converted to a JSON array.,push_back}
2660ccea Poul Sander 2023-09-22 19:25 19403
2660ccea Poul Sander 2023-09-22 19:25 19404
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 19405
    */
2660ccea Poul Sander 2023-09-22 19:25 19406
    void push_back(basic_json&& val)
2660ccea Poul Sander 2023-09-22 19:25 19407
    {
2660ccea Poul Sander 2023-09-22 19:25 19408
        // push_back only works for null objects or arrays
2660ccea Poul Sander 2023-09-22 19:25 19409
        if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
2660ccea Poul Sander 2023-09-22 19:25 19410
        {
2660ccea Poul Sander 2023-09-22 19:25 19411
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19412
        }
2660ccea Poul Sander 2023-09-22 19:25 19413
2660ccea Poul Sander 2023-09-22 19:25 19414
        // transform null object into an array
2660ccea Poul Sander 2023-09-22 19:25 19415
        if (is_null())
2660ccea Poul Sander 2023-09-22 19:25 19416
        {
2660ccea Poul Sander 2023-09-22 19:25 19417
            m_type = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 19418
            m_value = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 19419
            assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 19420
        }
2660ccea Poul Sander 2023-09-22 19:25 19421
2660ccea Poul Sander 2023-09-22 19:25 19422
        // add element to array (move semantics)
2660ccea Poul Sander 2023-09-22 19:25 19423
        m_value.array->push_back(std::move(val));
2660ccea Poul Sander 2023-09-22 19:25 19424
        // invalidate object: mark it null so we do not call the destructor
2660ccea Poul Sander 2023-09-22 19:25 19425
        // cppcheck-suppress accessMoved
2660ccea Poul Sander 2023-09-22 19:25 19426
        val.m_type = value_t::null;
2660ccea Poul Sander 2023-09-22 19:25 19427
    }
2660ccea Poul Sander 2023-09-22 19:25 19428
2660ccea Poul Sander 2023-09-22 19:25 19429
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19430
    @brief add an object to an array
2660ccea Poul Sander 2023-09-22 19:25 19431
    @copydoc push_back(basic_json&&)
2660ccea Poul Sander 2023-09-22 19:25 19432
    */
2660ccea Poul Sander 2023-09-22 19:25 19433
    reference operator+=(basic_json&& val)
2660ccea Poul Sander 2023-09-22 19:25 19434
    {
2660ccea Poul Sander 2023-09-22 19:25 19435
        push_back(std::move(val));
2660ccea Poul Sander 2023-09-22 19:25 19436
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 19437
    }
2660ccea Poul Sander 2023-09-22 19:25 19438
2660ccea Poul Sander 2023-09-22 19:25 19439
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19440
    @brief add an object to an array
2660ccea Poul Sander 2023-09-22 19:25 19441
    @copydoc push_back(basic_json&&)
2660ccea Poul Sander 2023-09-22 19:25 19442
    */
2660ccea Poul Sander 2023-09-22 19:25 19443
    void push_back(const basic_json& val)
2660ccea Poul Sander 2023-09-22 19:25 19444
    {
2660ccea Poul Sander 2023-09-22 19:25 19445
        // push_back only works for null objects or arrays
2660ccea Poul Sander 2023-09-22 19:25 19446
        if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
2660ccea Poul Sander 2023-09-22 19:25 19447
        {
2660ccea Poul Sander 2023-09-22 19:25 19448
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19449
        }
2660ccea Poul Sander 2023-09-22 19:25 19450
2660ccea Poul Sander 2023-09-22 19:25 19451
        // transform null object into an array
2660ccea Poul Sander 2023-09-22 19:25 19452
        if (is_null())
2660ccea Poul Sander 2023-09-22 19:25 19453
        {
2660ccea Poul Sander 2023-09-22 19:25 19454
            m_type = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 19455
            m_value = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 19456
            assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 19457
        }
2660ccea Poul Sander 2023-09-22 19:25 19458
2660ccea Poul Sander 2023-09-22 19:25 19459
        // add element to array
2660ccea Poul Sander 2023-09-22 19:25 19460
        m_value.array->push_back(val);
2660ccea Poul Sander 2023-09-22 19:25 19461
    }
2660ccea Poul Sander 2023-09-22 19:25 19462
2660ccea Poul Sander 2023-09-22 19:25 19463
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19464
    @brief add an object to an array
2660ccea Poul Sander 2023-09-22 19:25 19465
    @copydoc push_back(basic_json&&)
2660ccea Poul Sander 2023-09-22 19:25 19466
    */
2660ccea Poul Sander 2023-09-22 19:25 19467
    reference operator+=(const basic_json& val)
2660ccea Poul Sander 2023-09-22 19:25 19468
    {
2660ccea Poul Sander 2023-09-22 19:25 19469
        push_back(val);
2660ccea Poul Sander 2023-09-22 19:25 19470
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 19471
    }
2660ccea Poul Sander 2023-09-22 19:25 19472
2660ccea Poul Sander 2023-09-22 19:25 19473
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19474
    @brief add an object to an object
2660ccea Poul Sander 2023-09-22 19:25 19475
2660ccea Poul Sander 2023-09-22 19:25 19476
    Inserts the given element @a val to the JSON object. If the function is
2660ccea Poul Sander 2023-09-22 19:25 19477
    called on a JSON null value, an empty object is created before inserting
2660ccea Poul Sander 2023-09-22 19:25 19478
    @a val.
2660ccea Poul Sander 2023-09-22 19:25 19479
2660ccea Poul Sander 2023-09-22 19:25 19480
    @param[in] val the value to add to the JSON object
2660ccea Poul Sander 2023-09-22 19:25 19481
2660ccea Poul Sander 2023-09-22 19:25 19482
    @throw type_error.308 when called on a type other than JSON object or
2660ccea Poul Sander 2023-09-22 19:25 19483
    null; example: `"cannot use push_back() with number"`
2660ccea Poul Sander 2023-09-22 19:25 19484
2660ccea Poul Sander 2023-09-22 19:25 19485
    @complexity Logarithmic in the size of the container, O(log(`size()`)).
2660ccea Poul Sander 2023-09-22 19:25 19486
2660ccea Poul Sander 2023-09-22 19:25 19487
    @liveexample{The example shows how `push_back()` and `+=` can be used to
2660ccea Poul Sander 2023-09-22 19:25 19488
    add elements to a JSON object. Note how the `null` value was silently
2660ccea Poul Sander 2023-09-22 19:25 19489
    converted to a JSON object.,push_back__object_t__value}
2660ccea Poul Sander 2023-09-22 19:25 19490
2660ccea Poul Sander 2023-09-22 19:25 19491
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 19492
    */
2660ccea Poul Sander 2023-09-22 19:25 19493
    void push_back(const typename object_t::value_type& val)
2660ccea Poul Sander 2023-09-22 19:25 19494
    {
2660ccea Poul Sander 2023-09-22 19:25 19495
        // push_back only works for null objects or objects
2660ccea Poul Sander 2023-09-22 19:25 19496
        if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
2660ccea Poul Sander 2023-09-22 19:25 19497
        {
2660ccea Poul Sander 2023-09-22 19:25 19498
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19499
        }
2660ccea Poul Sander 2023-09-22 19:25 19500
2660ccea Poul Sander 2023-09-22 19:25 19501
        // transform null object into an object
2660ccea Poul Sander 2023-09-22 19:25 19502
        if (is_null())
2660ccea Poul Sander 2023-09-22 19:25 19503
        {
2660ccea Poul Sander 2023-09-22 19:25 19504
            m_type = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 19505
            m_value = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 19506
            assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 19507
        }
2660ccea Poul Sander 2023-09-22 19:25 19508
2660ccea Poul Sander 2023-09-22 19:25 19509
        // add element to array
2660ccea Poul Sander 2023-09-22 19:25 19510
        m_value.object->insert(val);
2660ccea Poul Sander 2023-09-22 19:25 19511
    }
2660ccea Poul Sander 2023-09-22 19:25 19512
2660ccea Poul Sander 2023-09-22 19:25 19513
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19514
    @brief add an object to an object
2660ccea Poul Sander 2023-09-22 19:25 19515
    @copydoc push_back(const typename object_t::value_type&)
2660ccea Poul Sander 2023-09-22 19:25 19516
    */
2660ccea Poul Sander 2023-09-22 19:25 19517
    reference operator+=(const typename object_t::value_type& val)
2660ccea Poul Sander 2023-09-22 19:25 19518
    {
2660ccea Poul Sander 2023-09-22 19:25 19519
        push_back(val);
2660ccea Poul Sander 2023-09-22 19:25 19520
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 19521
    }
2660ccea Poul Sander 2023-09-22 19:25 19522
2660ccea Poul Sander 2023-09-22 19:25 19523
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19524
    @brief add an object to an object
2660ccea Poul Sander 2023-09-22 19:25 19525
2660ccea Poul Sander 2023-09-22 19:25 19526
    This function allows to use `push_back` with an initializer list. In case
2660ccea Poul Sander 2023-09-22 19:25 19527
2660ccea Poul Sander 2023-09-22 19:25 19528
    1. the current value is an object,
2660ccea Poul Sander 2023-09-22 19:25 19529
    2. the initializer list @a init contains only two elements, and
2660ccea Poul Sander 2023-09-22 19:25 19530
    3. the first element of @a init is a string,
2660ccea Poul Sander 2023-09-22 19:25 19531
2660ccea Poul Sander 2023-09-22 19:25 19532
    @a init is converted into an object element and added using
2660ccea Poul Sander 2023-09-22 19:25 19533
    @ref push_back(const typename object_t::value_type&). Otherwise, @a init
2660ccea Poul Sander 2023-09-22 19:25 19534
    is converted to a JSON value and added using @ref push_back(basic_json&&).
2660ccea Poul Sander 2023-09-22 19:25 19535
2660ccea Poul Sander 2023-09-22 19:25 19536
    @param[in] init  an initializer list
2660ccea Poul Sander 2023-09-22 19:25 19537
2660ccea Poul Sander 2023-09-22 19:25 19538
    @complexity Linear in the size of the initializer list @a init.
2660ccea Poul Sander 2023-09-22 19:25 19539
2660ccea Poul Sander 2023-09-22 19:25 19540
    @note This function is required to resolve an ambiguous overload error,
2660ccea Poul Sander 2023-09-22 19:25 19541
          because pairs like `{"key", "value"}` can be both interpreted as
2660ccea Poul Sander 2023-09-22 19:25 19542
          `object_t::value_type` or `std::initializer_list<basic_json>`, see
2660ccea Poul Sander 2023-09-22 19:25 19543
          https://github.com/nlohmann/json/issues/235 for more information.
2660ccea Poul Sander 2023-09-22 19:25 19544
2660ccea Poul Sander 2023-09-22 19:25 19545
    @liveexample{The example shows how initializer lists are treated as
2660ccea Poul Sander 2023-09-22 19:25 19546
    objects when possible.,push_back__initializer_list}
2660ccea Poul Sander 2023-09-22 19:25 19547
    */
2660ccea Poul Sander 2023-09-22 19:25 19548
    void push_back(initializer_list_t init)
2660ccea Poul Sander 2023-09-22 19:25 19549
    {
2660ccea Poul Sander 2023-09-22 19:25 19550
        if (is_object() and init.size() == 2 and (*init.begin())->is_string())
2660ccea Poul Sander 2023-09-22 19:25 19551
        {
2660ccea Poul Sander 2023-09-22 19:25 19552
            basic_json&& key = init.begin()->moved_or_copied();
2660ccea Poul Sander 2023-09-22 19:25 19553
            push_back(typename object_t::value_type(
2660ccea Poul Sander 2023-09-22 19:25 19554
                          std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
2660ccea Poul Sander 2023-09-22 19:25 19555
        }
2660ccea Poul Sander 2023-09-22 19:25 19556
        else
2660ccea Poul Sander 2023-09-22 19:25 19557
        {
2660ccea Poul Sander 2023-09-22 19:25 19558
            push_back(basic_json(init));
2660ccea Poul Sander 2023-09-22 19:25 19559
        }
2660ccea Poul Sander 2023-09-22 19:25 19560
    }
2660ccea Poul Sander 2023-09-22 19:25 19561
2660ccea Poul Sander 2023-09-22 19:25 19562
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19563
    @brief add an object to an object
2660ccea Poul Sander 2023-09-22 19:25 19564
    @copydoc push_back(initializer_list_t)
2660ccea Poul Sander 2023-09-22 19:25 19565
    */
2660ccea Poul Sander 2023-09-22 19:25 19566
    reference operator+=(initializer_list_t init)
2660ccea Poul Sander 2023-09-22 19:25 19567
    {
2660ccea Poul Sander 2023-09-22 19:25 19568
        push_back(init);
2660ccea Poul Sander 2023-09-22 19:25 19569
        return *this;
2660ccea Poul Sander 2023-09-22 19:25 19570
    }
2660ccea Poul Sander 2023-09-22 19:25 19571
2660ccea Poul Sander 2023-09-22 19:25 19572
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19573
    @brief add an object to an array
2660ccea Poul Sander 2023-09-22 19:25 19574
2660ccea Poul Sander 2023-09-22 19:25 19575
    Creates a JSON value from the passed parameters @a args to the end of the
2660ccea Poul Sander 2023-09-22 19:25 19576
    JSON value. If the function is called on a JSON null value, an empty array
2660ccea Poul Sander 2023-09-22 19:25 19577
    is created before appending the value created from @a args.
2660ccea Poul Sander 2023-09-22 19:25 19578
2660ccea Poul Sander 2023-09-22 19:25 19579
    @param[in] args arguments to forward to a constructor of @ref basic_json
2660ccea Poul Sander 2023-09-22 19:25 19580
    @tparam Args compatible types to create a @ref basic_json object
2660ccea Poul Sander 2023-09-22 19:25 19581
2660ccea Poul Sander 2023-09-22 19:25 19582
    @return reference to the inserted element
2660ccea Poul Sander 2023-09-22 19:25 19583
2660ccea Poul Sander 2023-09-22 19:25 19584
    @throw type_error.311 when called on a type other than JSON array or
2660ccea Poul Sander 2023-09-22 19:25 19585
    null; example: `"cannot use emplace_back() with number"`
2660ccea Poul Sander 2023-09-22 19:25 19586
2660ccea Poul Sander 2023-09-22 19:25 19587
    @complexity Amortized constant.
2660ccea Poul Sander 2023-09-22 19:25 19588
2660ccea Poul Sander 2023-09-22 19:25 19589
    @liveexample{The example shows how `push_back()` can be used to add
2660ccea Poul Sander 2023-09-22 19:25 19590
    elements to a JSON array. Note how the `null` value was silently converted
2660ccea Poul Sander 2023-09-22 19:25 19591
    to a JSON array.,emplace_back}
2660ccea Poul Sander 2023-09-22 19:25 19592
2660ccea Poul Sander 2023-09-22 19:25 19593
    @since version 2.0.8, returns reference since 3.7.0
2660ccea Poul Sander 2023-09-22 19:25 19594
    */
2660ccea Poul Sander 2023-09-22 19:25 19595
    template<class... Args>
2660ccea Poul Sander 2023-09-22 19:25 19596
    reference emplace_back(Args&& ... args)
2660ccea Poul Sander 2023-09-22 19:25 19597
    {
2660ccea Poul Sander 2023-09-22 19:25 19598
        // emplace_back only works for null objects or arrays
2660ccea Poul Sander 2023-09-22 19:25 19599
        if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
2660ccea Poul Sander 2023-09-22 19:25 19600
        {
2660ccea Poul Sander 2023-09-22 19:25 19601
            JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19602
        }
2660ccea Poul Sander 2023-09-22 19:25 19603
2660ccea Poul Sander 2023-09-22 19:25 19604
        // transform null object into an array
2660ccea Poul Sander 2023-09-22 19:25 19605
        if (is_null())
2660ccea Poul Sander 2023-09-22 19:25 19606
        {
2660ccea Poul Sander 2023-09-22 19:25 19607
            m_type = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 19608
            m_value = value_t::array;
2660ccea Poul Sander 2023-09-22 19:25 19609
            assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 19610
        }
2660ccea Poul Sander 2023-09-22 19:25 19611
2660ccea Poul Sander 2023-09-22 19:25 19612
        // add element to array (perfect forwarding)
2660ccea Poul Sander 2023-09-22 19:25 19613
#ifdef JSON_HAS_CPP_17
2660ccea Poul Sander 2023-09-22 19:25 19614
        return m_value.array->emplace_back(std::forward<Args>(args)...);
2660ccea Poul Sander 2023-09-22 19:25 19615
#else
2660ccea Poul Sander 2023-09-22 19:25 19616
        m_value.array->emplace_back(std::forward<Args>(args)...);
2660ccea Poul Sander 2023-09-22 19:25 19617
        return m_value.array->back();
2660ccea Poul Sander 2023-09-22 19:25 19618
#endif
2660ccea Poul Sander 2023-09-22 19:25 19619
    }
2660ccea Poul Sander 2023-09-22 19:25 19620
2660ccea Poul Sander 2023-09-22 19:25 19621
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19622
    @brief add an object to an object if key does not exist
2660ccea Poul Sander 2023-09-22 19:25 19623
2660ccea Poul Sander 2023-09-22 19:25 19624
    Inserts a new element into a JSON object constructed in-place with the
2660ccea Poul Sander 2023-09-22 19:25 19625
    given @a args if there is no element with the key in the container. If the
2660ccea Poul Sander 2023-09-22 19:25 19626
    function is called on a JSON null value, an empty object is created before
2660ccea Poul Sander 2023-09-22 19:25 19627
    appending the value created from @a args.
2660ccea Poul Sander 2023-09-22 19:25 19628
2660ccea Poul Sander 2023-09-22 19:25 19629
    @param[in] args arguments to forward to a constructor of @ref basic_json
2660ccea Poul Sander 2023-09-22 19:25 19630
    @tparam Args compatible types to create a @ref basic_json object
2660ccea Poul Sander 2023-09-22 19:25 19631
2660ccea Poul Sander 2023-09-22 19:25 19632
    @return a pair consisting of an iterator to the inserted element, or the
2660ccea Poul Sander 2023-09-22 19:25 19633
            already-existing element if no insertion happened, and a bool
2660ccea Poul Sander 2023-09-22 19:25 19634
            denoting whether the insertion took place.
2660ccea Poul Sander 2023-09-22 19:25 19635
2660ccea Poul Sander 2023-09-22 19:25 19636
    @throw type_error.311 when called on a type other than JSON object or
2660ccea Poul Sander 2023-09-22 19:25 19637
    null; example: `"cannot use emplace() with number"`
2660ccea Poul Sander 2023-09-22 19:25 19638
2660ccea Poul Sander 2023-09-22 19:25 19639
    @complexity Logarithmic in the size of the container, O(log(`size()`)).
2660ccea Poul Sander 2023-09-22 19:25 19640
2660ccea Poul Sander 2023-09-22 19:25 19641
    @liveexample{The example shows how `emplace()` can be used to add elements
2660ccea Poul Sander 2023-09-22 19:25 19642
    to a JSON object. Note how the `null` value was silently converted to a
2660ccea Poul Sander 2023-09-22 19:25 19643
    JSON object. Further note how no value is added if there was already one
2660ccea Poul Sander 2023-09-22 19:25 19644
    value stored with the same key.,emplace}
2660ccea Poul Sander 2023-09-22 19:25 19645
2660ccea Poul Sander 2023-09-22 19:25 19646
    @since version 2.0.8
2660ccea Poul Sander 2023-09-22 19:25 19647
    */
2660ccea Poul Sander 2023-09-22 19:25 19648
    template<class... Args>
2660ccea Poul Sander 2023-09-22 19:25 19649
    std::pair<iterator, bool> emplace(Args&& ... args)
2660ccea Poul Sander 2023-09-22 19:25 19650
    {
2660ccea Poul Sander 2023-09-22 19:25 19651
        // emplace only works for null objects or arrays
2660ccea Poul Sander 2023-09-22 19:25 19652
        if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
2660ccea Poul Sander 2023-09-22 19:25 19653
        {
2660ccea Poul Sander 2023-09-22 19:25 19654
            JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19655
        }
2660ccea Poul Sander 2023-09-22 19:25 19656
2660ccea Poul Sander 2023-09-22 19:25 19657
        // transform null object into an object
2660ccea Poul Sander 2023-09-22 19:25 19658
        if (is_null())
2660ccea Poul Sander 2023-09-22 19:25 19659
        {
2660ccea Poul Sander 2023-09-22 19:25 19660
            m_type = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 19661
            m_value = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 19662
            assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 19663
        }
2660ccea Poul Sander 2023-09-22 19:25 19664
2660ccea Poul Sander 2023-09-22 19:25 19665
        // add element to array (perfect forwarding)
2660ccea Poul Sander 2023-09-22 19:25 19666
        auto res = m_value.object->emplace(std::forward<Args>(args)...);
2660ccea Poul Sander 2023-09-22 19:25 19667
        // create result iterator and set iterator to the result of emplace
2660ccea Poul Sander 2023-09-22 19:25 19668
        auto it = begin();
2660ccea Poul Sander 2023-09-22 19:25 19669
        it.m_it.object_iterator = res.first;
2660ccea Poul Sander 2023-09-22 19:25 19670
2660ccea Poul Sander 2023-09-22 19:25 19671
        // return pair of iterator and boolean
2660ccea Poul Sander 2023-09-22 19:25 19672
        return {it, res.second};
2660ccea Poul Sander 2023-09-22 19:25 19673
    }
2660ccea Poul Sander 2023-09-22 19:25 19674
2660ccea Poul Sander 2023-09-22 19:25 19675
    /// Helper for insertion of an iterator
2660ccea Poul Sander 2023-09-22 19:25 19676
    /// @note: This uses std::distance to support GCC 4.8,
2660ccea Poul Sander 2023-09-22 19:25 19677
    ///        see https://github.com/nlohmann/json/pull/1257
2660ccea Poul Sander 2023-09-22 19:25 19678
    template<typename... Args>
2660ccea Poul Sander 2023-09-22 19:25 19679
    iterator insert_iterator(const_iterator pos, Args&& ... args)
2660ccea Poul Sander 2023-09-22 19:25 19680
    {
2660ccea Poul Sander 2023-09-22 19:25 19681
        iterator result(this);
2660ccea Poul Sander 2023-09-22 19:25 19682
        assert(m_value.array != nullptr);
2660ccea Poul Sander 2023-09-22 19:25 19683
2660ccea Poul Sander 2023-09-22 19:25 19684
        auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
2660ccea Poul Sander 2023-09-22 19:25 19685
        m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
2660ccea Poul Sander 2023-09-22 19:25 19686
        result.m_it.array_iterator = m_value.array->begin() + insert_pos;
2660ccea Poul Sander 2023-09-22 19:25 19687
2660ccea Poul Sander 2023-09-22 19:25 19688
        // This could have been written as:
2660ccea Poul Sander 2023-09-22 19:25 19689
        // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
2660ccea Poul Sander 2023-09-22 19:25 19690
        // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
2660ccea Poul Sander 2023-09-22 19:25 19691
2660ccea Poul Sander 2023-09-22 19:25 19692
        return result;
2660ccea Poul Sander 2023-09-22 19:25 19693
    }
2660ccea Poul Sander 2023-09-22 19:25 19694
2660ccea Poul Sander 2023-09-22 19:25 19695
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19696
    @brief inserts element
2660ccea Poul Sander 2023-09-22 19:25 19697
2660ccea Poul Sander 2023-09-22 19:25 19698
    Inserts element @a val before iterator @a pos.
2660ccea Poul Sander 2023-09-22 19:25 19699
2660ccea Poul Sander 2023-09-22 19:25 19700
    @param[in] pos iterator before which the content will be inserted; may be
2660ccea Poul Sander 2023-09-22 19:25 19701
    the end() iterator
2660ccea Poul Sander 2023-09-22 19:25 19702
    @param[in] val element to insert
2660ccea Poul Sander 2023-09-22 19:25 19703
    @return iterator pointing to the inserted @a val.
2660ccea Poul Sander 2023-09-22 19:25 19704
2660ccea Poul Sander 2023-09-22 19:25 19705
    @throw type_error.309 if called on JSON values other than arrays;
2660ccea Poul Sander 2023-09-22 19:25 19706
    example: `"cannot use insert() with string"`
2660ccea Poul Sander 2023-09-22 19:25 19707
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
2660ccea Poul Sander 2023-09-22 19:25 19708
    example: `"iterator does not fit current value"`
2660ccea Poul Sander 2023-09-22 19:25 19709
2660ccea Poul Sander 2023-09-22 19:25 19710
    @complexity Constant plus linear in the distance between @a pos and end of
2660ccea Poul Sander 2023-09-22 19:25 19711
    the container.
2660ccea Poul Sander 2023-09-22 19:25 19712
2660ccea Poul Sander 2023-09-22 19:25 19713
    @liveexample{The example shows how `insert()` is used.,insert}
2660ccea Poul Sander 2023-09-22 19:25 19714
2660ccea Poul Sander 2023-09-22 19:25 19715
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 19716
    */
2660ccea Poul Sander 2023-09-22 19:25 19717
    iterator insert(const_iterator pos, const basic_json& val)
2660ccea Poul Sander 2023-09-22 19:25 19718
    {
2660ccea Poul Sander 2023-09-22 19:25 19719
        // insert only works for arrays
2660ccea Poul Sander 2023-09-22 19:25 19720
        if (JSON_HEDLEY_LIKELY(is_array()))
2660ccea Poul Sander 2023-09-22 19:25 19721
        {
2660ccea Poul Sander 2023-09-22 19:25 19722
            // check if iterator pos fits to this JSON value
2660ccea Poul Sander 2023-09-22 19:25 19723
            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
2660ccea Poul Sander 2023-09-22 19:25 19724
            {
2660ccea Poul Sander 2023-09-22 19:25 19725
                JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
2660ccea Poul Sander 2023-09-22 19:25 19726
            }
2660ccea Poul Sander 2023-09-22 19:25 19727
2660ccea Poul Sander 2023-09-22 19:25 19728
            // insert to array and return iterator
2660ccea Poul Sander 2023-09-22 19:25 19729
            return insert_iterator(pos, val);
2660ccea Poul Sander 2023-09-22 19:25 19730
        }
2660ccea Poul Sander 2023-09-22 19:25 19731
2660ccea Poul Sander 2023-09-22 19:25 19732
        JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19733
    }
2660ccea Poul Sander 2023-09-22 19:25 19734
2660ccea Poul Sander 2023-09-22 19:25 19735
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19736
    @brief inserts element
2660ccea Poul Sander 2023-09-22 19:25 19737
    @copydoc insert(const_iterator, const basic_json&)
2660ccea Poul Sander 2023-09-22 19:25 19738
    */
2660ccea Poul Sander 2023-09-22 19:25 19739
    iterator insert(const_iterator pos, basic_json&& val)
2660ccea Poul Sander 2023-09-22 19:25 19740
    {
2660ccea Poul Sander 2023-09-22 19:25 19741
        return insert(pos, val);
2660ccea Poul Sander 2023-09-22 19:25 19742
    }
2660ccea Poul Sander 2023-09-22 19:25 19743
2660ccea Poul Sander 2023-09-22 19:25 19744
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19745
    @brief inserts elements
2660ccea Poul Sander 2023-09-22 19:25 19746
2660ccea Poul Sander 2023-09-22 19:25 19747
    Inserts @a cnt copies of @a val before iterator @a pos.
2660ccea Poul Sander 2023-09-22 19:25 19748
2660ccea Poul Sander 2023-09-22 19:25 19749
    @param[in] pos iterator before which the content will be inserted; may be
2660ccea Poul Sander 2023-09-22 19:25 19750
    the end() iterator
2660ccea Poul Sander 2023-09-22 19:25 19751
    @param[in] cnt number of copies of @a val to insert
2660ccea Poul Sander 2023-09-22 19:25 19752
    @param[in] val element to insert
2660ccea Poul Sander 2023-09-22 19:25 19753
    @return iterator pointing to the first element inserted, or @a pos if
2660ccea Poul Sander 2023-09-22 19:25 19754
    `cnt==0`
2660ccea Poul Sander 2023-09-22 19:25 19755
2660ccea Poul Sander 2023-09-22 19:25 19756
    @throw type_error.309 if called on JSON values other than arrays; example:
2660ccea Poul Sander 2023-09-22 19:25 19757
    `"cannot use insert() with string"`
2660ccea Poul Sander 2023-09-22 19:25 19758
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
2660ccea Poul Sander 2023-09-22 19:25 19759
    example: `"iterator does not fit current value"`
2660ccea Poul Sander 2023-09-22 19:25 19760
2660ccea Poul Sander 2023-09-22 19:25 19761
    @complexity Linear in @a cnt plus linear in the distance between @a pos
2660ccea Poul Sander 2023-09-22 19:25 19762
    and end of the container.
2660ccea Poul Sander 2023-09-22 19:25 19763
2660ccea Poul Sander 2023-09-22 19:25 19764
    @liveexample{The example shows how `insert()` is used.,insert__count}
2660ccea Poul Sander 2023-09-22 19:25 19765
2660ccea Poul Sander 2023-09-22 19:25 19766
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 19767
    */
2660ccea Poul Sander 2023-09-22 19:25 19768
    iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
2660ccea Poul Sander 2023-09-22 19:25 19769
    {
2660ccea Poul Sander 2023-09-22 19:25 19770
        // insert only works for arrays
2660ccea Poul Sander 2023-09-22 19:25 19771
        if (JSON_HEDLEY_LIKELY(is_array()))
2660ccea Poul Sander 2023-09-22 19:25 19772
        {
2660ccea Poul Sander 2023-09-22 19:25 19773
            // check if iterator pos fits to this JSON value
2660ccea Poul Sander 2023-09-22 19:25 19774
            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
2660ccea Poul Sander 2023-09-22 19:25 19775
            {
2660ccea Poul Sander 2023-09-22 19:25 19776
                JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
2660ccea Poul Sander 2023-09-22 19:25 19777
            }
2660ccea Poul Sander 2023-09-22 19:25 19778
2660ccea Poul Sander 2023-09-22 19:25 19779
            // insert to array and return iterator
2660ccea Poul Sander 2023-09-22 19:25 19780
            return insert_iterator(pos, cnt, val);
2660ccea Poul Sander 2023-09-22 19:25 19781
        }
2660ccea Poul Sander 2023-09-22 19:25 19782
2660ccea Poul Sander 2023-09-22 19:25 19783
        JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19784
    }
2660ccea Poul Sander 2023-09-22 19:25 19785
2660ccea Poul Sander 2023-09-22 19:25 19786
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19787
    @brief inserts elements
2660ccea Poul Sander 2023-09-22 19:25 19788
2660ccea Poul Sander 2023-09-22 19:25 19789
    Inserts elements from range `[first, last)` before iterator @a pos.
2660ccea Poul Sander 2023-09-22 19:25 19790
2660ccea Poul Sander 2023-09-22 19:25 19791
    @param[in] pos iterator before which the content will be inserted; may be
2660ccea Poul Sander 2023-09-22 19:25 19792
    the end() iterator
2660ccea Poul Sander 2023-09-22 19:25 19793
    @param[in] first begin of the range of elements to insert
2660ccea Poul Sander 2023-09-22 19:25 19794
    @param[in] last end of the range of elements to insert
2660ccea Poul Sander 2023-09-22 19:25 19795
2660ccea Poul Sander 2023-09-22 19:25 19796
    @throw type_error.309 if called on JSON values other than arrays; example:
2660ccea Poul Sander 2023-09-22 19:25 19797
    `"cannot use insert() with string"`
2660ccea Poul Sander 2023-09-22 19:25 19798
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
2660ccea Poul Sander 2023-09-22 19:25 19799
    example: `"iterator does not fit current value"`
2660ccea Poul Sander 2023-09-22 19:25 19800
    @throw invalid_iterator.210 if @a first and @a last do not belong to the
2660ccea Poul Sander 2023-09-22 19:25 19801
    same JSON value; example: `"iterators do not fit"`
2660ccea Poul Sander 2023-09-22 19:25 19802
    @throw invalid_iterator.211 if @a first or @a last are iterators into
2660ccea Poul Sander 2023-09-22 19:25 19803
    container for which insert is called; example: `"passed iterators may not
2660ccea Poul Sander 2023-09-22 19:25 19804
    belong to container"`
2660ccea Poul Sander 2023-09-22 19:25 19805
2660ccea Poul Sander 2023-09-22 19:25 19806
    @return iterator pointing to the first element inserted, or @a pos if
2660ccea Poul Sander 2023-09-22 19:25 19807
    `first==last`
2660ccea Poul Sander 2023-09-22 19:25 19808
2660ccea Poul Sander 2023-09-22 19:25 19809
    @complexity Linear in `std::distance(first, last)` plus linear in the
2660ccea Poul Sander 2023-09-22 19:25 19810
    distance between @a pos and end of the container.
2660ccea Poul Sander 2023-09-22 19:25 19811
2660ccea Poul Sander 2023-09-22 19:25 19812
    @liveexample{The example shows how `insert()` is used.,insert__range}
2660ccea Poul Sander 2023-09-22 19:25 19813
2660ccea Poul Sander 2023-09-22 19:25 19814
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 19815
    */
2660ccea Poul Sander 2023-09-22 19:25 19816
    iterator insert(const_iterator pos, const_iterator first, const_iterator last)
2660ccea Poul Sander 2023-09-22 19:25 19817
    {
2660ccea Poul Sander 2023-09-22 19:25 19818
        // insert only works for arrays
2660ccea Poul Sander 2023-09-22 19:25 19819
        if (JSON_HEDLEY_UNLIKELY(not is_array()))
2660ccea Poul Sander 2023-09-22 19:25 19820
        {
2660ccea Poul Sander 2023-09-22 19:25 19821
            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19822
        }
2660ccea Poul Sander 2023-09-22 19:25 19823
2660ccea Poul Sander 2023-09-22 19:25 19824
        // check if iterator pos fits to this JSON value
2660ccea Poul Sander 2023-09-22 19:25 19825
        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
2660ccea Poul Sander 2023-09-22 19:25 19826
        {
2660ccea Poul Sander 2023-09-22 19:25 19827
            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
2660ccea Poul Sander 2023-09-22 19:25 19828
        }
2660ccea Poul Sander 2023-09-22 19:25 19829
2660ccea Poul Sander 2023-09-22 19:25 19830
        // check if range iterators belong to the same JSON object
2660ccea Poul Sander 2023-09-22 19:25 19831
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
2660ccea Poul Sander 2023-09-22 19:25 19832
        {
2660ccea Poul Sander 2023-09-22 19:25 19833
            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
2660ccea Poul Sander 2023-09-22 19:25 19834
        }
2660ccea Poul Sander 2023-09-22 19:25 19835
2660ccea Poul Sander 2023-09-22 19:25 19836
        if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
2660ccea Poul Sander 2023-09-22 19:25 19837
        {
2660ccea Poul Sander 2023-09-22 19:25 19838
            JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
2660ccea Poul Sander 2023-09-22 19:25 19839
        }
2660ccea Poul Sander 2023-09-22 19:25 19840
2660ccea Poul Sander 2023-09-22 19:25 19841
        // insert to array and return iterator
2660ccea Poul Sander 2023-09-22 19:25 19842
        return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
2660ccea Poul Sander 2023-09-22 19:25 19843
    }
2660ccea Poul Sander 2023-09-22 19:25 19844
2660ccea Poul Sander 2023-09-22 19:25 19845
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19846
    @brief inserts elements
2660ccea Poul Sander 2023-09-22 19:25 19847
2660ccea Poul Sander 2023-09-22 19:25 19848
    Inserts elements from initializer list @a ilist before iterator @a pos.
2660ccea Poul Sander 2023-09-22 19:25 19849
2660ccea Poul Sander 2023-09-22 19:25 19850
    @param[in] pos iterator before which the content will be inserted; may be
2660ccea Poul Sander 2023-09-22 19:25 19851
    the end() iterator
2660ccea Poul Sander 2023-09-22 19:25 19852
    @param[in] ilist initializer list to insert the values from
2660ccea Poul Sander 2023-09-22 19:25 19853
2660ccea Poul Sander 2023-09-22 19:25 19854
    @throw type_error.309 if called on JSON values other than arrays; example:
2660ccea Poul Sander 2023-09-22 19:25 19855
    `"cannot use insert() with string"`
2660ccea Poul Sander 2023-09-22 19:25 19856
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
2660ccea Poul Sander 2023-09-22 19:25 19857
    example: `"iterator does not fit current value"`
2660ccea Poul Sander 2023-09-22 19:25 19858
2660ccea Poul Sander 2023-09-22 19:25 19859
    @return iterator pointing to the first element inserted, or @a pos if
2660ccea Poul Sander 2023-09-22 19:25 19860
    `ilist` is empty
2660ccea Poul Sander 2023-09-22 19:25 19861
2660ccea Poul Sander 2023-09-22 19:25 19862
    @complexity Linear in `ilist.size()` plus linear in the distance between
2660ccea Poul Sander 2023-09-22 19:25 19863
    @a pos and end of the container.
2660ccea Poul Sander 2023-09-22 19:25 19864
2660ccea Poul Sander 2023-09-22 19:25 19865
    @liveexample{The example shows how `insert()` is used.,insert__ilist}
2660ccea Poul Sander 2023-09-22 19:25 19866
2660ccea Poul Sander 2023-09-22 19:25 19867
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 19868
    */
2660ccea Poul Sander 2023-09-22 19:25 19869
    iterator insert(const_iterator pos, initializer_list_t ilist)
2660ccea Poul Sander 2023-09-22 19:25 19870
    {
2660ccea Poul Sander 2023-09-22 19:25 19871
        // insert only works for arrays
2660ccea Poul Sander 2023-09-22 19:25 19872
        if (JSON_HEDLEY_UNLIKELY(not is_array()))
2660ccea Poul Sander 2023-09-22 19:25 19873
        {
2660ccea Poul Sander 2023-09-22 19:25 19874
            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19875
        }
2660ccea Poul Sander 2023-09-22 19:25 19876
2660ccea Poul Sander 2023-09-22 19:25 19877
        // check if iterator pos fits to this JSON value
2660ccea Poul Sander 2023-09-22 19:25 19878
        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
2660ccea Poul Sander 2023-09-22 19:25 19879
        {
2660ccea Poul Sander 2023-09-22 19:25 19880
            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
2660ccea Poul Sander 2023-09-22 19:25 19881
        }
2660ccea Poul Sander 2023-09-22 19:25 19882
2660ccea Poul Sander 2023-09-22 19:25 19883
        // insert to array and return iterator
2660ccea Poul Sander 2023-09-22 19:25 19884
        return insert_iterator(pos, ilist.begin(), ilist.end());
2660ccea Poul Sander 2023-09-22 19:25 19885
    }
2660ccea Poul Sander 2023-09-22 19:25 19886
2660ccea Poul Sander 2023-09-22 19:25 19887
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19888
    @brief inserts elements
2660ccea Poul Sander 2023-09-22 19:25 19889
2660ccea Poul Sander 2023-09-22 19:25 19890
    Inserts elements from range `[first, last)`.
2660ccea Poul Sander 2023-09-22 19:25 19891
2660ccea Poul Sander 2023-09-22 19:25 19892
    @param[in] first begin of the range of elements to insert
2660ccea Poul Sander 2023-09-22 19:25 19893
    @param[in] last end of the range of elements to insert
2660ccea Poul Sander 2023-09-22 19:25 19894
2660ccea Poul Sander 2023-09-22 19:25 19895
    @throw type_error.309 if called on JSON values other than objects; example:
2660ccea Poul Sander 2023-09-22 19:25 19896
    `"cannot use insert() with string"`
2660ccea Poul Sander 2023-09-22 19:25 19897
    @throw invalid_iterator.202 if iterator @a first or @a last does does not
2660ccea Poul Sander 2023-09-22 19:25 19898
    point to an object; example: `"iterators first and last must point to
2660ccea Poul Sander 2023-09-22 19:25 19899
    objects"`
2660ccea Poul Sander 2023-09-22 19:25 19900
    @throw invalid_iterator.210 if @a first and @a last do not belong to the
2660ccea Poul Sander 2023-09-22 19:25 19901
    same JSON value; example: `"iterators do not fit"`
2660ccea Poul Sander 2023-09-22 19:25 19902
2660ccea Poul Sander 2023-09-22 19:25 19903
    @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
2660ccea Poul Sander 2023-09-22 19:25 19904
    of elements to insert.
2660ccea Poul Sander 2023-09-22 19:25 19905
2660ccea Poul Sander 2023-09-22 19:25 19906
    @liveexample{The example shows how `insert()` is used.,insert__range_object}
2660ccea Poul Sander 2023-09-22 19:25 19907
2660ccea Poul Sander 2023-09-22 19:25 19908
    @since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 19909
    */
2660ccea Poul Sander 2023-09-22 19:25 19910
    void insert(const_iterator first, const_iterator last)
2660ccea Poul Sander 2023-09-22 19:25 19911
    {
2660ccea Poul Sander 2023-09-22 19:25 19912
        // insert only works for objects
2660ccea Poul Sander 2023-09-22 19:25 19913
        if (JSON_HEDLEY_UNLIKELY(not is_object()))
2660ccea Poul Sander 2023-09-22 19:25 19914
        {
2660ccea Poul Sander 2023-09-22 19:25 19915
            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19916
        }
2660ccea Poul Sander 2023-09-22 19:25 19917
2660ccea Poul Sander 2023-09-22 19:25 19918
        // check if range iterators belong to the same JSON object
2660ccea Poul Sander 2023-09-22 19:25 19919
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
2660ccea Poul Sander 2023-09-22 19:25 19920
        {
2660ccea Poul Sander 2023-09-22 19:25 19921
            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
2660ccea Poul Sander 2023-09-22 19:25 19922
        }
2660ccea Poul Sander 2023-09-22 19:25 19923
2660ccea Poul Sander 2023-09-22 19:25 19924
        // passed iterators must belong to objects
2660ccea Poul Sander 2023-09-22 19:25 19925
        if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()))
2660ccea Poul Sander 2023-09-22 19:25 19926
        {
2660ccea Poul Sander 2023-09-22 19:25 19927
            JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
2660ccea Poul Sander 2023-09-22 19:25 19928
        }
2660ccea Poul Sander 2023-09-22 19:25 19929
2660ccea Poul Sander 2023-09-22 19:25 19930
        m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
2660ccea Poul Sander 2023-09-22 19:25 19931
    }
2660ccea Poul Sander 2023-09-22 19:25 19932
2660ccea Poul Sander 2023-09-22 19:25 19933
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19934
    @brief updates a JSON object from another object, overwriting existing keys
2660ccea Poul Sander 2023-09-22 19:25 19935
2660ccea Poul Sander 2023-09-22 19:25 19936
    Inserts all values from JSON object @a j and overwrites existing keys.
2660ccea Poul Sander 2023-09-22 19:25 19937
2660ccea Poul Sander 2023-09-22 19:25 19938
    @param[in] j  JSON object to read values from
2660ccea Poul Sander 2023-09-22 19:25 19939
2660ccea Poul Sander 2023-09-22 19:25 19940
    @throw type_error.312 if called on JSON values other than objects; example:
2660ccea Poul Sander 2023-09-22 19:25 19941
    `"cannot use update() with string"`
2660ccea Poul Sander 2023-09-22 19:25 19942
2660ccea Poul Sander 2023-09-22 19:25 19943
    @complexity O(N*log(size() + N)), where N is the number of elements to
2660ccea Poul Sander 2023-09-22 19:25 19944
                insert.
2660ccea Poul Sander 2023-09-22 19:25 19945
2660ccea Poul Sander 2023-09-22 19:25 19946
    @liveexample{The example shows how `update()` is used.,update}
2660ccea Poul Sander 2023-09-22 19:25 19947
2660ccea Poul Sander 2023-09-22 19:25 19948
    @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
2660ccea Poul Sander 2023-09-22 19:25 19949
2660ccea Poul Sander 2023-09-22 19:25 19950
    @since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 19951
    */
2660ccea Poul Sander 2023-09-22 19:25 19952
    void update(const_reference j)
2660ccea Poul Sander 2023-09-22 19:25 19953
    {
2660ccea Poul Sander 2023-09-22 19:25 19954
        // implicitly convert null value to an empty object
2660ccea Poul Sander 2023-09-22 19:25 19955
        if (is_null())
2660ccea Poul Sander 2023-09-22 19:25 19956
        {
2660ccea Poul Sander 2023-09-22 19:25 19957
            m_type = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 19958
            m_value.object = create<object_t>();
2660ccea Poul Sander 2023-09-22 19:25 19959
            assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 19960
        }
2660ccea Poul Sander 2023-09-22 19:25 19961
2660ccea Poul Sander 2023-09-22 19:25 19962
        if (JSON_HEDLEY_UNLIKELY(not is_object()))
2660ccea Poul Sander 2023-09-22 19:25 19963
        {
2660ccea Poul Sander 2023-09-22 19:25 19964
            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19965
        }
2660ccea Poul Sander 2023-09-22 19:25 19966
        if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
2660ccea Poul Sander 2023-09-22 19:25 19967
        {
2660ccea Poul Sander 2023-09-22 19:25 19968
            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
2660ccea Poul Sander 2023-09-22 19:25 19969
        }
2660ccea Poul Sander 2023-09-22 19:25 19970
2660ccea Poul Sander 2023-09-22 19:25 19971
        for (auto it = j.cbegin(); it != j.cend(); ++it)
2660ccea Poul Sander 2023-09-22 19:25 19972
        {
2660ccea Poul Sander 2023-09-22 19:25 19973
            m_value.object->operator[](it.key()) = it.value();
2660ccea Poul Sander 2023-09-22 19:25 19974
        }
2660ccea Poul Sander 2023-09-22 19:25 19975
    }
2660ccea Poul Sander 2023-09-22 19:25 19976
2660ccea Poul Sander 2023-09-22 19:25 19977
    /*!
2660ccea Poul Sander 2023-09-22 19:25 19978
    @brief updates a JSON object from another object, overwriting existing keys
2660ccea Poul Sander 2023-09-22 19:25 19979
2660ccea Poul Sander 2023-09-22 19:25 19980
    Inserts all values from from range `[first, last)` and overwrites existing
2660ccea Poul Sander 2023-09-22 19:25 19981
    keys.
2660ccea Poul Sander 2023-09-22 19:25 19982
2660ccea Poul Sander 2023-09-22 19:25 19983
    @param[in] first begin of the range of elements to insert
2660ccea Poul Sander 2023-09-22 19:25 19984
    @param[in] last end of the range of elements to insert
2660ccea Poul Sander 2023-09-22 19:25 19985
2660ccea Poul Sander 2023-09-22 19:25 19986
    @throw type_error.312 if called on JSON values other than objects; example:
2660ccea Poul Sander 2023-09-22 19:25 19987
    `"cannot use update() with string"`
2660ccea Poul Sander 2023-09-22 19:25 19988
    @throw invalid_iterator.202 if iterator @a first or @a last does does not
2660ccea Poul Sander 2023-09-22 19:25 19989
    point to an object; example: `"iterators first and last must point to
2660ccea Poul Sander 2023-09-22 19:25 19990
    objects"`
2660ccea Poul Sander 2023-09-22 19:25 19991
    @throw invalid_iterator.210 if @a first and @a last do not belong to the
2660ccea Poul Sander 2023-09-22 19:25 19992
    same JSON value; example: `"iterators do not fit"`
2660ccea Poul Sander 2023-09-22 19:25 19993
2660ccea Poul Sander 2023-09-22 19:25 19994
    @complexity O(N*log(size() + N)), where N is the number of elements to
2660ccea Poul Sander 2023-09-22 19:25 19995
                insert.
2660ccea Poul Sander 2023-09-22 19:25 19996
2660ccea Poul Sander 2023-09-22 19:25 19997
    @liveexample{The example shows how `update()` is used__range.,update}
2660ccea Poul Sander 2023-09-22 19:25 19998
2660ccea Poul Sander 2023-09-22 19:25 19999
    @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
2660ccea Poul Sander 2023-09-22 19:25 20000
2660ccea Poul Sander 2023-09-22 19:25 20001
    @since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 20002
    */
2660ccea Poul Sander 2023-09-22 19:25 20003
    void update(const_iterator first, const_iterator last)
2660ccea Poul Sander 2023-09-22 19:25 20004
    {
2660ccea Poul Sander 2023-09-22 19:25 20005
        // implicitly convert null value to an empty object
2660ccea Poul Sander 2023-09-22 19:25 20006
        if (is_null())
2660ccea Poul Sander 2023-09-22 19:25 20007
        {
2660ccea Poul Sander 2023-09-22 19:25 20008
            m_type = value_t::object;
2660ccea Poul Sander 2023-09-22 19:25 20009
            m_value.object = create<object_t>();
2660ccea Poul Sander 2023-09-22 19:25 20010
            assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 20011
        }
2660ccea Poul Sander 2023-09-22 19:25 20012
2660ccea Poul Sander 2023-09-22 19:25 20013
        if (JSON_HEDLEY_UNLIKELY(not is_object()))
2660ccea Poul Sander 2023-09-22 19:25 20014
        {
2660ccea Poul Sander 2023-09-22 19:25 20015
            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 20016
        }
2660ccea Poul Sander 2023-09-22 19:25 20017
2660ccea Poul Sander 2023-09-22 19:25 20018
        // check if range iterators belong to the same JSON object
2660ccea Poul Sander 2023-09-22 19:25 20019
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
2660ccea Poul Sander 2023-09-22 19:25 20020
        {
2660ccea Poul Sander 2023-09-22 19:25 20021
            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
2660ccea Poul Sander 2023-09-22 19:25 20022
        }
2660ccea Poul Sander 2023-09-22 19:25 20023
2660ccea Poul Sander 2023-09-22 19:25 20024
        // passed iterators must belong to objects
2660ccea Poul Sander 2023-09-22 19:25 20025
        if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()
2660ccea Poul Sander 2023-09-22 19:25 20026
                                 or not last.m_object->is_object()))
2660ccea Poul Sander 2023-09-22 19:25 20027
        {
2660ccea Poul Sander 2023-09-22 19:25 20028
            JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
2660ccea Poul Sander 2023-09-22 19:25 20029
        }
2660ccea Poul Sander 2023-09-22 19:25 20030
2660ccea Poul Sander 2023-09-22 19:25 20031
        for (auto it = first; it != last; ++it)
2660ccea Poul Sander 2023-09-22 19:25 20032
        {
2660ccea Poul Sander 2023-09-22 19:25 20033
            m_value.object->operator[](it.key()) = it.value();
2660ccea Poul Sander 2023-09-22 19:25 20034
        }
2660ccea Poul Sander 2023-09-22 19:25 20035
    }
2660ccea Poul Sander 2023-09-22 19:25 20036
2660ccea Poul Sander 2023-09-22 19:25 20037
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20038
    @brief exchanges the values
2660ccea Poul Sander 2023-09-22 19:25 20039
2660ccea Poul Sander 2023-09-22 19:25 20040
    Exchanges the contents of the JSON value with those of @a other. Does not
2660ccea Poul Sander 2023-09-22 19:25 20041
    invoke any move, copy, or swap operations on individual elements. All
2660ccea Poul Sander 2023-09-22 19:25 20042
    iterators and references remain valid. The past-the-end iterator is
2660ccea Poul Sander 2023-09-22 19:25 20043
    invalidated.
2660ccea Poul Sander 2023-09-22 19:25 20044
2660ccea Poul Sander 2023-09-22 19:25 20045
    @param[in,out] other JSON value to exchange the contents with
2660ccea Poul Sander 2023-09-22 19:25 20046
2660ccea Poul Sander 2023-09-22 19:25 20047
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 20048
2660ccea Poul Sander 2023-09-22 19:25 20049
    @liveexample{The example below shows how JSON values can be swapped with
2660ccea Poul Sander 2023-09-22 19:25 20050
    `swap()`.,swap__reference}
2660ccea Poul Sander 2023-09-22 19:25 20051
2660ccea Poul Sander 2023-09-22 19:25 20052
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 20053
    */
2660ccea Poul Sander 2023-09-22 19:25 20054
    void swap(reference other) noexcept (
2660ccea Poul Sander 2023-09-22 19:25 20055
        std::is_nothrow_move_constructible<value_t>::value and
2660ccea Poul Sander 2023-09-22 19:25 20056
        std::is_nothrow_move_assignable<value_t>::value and
2660ccea Poul Sander 2023-09-22 19:25 20057
        std::is_nothrow_move_constructible<json_value>::value and
2660ccea Poul Sander 2023-09-22 19:25 20058
        std::is_nothrow_move_assignable<json_value>::value
2660ccea Poul Sander 2023-09-22 19:25 20059
    )
2660ccea Poul Sander 2023-09-22 19:25 20060
    {
2660ccea Poul Sander 2023-09-22 19:25 20061
        std::swap(m_type, other.m_type);
2660ccea Poul Sander 2023-09-22 19:25 20062
        std::swap(m_value, other.m_value);
2660ccea Poul Sander 2023-09-22 19:25 20063
        assert_invariant();
2660ccea Poul Sander 2023-09-22 19:25 20064
    }
2660ccea Poul Sander 2023-09-22 19:25 20065
2660ccea Poul Sander 2023-09-22 19:25 20066
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20067
    @brief exchanges the values
2660ccea Poul Sander 2023-09-22 19:25 20068
2660ccea Poul Sander 2023-09-22 19:25 20069
    Exchanges the contents of a JSON array with those of @a other. Does not
2660ccea Poul Sander 2023-09-22 19:25 20070
    invoke any move, copy, or swap operations on individual elements. All
2660ccea Poul Sander 2023-09-22 19:25 20071
    iterators and references remain valid. The past-the-end iterator is
2660ccea Poul Sander 2023-09-22 19:25 20072
    invalidated.
2660ccea Poul Sander 2023-09-22 19:25 20073
2660ccea Poul Sander 2023-09-22 19:25 20074
    @param[in,out] other array to exchange the contents with
2660ccea Poul Sander 2023-09-22 19:25 20075
2660ccea Poul Sander 2023-09-22 19:25 20076
    @throw type_error.310 when JSON value is not an array; example: `"cannot
2660ccea Poul Sander 2023-09-22 19:25 20077
    use swap() with string"`
2660ccea Poul Sander 2023-09-22 19:25 20078
2660ccea Poul Sander 2023-09-22 19:25 20079
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 20080
2660ccea Poul Sander 2023-09-22 19:25 20081
    @liveexample{The example below shows how arrays can be swapped with
2660ccea Poul Sander 2023-09-22 19:25 20082
    `swap()`.,swap__array_t}
2660ccea Poul Sander 2023-09-22 19:25 20083
2660ccea Poul Sander 2023-09-22 19:25 20084
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 20085
    */
2660ccea Poul Sander 2023-09-22 19:25 20086
    void swap(array_t& other)
2660ccea Poul Sander 2023-09-22 19:25 20087
    {
2660ccea Poul Sander 2023-09-22 19:25 20088
        // swap only works for arrays
2660ccea Poul Sander 2023-09-22 19:25 20089
        if (JSON_HEDLEY_LIKELY(is_array()))
2660ccea Poul Sander 2023-09-22 19:25 20090
        {
2660ccea Poul Sander 2023-09-22 19:25 20091
            std::swap(*(m_value.array), other);
2660ccea Poul Sander 2023-09-22 19:25 20092
        }
2660ccea Poul Sander 2023-09-22 19:25 20093
        else
2660ccea Poul Sander 2023-09-22 19:25 20094
        {
2660ccea Poul Sander 2023-09-22 19:25 20095
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 20096
        }
2660ccea Poul Sander 2023-09-22 19:25 20097
    }
2660ccea Poul Sander 2023-09-22 19:25 20098
2660ccea Poul Sander 2023-09-22 19:25 20099
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20100
    @brief exchanges the values
2660ccea Poul Sander 2023-09-22 19:25 20101
2660ccea Poul Sander 2023-09-22 19:25 20102
    Exchanges the contents of a JSON object with those of @a other. Does not
2660ccea Poul Sander 2023-09-22 19:25 20103
    invoke any move, copy, or swap operations on individual elements. All
2660ccea Poul Sander 2023-09-22 19:25 20104
    iterators and references remain valid. The past-the-end iterator is
2660ccea Poul Sander 2023-09-22 19:25 20105
    invalidated.
2660ccea Poul Sander 2023-09-22 19:25 20106
2660ccea Poul Sander 2023-09-22 19:25 20107
    @param[in,out] other object to exchange the contents with
2660ccea Poul Sander 2023-09-22 19:25 20108
2660ccea Poul Sander 2023-09-22 19:25 20109
    @throw type_error.310 when JSON value is not an object; example:
2660ccea Poul Sander 2023-09-22 19:25 20110
    `"cannot use swap() with string"`
2660ccea Poul Sander 2023-09-22 19:25 20111
2660ccea Poul Sander 2023-09-22 19:25 20112
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 20113
2660ccea Poul Sander 2023-09-22 19:25 20114
    @liveexample{The example below shows how objects can be swapped with
2660ccea Poul Sander 2023-09-22 19:25 20115
    `swap()`.,swap__object_t}
2660ccea Poul Sander 2023-09-22 19:25 20116
2660ccea Poul Sander 2023-09-22 19:25 20117
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 20118
    */
2660ccea Poul Sander 2023-09-22 19:25 20119
    void swap(object_t& other)
2660ccea Poul Sander 2023-09-22 19:25 20120
    {
2660ccea Poul Sander 2023-09-22 19:25 20121
        // swap only works for objects
2660ccea Poul Sander 2023-09-22 19:25 20122
        if (JSON_HEDLEY_LIKELY(is_object()))
2660ccea Poul Sander 2023-09-22 19:25 20123
        {
2660ccea Poul Sander 2023-09-22 19:25 20124
            std::swap(*(m_value.object), other);
2660ccea Poul Sander 2023-09-22 19:25 20125
        }
2660ccea Poul Sander 2023-09-22 19:25 20126
        else
2660ccea Poul Sander 2023-09-22 19:25 20127
        {
2660ccea Poul Sander 2023-09-22 19:25 20128
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 20129
        }
2660ccea Poul Sander 2023-09-22 19:25 20130
    }
2660ccea Poul Sander 2023-09-22 19:25 20131
2660ccea Poul Sander 2023-09-22 19:25 20132
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20133
    @brief exchanges the values
2660ccea Poul Sander 2023-09-22 19:25 20134
2660ccea Poul Sander 2023-09-22 19:25 20135
    Exchanges the contents of a JSON string with those of @a other. Does not
2660ccea Poul Sander 2023-09-22 19:25 20136
    invoke any move, copy, or swap operations on individual elements. All
2660ccea Poul Sander 2023-09-22 19:25 20137
    iterators and references remain valid. The past-the-end iterator is
2660ccea Poul Sander 2023-09-22 19:25 20138
    invalidated.
2660ccea Poul Sander 2023-09-22 19:25 20139
2660ccea Poul Sander 2023-09-22 19:25 20140
    @param[in,out] other string to exchange the contents with
2660ccea Poul Sander 2023-09-22 19:25 20141
2660ccea Poul Sander 2023-09-22 19:25 20142
    @throw type_error.310 when JSON value is not a string; example: `"cannot
2660ccea Poul Sander 2023-09-22 19:25 20143
    use swap() with boolean"`
2660ccea Poul Sander 2023-09-22 19:25 20144
2660ccea Poul Sander 2023-09-22 19:25 20145
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 20146
2660ccea Poul Sander 2023-09-22 19:25 20147
    @liveexample{The example below shows how strings can be swapped with
2660ccea Poul Sander 2023-09-22 19:25 20148
    `swap()`.,swap__string_t}
2660ccea Poul Sander 2023-09-22 19:25 20149
2660ccea Poul Sander 2023-09-22 19:25 20150
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 20151
    */
2660ccea Poul Sander 2023-09-22 19:25 20152
    void swap(string_t& other)
2660ccea Poul Sander 2023-09-22 19:25 20153
    {
2660ccea Poul Sander 2023-09-22 19:25 20154
        // swap only works for strings
2660ccea Poul Sander 2023-09-22 19:25 20155
        if (JSON_HEDLEY_LIKELY(is_string()))
2660ccea Poul Sander 2023-09-22 19:25 20156
        {
2660ccea Poul Sander 2023-09-22 19:25 20157
            std::swap(*(m_value.string), other);
2660ccea Poul Sander 2023-09-22 19:25 20158
        }
2660ccea Poul Sander 2023-09-22 19:25 20159
        else
2660ccea Poul Sander 2023-09-22 19:25 20160
        {
2660ccea Poul Sander 2023-09-22 19:25 20161
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
2660ccea Poul Sander 2023-09-22 19:25 20162
        }
2660ccea Poul Sander 2023-09-22 19:25 20163
    }
2660ccea Poul Sander 2023-09-22 19:25 20164
2660ccea Poul Sander 2023-09-22 19:25 20165
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 20166
2660ccea Poul Sander 2023-09-22 19:25 20167
  public:
2660ccea Poul Sander 2023-09-22 19:25 20168
    //////////////////////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 20169
    // lexicographical comparison operators //
2660ccea Poul Sander 2023-09-22 19:25 20170
    //////////////////////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 20171
2660ccea Poul Sander 2023-09-22 19:25 20172
    /// @name lexicographical comparison operators
2660ccea Poul Sander 2023-09-22 19:25 20173
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 20174
2660ccea Poul Sander 2023-09-22 19:25 20175
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20176
    @brief comparison: equal
2660ccea Poul Sander 2023-09-22 19:25 20177
2660ccea Poul Sander 2023-09-22 19:25 20178
    Compares two JSON values for equality according to the following rules:
2660ccea Poul Sander 2023-09-22 19:25 20179
    - Two JSON values are equal if (1) they are from the same type and (2)
2660ccea Poul Sander 2023-09-22 19:25 20180
      their stored values are the same according to their respective
2660ccea Poul Sander 2023-09-22 19:25 20181
      `operator==`.
2660ccea Poul Sander 2023-09-22 19:25 20182
    - Integer and floating-point numbers are automatically converted before
2660ccea Poul Sander 2023-09-22 19:25 20183
      comparison. Note than two NaN values are always treated as unequal.
2660ccea Poul Sander 2023-09-22 19:25 20184
    - Two JSON null values are equal.
2660ccea Poul Sander 2023-09-22 19:25 20185
2660ccea Poul Sander 2023-09-22 19:25 20186
    @note Floating-point inside JSON values numbers are compared with
2660ccea Poul Sander 2023-09-22 19:25 20187
    `json::number_float_t::operator==` which is `double::operator==` by
2660ccea Poul Sander 2023-09-22 19:25 20188
    default. To compare floating-point while respecting an epsilon, an alternative
2660ccea Poul Sander 2023-09-22 19:25 20189
    [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
2660ccea Poul Sander 2023-09-22 19:25 20190
    could be used, for instance
2660ccea Poul Sander 2023-09-22 19:25 20191
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 20192
    template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
2660ccea Poul Sander 2023-09-22 19:25 20193
    inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20194
    {
2660ccea Poul Sander 2023-09-22 19:25 20195
        return std::abs(a - b) <= epsilon;
2660ccea Poul Sander 2023-09-22 19:25 20196
    }
2660ccea Poul Sander 2023-09-22 19:25 20197
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 20198
2660ccea Poul Sander 2023-09-22 19:25 20199
    @note NaN values never compare equal to themselves or to other NaN values.
2660ccea Poul Sander 2023-09-22 19:25 20200
2660ccea Poul Sander 2023-09-22 19:25 20201
    @param[in] lhs  first JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20202
    @param[in] rhs  second JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20203
    @return whether the values @a lhs and @a rhs are equal
2660ccea Poul Sander 2023-09-22 19:25 20204
2660ccea Poul Sander 2023-09-22 19:25 20205
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 20206
2660ccea Poul Sander 2023-09-22 19:25 20207
    @complexity Linear.
2660ccea Poul Sander 2023-09-22 19:25 20208
2660ccea Poul Sander 2023-09-22 19:25 20209
    @liveexample{The example demonstrates comparing several JSON
2660ccea Poul Sander 2023-09-22 19:25 20210
    types.,operator__equal}
2660ccea Poul Sander 2023-09-22 19:25 20211
2660ccea Poul Sander 2023-09-22 19:25 20212
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 20213
    */
2660ccea Poul Sander 2023-09-22 19:25 20214
    friend bool operator==(const_reference lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20215
    {
2660ccea Poul Sander 2023-09-22 19:25 20216
        const auto lhs_type = lhs.type();
2660ccea Poul Sander 2023-09-22 19:25 20217
        const auto rhs_type = rhs.type();
2660ccea Poul Sander 2023-09-22 19:25 20218
2660ccea Poul Sander 2023-09-22 19:25 20219
        if (lhs_type == rhs_type)
2660ccea Poul Sander 2023-09-22 19:25 20220
        {
2660ccea Poul Sander 2023-09-22 19:25 20221
            switch (lhs_type)
2660ccea Poul Sander 2023-09-22 19:25 20222
            {
2660ccea Poul Sander 2023-09-22 19:25 20223
                case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 20224
                    return *lhs.m_value.array == *rhs.m_value.array;
2660ccea Poul Sander 2023-09-22 19:25 20225
2660ccea Poul Sander 2023-09-22 19:25 20226
                case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 20227
                    return *lhs.m_value.object == *rhs.m_value.object;
2660ccea Poul Sander 2023-09-22 19:25 20228
2660ccea Poul Sander 2023-09-22 19:25 20229
                case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 20230
                    return true;
2660ccea Poul Sander 2023-09-22 19:25 20231
2660ccea Poul Sander 2023-09-22 19:25 20232
                case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 20233
                    return *lhs.m_value.string == *rhs.m_value.string;
2660ccea Poul Sander 2023-09-22 19:25 20234
2660ccea Poul Sander 2023-09-22 19:25 20235
                case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 20236
                    return lhs.m_value.boolean == rhs.m_value.boolean;
2660ccea Poul Sander 2023-09-22 19:25 20237
2660ccea Poul Sander 2023-09-22 19:25 20238
                case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 20239
                    return lhs.m_value.number_integer == rhs.m_value.number_integer;
2660ccea Poul Sander 2023-09-22 19:25 20240
2660ccea Poul Sander 2023-09-22 19:25 20241
                case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 20242
                    return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
2660ccea Poul Sander 2023-09-22 19:25 20243
2660ccea Poul Sander 2023-09-22 19:25 20244
                case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 20245
                    return lhs.m_value.number_float == rhs.m_value.number_float;
2660ccea Poul Sander 2023-09-22 19:25 20246
2660ccea Poul Sander 2023-09-22 19:25 20247
                default:
2660ccea Poul Sander 2023-09-22 19:25 20248
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 20249
            }
2660ccea Poul Sander 2023-09-22 19:25 20250
        }
2660ccea Poul Sander 2023-09-22 19:25 20251
        else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
2660ccea Poul Sander 2023-09-22 19:25 20252
        {
2660ccea Poul Sander 2023-09-22 19:25 20253
            return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
2660ccea Poul Sander 2023-09-22 19:25 20254
        }
2660ccea Poul Sander 2023-09-22 19:25 20255
        else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
2660ccea Poul Sander 2023-09-22 19:25 20256
        {
2660ccea Poul Sander 2023-09-22 19:25 20257
            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
2660ccea Poul Sander 2023-09-22 19:25 20258
        }
2660ccea Poul Sander 2023-09-22 19:25 20259
        else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
2660ccea Poul Sander 2023-09-22 19:25 20260
        {
2660ccea Poul Sander 2023-09-22 19:25 20261
            return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
2660ccea Poul Sander 2023-09-22 19:25 20262
        }
2660ccea Poul Sander 2023-09-22 19:25 20263
        else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
2660ccea Poul Sander 2023-09-22 19:25 20264
        {
2660ccea Poul Sander 2023-09-22 19:25 20265
            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
2660ccea Poul Sander 2023-09-22 19:25 20266
        }
2660ccea Poul Sander 2023-09-22 19:25 20267
        else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
2660ccea Poul Sander 2023-09-22 19:25 20268
        {
2660ccea Poul Sander 2023-09-22 19:25 20269
            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
2660ccea Poul Sander 2023-09-22 19:25 20270
        }
2660ccea Poul Sander 2023-09-22 19:25 20271
        else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
2660ccea Poul Sander 2023-09-22 19:25 20272
        {
2660ccea Poul Sander 2023-09-22 19:25 20273
            return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
2660ccea Poul Sander 2023-09-22 19:25 20274
        }
2660ccea Poul Sander 2023-09-22 19:25 20275
2660ccea Poul Sander 2023-09-22 19:25 20276
        return false;
2660ccea Poul Sander 2023-09-22 19:25 20277
    }
2660ccea Poul Sander 2023-09-22 19:25 20278
2660ccea Poul Sander 2023-09-22 19:25 20279
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20280
    @brief comparison: equal
2660ccea Poul Sander 2023-09-22 19:25 20281
    @copydoc operator==(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20282
    */
2660ccea Poul Sander 2023-09-22 19:25 20283
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20284
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20285
    friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20286
    {
2660ccea Poul Sander 2023-09-22 19:25 20287
        return lhs == basic_json(rhs);
2660ccea Poul Sander 2023-09-22 19:25 20288
    }
2660ccea Poul Sander 2023-09-22 19:25 20289
2660ccea Poul Sander 2023-09-22 19:25 20290
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20291
    @brief comparison: equal
2660ccea Poul Sander 2023-09-22 19:25 20292
    @copydoc operator==(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20293
    */
2660ccea Poul Sander 2023-09-22 19:25 20294
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20295
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20296
    friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20297
    {
2660ccea Poul Sander 2023-09-22 19:25 20298
        return basic_json(lhs) == rhs;
2660ccea Poul Sander 2023-09-22 19:25 20299
    }
2660ccea Poul Sander 2023-09-22 19:25 20300
2660ccea Poul Sander 2023-09-22 19:25 20301
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20302
    @brief comparison: not equal
2660ccea Poul Sander 2023-09-22 19:25 20303
2660ccea Poul Sander 2023-09-22 19:25 20304
    Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
2660ccea Poul Sander 2023-09-22 19:25 20305
2660ccea Poul Sander 2023-09-22 19:25 20306
    @param[in] lhs  first JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20307
    @param[in] rhs  second JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20308
    @return whether the values @a lhs and @a rhs are not equal
2660ccea Poul Sander 2023-09-22 19:25 20309
2660ccea Poul Sander 2023-09-22 19:25 20310
    @complexity Linear.
2660ccea Poul Sander 2023-09-22 19:25 20311
2660ccea Poul Sander 2023-09-22 19:25 20312
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 20313
2660ccea Poul Sander 2023-09-22 19:25 20314
    @liveexample{The example demonstrates comparing several JSON
2660ccea Poul Sander 2023-09-22 19:25 20315
    types.,operator__notequal}
2660ccea Poul Sander 2023-09-22 19:25 20316
2660ccea Poul Sander 2023-09-22 19:25 20317
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 20318
    */
2660ccea Poul Sander 2023-09-22 19:25 20319
    friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20320
    {
2660ccea Poul Sander 2023-09-22 19:25 20321
        return not (lhs == rhs);
2660ccea Poul Sander 2023-09-22 19:25 20322
    }
2660ccea Poul Sander 2023-09-22 19:25 20323
2660ccea Poul Sander 2023-09-22 19:25 20324
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20325
    @brief comparison: not equal
2660ccea Poul Sander 2023-09-22 19:25 20326
    @copydoc operator!=(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20327
    */
2660ccea Poul Sander 2023-09-22 19:25 20328
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20329
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20330
    friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20331
    {
2660ccea Poul Sander 2023-09-22 19:25 20332
        return lhs != basic_json(rhs);
2660ccea Poul Sander 2023-09-22 19:25 20333
    }
2660ccea Poul Sander 2023-09-22 19:25 20334
2660ccea Poul Sander 2023-09-22 19:25 20335
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20336
    @brief comparison: not equal
2660ccea Poul Sander 2023-09-22 19:25 20337
    @copydoc operator!=(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20338
    */
2660ccea Poul Sander 2023-09-22 19:25 20339
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20340
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20341
    friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20342
    {
2660ccea Poul Sander 2023-09-22 19:25 20343
        return basic_json(lhs) != rhs;
2660ccea Poul Sander 2023-09-22 19:25 20344
    }
2660ccea Poul Sander 2023-09-22 19:25 20345
2660ccea Poul Sander 2023-09-22 19:25 20346
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20347
    @brief comparison: less than
2660ccea Poul Sander 2023-09-22 19:25 20348
2660ccea Poul Sander 2023-09-22 19:25 20349
    Compares whether one JSON value @a lhs is less than another JSON value @a
2660ccea Poul Sander 2023-09-22 19:25 20350
    rhs according to the following rules:
2660ccea Poul Sander 2023-09-22 19:25 20351
    - If @a lhs and @a rhs have the same type, the values are compared using
2660ccea Poul Sander 2023-09-22 19:25 20352
      the default `<` operator.
2660ccea Poul Sander 2023-09-22 19:25 20353
    - Integer and floating-point numbers are automatically converted before
2660ccea Poul Sander 2023-09-22 19:25 20354
      comparison
2660ccea Poul Sander 2023-09-22 19:25 20355
    - In case @a lhs and @a rhs have different types, the values are ignored
2660ccea Poul Sander 2023-09-22 19:25 20356
      and the order of the types is considered, see
2660ccea Poul Sander 2023-09-22 19:25 20357
      @ref operator<(const value_t, const value_t).
2660ccea Poul Sander 2023-09-22 19:25 20358
2660ccea Poul Sander 2023-09-22 19:25 20359
    @param[in] lhs  first JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20360
    @param[in] rhs  second JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20361
    @return whether @a lhs is less than @a rhs
2660ccea Poul Sander 2023-09-22 19:25 20362
2660ccea Poul Sander 2023-09-22 19:25 20363
    @complexity Linear.
2660ccea Poul Sander 2023-09-22 19:25 20364
2660ccea Poul Sander 2023-09-22 19:25 20365
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 20366
2660ccea Poul Sander 2023-09-22 19:25 20367
    @liveexample{The example demonstrates comparing several JSON
2660ccea Poul Sander 2023-09-22 19:25 20368
    types.,operator__less}
2660ccea Poul Sander 2023-09-22 19:25 20369
2660ccea Poul Sander 2023-09-22 19:25 20370
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 20371
    */
2660ccea Poul Sander 2023-09-22 19:25 20372
    friend bool operator<(const_reference lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20373
    {
2660ccea Poul Sander 2023-09-22 19:25 20374
        const auto lhs_type = lhs.type();
2660ccea Poul Sander 2023-09-22 19:25 20375
        const auto rhs_type = rhs.type();
2660ccea Poul Sander 2023-09-22 19:25 20376
2660ccea Poul Sander 2023-09-22 19:25 20377
        if (lhs_type == rhs_type)
2660ccea Poul Sander 2023-09-22 19:25 20378
        {
2660ccea Poul Sander 2023-09-22 19:25 20379
            switch (lhs_type)
2660ccea Poul Sander 2023-09-22 19:25 20380
            {
2660ccea Poul Sander 2023-09-22 19:25 20381
                case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 20382
                    // note parentheses are necessary, see
2660ccea Poul Sander 2023-09-22 19:25 20383
                    // https://github.com/nlohmann/json/issues/1530
2660ccea Poul Sander 2023-09-22 19:25 20384
                    return (*lhs.m_value.array) < (*rhs.m_value.array);
2660ccea Poul Sander 2023-09-22 19:25 20385
2660ccea Poul Sander 2023-09-22 19:25 20386
                case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 20387
                    return (*lhs.m_value.object) < (*rhs.m_value.object);
2660ccea Poul Sander 2023-09-22 19:25 20388
2660ccea Poul Sander 2023-09-22 19:25 20389
                case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 20390
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 20391
2660ccea Poul Sander 2023-09-22 19:25 20392
                case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 20393
                    return (*lhs.m_value.string) < (*rhs.m_value.string);
2660ccea Poul Sander 2023-09-22 19:25 20394
2660ccea Poul Sander 2023-09-22 19:25 20395
                case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 20396
                    return (lhs.m_value.boolean) < (rhs.m_value.boolean);
2660ccea Poul Sander 2023-09-22 19:25 20397
2660ccea Poul Sander 2023-09-22 19:25 20398
                case value_t::number_integer:
2660ccea Poul Sander 2023-09-22 19:25 20399
                    return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
2660ccea Poul Sander 2023-09-22 19:25 20400
2660ccea Poul Sander 2023-09-22 19:25 20401
                case value_t::number_unsigned:
2660ccea Poul Sander 2023-09-22 19:25 20402
                    return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
2660ccea Poul Sander 2023-09-22 19:25 20403
2660ccea Poul Sander 2023-09-22 19:25 20404
                case value_t::number_float:
2660ccea Poul Sander 2023-09-22 19:25 20405
                    return (lhs.m_value.number_float) < (rhs.m_value.number_float);
2660ccea Poul Sander 2023-09-22 19:25 20406
2660ccea Poul Sander 2023-09-22 19:25 20407
                default:
2660ccea Poul Sander 2023-09-22 19:25 20408
                    return false;
2660ccea Poul Sander 2023-09-22 19:25 20409
            }
2660ccea Poul Sander 2023-09-22 19:25 20410
        }
2660ccea Poul Sander 2023-09-22 19:25 20411
        else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
2660ccea Poul Sander 2023-09-22 19:25 20412
        {
2660ccea Poul Sander 2023-09-22 19:25 20413
            return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
2660ccea Poul Sander 2023-09-22 19:25 20414
        }
2660ccea Poul Sander 2023-09-22 19:25 20415
        else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
2660ccea Poul Sander 2023-09-22 19:25 20416
        {
2660ccea Poul Sander 2023-09-22 19:25 20417
            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
2660ccea Poul Sander 2023-09-22 19:25 20418
        }
2660ccea Poul Sander 2023-09-22 19:25 20419
        else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
2660ccea Poul Sander 2023-09-22 19:25 20420
        {
2660ccea Poul Sander 2023-09-22 19:25 20421
            return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
2660ccea Poul Sander 2023-09-22 19:25 20422
        }
2660ccea Poul Sander 2023-09-22 19:25 20423
        else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
2660ccea Poul Sander 2023-09-22 19:25 20424
        {
2660ccea Poul Sander 2023-09-22 19:25 20425
            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
2660ccea Poul Sander 2023-09-22 19:25 20426
        }
2660ccea Poul Sander 2023-09-22 19:25 20427
        else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
2660ccea Poul Sander 2023-09-22 19:25 20428
        {
2660ccea Poul Sander 2023-09-22 19:25 20429
            return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
2660ccea Poul Sander 2023-09-22 19:25 20430
        }
2660ccea Poul Sander 2023-09-22 19:25 20431
        else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
2660ccea Poul Sander 2023-09-22 19:25 20432
        {
2660ccea Poul Sander 2023-09-22 19:25 20433
            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
2660ccea Poul Sander 2023-09-22 19:25 20434
        }
2660ccea Poul Sander 2023-09-22 19:25 20435
2660ccea Poul Sander 2023-09-22 19:25 20436
        // We only reach this line if we cannot compare values. In that case,
2660ccea Poul Sander 2023-09-22 19:25 20437
        // we compare types. Note we have to call the operator explicitly,
2660ccea Poul Sander 2023-09-22 19:25 20438
        // because MSVC has problems otherwise.
2660ccea Poul Sander 2023-09-22 19:25 20439
        return operator<(lhs_type, rhs_type);
2660ccea Poul Sander 2023-09-22 19:25 20440
    }
2660ccea Poul Sander 2023-09-22 19:25 20441
2660ccea Poul Sander 2023-09-22 19:25 20442
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20443
    @brief comparison: less than
2660ccea Poul Sander 2023-09-22 19:25 20444
    @copydoc operator<(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20445
    */
2660ccea Poul Sander 2023-09-22 19:25 20446
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20447
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20448
    friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20449
    {
2660ccea Poul Sander 2023-09-22 19:25 20450
        return lhs < basic_json(rhs);
2660ccea Poul Sander 2023-09-22 19:25 20451
    }
2660ccea Poul Sander 2023-09-22 19:25 20452
2660ccea Poul Sander 2023-09-22 19:25 20453
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20454
    @brief comparison: less than
2660ccea Poul Sander 2023-09-22 19:25 20455
    @copydoc operator<(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20456
    */
2660ccea Poul Sander 2023-09-22 19:25 20457
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20458
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20459
    friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20460
    {
2660ccea Poul Sander 2023-09-22 19:25 20461
        return basic_json(lhs) < rhs;
2660ccea Poul Sander 2023-09-22 19:25 20462
    }
2660ccea Poul Sander 2023-09-22 19:25 20463
2660ccea Poul Sander 2023-09-22 19:25 20464
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20465
    @brief comparison: less than or equal
2660ccea Poul Sander 2023-09-22 19:25 20466
2660ccea Poul Sander 2023-09-22 19:25 20467
    Compares whether one JSON value @a lhs is less than or equal to another
2660ccea Poul Sander 2023-09-22 19:25 20468
    JSON value by calculating `not (rhs < lhs)`.
2660ccea Poul Sander 2023-09-22 19:25 20469
2660ccea Poul Sander 2023-09-22 19:25 20470
    @param[in] lhs  first JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20471
    @param[in] rhs  second JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20472
    @return whether @a lhs is less than or equal to @a rhs
2660ccea Poul Sander 2023-09-22 19:25 20473
2660ccea Poul Sander 2023-09-22 19:25 20474
    @complexity Linear.
2660ccea Poul Sander 2023-09-22 19:25 20475
2660ccea Poul Sander 2023-09-22 19:25 20476
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 20477
2660ccea Poul Sander 2023-09-22 19:25 20478
    @liveexample{The example demonstrates comparing several JSON
2660ccea Poul Sander 2023-09-22 19:25 20479
    types.,operator__greater}
2660ccea Poul Sander 2023-09-22 19:25 20480
2660ccea Poul Sander 2023-09-22 19:25 20481
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 20482
    */
2660ccea Poul Sander 2023-09-22 19:25 20483
    friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20484
    {
2660ccea Poul Sander 2023-09-22 19:25 20485
        return not (rhs < lhs);
2660ccea Poul Sander 2023-09-22 19:25 20486
    }
2660ccea Poul Sander 2023-09-22 19:25 20487
2660ccea Poul Sander 2023-09-22 19:25 20488
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20489
    @brief comparison: less than or equal
2660ccea Poul Sander 2023-09-22 19:25 20490
    @copydoc operator<=(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20491
    */
2660ccea Poul Sander 2023-09-22 19:25 20492
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20493
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20494
    friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20495
    {
2660ccea Poul Sander 2023-09-22 19:25 20496
        return lhs <= basic_json(rhs);
2660ccea Poul Sander 2023-09-22 19:25 20497
    }
2660ccea Poul Sander 2023-09-22 19:25 20498
2660ccea Poul Sander 2023-09-22 19:25 20499
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20500
    @brief comparison: less than or equal
2660ccea Poul Sander 2023-09-22 19:25 20501
    @copydoc operator<=(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20502
    */
2660ccea Poul Sander 2023-09-22 19:25 20503
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20504
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20505
    friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20506
    {
2660ccea Poul Sander 2023-09-22 19:25 20507
        return basic_json(lhs) <= rhs;
2660ccea Poul Sander 2023-09-22 19:25 20508
    }
2660ccea Poul Sander 2023-09-22 19:25 20509
2660ccea Poul Sander 2023-09-22 19:25 20510
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20511
    @brief comparison: greater than
2660ccea Poul Sander 2023-09-22 19:25 20512
2660ccea Poul Sander 2023-09-22 19:25 20513
    Compares whether one JSON value @a lhs is greater than another
2660ccea Poul Sander 2023-09-22 19:25 20514
    JSON value by calculating `not (lhs <= rhs)`.
2660ccea Poul Sander 2023-09-22 19:25 20515
2660ccea Poul Sander 2023-09-22 19:25 20516
    @param[in] lhs  first JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20517
    @param[in] rhs  second JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20518
    @return whether @a lhs is greater than to @a rhs
2660ccea Poul Sander 2023-09-22 19:25 20519
2660ccea Poul Sander 2023-09-22 19:25 20520
    @complexity Linear.
2660ccea Poul Sander 2023-09-22 19:25 20521
2660ccea Poul Sander 2023-09-22 19:25 20522
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 20523
2660ccea Poul Sander 2023-09-22 19:25 20524
    @liveexample{The example demonstrates comparing several JSON
2660ccea Poul Sander 2023-09-22 19:25 20525
    types.,operator__lessequal}
2660ccea Poul Sander 2023-09-22 19:25 20526
2660ccea Poul Sander 2023-09-22 19:25 20527
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 20528
    */
2660ccea Poul Sander 2023-09-22 19:25 20529
    friend bool operator>(const_reference lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20530
    {
2660ccea Poul Sander 2023-09-22 19:25 20531
        return not (lhs <= rhs);
2660ccea Poul Sander 2023-09-22 19:25 20532
    }
2660ccea Poul Sander 2023-09-22 19:25 20533
2660ccea Poul Sander 2023-09-22 19:25 20534
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20535
    @brief comparison: greater than
2660ccea Poul Sander 2023-09-22 19:25 20536
    @copydoc operator>(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20537
    */
2660ccea Poul Sander 2023-09-22 19:25 20538
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20539
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20540
    friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20541
    {
2660ccea Poul Sander 2023-09-22 19:25 20542
        return lhs > basic_json(rhs);
2660ccea Poul Sander 2023-09-22 19:25 20543
    }
2660ccea Poul Sander 2023-09-22 19:25 20544
2660ccea Poul Sander 2023-09-22 19:25 20545
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20546
    @brief comparison: greater than
2660ccea Poul Sander 2023-09-22 19:25 20547
    @copydoc operator>(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20548
    */
2660ccea Poul Sander 2023-09-22 19:25 20549
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20550
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20551
    friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20552
    {
2660ccea Poul Sander 2023-09-22 19:25 20553
        return basic_json(lhs) > rhs;
2660ccea Poul Sander 2023-09-22 19:25 20554
    }
2660ccea Poul Sander 2023-09-22 19:25 20555
2660ccea Poul Sander 2023-09-22 19:25 20556
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20557
    @brief comparison: greater than or equal
2660ccea Poul Sander 2023-09-22 19:25 20558
2660ccea Poul Sander 2023-09-22 19:25 20559
    Compares whether one JSON value @a lhs is greater than or equal to another
2660ccea Poul Sander 2023-09-22 19:25 20560
    JSON value by calculating `not (lhs < rhs)`.
2660ccea Poul Sander 2023-09-22 19:25 20561
2660ccea Poul Sander 2023-09-22 19:25 20562
    @param[in] lhs  first JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20563
    @param[in] rhs  second JSON value to consider
2660ccea Poul Sander 2023-09-22 19:25 20564
    @return whether @a lhs is greater than or equal to @a rhs
2660ccea Poul Sander 2023-09-22 19:25 20565
2660ccea Poul Sander 2023-09-22 19:25 20566
    @complexity Linear.
2660ccea Poul Sander 2023-09-22 19:25 20567
2660ccea Poul Sander 2023-09-22 19:25 20568
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 20569
2660ccea Poul Sander 2023-09-22 19:25 20570
    @liveexample{The example demonstrates comparing several JSON
2660ccea Poul Sander 2023-09-22 19:25 20571
    types.,operator__greaterequal}
2660ccea Poul Sander 2023-09-22 19:25 20572
2660ccea Poul Sander 2023-09-22 19:25 20573
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 20574
    */
2660ccea Poul Sander 2023-09-22 19:25 20575
    friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20576
    {
2660ccea Poul Sander 2023-09-22 19:25 20577
        return not (lhs < rhs);
2660ccea Poul Sander 2023-09-22 19:25 20578
    }
2660ccea Poul Sander 2023-09-22 19:25 20579
2660ccea Poul Sander 2023-09-22 19:25 20580
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20581
    @brief comparison: greater than or equal
2660ccea Poul Sander 2023-09-22 19:25 20582
    @copydoc operator>=(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20583
    */
2660ccea Poul Sander 2023-09-22 19:25 20584
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20585
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20586
    friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20587
    {
2660ccea Poul Sander 2023-09-22 19:25 20588
        return lhs >= basic_json(rhs);
2660ccea Poul Sander 2023-09-22 19:25 20589
    }
2660ccea Poul Sander 2023-09-22 19:25 20590
2660ccea Poul Sander 2023-09-22 19:25 20591
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20592
    @brief comparison: greater than or equal
2660ccea Poul Sander 2023-09-22 19:25 20593
    @copydoc operator>=(const_reference, const_reference)
2660ccea Poul Sander 2023-09-22 19:25 20594
    */
2660ccea Poul Sander 2023-09-22 19:25 20595
    template<typename ScalarType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20596
                 std::is_scalar<ScalarType>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20597
    friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
2660ccea Poul Sander 2023-09-22 19:25 20598
    {
2660ccea Poul Sander 2023-09-22 19:25 20599
        return basic_json(lhs) >= rhs;
2660ccea Poul Sander 2023-09-22 19:25 20600
    }
2660ccea Poul Sander 2023-09-22 19:25 20601
2660ccea Poul Sander 2023-09-22 19:25 20602
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 20603
2660ccea Poul Sander 2023-09-22 19:25 20604
    ///////////////////
2660ccea Poul Sander 2023-09-22 19:25 20605
    // serialization //
2660ccea Poul Sander 2023-09-22 19:25 20606
    ///////////////////
2660ccea Poul Sander 2023-09-22 19:25 20607
2660ccea Poul Sander 2023-09-22 19:25 20608
    /// @name serialization
2660ccea Poul Sander 2023-09-22 19:25 20609
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 20610
2660ccea Poul Sander 2023-09-22 19:25 20611
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20612
    @brief serialize to stream
2660ccea Poul Sander 2023-09-22 19:25 20613
2660ccea Poul Sander 2023-09-22 19:25 20614
    Serialize the given JSON value @a j to the output stream @a o. The JSON
2660ccea Poul Sander 2023-09-22 19:25 20615
    value will be serialized using the @ref dump member function.
2660ccea Poul Sander 2023-09-22 19:25 20616
2660ccea Poul Sander 2023-09-22 19:25 20617
    - The indentation of the output can be controlled with the member variable
2660ccea Poul Sander 2023-09-22 19:25 20618
      `width` of the output stream @a o. For instance, using the manipulator
2660ccea Poul Sander 2023-09-22 19:25 20619
      `std::setw(4)` on @a o sets the indentation level to `4` and the
2660ccea Poul Sander 2023-09-22 19:25 20620
      serialization result is the same as calling `dump(4)`.
2660ccea Poul Sander 2023-09-22 19:25 20621
2660ccea Poul Sander 2023-09-22 19:25 20622
    - The indentation character can be controlled with the member variable
2660ccea Poul Sander 2023-09-22 19:25 20623
      `fill` of the output stream @a o. For instance, the manipulator
2660ccea Poul Sander 2023-09-22 19:25 20624
      `std::setfill('\\t')` sets indentation to use a tab character rather than
2660ccea Poul Sander 2023-09-22 19:25 20625
      the default space character.
2660ccea Poul Sander 2023-09-22 19:25 20626
2660ccea Poul Sander 2023-09-22 19:25 20627
    @param[in,out] o  stream to serialize to
2660ccea Poul Sander 2023-09-22 19:25 20628
    @param[in] j  JSON value to serialize
2660ccea Poul Sander 2023-09-22 19:25 20629
2660ccea Poul Sander 2023-09-22 19:25 20630
    @return the stream @a o
2660ccea Poul Sander 2023-09-22 19:25 20631
2660ccea Poul Sander 2023-09-22 19:25 20632
    @throw type_error.316 if a string stored inside the JSON value is not
2660ccea Poul Sander 2023-09-22 19:25 20633
                          UTF-8 encoded
2660ccea Poul Sander 2023-09-22 19:25 20634
2660ccea Poul Sander 2023-09-22 19:25 20635
    @complexity Linear.
2660ccea Poul Sander 2023-09-22 19:25 20636
2660ccea Poul Sander 2023-09-22 19:25 20637
    @liveexample{The example below shows the serialization with different
2660ccea Poul Sander 2023-09-22 19:25 20638
    parameters to `width` to adjust the indentation level.,operator_serialize}
2660ccea Poul Sander 2023-09-22 19:25 20639
2660ccea Poul Sander 2023-09-22 19:25 20640
    @since version 1.0.0; indentation character added in version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 20641
    */
2660ccea Poul Sander 2023-09-22 19:25 20642
    friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
2660ccea Poul Sander 2023-09-22 19:25 20643
    {
2660ccea Poul Sander 2023-09-22 19:25 20644
        // read width member and use it as indentation parameter if nonzero
2660ccea Poul Sander 2023-09-22 19:25 20645
        const bool pretty_print = o.width() > 0;
2660ccea Poul Sander 2023-09-22 19:25 20646
        const auto indentation = pretty_print ? o.width() : 0;
2660ccea Poul Sander 2023-09-22 19:25 20647
2660ccea Poul Sander 2023-09-22 19:25 20648
        // reset width to 0 for subsequent calls to this stream
2660ccea Poul Sander 2023-09-22 19:25 20649
        o.width(0);
2660ccea Poul Sander 2023-09-22 19:25 20650
2660ccea Poul Sander 2023-09-22 19:25 20651
        // do the actual serialization
2660ccea Poul Sander 2023-09-22 19:25 20652
        serializer s(detail::output_adapter<char>(o), o.fill());
2660ccea Poul Sander 2023-09-22 19:25 20653
        s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
2660ccea Poul Sander 2023-09-22 19:25 20654
        return o;
2660ccea Poul Sander 2023-09-22 19:25 20655
    }
2660ccea Poul Sander 2023-09-22 19:25 20656
2660ccea Poul Sander 2023-09-22 19:25 20657
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20658
    @brief serialize to stream
2660ccea Poul Sander 2023-09-22 19:25 20659
    @deprecated This stream operator is deprecated and will be removed in
2660ccea Poul Sander 2023-09-22 19:25 20660
                future 4.0.0 of the library. Please use
2660ccea Poul Sander 2023-09-22 19:25 20661
                @ref operator<<(std::ostream&, const basic_json&)
2660ccea Poul Sander 2023-09-22 19:25 20662
                instead; that is, replace calls like `j >> o;` with `o << j;`.
2660ccea Poul Sander 2023-09-22 19:25 20663
    @since version 1.0.0; deprecated since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 20664
    */
2660ccea Poul Sander 2023-09-22 19:25 20665
    JSON_HEDLEY_DEPRECATED(3.0.0)
2660ccea Poul Sander 2023-09-22 19:25 20666
    friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
2660ccea Poul Sander 2023-09-22 19:25 20667
    {
2660ccea Poul Sander 2023-09-22 19:25 20668
        return o << j;
2660ccea Poul Sander 2023-09-22 19:25 20669
    }
2660ccea Poul Sander 2023-09-22 19:25 20670
2660ccea Poul Sander 2023-09-22 19:25 20671
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 20672
2660ccea Poul Sander 2023-09-22 19:25 20673
2660ccea Poul Sander 2023-09-22 19:25 20674
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 20675
    // deserialization //
2660ccea Poul Sander 2023-09-22 19:25 20676
    /////////////////////
2660ccea Poul Sander 2023-09-22 19:25 20677
2660ccea Poul Sander 2023-09-22 19:25 20678
    /// @name deserialization
2660ccea Poul Sander 2023-09-22 19:25 20679
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 20680
2660ccea Poul Sander 2023-09-22 19:25 20681
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20682
    @brief deserialize from a compatible input
2660ccea Poul Sander 2023-09-22 19:25 20683
2660ccea Poul Sander 2023-09-22 19:25 20684
    This function reads from a compatible input. Examples are:
2660ccea Poul Sander 2023-09-22 19:25 20685
    - an array of 1-byte values
2660ccea Poul Sander 2023-09-22 19:25 20686
    - strings with character/literal type with size of 1 byte
2660ccea Poul Sander 2023-09-22 19:25 20687
    - input streams
2660ccea Poul Sander 2023-09-22 19:25 20688
    - container with contiguous storage of 1-byte values. Compatible container
2660ccea Poul Sander 2023-09-22 19:25 20689
      types include `std::vector`, `std::string`, `std::array`,
2660ccea Poul Sander 2023-09-22 19:25 20690
      `std::valarray`, and `std::initializer_list`. Furthermore, C-style
2660ccea Poul Sander 2023-09-22 19:25 20691
      arrays can be used with `std::begin()`/`std::end()`. User-defined
2660ccea Poul Sander 2023-09-22 19:25 20692
      containers can be used as long as they implement random-access iterators
2660ccea Poul Sander 2023-09-22 19:25 20693
      and a contiguous storage.
2660ccea Poul Sander 2023-09-22 19:25 20694
2660ccea Poul Sander 2023-09-22 19:25 20695
    @pre Each element of the container has a size of 1 byte. Violating this
2660ccea Poul Sander 2023-09-22 19:25 20696
    precondition yields undefined behavior. **This precondition is enforced
2660ccea Poul Sander 2023-09-22 19:25 20697
    with a static assertion.**
2660ccea Poul Sander 2023-09-22 19:25 20698
2660ccea Poul Sander 2023-09-22 19:25 20699
    @pre The container storage is contiguous. Violating this precondition
2660ccea Poul Sander 2023-09-22 19:25 20700
    yields undefined behavior. **This precondition is enforced with an
2660ccea Poul Sander 2023-09-22 19:25 20701
    assertion.**
2660ccea Poul Sander 2023-09-22 19:25 20702
2660ccea Poul Sander 2023-09-22 19:25 20703
    @warning There is no way to enforce all preconditions at compile-time. If
2660ccea Poul Sander 2023-09-22 19:25 20704
             the function is called with a noncompliant container and with
2660ccea Poul Sander 2023-09-22 19:25 20705
             assertions switched off, the behavior is undefined and will most
2660ccea Poul Sander 2023-09-22 19:25 20706
             likely yield segmentation violation.
2660ccea Poul Sander 2023-09-22 19:25 20707
2660ccea Poul Sander 2023-09-22 19:25 20708
    @param[in] i  input to read from
2660ccea Poul Sander 2023-09-22 19:25 20709
    @param[in] cb  a parser callback function of type @ref parser_callback_t
2660ccea Poul Sander 2023-09-22 19:25 20710
    which is used to control the deserialization by filtering unwanted values
2660ccea Poul Sander 2023-09-22 19:25 20711
    (optional)
2660ccea Poul Sander 2023-09-22 19:25 20712
    @param[in] allow_exceptions  whether to throw exceptions in case of a
2660ccea Poul Sander 2023-09-22 19:25 20713
    parse error (optional, true by default)
2660ccea Poul Sander 2023-09-22 19:25 20714
2660ccea Poul Sander 2023-09-22 19:25 20715
    @return deserialized JSON value; in case of a parse error and
2660ccea Poul Sander 2023-09-22 19:25 20716
            @a allow_exceptions set to `false`, the return value will be
2660ccea Poul Sander 2023-09-22 19:25 20717
            value_t::discarded.
2660ccea Poul Sander 2023-09-22 19:25 20718
2660ccea Poul Sander 2023-09-22 19:25 20719
    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
2660ccea Poul Sander 2023-09-22 19:25 20720
    of input; expected string literal""`
2660ccea Poul Sander 2023-09-22 19:25 20721
    @throw parse_error.102 if to_unicode fails or surrogate error
2660ccea Poul Sander 2023-09-22 19:25 20722
    @throw parse_error.103 if to_unicode fails
2660ccea Poul Sander 2023-09-22 19:25 20723
2660ccea Poul Sander 2023-09-22 19:25 20724
    @complexity Linear in the length of the input. The parser is a predictive
2660ccea Poul Sander 2023-09-22 19:25 20725
    LL(1) parser. The complexity can be higher if the parser callback function
2660ccea Poul Sander 2023-09-22 19:25 20726
    @a cb has a super-linear complexity.
2660ccea Poul Sander 2023-09-22 19:25 20727
2660ccea Poul Sander 2023-09-22 19:25 20728
    @note A UTF-8 byte order mark is silently ignored.
2660ccea Poul Sander 2023-09-22 19:25 20729
2660ccea Poul Sander 2023-09-22 19:25 20730
    @liveexample{The example below demonstrates the `parse()` function reading
2660ccea Poul Sander 2023-09-22 19:25 20731
    from an array.,parse__array__parser_callback_t}
2660ccea Poul Sander 2023-09-22 19:25 20732
2660ccea Poul Sander 2023-09-22 19:25 20733
    @liveexample{The example below demonstrates the `parse()` function with
2660ccea Poul Sander 2023-09-22 19:25 20734
    and without callback function.,parse__string__parser_callback_t}
2660ccea Poul Sander 2023-09-22 19:25 20735
2660ccea Poul Sander 2023-09-22 19:25 20736
    @liveexample{The example below demonstrates the `parse()` function with
2660ccea Poul Sander 2023-09-22 19:25 20737
    and without callback function.,parse__istream__parser_callback_t}
2660ccea Poul Sander 2023-09-22 19:25 20738
2660ccea Poul Sander 2023-09-22 19:25 20739
    @liveexample{The example below demonstrates the `parse()` function reading
2660ccea Poul Sander 2023-09-22 19:25 20740
    from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
2660ccea Poul Sander 2023-09-22 19:25 20741
2660ccea Poul Sander 2023-09-22 19:25 20742
    @since version 2.0.3 (contiguous containers)
2660ccea Poul Sander 2023-09-22 19:25 20743
    */
2660ccea Poul Sander 2023-09-22 19:25 20744
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 20745
    static basic_json parse(detail::input_adapter&& i,
2660ccea Poul Sander 2023-09-22 19:25 20746
                            const parser_callback_t cb = nullptr,
2660ccea Poul Sander 2023-09-22 19:25 20747
                            const bool allow_exceptions = true)
2660ccea Poul Sander 2023-09-22 19:25 20748
    {
2660ccea Poul Sander 2023-09-22 19:25 20749
        basic_json result;
2660ccea Poul Sander 2023-09-22 19:25 20750
        parser(i, cb, allow_exceptions).parse(true, result);
2660ccea Poul Sander 2023-09-22 19:25 20751
        return result;
2660ccea Poul Sander 2023-09-22 19:25 20752
    }
2660ccea Poul Sander 2023-09-22 19:25 20753
2660ccea Poul Sander 2023-09-22 19:25 20754
    static bool accept(detail::input_adapter&& i)
2660ccea Poul Sander 2023-09-22 19:25 20755
    {
2660ccea Poul Sander 2023-09-22 19:25 20756
        return parser(i).accept(true);
2660ccea Poul Sander 2023-09-22 19:25 20757
    }
2660ccea Poul Sander 2023-09-22 19:25 20758
2660ccea Poul Sander 2023-09-22 19:25 20759
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20760
    @brief generate SAX events
2660ccea Poul Sander 2023-09-22 19:25 20761
2660ccea Poul Sander 2023-09-22 19:25 20762
    The SAX event lister must follow the interface of @ref json_sax.
2660ccea Poul Sander 2023-09-22 19:25 20763
2660ccea Poul Sander 2023-09-22 19:25 20764
    This function reads from a compatible input. Examples are:
2660ccea Poul Sander 2023-09-22 19:25 20765
    - an array of 1-byte values
2660ccea Poul Sander 2023-09-22 19:25 20766
    - strings with character/literal type with size of 1 byte
2660ccea Poul Sander 2023-09-22 19:25 20767
    - input streams
2660ccea Poul Sander 2023-09-22 19:25 20768
    - container with contiguous storage of 1-byte values. Compatible container
2660ccea Poul Sander 2023-09-22 19:25 20769
      types include `std::vector`, `std::string`, `std::array`,
2660ccea Poul Sander 2023-09-22 19:25 20770
      `std::valarray`, and `std::initializer_list`. Furthermore, C-style
2660ccea Poul Sander 2023-09-22 19:25 20771
      arrays can be used with `std::begin()`/`std::end()`. User-defined
2660ccea Poul Sander 2023-09-22 19:25 20772
      containers can be used as long as they implement random-access iterators
2660ccea Poul Sander 2023-09-22 19:25 20773
      and a contiguous storage.
2660ccea Poul Sander 2023-09-22 19:25 20774
2660ccea Poul Sander 2023-09-22 19:25 20775
    @pre Each element of the container has a size of 1 byte. Violating this
2660ccea Poul Sander 2023-09-22 19:25 20776
    precondition yields undefined behavior. **This precondition is enforced
2660ccea Poul Sander 2023-09-22 19:25 20777
    with a static assertion.**
2660ccea Poul Sander 2023-09-22 19:25 20778
2660ccea Poul Sander 2023-09-22 19:25 20779
    @pre The container storage is contiguous. Violating this precondition
2660ccea Poul Sander 2023-09-22 19:25 20780
    yields undefined behavior. **This precondition is enforced with an
2660ccea Poul Sander 2023-09-22 19:25 20781
    assertion.**
2660ccea Poul Sander 2023-09-22 19:25 20782
2660ccea Poul Sander 2023-09-22 19:25 20783
    @warning There is no way to enforce all preconditions at compile-time. If
2660ccea Poul Sander 2023-09-22 19:25 20784
             the function is called with a noncompliant container and with
2660ccea Poul Sander 2023-09-22 19:25 20785
             assertions switched off, the behavior is undefined and will most
2660ccea Poul Sander 2023-09-22 19:25 20786
             likely yield segmentation violation.
2660ccea Poul Sander 2023-09-22 19:25 20787
2660ccea Poul Sander 2023-09-22 19:25 20788
    @param[in] i  input to read from
2660ccea Poul Sander 2023-09-22 19:25 20789
    @param[in,out] sax  SAX event listener
2660ccea Poul Sander 2023-09-22 19:25 20790
    @param[in] format  the format to parse (JSON, CBOR, MessagePack, or UBJSON)
2660ccea Poul Sander 2023-09-22 19:25 20791
    @param[in] strict  whether the input has to be consumed completely
2660ccea Poul Sander 2023-09-22 19:25 20792
2660ccea Poul Sander 2023-09-22 19:25 20793
    @return return value of the last processed SAX event
2660ccea Poul Sander 2023-09-22 19:25 20794
2660ccea Poul Sander 2023-09-22 19:25 20795
    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
2660ccea Poul Sander 2023-09-22 19:25 20796
    of input; expected string literal""`
2660ccea Poul Sander 2023-09-22 19:25 20797
    @throw parse_error.102 if to_unicode fails or surrogate error
2660ccea Poul Sander 2023-09-22 19:25 20798
    @throw parse_error.103 if to_unicode fails
2660ccea Poul Sander 2023-09-22 19:25 20799
2660ccea Poul Sander 2023-09-22 19:25 20800
    @complexity Linear in the length of the input. The parser is a predictive
2660ccea Poul Sander 2023-09-22 19:25 20801
    LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
2660ccea Poul Sander 2023-09-22 19:25 20802
    a super-linear complexity.
2660ccea Poul Sander 2023-09-22 19:25 20803
2660ccea Poul Sander 2023-09-22 19:25 20804
    @note A UTF-8 byte order mark is silently ignored.
2660ccea Poul Sander 2023-09-22 19:25 20805
2660ccea Poul Sander 2023-09-22 19:25 20806
    @liveexample{The example below demonstrates the `sax_parse()` function
2660ccea Poul Sander 2023-09-22 19:25 20807
    reading from string and processing the events with a user-defined SAX
2660ccea Poul Sander 2023-09-22 19:25 20808
    event consumer.,sax_parse}
2660ccea Poul Sander 2023-09-22 19:25 20809
2660ccea Poul Sander 2023-09-22 19:25 20810
    @since version 3.2.0
2660ccea Poul Sander 2023-09-22 19:25 20811
    */
2660ccea Poul Sander 2023-09-22 19:25 20812
    template <typename SAX>
2660ccea Poul Sander 2023-09-22 19:25 20813
    JSON_HEDLEY_NON_NULL(2)
2660ccea Poul Sander 2023-09-22 19:25 20814
    static bool sax_parse(detail::input_adapter&& i, SAX* sax,
2660ccea Poul Sander 2023-09-22 19:25 20815
                          input_format_t format = input_format_t::json,
2660ccea Poul Sander 2023-09-22 19:25 20816
                          const bool strict = true)
2660ccea Poul Sander 2023-09-22 19:25 20817
    {
2660ccea Poul Sander 2023-09-22 19:25 20818
        assert(sax);
2660ccea Poul Sander 2023-09-22 19:25 20819
        return format == input_format_t::json
2660ccea Poul Sander 2023-09-22 19:25 20820
               ? parser(std::move(i)).sax_parse(sax, strict)
2660ccea Poul Sander 2023-09-22 19:25 20821
               : detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
2660ccea Poul Sander 2023-09-22 19:25 20822
    }
2660ccea Poul Sander 2023-09-22 19:25 20823
2660ccea Poul Sander 2023-09-22 19:25 20824
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20825
    @brief deserialize from an iterator range with contiguous storage
2660ccea Poul Sander 2023-09-22 19:25 20826
2660ccea Poul Sander 2023-09-22 19:25 20827
    This function reads from an iterator range of a container with contiguous
2660ccea Poul Sander 2023-09-22 19:25 20828
    storage of 1-byte values. Compatible container types include
2660ccea Poul Sander 2023-09-22 19:25 20829
    `std::vector`, `std::string`, `std::array`, `std::valarray`, and
2660ccea Poul Sander 2023-09-22 19:25 20830
    `std::initializer_list`. Furthermore, C-style arrays can be used with
2660ccea Poul Sander 2023-09-22 19:25 20831
    `std::begin()`/`std::end()`. User-defined containers can be used as long
2660ccea Poul Sander 2023-09-22 19:25 20832
    as they implement random-access iterators and a contiguous storage.
2660ccea Poul Sander 2023-09-22 19:25 20833
2660ccea Poul Sander 2023-09-22 19:25 20834
    @pre The iterator range is contiguous. Violating this precondition yields
2660ccea Poul Sander 2023-09-22 19:25 20835
    undefined behavior. **This precondition is enforced with an assertion.**
2660ccea Poul Sander 2023-09-22 19:25 20836
    @pre Each element in the range has a size of 1 byte. Violating this
2660ccea Poul Sander 2023-09-22 19:25 20837
    precondition yields undefined behavior. **This precondition is enforced
2660ccea Poul Sander 2023-09-22 19:25 20838
    with a static assertion.**
2660ccea Poul Sander 2023-09-22 19:25 20839
2660ccea Poul Sander 2023-09-22 19:25 20840
    @warning There is no way to enforce all preconditions at compile-time. If
2660ccea Poul Sander 2023-09-22 19:25 20841
             the function is called with noncompliant iterators and with
2660ccea Poul Sander 2023-09-22 19:25 20842
             assertions switched off, the behavior is undefined and will most
2660ccea Poul Sander 2023-09-22 19:25 20843
             likely yield segmentation violation.
2660ccea Poul Sander 2023-09-22 19:25 20844
2660ccea Poul Sander 2023-09-22 19:25 20845
    @tparam IteratorType iterator of container with contiguous storage
2660ccea Poul Sander 2023-09-22 19:25 20846
    @param[in] first  begin of the range to parse (included)
2660ccea Poul Sander 2023-09-22 19:25 20847
    @param[in] last  end of the range to parse (excluded)
2660ccea Poul Sander 2023-09-22 19:25 20848
    @param[in] cb  a parser callback function of type @ref parser_callback_t
2660ccea Poul Sander 2023-09-22 19:25 20849
    which is used to control the deserialization by filtering unwanted values
2660ccea Poul Sander 2023-09-22 19:25 20850
    (optional)
2660ccea Poul Sander 2023-09-22 19:25 20851
    @param[in] allow_exceptions  whether to throw exceptions in case of a
2660ccea Poul Sander 2023-09-22 19:25 20852
    parse error (optional, true by default)
2660ccea Poul Sander 2023-09-22 19:25 20853
2660ccea Poul Sander 2023-09-22 19:25 20854
    @return deserialized JSON value; in case of a parse error and
2660ccea Poul Sander 2023-09-22 19:25 20855
            @a allow_exceptions set to `false`, the return value will be
2660ccea Poul Sander 2023-09-22 19:25 20856
            value_t::discarded.
2660ccea Poul Sander 2023-09-22 19:25 20857
2660ccea Poul Sander 2023-09-22 19:25 20858
    @throw parse_error.101 in case of an unexpected token
2660ccea Poul Sander 2023-09-22 19:25 20859
    @throw parse_error.102 if to_unicode fails or surrogate error
2660ccea Poul Sander 2023-09-22 19:25 20860
    @throw parse_error.103 if to_unicode fails
2660ccea Poul Sander 2023-09-22 19:25 20861
2660ccea Poul Sander 2023-09-22 19:25 20862
    @complexity Linear in the length of the input. The parser is a predictive
2660ccea Poul Sander 2023-09-22 19:25 20863
    LL(1) parser. The complexity can be higher if the parser callback function
2660ccea Poul Sander 2023-09-22 19:25 20864
    @a cb has a super-linear complexity.
2660ccea Poul Sander 2023-09-22 19:25 20865
2660ccea Poul Sander 2023-09-22 19:25 20866
    @note A UTF-8 byte order mark is silently ignored.
2660ccea Poul Sander 2023-09-22 19:25 20867
2660ccea Poul Sander 2023-09-22 19:25 20868
    @liveexample{The example below demonstrates the `parse()` function reading
2660ccea Poul Sander 2023-09-22 19:25 20869
    from an iterator range.,parse__iteratortype__parser_callback_t}
2660ccea Poul Sander 2023-09-22 19:25 20870
2660ccea Poul Sander 2023-09-22 19:25 20871
    @since version 2.0.3
2660ccea Poul Sander 2023-09-22 19:25 20872
    */
2660ccea Poul Sander 2023-09-22 19:25 20873
    template<class IteratorType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20874
                 std::is_base_of<
2660ccea Poul Sander 2023-09-22 19:25 20875
                     std::random_access_iterator_tag,
2660ccea Poul Sander 2023-09-22 19:25 20876
                     typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20877
    static basic_json parse(IteratorType first, IteratorType last,
2660ccea Poul Sander 2023-09-22 19:25 20878
                            const parser_callback_t cb = nullptr,
2660ccea Poul Sander 2023-09-22 19:25 20879
                            const bool allow_exceptions = true)
2660ccea Poul Sander 2023-09-22 19:25 20880
    {
2660ccea Poul Sander 2023-09-22 19:25 20881
        basic_json result;
2660ccea Poul Sander 2023-09-22 19:25 20882
        parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
2660ccea Poul Sander 2023-09-22 19:25 20883
        return result;
2660ccea Poul Sander 2023-09-22 19:25 20884
    }
2660ccea Poul Sander 2023-09-22 19:25 20885
2660ccea Poul Sander 2023-09-22 19:25 20886
    template<class IteratorType, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20887
                 std::is_base_of<
2660ccea Poul Sander 2023-09-22 19:25 20888
                     std::random_access_iterator_tag,
2660ccea Poul Sander 2023-09-22 19:25 20889
                     typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20890
    static bool accept(IteratorType first, IteratorType last)
2660ccea Poul Sander 2023-09-22 19:25 20891
    {
2660ccea Poul Sander 2023-09-22 19:25 20892
        return parser(detail::input_adapter(first, last)).accept(true);
2660ccea Poul Sander 2023-09-22 19:25 20893
    }
2660ccea Poul Sander 2023-09-22 19:25 20894
2660ccea Poul Sander 2023-09-22 19:25 20895
    template<class IteratorType, class SAX, typename std::enable_if<
2660ccea Poul Sander 2023-09-22 19:25 20896
                 std::is_base_of<
2660ccea Poul Sander 2023-09-22 19:25 20897
                     std::random_access_iterator_tag,
2660ccea Poul Sander 2023-09-22 19:25 20898
                     typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
2660ccea Poul Sander 2023-09-22 19:25 20899
    JSON_HEDLEY_NON_NULL(3)
2660ccea Poul Sander 2023-09-22 19:25 20900
    static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
2660ccea Poul Sander 2023-09-22 19:25 20901
    {
2660ccea Poul Sander 2023-09-22 19:25 20902
        return parser(detail::input_adapter(first, last)).sax_parse(sax);
2660ccea Poul Sander 2023-09-22 19:25 20903
    }
2660ccea Poul Sander 2023-09-22 19:25 20904
2660ccea Poul Sander 2023-09-22 19:25 20905
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20906
    @brief deserialize from stream
2660ccea Poul Sander 2023-09-22 19:25 20907
    @deprecated This stream operator is deprecated and will be removed in
2660ccea Poul Sander 2023-09-22 19:25 20908
                version 4.0.0 of the library. Please use
2660ccea Poul Sander 2023-09-22 19:25 20909
                @ref operator>>(std::istream&, basic_json&)
2660ccea Poul Sander 2023-09-22 19:25 20910
                instead; that is, replace calls like `j << i;` with `i >> j;`.
2660ccea Poul Sander 2023-09-22 19:25 20911
    @since version 1.0.0; deprecated since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 20912
    */
2660ccea Poul Sander 2023-09-22 19:25 20913
    JSON_HEDLEY_DEPRECATED(3.0.0)
2660ccea Poul Sander 2023-09-22 19:25 20914
    friend std::istream& operator<<(basic_json& j, std::istream& i)
2660ccea Poul Sander 2023-09-22 19:25 20915
    {
2660ccea Poul Sander 2023-09-22 19:25 20916
        return operator>>(i, j);
2660ccea Poul Sander 2023-09-22 19:25 20917
    }
2660ccea Poul Sander 2023-09-22 19:25 20918
2660ccea Poul Sander 2023-09-22 19:25 20919
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20920
    @brief deserialize from stream
2660ccea Poul Sander 2023-09-22 19:25 20921
2660ccea Poul Sander 2023-09-22 19:25 20922
    Deserializes an input stream to a JSON value.
2660ccea Poul Sander 2023-09-22 19:25 20923
2660ccea Poul Sander 2023-09-22 19:25 20924
    @param[in,out] i  input stream to read a serialized JSON value from
2660ccea Poul Sander 2023-09-22 19:25 20925
    @param[in,out] j  JSON value to write the deserialized input to
2660ccea Poul Sander 2023-09-22 19:25 20926
2660ccea Poul Sander 2023-09-22 19:25 20927
    @throw parse_error.101 in case of an unexpected token
2660ccea Poul Sander 2023-09-22 19:25 20928
    @throw parse_error.102 if to_unicode fails or surrogate error
2660ccea Poul Sander 2023-09-22 19:25 20929
    @throw parse_error.103 if to_unicode fails
2660ccea Poul Sander 2023-09-22 19:25 20930
2660ccea Poul Sander 2023-09-22 19:25 20931
    @complexity Linear in the length of the input. The parser is a predictive
2660ccea Poul Sander 2023-09-22 19:25 20932
    LL(1) parser.
2660ccea Poul Sander 2023-09-22 19:25 20933
2660ccea Poul Sander 2023-09-22 19:25 20934
    @note A UTF-8 byte order mark is silently ignored.
2660ccea Poul Sander 2023-09-22 19:25 20935
2660ccea Poul Sander 2023-09-22 19:25 20936
    @liveexample{The example below shows how a JSON value is constructed by
2660ccea Poul Sander 2023-09-22 19:25 20937
    reading a serialization from a stream.,operator_deserialize}
2660ccea Poul Sander 2023-09-22 19:25 20938
2660ccea Poul Sander 2023-09-22 19:25 20939
    @sa parse(std::istream&, const parser_callback_t) for a variant with a
2660ccea Poul Sander 2023-09-22 19:25 20940
    parser callback function to filter values while parsing
2660ccea Poul Sander 2023-09-22 19:25 20941
2660ccea Poul Sander 2023-09-22 19:25 20942
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 20943
    */
2660ccea Poul Sander 2023-09-22 19:25 20944
    friend std::istream& operator>>(std::istream& i, basic_json& j)
2660ccea Poul Sander 2023-09-22 19:25 20945
    {
2660ccea Poul Sander 2023-09-22 19:25 20946
        parser(detail::input_adapter(i)).parse(false, j);
2660ccea Poul Sander 2023-09-22 19:25 20947
        return i;
2660ccea Poul Sander 2023-09-22 19:25 20948
    }
2660ccea Poul Sander 2023-09-22 19:25 20949
2660ccea Poul Sander 2023-09-22 19:25 20950
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 20951
2660ccea Poul Sander 2023-09-22 19:25 20952
    ///////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 20953
    // convenience functions //
2660ccea Poul Sander 2023-09-22 19:25 20954
    ///////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 20955
2660ccea Poul Sander 2023-09-22 19:25 20956
    /*!
2660ccea Poul Sander 2023-09-22 19:25 20957
    @brief return the type as string
2660ccea Poul Sander 2023-09-22 19:25 20958
2660ccea Poul Sander 2023-09-22 19:25 20959
    Returns the type name as string to be used in error messages - usually to
2660ccea Poul Sander 2023-09-22 19:25 20960
    indicate that a function was called on a wrong JSON type.
2660ccea Poul Sander 2023-09-22 19:25 20961
2660ccea Poul Sander 2023-09-22 19:25 20962
    @return a string representation of a the @a m_type member:
2660ccea Poul Sander 2023-09-22 19:25 20963
            Value type  | return value
2660ccea Poul Sander 2023-09-22 19:25 20964
            ----------- | -------------
2660ccea Poul Sander 2023-09-22 19:25 20965
            null        | `"null"`
2660ccea Poul Sander 2023-09-22 19:25 20966
            boolean     | `"boolean"`
2660ccea Poul Sander 2023-09-22 19:25 20967
            string      | `"string"`
2660ccea Poul Sander 2023-09-22 19:25 20968
            number      | `"number"` (for all number types)
2660ccea Poul Sander 2023-09-22 19:25 20969
            object      | `"object"`
2660ccea Poul Sander 2023-09-22 19:25 20970
            array       | `"array"`
2660ccea Poul Sander 2023-09-22 19:25 20971
            discarded   | `"discarded"`
2660ccea Poul Sander 2023-09-22 19:25 20972
2660ccea Poul Sander 2023-09-22 19:25 20973
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
2660ccea Poul Sander 2023-09-22 19:25 20974
2660ccea Poul Sander 2023-09-22 19:25 20975
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 20976
2660ccea Poul Sander 2023-09-22 19:25 20977
    @liveexample{The following code exemplifies `type_name()` for all JSON
2660ccea Poul Sander 2023-09-22 19:25 20978
    types.,type_name}
2660ccea Poul Sander 2023-09-22 19:25 20979
2660ccea Poul Sander 2023-09-22 19:25 20980
    @sa @ref type() -- return the type of the JSON value
2660ccea Poul Sander 2023-09-22 19:25 20981
    @sa @ref operator value_t() -- return the type of the JSON value (implicit)
2660ccea Poul Sander 2023-09-22 19:25 20982
2660ccea Poul Sander 2023-09-22 19:25 20983
    @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
2660ccea Poul Sander 2023-09-22 19:25 20984
    since 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 20985
    */
2660ccea Poul Sander 2023-09-22 19:25 20986
    JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 20987
    const char* type_name() const noexcept
2660ccea Poul Sander 2023-09-22 19:25 20988
    {
2660ccea Poul Sander 2023-09-22 19:25 20989
        {
2660ccea Poul Sander 2023-09-22 19:25 20990
            switch (m_type)
2660ccea Poul Sander 2023-09-22 19:25 20991
            {
2660ccea Poul Sander 2023-09-22 19:25 20992
                case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 20993
                    return "null";
2660ccea Poul Sander 2023-09-22 19:25 20994
                case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 20995
                    return "object";
2660ccea Poul Sander 2023-09-22 19:25 20996
                case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 20997
                    return "array";
2660ccea Poul Sander 2023-09-22 19:25 20998
                case value_t::string:
2660ccea Poul Sander 2023-09-22 19:25 20999
                    return "string";
2660ccea Poul Sander 2023-09-22 19:25 21000
                case value_t::boolean:
2660ccea Poul Sander 2023-09-22 19:25 21001
                    return "boolean";
2660ccea Poul Sander 2023-09-22 19:25 21002
                case value_t::discarded:
2660ccea Poul Sander 2023-09-22 19:25 21003
                    return "discarded";
2660ccea Poul Sander 2023-09-22 19:25 21004
                default:
2660ccea Poul Sander 2023-09-22 19:25 21005
                    return "number";
2660ccea Poul Sander 2023-09-22 19:25 21006
            }
2660ccea Poul Sander 2023-09-22 19:25 21007
        }
2660ccea Poul Sander 2023-09-22 19:25 21008
    }
2660ccea Poul Sander 2023-09-22 19:25 21009
2660ccea Poul Sander 2023-09-22 19:25 21010
2660ccea Poul Sander 2023-09-22 19:25 21011
  private:
2660ccea Poul Sander 2023-09-22 19:25 21012
    //////////////////////
2660ccea Poul Sander 2023-09-22 19:25 21013
    // member variables //
2660ccea Poul Sander 2023-09-22 19:25 21014
    //////////////////////
2660ccea Poul Sander 2023-09-22 19:25 21015
2660ccea Poul Sander 2023-09-22 19:25 21016
    /// the type of the current element
2660ccea Poul Sander 2023-09-22 19:25 21017
    value_t m_type = value_t::null;
2660ccea Poul Sander 2023-09-22 19:25 21018
2660ccea Poul Sander 2023-09-22 19:25 21019
    /// the value of the current element
2660ccea Poul Sander 2023-09-22 19:25 21020
    json_value m_value = {};
2660ccea Poul Sander 2023-09-22 19:25 21021
2660ccea Poul Sander 2023-09-22 19:25 21022
    //////////////////////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 21023
    // binary serialization/deserialization //
2660ccea Poul Sander 2023-09-22 19:25 21024
    //////////////////////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 21025
2660ccea Poul Sander 2023-09-22 19:25 21026
    /// @name binary serialization/deserialization support
2660ccea Poul Sander 2023-09-22 19:25 21027
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 21028
2660ccea Poul Sander 2023-09-22 19:25 21029
  public:
2660ccea Poul Sander 2023-09-22 19:25 21030
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21031
    @brief create a CBOR serialization of a given JSON value
2660ccea Poul Sander 2023-09-22 19:25 21032
2660ccea Poul Sander 2023-09-22 19:25 21033
    Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
2660ccea Poul Sander 2023-09-22 19:25 21034
    Binary Object Representation) serialization format. CBOR is a binary
2660ccea Poul Sander 2023-09-22 19:25 21035
    serialization format which aims to be more compact than JSON itself, yet
2660ccea Poul Sander 2023-09-22 19:25 21036
    more efficient to parse.
2660ccea Poul Sander 2023-09-22 19:25 21037
2660ccea Poul Sander 2023-09-22 19:25 21038
    The library uses the following mapping from JSON values types to
2660ccea Poul Sander 2023-09-22 19:25 21039
    CBOR types according to the CBOR specification (RFC 7049):
2660ccea Poul Sander 2023-09-22 19:25 21040
2660ccea Poul Sander 2023-09-22 19:25 21041
    JSON value type | value/range                                | CBOR type                          | first byte
2660ccea Poul Sander 2023-09-22 19:25 21042
    --------------- | ------------------------------------------ | ---------------------------------- | ---------------
2660ccea Poul Sander 2023-09-22 19:25 21043
    null            | `null`                                     | Null                               | 0xF6
2660ccea Poul Sander 2023-09-22 19:25 21044
    boolean         | `true`                                     | True                               | 0xF5
2660ccea Poul Sander 2023-09-22 19:25 21045
    boolean         | `false`                                    | False                              | 0xF4
2660ccea Poul Sander 2023-09-22 19:25 21046
    number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3B
2660ccea Poul Sander 2023-09-22 19:25 21047
    number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3A
2660ccea Poul Sander 2023-09-22 19:25 21048
    number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
2660ccea Poul Sander 2023-09-22 19:25 21049
    number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
2660ccea Poul Sander 2023-09-22 19:25 21050
    number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
2660ccea Poul Sander 2023-09-22 19:25 21051
    number_integer  | 0..23                                      | Integer                            | 0x00..0x17
2660ccea Poul Sander 2023-09-22 19:25 21052
    number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
2660ccea Poul Sander 2023-09-22 19:25 21053
    number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
2660ccea Poul Sander 2023-09-22 19:25 21054
    number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
2660ccea Poul Sander 2023-09-22 19:25 21055
    number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
2660ccea Poul Sander 2023-09-22 19:25 21056
    number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
2660ccea Poul Sander 2023-09-22 19:25 21057
    number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
2660ccea Poul Sander 2023-09-22 19:25 21058
    number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
2660ccea Poul Sander 2023-09-22 19:25 21059
    number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
2660ccea Poul Sander 2023-09-22 19:25 21060
    number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
2660ccea Poul Sander 2023-09-22 19:25 21061
    number_float    | *any value*                                | Double-Precision Float             | 0xFB
2660ccea Poul Sander 2023-09-22 19:25 21062
    string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
2660ccea Poul Sander 2023-09-22 19:25 21063
    string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
2660ccea Poul Sander 2023-09-22 19:25 21064
    string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
2660ccea Poul Sander 2023-09-22 19:25 21065
    string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7A
2660ccea Poul Sander 2023-09-22 19:25 21066
    string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7B
2660ccea Poul Sander 2023-09-22 19:25 21067
    array           | *size*: 0..23                              | array                              | 0x80..0x97
2660ccea Poul Sander 2023-09-22 19:25 21068
    array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
2660ccea Poul Sander 2023-09-22 19:25 21069
    array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
2660ccea Poul Sander 2023-09-22 19:25 21070
    array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9A
2660ccea Poul Sander 2023-09-22 19:25 21071
    array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9B
2660ccea Poul Sander 2023-09-22 19:25 21072
    object          | *size*: 0..23                              | map                                | 0xA0..0xB7
2660ccea Poul Sander 2023-09-22 19:25 21073
    object          | *size*: 23..255                            | map (1 byte follow)                | 0xB8
2660ccea Poul Sander 2023-09-22 19:25 21074
    object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xB9
2660ccea Poul Sander 2023-09-22 19:25 21075
    object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xBA
2660ccea Poul Sander 2023-09-22 19:25 21076
    object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xBB
2660ccea Poul Sander 2023-09-22 19:25 21077
2660ccea Poul Sander 2023-09-22 19:25 21078
    @note The mapping is **complete** in the sense that any JSON value type
2660ccea Poul Sander 2023-09-22 19:25 21079
          can be converted to a CBOR value.
2660ccea Poul Sander 2023-09-22 19:25 21080
2660ccea Poul Sander 2023-09-22 19:25 21081
    @note If NaN or Infinity are stored inside a JSON number, they are
2660ccea Poul Sander 2023-09-22 19:25 21082
          serialized properly. This behavior differs from the @ref dump()
2660ccea Poul Sander 2023-09-22 19:25 21083
          function which serializes NaN or Infinity to `null`.
2660ccea Poul Sander 2023-09-22 19:25 21084
2660ccea Poul Sander 2023-09-22 19:25 21085
    @note The following CBOR types are not used in the conversion:
2660ccea Poul Sander 2023-09-22 19:25 21086
          - byte strings (0x40..0x5F)
2660ccea Poul Sander 2023-09-22 19:25 21087
          - UTF-8 strings terminated by "break" (0x7F)
2660ccea Poul Sander 2023-09-22 19:25 21088
          - arrays terminated by "break" (0x9F)
2660ccea Poul Sander 2023-09-22 19:25 21089
          - maps terminated by "break" (0xBF)
2660ccea Poul Sander 2023-09-22 19:25 21090
          - date/time (0xC0..0xC1)
2660ccea Poul Sander 2023-09-22 19:25 21091
          - bignum (0xC2..0xC3)
2660ccea Poul Sander 2023-09-22 19:25 21092
          - decimal fraction (0xC4)
2660ccea Poul Sander 2023-09-22 19:25 21093
          - bigfloat (0xC5)
2660ccea Poul Sander 2023-09-22 19:25 21094
          - tagged items (0xC6..0xD4, 0xD8..0xDB)
2660ccea Poul Sander 2023-09-22 19:25 21095
          - expected conversions (0xD5..0xD7)
2660ccea Poul Sander 2023-09-22 19:25 21096
          - simple values (0xE0..0xF3, 0xF8)
2660ccea Poul Sander 2023-09-22 19:25 21097
          - undefined (0xF7)
2660ccea Poul Sander 2023-09-22 19:25 21098
          - half and single-precision floats (0xF9-0xFA)
2660ccea Poul Sander 2023-09-22 19:25 21099
          - break (0xFF)
2660ccea Poul Sander 2023-09-22 19:25 21100
2660ccea Poul Sander 2023-09-22 19:25 21101
    @param[in] j  JSON value to serialize
2660ccea Poul Sander 2023-09-22 19:25 21102
    @return MessagePack serialization as byte vector
2660ccea Poul Sander 2023-09-22 19:25 21103
2660ccea Poul Sander 2023-09-22 19:25 21104
    @complexity Linear in the size of the JSON value @a j.
2660ccea Poul Sander 2023-09-22 19:25 21105
2660ccea Poul Sander 2023-09-22 19:25 21106
    @liveexample{The example shows the serialization of a JSON value to a byte
2660ccea Poul Sander 2023-09-22 19:25 21107
    vector in CBOR format.,to_cbor}
2660ccea Poul Sander 2023-09-22 19:25 21108
2660ccea Poul Sander 2023-09-22 19:25 21109
    @sa http://cbor.io
2660ccea Poul Sander 2023-09-22 19:25 21110
    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21111
        analogous deserialization
2660ccea Poul Sander 2023-09-22 19:25 21112
    @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
2660ccea Poul Sander 2023-09-22 19:25 21113
    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21114
             related UBJSON format
2660ccea Poul Sander 2023-09-22 19:25 21115
2660ccea Poul Sander 2023-09-22 19:25 21116
    @since version 2.0.9
2660ccea Poul Sander 2023-09-22 19:25 21117
    */
2660ccea Poul Sander 2023-09-22 19:25 21118
    static std::vector<uint8_t> to_cbor(const basic_json& j)
2660ccea Poul Sander 2023-09-22 19:25 21119
    {
2660ccea Poul Sander 2023-09-22 19:25 21120
        std::vector<uint8_t> result;
2660ccea Poul Sander 2023-09-22 19:25 21121
        to_cbor(j, result);
2660ccea Poul Sander 2023-09-22 19:25 21122
        return result;
2660ccea Poul Sander 2023-09-22 19:25 21123
    }
2660ccea Poul Sander 2023-09-22 19:25 21124
2660ccea Poul Sander 2023-09-22 19:25 21125
    static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
2660ccea Poul Sander 2023-09-22 19:25 21126
    {
2660ccea Poul Sander 2023-09-22 19:25 21127
        binary_writer<uint8_t>(o).write_cbor(j);
2660ccea Poul Sander 2023-09-22 19:25 21128
    }
2660ccea Poul Sander 2023-09-22 19:25 21129
2660ccea Poul Sander 2023-09-22 19:25 21130
    static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
2660ccea Poul Sander 2023-09-22 19:25 21131
    {
2660ccea Poul Sander 2023-09-22 19:25 21132
        binary_writer<char>(o).write_cbor(j);
2660ccea Poul Sander 2023-09-22 19:25 21133
    }
2660ccea Poul Sander 2023-09-22 19:25 21134
2660ccea Poul Sander 2023-09-22 19:25 21135
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21136
    @brief create a MessagePack serialization of a given JSON value
2660ccea Poul Sander 2023-09-22 19:25 21137
2660ccea Poul Sander 2023-09-22 19:25 21138
    Serializes a given JSON value @a j to a byte vector using the MessagePack
2660ccea Poul Sander 2023-09-22 19:25 21139
    serialization format. MessagePack is a binary serialization format which
2660ccea Poul Sander 2023-09-22 19:25 21140
    aims to be more compact than JSON itself, yet more efficient to parse.
2660ccea Poul Sander 2023-09-22 19:25 21141
2660ccea Poul Sander 2023-09-22 19:25 21142
    The library uses the following mapping from JSON values types to
2660ccea Poul Sander 2023-09-22 19:25 21143
    MessagePack types according to the MessagePack specification:
2660ccea Poul Sander 2023-09-22 19:25 21144
2660ccea Poul Sander 2023-09-22 19:25 21145
    JSON value type | value/range                       | MessagePack type | first byte
2660ccea Poul Sander 2023-09-22 19:25 21146
    --------------- | --------------------------------- | ---------------- | ----------
2660ccea Poul Sander 2023-09-22 19:25 21147
    null            | `null`                            | nil              | 0xC0
2660ccea Poul Sander 2023-09-22 19:25 21148
    boolean         | `true`                            | true             | 0xC3
2660ccea Poul Sander 2023-09-22 19:25 21149
    boolean         | `false`                           | false            | 0xC2
2660ccea Poul Sander 2023-09-22 19:25 21150
    number_integer  | -9223372036854775808..-2147483649 | int64            | 0xD3
2660ccea Poul Sander 2023-09-22 19:25 21151
    number_integer  | -2147483648..-32769               | int32            | 0xD2
2660ccea Poul Sander 2023-09-22 19:25 21152
    number_integer  | -32768..-129                      | int16            | 0xD1
2660ccea Poul Sander 2023-09-22 19:25 21153
    number_integer  | -128..-33                         | int8             | 0xD0
2660ccea Poul Sander 2023-09-22 19:25 21154
    number_integer  | -32..-1                           | negative fixint  | 0xE0..0xFF
2660ccea Poul Sander 2023-09-22 19:25 21155
    number_integer  | 0..127                            | positive fixint  | 0x00..0x7F
2660ccea Poul Sander 2023-09-22 19:25 21156
    number_integer  | 128..255                          | uint 8           | 0xCC
2660ccea Poul Sander 2023-09-22 19:25 21157
    number_integer  | 256..65535                        | uint 16          | 0xCD
2660ccea Poul Sander 2023-09-22 19:25 21158
    number_integer  | 65536..4294967295                 | uint 32          | 0xCE
2660ccea Poul Sander 2023-09-22 19:25 21159
    number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xCF
2660ccea Poul Sander 2023-09-22 19:25 21160
    number_unsigned | 0..127                            | positive fixint  | 0x00..0x7F
2660ccea Poul Sander 2023-09-22 19:25 21161
    number_unsigned | 128..255                          | uint 8           | 0xCC
2660ccea Poul Sander 2023-09-22 19:25 21162
    number_unsigned | 256..65535                        | uint 16          | 0xCD
2660ccea Poul Sander 2023-09-22 19:25 21163
    number_unsigned | 65536..4294967295                 | uint 32          | 0xCE
2660ccea Poul Sander 2023-09-22 19:25 21164
    number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xCF
2660ccea Poul Sander 2023-09-22 19:25 21165
    number_float    | *any value*                       | float 64         | 0xCB
2660ccea Poul Sander 2023-09-22 19:25 21166
    string          | *length*: 0..31                   | fixstr           | 0xA0..0xBF
2660ccea Poul Sander 2023-09-22 19:25 21167
    string          | *length*: 32..255                 | str 8            | 0xD9
2660ccea Poul Sander 2023-09-22 19:25 21168
    string          | *length*: 256..65535              | str 16           | 0xDA
2660ccea Poul Sander 2023-09-22 19:25 21169
    string          | *length*: 65536..4294967295       | str 32           | 0xDB
2660ccea Poul Sander 2023-09-22 19:25 21170
    array           | *size*: 0..15                     | fixarray         | 0x90..0x9F
2660ccea Poul Sander 2023-09-22 19:25 21171
    array           | *size*: 16..65535                 | array 16         | 0xDC
2660ccea Poul Sander 2023-09-22 19:25 21172
    array           | *size*: 65536..4294967295         | array 32         | 0xDD
2660ccea Poul Sander 2023-09-22 19:25 21173
    object          | *size*: 0..15                     | fix map          | 0x80..0x8F
2660ccea Poul Sander 2023-09-22 19:25 21174
    object          | *size*: 16..65535                 | map 16           | 0xDE
2660ccea Poul Sander 2023-09-22 19:25 21175
    object          | *size*: 65536..4294967295         | map 32           | 0xDF
2660ccea Poul Sander 2023-09-22 19:25 21176
2660ccea Poul Sander 2023-09-22 19:25 21177
    @note The mapping is **complete** in the sense that any JSON value type
2660ccea Poul Sander 2023-09-22 19:25 21178
          can be converted to a MessagePack value.
2660ccea Poul Sander 2023-09-22 19:25 21179
2660ccea Poul Sander 2023-09-22 19:25 21180
    @note The following values can **not** be converted to a MessagePack value:
2660ccea Poul Sander 2023-09-22 19:25 21181
          - strings with more than 4294967295 bytes
2660ccea Poul Sander 2023-09-22 19:25 21182
          - arrays with more than 4294967295 elements
2660ccea Poul Sander 2023-09-22 19:25 21183
          - objects with more than 4294967295 elements
2660ccea Poul Sander 2023-09-22 19:25 21184
2660ccea Poul Sander 2023-09-22 19:25 21185
    @note The following MessagePack types are not used in the conversion:
2660ccea Poul Sander 2023-09-22 19:25 21186
          - bin 8 - bin 32 (0xC4..0xC6)
2660ccea Poul Sander 2023-09-22 19:25 21187
          - ext 8 - ext 32 (0xC7..0xC9)
2660ccea Poul Sander 2023-09-22 19:25 21188
          - float 32 (0xCA)
2660ccea Poul Sander 2023-09-22 19:25 21189
          - fixext 1 - fixext 16 (0xD4..0xD8)
2660ccea Poul Sander 2023-09-22 19:25 21190
2660ccea Poul Sander 2023-09-22 19:25 21191
    @note Any MessagePack output created @ref to_msgpack can be successfully
2660ccea Poul Sander 2023-09-22 19:25 21192
          parsed by @ref from_msgpack.
2660ccea Poul Sander 2023-09-22 19:25 21193
2660ccea Poul Sander 2023-09-22 19:25 21194
    @note If NaN or Infinity are stored inside a JSON number, they are
2660ccea Poul Sander 2023-09-22 19:25 21195
          serialized properly. This behavior differs from the @ref dump()
2660ccea Poul Sander 2023-09-22 19:25 21196
          function which serializes NaN or Infinity to `null`.
2660ccea Poul Sander 2023-09-22 19:25 21197
2660ccea Poul Sander 2023-09-22 19:25 21198
    @param[in] j  JSON value to serialize
2660ccea Poul Sander 2023-09-22 19:25 21199
    @return MessagePack serialization as byte vector
2660ccea Poul Sander 2023-09-22 19:25 21200
2660ccea Poul Sander 2023-09-22 19:25 21201
    @complexity Linear in the size of the JSON value @a j.
2660ccea Poul Sander 2023-09-22 19:25 21202
2660ccea Poul Sander 2023-09-22 19:25 21203
    @liveexample{The example shows the serialization of a JSON value to a byte
2660ccea Poul Sander 2023-09-22 19:25 21204
    vector in MessagePack format.,to_msgpack}
2660ccea Poul Sander 2023-09-22 19:25 21205
2660ccea Poul Sander 2023-09-22 19:25 21206
    @sa http://msgpack.org
2660ccea Poul Sander 2023-09-22 19:25 21207
    @sa @ref from_msgpack for the analogous deserialization
2660ccea Poul Sander 2023-09-22 19:25 21208
    @sa @ref to_cbor(const basic_json& for the related CBOR format
2660ccea Poul Sander 2023-09-22 19:25 21209
    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21210
             related UBJSON format
2660ccea Poul Sander 2023-09-22 19:25 21211
2660ccea Poul Sander 2023-09-22 19:25 21212
    @since version 2.0.9
2660ccea Poul Sander 2023-09-22 19:25 21213
    */
2660ccea Poul Sander 2023-09-22 19:25 21214
    static std::vector<uint8_t> to_msgpack(const basic_json& j)
2660ccea Poul Sander 2023-09-22 19:25 21215
    {
2660ccea Poul Sander 2023-09-22 19:25 21216
        std::vector<uint8_t> result;
2660ccea Poul Sander 2023-09-22 19:25 21217
        to_msgpack(j, result);
2660ccea Poul Sander 2023-09-22 19:25 21218
        return result;
2660ccea Poul Sander 2023-09-22 19:25 21219
    }
2660ccea Poul Sander 2023-09-22 19:25 21220
2660ccea Poul Sander 2023-09-22 19:25 21221
    static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
2660ccea Poul Sander 2023-09-22 19:25 21222
    {
2660ccea Poul Sander 2023-09-22 19:25 21223
        binary_writer<uint8_t>(o).write_msgpack(j);
2660ccea Poul Sander 2023-09-22 19:25 21224
    }
2660ccea Poul Sander 2023-09-22 19:25 21225
2660ccea Poul Sander 2023-09-22 19:25 21226
    static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
2660ccea Poul Sander 2023-09-22 19:25 21227
    {
2660ccea Poul Sander 2023-09-22 19:25 21228
        binary_writer<char>(o).write_msgpack(j);
2660ccea Poul Sander 2023-09-22 19:25 21229
    }
2660ccea Poul Sander 2023-09-22 19:25 21230
2660ccea Poul Sander 2023-09-22 19:25 21231
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21232
    @brief create a UBJSON serialization of a given JSON value
2660ccea Poul Sander 2023-09-22 19:25 21233
2660ccea Poul Sander 2023-09-22 19:25 21234
    Serializes a given JSON value @a j to a byte vector using the UBJSON
2660ccea Poul Sander 2023-09-22 19:25 21235
    (Universal Binary JSON) serialization format. UBJSON aims to be more compact
2660ccea Poul Sander 2023-09-22 19:25 21236
    than JSON itself, yet more efficient to parse.
2660ccea Poul Sander 2023-09-22 19:25 21237
2660ccea Poul Sander 2023-09-22 19:25 21238
    The library uses the following mapping from JSON values types to
2660ccea Poul Sander 2023-09-22 19:25 21239
    UBJSON types according to the UBJSON specification:
2660ccea Poul Sander 2023-09-22 19:25 21240
2660ccea Poul Sander 2023-09-22 19:25 21241
    JSON value type | value/range                       | UBJSON type | marker
2660ccea Poul Sander 2023-09-22 19:25 21242
    --------------- | --------------------------------- | ----------- | ------
2660ccea Poul Sander 2023-09-22 19:25 21243
    null            | `null`                            | null        | `Z`
2660ccea Poul Sander 2023-09-22 19:25 21244
    boolean         | `true`                            | true        | `T`
2660ccea Poul Sander 2023-09-22 19:25 21245
    boolean         | `false`                           | false       | `F`
2660ccea Poul Sander 2023-09-22 19:25 21246
    number_integer  | -9223372036854775808..-2147483649 | int64       | `L`
2660ccea Poul Sander 2023-09-22 19:25 21247
    number_integer  | -2147483648..-32769               | int32       | `l`
2660ccea Poul Sander 2023-09-22 19:25 21248
    number_integer  | -32768..-129                      | int16       | `I`
2660ccea Poul Sander 2023-09-22 19:25 21249
    number_integer  | -128..127                         | int8        | `i`
2660ccea Poul Sander 2023-09-22 19:25 21250
    number_integer  | 128..255                          | uint8       | `U`
2660ccea Poul Sander 2023-09-22 19:25 21251
    number_integer  | 256..32767                        | int16       | `I`
2660ccea Poul Sander 2023-09-22 19:25 21252
    number_integer  | 32768..2147483647                 | int32       | `l`
2660ccea Poul Sander 2023-09-22 19:25 21253
    number_integer  | 2147483648..9223372036854775807   | int64       | `L`
2660ccea Poul Sander 2023-09-22 19:25 21254
    number_unsigned | 0..127                            | int8        | `i`
2660ccea Poul Sander 2023-09-22 19:25 21255
    number_unsigned | 128..255                          | uint8       | `U`
2660ccea Poul Sander 2023-09-22 19:25 21256
    number_unsigned | 256..32767                        | int16       | `I`
2660ccea Poul Sander 2023-09-22 19:25 21257
    number_unsigned | 32768..2147483647                 | int32       | `l`
2660ccea Poul Sander 2023-09-22 19:25 21258
    number_unsigned | 2147483648..9223372036854775807   | int64       | `L`
2660ccea Poul Sander 2023-09-22 19:25 21259
    number_float    | *any value*                       | float64     | `D`
2660ccea Poul Sander 2023-09-22 19:25 21260
    string          | *with shortest length indicator*  | string      | `S`
2660ccea Poul Sander 2023-09-22 19:25 21261
    array           | *see notes on optimized format*   | array       | `[`
2660ccea Poul Sander 2023-09-22 19:25 21262
    object          | *see notes on optimized format*   | map         | `{`
2660ccea Poul Sander 2023-09-22 19:25 21263
2660ccea Poul Sander 2023-09-22 19:25 21264
    @note The mapping is **complete** in the sense that any JSON value type
2660ccea Poul Sander 2023-09-22 19:25 21265
          can be converted to a UBJSON value.
2660ccea Poul Sander 2023-09-22 19:25 21266
2660ccea Poul Sander 2023-09-22 19:25 21267
    @note The following values can **not** be converted to a UBJSON value:
2660ccea Poul Sander 2023-09-22 19:25 21268
          - strings with more than 9223372036854775807 bytes (theoretical)
2660ccea Poul Sander 2023-09-22 19:25 21269
          - unsigned integer numbers above 9223372036854775807
2660ccea Poul Sander 2023-09-22 19:25 21270
2660ccea Poul Sander 2023-09-22 19:25 21271
    @note The following markers are not used in the conversion:
2660ccea Poul Sander 2023-09-22 19:25 21272
          - `Z`: no-op values are not created.
2660ccea Poul Sander 2023-09-22 19:25 21273
          - `C`: single-byte strings are serialized with `S` markers.
2660ccea Poul Sander 2023-09-22 19:25 21274
2660ccea Poul Sander 2023-09-22 19:25 21275
    @note Any UBJSON output created @ref to_ubjson can be successfully parsed
2660ccea Poul Sander 2023-09-22 19:25 21276
          by @ref from_ubjson.
2660ccea Poul Sander 2023-09-22 19:25 21277
2660ccea Poul Sander 2023-09-22 19:25 21278
    @note If NaN or Infinity are stored inside a JSON number, they are
2660ccea Poul Sander 2023-09-22 19:25 21279
          serialized properly. This behavior differs from the @ref dump()
2660ccea Poul Sander 2023-09-22 19:25 21280
          function which serializes NaN or Infinity to `null`.
2660ccea Poul Sander 2023-09-22 19:25 21281
2660ccea Poul Sander 2023-09-22 19:25 21282
    @note The optimized formats for containers are supported: Parameter
2660ccea Poul Sander 2023-09-22 19:25 21283
          @a use_size adds size information to the beginning of a container and
2660ccea Poul Sander 2023-09-22 19:25 21284
          removes the closing marker. Parameter @a use_type further checks
2660ccea Poul Sander 2023-09-22 19:25 21285
          whether all elements of a container have the same type and adds the
2660ccea Poul Sander 2023-09-22 19:25 21286
          type marker to the beginning of the container. The @a use_type
2660ccea Poul Sander 2023-09-22 19:25 21287
          parameter must only be used together with @a use_size = true. Note
2660ccea Poul Sander 2023-09-22 19:25 21288
          that @a use_size = true alone may result in larger representations -
2660ccea Poul Sander 2023-09-22 19:25 21289
          the benefit of this parameter is that the receiving side is
2660ccea Poul Sander 2023-09-22 19:25 21290
          immediately informed on the number of elements of the container.
2660ccea Poul Sander 2023-09-22 19:25 21291
2660ccea Poul Sander 2023-09-22 19:25 21292
    @param[in] j  JSON value to serialize
2660ccea Poul Sander 2023-09-22 19:25 21293
    @param[in] use_size  whether to add size annotations to container types
2660ccea Poul Sander 2023-09-22 19:25 21294
    @param[in] use_type  whether to add type annotations to container types
2660ccea Poul Sander 2023-09-22 19:25 21295
                         (must be combined with @a use_size = true)
2660ccea Poul Sander 2023-09-22 19:25 21296
    @return UBJSON serialization as byte vector
2660ccea Poul Sander 2023-09-22 19:25 21297
2660ccea Poul Sander 2023-09-22 19:25 21298
    @complexity Linear in the size of the JSON value @a j.
2660ccea Poul Sander 2023-09-22 19:25 21299
2660ccea Poul Sander 2023-09-22 19:25 21300
    @liveexample{The example shows the serialization of a JSON value to a byte
2660ccea Poul Sander 2023-09-22 19:25 21301
    vector in UBJSON format.,to_ubjson}
2660ccea Poul Sander 2023-09-22 19:25 21302
2660ccea Poul Sander 2023-09-22 19:25 21303
    @sa http://ubjson.org
2660ccea Poul Sander 2023-09-22 19:25 21304
    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21305
        analogous deserialization
2660ccea Poul Sander 2023-09-22 19:25 21306
    @sa @ref to_cbor(const basic_json& for the related CBOR format
2660ccea Poul Sander 2023-09-22 19:25 21307
    @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
2660ccea Poul Sander 2023-09-22 19:25 21308
2660ccea Poul Sander 2023-09-22 19:25 21309
    @since version 3.1.0
2660ccea Poul Sander 2023-09-22 19:25 21310
    */
2660ccea Poul Sander 2023-09-22 19:25 21311
    static std::vector<uint8_t> to_ubjson(const basic_json& j,
2660ccea Poul Sander 2023-09-22 19:25 21312
                                          const bool use_size = false,
2660ccea Poul Sander 2023-09-22 19:25 21313
                                          const bool use_type = false)
2660ccea Poul Sander 2023-09-22 19:25 21314
    {
2660ccea Poul Sander 2023-09-22 19:25 21315
        std::vector<uint8_t> result;
2660ccea Poul Sander 2023-09-22 19:25 21316
        to_ubjson(j, result, use_size, use_type);
2660ccea Poul Sander 2023-09-22 19:25 21317
        return result;
2660ccea Poul Sander 2023-09-22 19:25 21318
    }
2660ccea Poul Sander 2023-09-22 19:25 21319
2660ccea Poul Sander 2023-09-22 19:25 21320
    static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
2660ccea Poul Sander 2023-09-22 19:25 21321
                          const bool use_size = false, const bool use_type = false)
2660ccea Poul Sander 2023-09-22 19:25 21322
    {
2660ccea Poul Sander 2023-09-22 19:25 21323
        binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
2660ccea Poul Sander 2023-09-22 19:25 21324
    }
2660ccea Poul Sander 2023-09-22 19:25 21325
2660ccea Poul Sander 2023-09-22 19:25 21326
    static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
2660ccea Poul Sander 2023-09-22 19:25 21327
                          const bool use_size = false, const bool use_type = false)
2660ccea Poul Sander 2023-09-22 19:25 21328
    {
2660ccea Poul Sander 2023-09-22 19:25 21329
        binary_writer<char>(o).write_ubjson(j, use_size, use_type);
2660ccea Poul Sander 2023-09-22 19:25 21330
    }
2660ccea Poul Sander 2023-09-22 19:25 21331
2660ccea Poul Sander 2023-09-22 19:25 21332
2660ccea Poul Sander 2023-09-22 19:25 21333
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21334
    @brief Serializes the given JSON object `j` to BSON and returns a vector
2660ccea Poul Sander 2023-09-22 19:25 21335
           containing the corresponding BSON-representation.
2660ccea Poul Sander 2023-09-22 19:25 21336
2660ccea Poul Sander 2023-09-22 19:25 21337
    BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
2660ccea Poul Sander 2023-09-22 19:25 21338
    stored as a single entity (a so-called document).
2660ccea Poul Sander 2023-09-22 19:25 21339
2660ccea Poul Sander 2023-09-22 19:25 21340
    The library uses the following mapping from JSON values types to BSON types:
2660ccea Poul Sander 2023-09-22 19:25 21341
2660ccea Poul Sander 2023-09-22 19:25 21342
    JSON value type | value/range                       | BSON type   | marker
2660ccea Poul Sander 2023-09-22 19:25 21343
    --------------- | --------------------------------- | ----------- | ------
2660ccea Poul Sander 2023-09-22 19:25 21344
    null            | `null`                            | null        | 0x0A
2660ccea Poul Sander 2023-09-22 19:25 21345
    boolean         | `true`, `false`                   | boolean     | 0x08
2660ccea Poul Sander 2023-09-22 19:25 21346
    number_integer  | -9223372036854775808..-2147483649 | int64       | 0x12
2660ccea Poul Sander 2023-09-22 19:25 21347
    number_integer  | -2147483648..2147483647           | int32       | 0x10
2660ccea Poul Sander 2023-09-22 19:25 21348
    number_integer  | 2147483648..9223372036854775807   | int64       | 0x12
2660ccea Poul Sander 2023-09-22 19:25 21349
    number_unsigned | 0..2147483647                     | int32       | 0x10
2660ccea Poul Sander 2023-09-22 19:25 21350
    number_unsigned | 2147483648..9223372036854775807   | int64       | 0x12
2660ccea Poul Sander 2023-09-22 19:25 21351
    number_unsigned | 9223372036854775808..18446744073709551615| --   | --
2660ccea Poul Sander 2023-09-22 19:25 21352
    number_float    | *any value*                       | double      | 0x01
2660ccea Poul Sander 2023-09-22 19:25 21353
    string          | *any value*                       | string      | 0x02
2660ccea Poul Sander 2023-09-22 19:25 21354
    array           | *any value*                       | document    | 0x04
2660ccea Poul Sander 2023-09-22 19:25 21355
    object          | *any value*                       | document    | 0x03
2660ccea Poul Sander 2023-09-22 19:25 21356
2660ccea Poul Sander 2023-09-22 19:25 21357
    @warning The mapping is **incomplete**, since only JSON-objects (and things
2660ccea Poul Sander 2023-09-22 19:25 21358
    contained therein) can be serialized to BSON.
2660ccea Poul Sander 2023-09-22 19:25 21359
    Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
2660ccea Poul Sander 2023-09-22 19:25 21360
    and the keys may not contain U+0000, since they are serialized a
2660ccea Poul Sander 2023-09-22 19:25 21361
    zero-terminated c-strings.
2660ccea Poul Sander 2023-09-22 19:25 21362
2660ccea Poul Sander 2023-09-22 19:25 21363
    @throw out_of_range.407  if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
2660ccea Poul Sander 2023-09-22 19:25 21364
    @throw out_of_range.409  if a key in `j` contains a NULL (U+0000)
2660ccea Poul Sander 2023-09-22 19:25 21365
    @throw type_error.317    if `!j.is_object()`
2660ccea Poul Sander 2023-09-22 19:25 21366
2660ccea Poul Sander 2023-09-22 19:25 21367
    @pre The input `j` is required to be an object: `j.is_object() == true`.
2660ccea Poul Sander 2023-09-22 19:25 21368
2660ccea Poul Sander 2023-09-22 19:25 21369
    @note Any BSON output created via @ref to_bson can be successfully parsed
2660ccea Poul Sander 2023-09-22 19:25 21370
          by @ref from_bson.
2660ccea Poul Sander 2023-09-22 19:25 21371
2660ccea Poul Sander 2023-09-22 19:25 21372
    @param[in] j  JSON value to serialize
2660ccea Poul Sander 2023-09-22 19:25 21373
    @return BSON serialization as byte vector
2660ccea Poul Sander 2023-09-22 19:25 21374
2660ccea Poul Sander 2023-09-22 19:25 21375
    @complexity Linear in the size of the JSON value @a j.
2660ccea Poul Sander 2023-09-22 19:25 21376
2660ccea Poul Sander 2023-09-22 19:25 21377
    @liveexample{The example shows the serialization of a JSON value to a byte
2660ccea Poul Sander 2023-09-22 19:25 21378
    vector in BSON format.,to_bson}
2660ccea Poul Sander 2023-09-22 19:25 21379
2660ccea Poul Sander 2023-09-22 19:25 21380
    @sa http://bsonspec.org/spec.html
2660ccea Poul Sander 2023-09-22 19:25 21381
    @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
2660ccea Poul Sander 2023-09-22 19:25 21382
        analogous deserialization
2660ccea Poul Sander 2023-09-22 19:25 21383
    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21384
             related UBJSON format
2660ccea Poul Sander 2023-09-22 19:25 21385
    @sa @ref to_cbor(const basic_json&) for the related CBOR format
2660ccea Poul Sander 2023-09-22 19:25 21386
    @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
2660ccea Poul Sander 2023-09-22 19:25 21387
    */
2660ccea Poul Sander 2023-09-22 19:25 21388
    static std::vector<uint8_t> to_bson(const basic_json& j)
2660ccea Poul Sander 2023-09-22 19:25 21389
    {
2660ccea Poul Sander 2023-09-22 19:25 21390
        std::vector<uint8_t> result;
2660ccea Poul Sander 2023-09-22 19:25 21391
        to_bson(j, result);
2660ccea Poul Sander 2023-09-22 19:25 21392
        return result;
2660ccea Poul Sander 2023-09-22 19:25 21393
    }
2660ccea Poul Sander 2023-09-22 19:25 21394
2660ccea Poul Sander 2023-09-22 19:25 21395
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21396
    @brief Serializes the given JSON object `j` to BSON and forwards the
2660ccea Poul Sander 2023-09-22 19:25 21397
           corresponding BSON-representation to the given output_adapter `o`.
2660ccea Poul Sander 2023-09-22 19:25 21398
    @param j The JSON object to convert to BSON.
2660ccea Poul Sander 2023-09-22 19:25 21399
    @param o The output adapter that receives the binary BSON representation.
2660ccea Poul Sander 2023-09-22 19:25 21400
    @pre The input `j` shall be an object: `j.is_object() == true`
2660ccea Poul Sander 2023-09-22 19:25 21401
    @sa @ref to_bson(const basic_json&)
2660ccea Poul Sander 2023-09-22 19:25 21402
    */
2660ccea Poul Sander 2023-09-22 19:25 21403
    static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
2660ccea Poul Sander 2023-09-22 19:25 21404
    {
2660ccea Poul Sander 2023-09-22 19:25 21405
        binary_writer<uint8_t>(o).write_bson(j);
2660ccea Poul Sander 2023-09-22 19:25 21406
    }
2660ccea Poul Sander 2023-09-22 19:25 21407
2660ccea Poul Sander 2023-09-22 19:25 21408
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21409
    @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
2660ccea Poul Sander 2023-09-22 19:25 21410
    */
2660ccea Poul Sander 2023-09-22 19:25 21411
    static void to_bson(const basic_json& j, detail::output_adapter<char> o)
2660ccea Poul Sander 2023-09-22 19:25 21412
    {
2660ccea Poul Sander 2023-09-22 19:25 21413
        binary_writer<char>(o).write_bson(j);
2660ccea Poul Sander 2023-09-22 19:25 21414
    }
2660ccea Poul Sander 2023-09-22 19:25 21415
2660ccea Poul Sander 2023-09-22 19:25 21416
2660ccea Poul Sander 2023-09-22 19:25 21417
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21418
    @brief create a JSON value from an input in CBOR format
2660ccea Poul Sander 2023-09-22 19:25 21419
2660ccea Poul Sander 2023-09-22 19:25 21420
    Deserializes a given input @a i to a JSON value using the CBOR (Concise
2660ccea Poul Sander 2023-09-22 19:25 21421
    Binary Object Representation) serialization format.
2660ccea Poul Sander 2023-09-22 19:25 21422
2660ccea Poul Sander 2023-09-22 19:25 21423
    The library maps CBOR types to JSON value types as follows:
2660ccea Poul Sander 2023-09-22 19:25 21424
2660ccea Poul Sander 2023-09-22 19:25 21425
    CBOR type              | JSON value type | first byte
2660ccea Poul Sander 2023-09-22 19:25 21426
    ---------------------- | --------------- | ----------
2660ccea Poul Sander 2023-09-22 19:25 21427
    Integer                | number_unsigned | 0x00..0x17
2660ccea Poul Sander 2023-09-22 19:25 21428
    Unsigned integer       | number_unsigned | 0x18
2660ccea Poul Sander 2023-09-22 19:25 21429
    Unsigned integer       | number_unsigned | 0x19
2660ccea Poul Sander 2023-09-22 19:25 21430
    Unsigned integer       | number_unsigned | 0x1A
2660ccea Poul Sander 2023-09-22 19:25 21431
    Unsigned integer       | number_unsigned | 0x1B
2660ccea Poul Sander 2023-09-22 19:25 21432
    Negative integer       | number_integer  | 0x20..0x37
2660ccea Poul Sander 2023-09-22 19:25 21433
    Negative integer       | number_integer  | 0x38
2660ccea Poul Sander 2023-09-22 19:25 21434
    Negative integer       | number_integer  | 0x39
2660ccea Poul Sander 2023-09-22 19:25 21435
    Negative integer       | number_integer  | 0x3A
2660ccea Poul Sander 2023-09-22 19:25 21436
    Negative integer       | number_integer  | 0x3B
2660ccea Poul Sander 2023-09-22 19:25 21437
    Negative integer       | number_integer  | 0x40..0x57
2660ccea Poul Sander 2023-09-22 19:25 21438
    UTF-8 string           | string          | 0x60..0x77
2660ccea Poul Sander 2023-09-22 19:25 21439
    UTF-8 string           | string          | 0x78
2660ccea Poul Sander 2023-09-22 19:25 21440
    UTF-8 string           | string          | 0x79
2660ccea Poul Sander 2023-09-22 19:25 21441
    UTF-8 string           | string          | 0x7A
2660ccea Poul Sander 2023-09-22 19:25 21442
    UTF-8 string           | string          | 0x7B
2660ccea Poul Sander 2023-09-22 19:25 21443
    UTF-8 string           | string          | 0x7F
2660ccea Poul Sander 2023-09-22 19:25 21444
    array                  | array           | 0x80..0x97
2660ccea Poul Sander 2023-09-22 19:25 21445
    array                  | array           | 0x98
2660ccea Poul Sander 2023-09-22 19:25 21446
    array                  | array           | 0x99
2660ccea Poul Sander 2023-09-22 19:25 21447
    array                  | array           | 0x9A
2660ccea Poul Sander 2023-09-22 19:25 21448
    array                  | array           | 0x9B
2660ccea Poul Sander 2023-09-22 19:25 21449
    array                  | array           | 0x9F
2660ccea Poul Sander 2023-09-22 19:25 21450
    map                    | object          | 0xA0..0xB7
2660ccea Poul Sander 2023-09-22 19:25 21451
    map                    | object          | 0xB8
2660ccea Poul Sander 2023-09-22 19:25 21452
    map                    | object          | 0xB9
2660ccea Poul Sander 2023-09-22 19:25 21453
    map                    | object          | 0xBA
2660ccea Poul Sander 2023-09-22 19:25 21454
    map                    | object          | 0xBB
2660ccea Poul Sander 2023-09-22 19:25 21455
    map                    | object          | 0xBF
2660ccea Poul Sander 2023-09-22 19:25 21456
    False                  | `false`         | 0xF4
2660ccea Poul Sander 2023-09-22 19:25 21457
    True                   | `true`          | 0xF5
2660ccea Poul Sander 2023-09-22 19:25 21458
    Null                   | `null`          | 0xF6
2660ccea Poul Sander 2023-09-22 19:25 21459
    Half-Precision Float   | number_float    | 0xF9
2660ccea Poul Sander 2023-09-22 19:25 21460
    Single-Precision Float | number_float    | 0xFA
2660ccea Poul Sander 2023-09-22 19:25 21461
    Double-Precision Float | number_float    | 0xFB
2660ccea Poul Sander 2023-09-22 19:25 21462
2660ccea Poul Sander 2023-09-22 19:25 21463
    @warning The mapping is **incomplete** in the sense that not all CBOR
2660ccea Poul Sander 2023-09-22 19:25 21464
             types can be converted to a JSON value. The following CBOR types
2660ccea Poul Sander 2023-09-22 19:25 21465
             are not supported and will yield parse errors (parse_error.112):
2660ccea Poul Sander 2023-09-22 19:25 21466
             - byte strings (0x40..0x5F)
2660ccea Poul Sander 2023-09-22 19:25 21467
             - date/time (0xC0..0xC1)
2660ccea Poul Sander 2023-09-22 19:25 21468
             - bignum (0xC2..0xC3)
2660ccea Poul Sander 2023-09-22 19:25 21469
             - decimal fraction (0xC4)
2660ccea Poul Sander 2023-09-22 19:25 21470
             - bigfloat (0xC5)
2660ccea Poul Sander 2023-09-22 19:25 21471
             - tagged items (0xC6..0xD4, 0xD8..0xDB)
2660ccea Poul Sander 2023-09-22 19:25 21472
             - expected conversions (0xD5..0xD7)
2660ccea Poul Sander 2023-09-22 19:25 21473
             - simple values (0xE0..0xF3, 0xF8)
2660ccea Poul Sander 2023-09-22 19:25 21474
             - undefined (0xF7)
2660ccea Poul Sander 2023-09-22 19:25 21475
2660ccea Poul Sander 2023-09-22 19:25 21476
    @warning CBOR allows map keys of any type, whereas JSON only allows
2660ccea Poul Sander 2023-09-22 19:25 21477
             strings as keys in object values. Therefore, CBOR maps with keys
2660ccea Poul Sander 2023-09-22 19:25 21478
             other than UTF-8 strings are rejected (parse_error.113).
2660ccea Poul Sander 2023-09-22 19:25 21479
2660ccea Poul Sander 2023-09-22 19:25 21480
    @note Any CBOR output created @ref to_cbor can be successfully parsed by
2660ccea Poul Sander 2023-09-22 19:25 21481
          @ref from_cbor.
2660ccea Poul Sander 2023-09-22 19:25 21482
2660ccea Poul Sander 2023-09-22 19:25 21483
    @param[in] i  an input in CBOR format convertible to an input adapter
2660ccea Poul Sander 2023-09-22 19:25 21484
    @param[in] strict  whether to expect the input to be consumed until EOF
2660ccea Poul Sander 2023-09-22 19:25 21485
                       (true by default)
2660ccea Poul Sander 2023-09-22 19:25 21486
    @param[in] allow_exceptions  whether to throw exceptions in case of a
2660ccea Poul Sander 2023-09-22 19:25 21487
    parse error (optional, true by default)
2660ccea Poul Sander 2023-09-22 19:25 21488
2660ccea Poul Sander 2023-09-22 19:25 21489
    @return deserialized JSON value; in case of a parse error and
2660ccea Poul Sander 2023-09-22 19:25 21490
            @a allow_exceptions set to `false`, the return value will be
2660ccea Poul Sander 2023-09-22 19:25 21491
            value_t::discarded.
2660ccea Poul Sander 2023-09-22 19:25 21492
2660ccea Poul Sander 2023-09-22 19:25 21493
    @throw parse_error.110 if the given input ends prematurely or the end of
2660ccea Poul Sander 2023-09-22 19:25 21494
    file was not reached when @a strict was set to true
2660ccea Poul Sander 2023-09-22 19:25 21495
    @throw parse_error.112 if unsupported features from CBOR were
2660ccea Poul Sander 2023-09-22 19:25 21496
    used in the given input @a v or if the input is not valid CBOR
2660ccea Poul Sander 2023-09-22 19:25 21497
    @throw parse_error.113 if a string was expected as map key, but not found
2660ccea Poul Sander 2023-09-22 19:25 21498
2660ccea Poul Sander 2023-09-22 19:25 21499
    @complexity Linear in the size of the input @a i.
2660ccea Poul Sander 2023-09-22 19:25 21500
2660ccea Poul Sander 2023-09-22 19:25 21501
    @liveexample{The example shows the deserialization of a byte vector in CBOR
2660ccea Poul Sander 2023-09-22 19:25 21502
    format to a JSON value.,from_cbor}
2660ccea Poul Sander 2023-09-22 19:25 21503
2660ccea Poul Sander 2023-09-22 19:25 21504
    @sa http://cbor.io
2660ccea Poul Sander 2023-09-22 19:25 21505
    @sa @ref to_cbor(const basic_json&) for the analogous serialization
2660ccea Poul Sander 2023-09-22 19:25 21506
    @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21507
        related MessagePack format
2660ccea Poul Sander 2023-09-22 19:25 21508
    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21509
        related UBJSON format
2660ccea Poul Sander 2023-09-22 19:25 21510
2660ccea Poul Sander 2023-09-22 19:25 21511
    @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
2660ccea Poul Sander 2023-09-22 19:25 21512
           consume input adapters, removed start_index parameter, and added
2660ccea Poul Sander 2023-09-22 19:25 21513
           @a strict parameter since 3.0.0; added @a allow_exceptions parameter
2660ccea Poul Sander 2023-09-22 19:25 21514
           since 3.2.0
2660ccea Poul Sander 2023-09-22 19:25 21515
    */
2660ccea Poul Sander 2023-09-22 19:25 21516
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 21517
    static basic_json from_cbor(detail::input_adapter&& i,
2660ccea Poul Sander 2023-09-22 19:25 21518
                                const bool strict = true,
2660ccea Poul Sander 2023-09-22 19:25 21519
                                const bool allow_exceptions = true)
2660ccea Poul Sander 2023-09-22 19:25 21520
    {
2660ccea Poul Sander 2023-09-22 19:25 21521
        basic_json result;
2660ccea Poul Sander 2023-09-22 19:25 21522
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2660ccea Poul Sander 2023-09-22 19:25 21523
        const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
2660ccea Poul Sander 2023-09-22 19:25 21524
        return res ? result : basic_json(value_t::discarded);
2660ccea Poul Sander 2023-09-22 19:25 21525
    }
2660ccea Poul Sander 2023-09-22 19:25 21526
2660ccea Poul Sander 2023-09-22 19:25 21527
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21528
    @copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
2660ccea Poul Sander 2023-09-22 19:25 21529
    */
2660ccea Poul Sander 2023-09-22 19:25 21530
    template<typename A1, typename A2,
2660ccea Poul Sander 2023-09-22 19:25 21531
             detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 21532
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 21533
    static basic_json from_cbor(A1 && a1, A2 && a2,
2660ccea Poul Sander 2023-09-22 19:25 21534
                                const bool strict = true,
2660ccea Poul Sander 2023-09-22 19:25 21535
                                const bool allow_exceptions = true)
2660ccea Poul Sander 2023-09-22 19:25 21536
    {
2660ccea Poul Sander 2023-09-22 19:25 21537
        basic_json result;
2660ccea Poul Sander 2023-09-22 19:25 21538
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2660ccea Poul Sander 2023-09-22 19:25 21539
        const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
2660ccea Poul Sander 2023-09-22 19:25 21540
        return res ? result : basic_json(value_t::discarded);
2660ccea Poul Sander 2023-09-22 19:25 21541
    }
2660ccea Poul Sander 2023-09-22 19:25 21542
2660ccea Poul Sander 2023-09-22 19:25 21543
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21544
    @brief create a JSON value from an input in MessagePack format
2660ccea Poul Sander 2023-09-22 19:25 21545
2660ccea Poul Sander 2023-09-22 19:25 21546
    Deserializes a given input @a i to a JSON value using the MessagePack
2660ccea Poul Sander 2023-09-22 19:25 21547
    serialization format.
2660ccea Poul Sander 2023-09-22 19:25 21548
2660ccea Poul Sander 2023-09-22 19:25 21549
    The library maps MessagePack types to JSON value types as follows:
2660ccea Poul Sander 2023-09-22 19:25 21550
2660ccea Poul Sander 2023-09-22 19:25 21551
    MessagePack type | JSON value type | first byte
2660ccea Poul Sander 2023-09-22 19:25 21552
    ---------------- | --------------- | ----------
2660ccea Poul Sander 2023-09-22 19:25 21553
    positive fixint  | number_unsigned | 0x00..0x7F
2660ccea Poul Sander 2023-09-22 19:25 21554
    fixmap           | object          | 0x80..0x8F
2660ccea Poul Sander 2023-09-22 19:25 21555
    fixarray         | array           | 0x90..0x9F
2660ccea Poul Sander 2023-09-22 19:25 21556
    fixstr           | string          | 0xA0..0xBF
2660ccea Poul Sander 2023-09-22 19:25 21557
    nil              | `null`          | 0xC0
2660ccea Poul Sander 2023-09-22 19:25 21558
    false            | `false`         | 0xC2
2660ccea Poul Sander 2023-09-22 19:25 21559
    true             | `true`          | 0xC3
2660ccea Poul Sander 2023-09-22 19:25 21560
    float 32         | number_float    | 0xCA
2660ccea Poul Sander 2023-09-22 19:25 21561
    float 64         | number_float    | 0xCB
2660ccea Poul Sander 2023-09-22 19:25 21562
    uint 8           | number_unsigned | 0xCC
2660ccea Poul Sander 2023-09-22 19:25 21563
    uint 16          | number_unsigned | 0xCD
2660ccea Poul Sander 2023-09-22 19:25 21564
    uint 32          | number_unsigned | 0xCE
2660ccea Poul Sander 2023-09-22 19:25 21565
    uint 64          | number_unsigned | 0xCF
2660ccea Poul Sander 2023-09-22 19:25 21566
    int 8            | number_integer  | 0xD0
2660ccea Poul Sander 2023-09-22 19:25 21567
    int 16           | number_integer  | 0xD1
2660ccea Poul Sander 2023-09-22 19:25 21568
    int 32           | number_integer  | 0xD2
2660ccea Poul Sander 2023-09-22 19:25 21569
    int 64           | number_integer  | 0xD3
2660ccea Poul Sander 2023-09-22 19:25 21570
    str 8            | string          | 0xD9
2660ccea Poul Sander 2023-09-22 19:25 21571
    str 16           | string          | 0xDA
2660ccea Poul Sander 2023-09-22 19:25 21572
    str 32           | string          | 0xDB
2660ccea Poul Sander 2023-09-22 19:25 21573
    array 16         | array           | 0xDC
2660ccea Poul Sander 2023-09-22 19:25 21574
    array 32         | array           | 0xDD
2660ccea Poul Sander 2023-09-22 19:25 21575
    map 16           | object          | 0xDE
2660ccea Poul Sander 2023-09-22 19:25 21576
    map 32           | object          | 0xDF
2660ccea Poul Sander 2023-09-22 19:25 21577
    negative fixint  | number_integer  | 0xE0-0xFF
2660ccea Poul Sander 2023-09-22 19:25 21578
2660ccea Poul Sander 2023-09-22 19:25 21579
    @warning The mapping is **incomplete** in the sense that not all
2660ccea Poul Sander 2023-09-22 19:25 21580
             MessagePack types can be converted to a JSON value. The following
2660ccea Poul Sander 2023-09-22 19:25 21581
             MessagePack types are not supported and will yield parse errors:
2660ccea Poul Sander 2023-09-22 19:25 21582
              - bin 8 - bin 32 (0xC4..0xC6)
2660ccea Poul Sander 2023-09-22 19:25 21583
              - ext 8 - ext 32 (0xC7..0xC9)
2660ccea Poul Sander 2023-09-22 19:25 21584
              - fixext 1 - fixext 16 (0xD4..0xD8)
2660ccea Poul Sander 2023-09-22 19:25 21585
2660ccea Poul Sander 2023-09-22 19:25 21586
    @note Any MessagePack output created @ref to_msgpack can be successfully
2660ccea Poul Sander 2023-09-22 19:25 21587
          parsed by @ref from_msgpack.
2660ccea Poul Sander 2023-09-22 19:25 21588
2660ccea Poul Sander 2023-09-22 19:25 21589
    @param[in] i  an input in MessagePack format convertible to an input
2660ccea Poul Sander 2023-09-22 19:25 21590
                  adapter
2660ccea Poul Sander 2023-09-22 19:25 21591
    @param[in] strict  whether to expect the input to be consumed until EOF
2660ccea Poul Sander 2023-09-22 19:25 21592
                       (true by default)
2660ccea Poul Sander 2023-09-22 19:25 21593
    @param[in] allow_exceptions  whether to throw exceptions in case of a
2660ccea Poul Sander 2023-09-22 19:25 21594
    parse error (optional, true by default)
2660ccea Poul Sander 2023-09-22 19:25 21595
2660ccea Poul Sander 2023-09-22 19:25 21596
    @return deserialized JSON value; in case of a parse error and
2660ccea Poul Sander 2023-09-22 19:25 21597
            @a allow_exceptions set to `false`, the return value will be
2660ccea Poul Sander 2023-09-22 19:25 21598
            value_t::discarded.
2660ccea Poul Sander 2023-09-22 19:25 21599
2660ccea Poul Sander 2023-09-22 19:25 21600
    @throw parse_error.110 if the given input ends prematurely or the end of
2660ccea Poul Sander 2023-09-22 19:25 21601
    file was not reached when @a strict was set to true
2660ccea Poul Sander 2023-09-22 19:25 21602
    @throw parse_error.112 if unsupported features from MessagePack were
2660ccea Poul Sander 2023-09-22 19:25 21603
    used in the given input @a i or if the input is not valid MessagePack
2660ccea Poul Sander 2023-09-22 19:25 21604
    @throw parse_error.113 if a string was expected as map key, but not found
2660ccea Poul Sander 2023-09-22 19:25 21605
2660ccea Poul Sander 2023-09-22 19:25 21606
    @complexity Linear in the size of the input @a i.
2660ccea Poul Sander 2023-09-22 19:25 21607
2660ccea Poul Sander 2023-09-22 19:25 21608
    @liveexample{The example shows the deserialization of a byte vector in
2660ccea Poul Sander 2023-09-22 19:25 21609
    MessagePack format to a JSON value.,from_msgpack}
2660ccea Poul Sander 2023-09-22 19:25 21610
2660ccea Poul Sander 2023-09-22 19:25 21611
    @sa http://msgpack.org
2660ccea Poul Sander 2023-09-22 19:25 21612
    @sa @ref to_msgpack(const basic_json&) for the analogous serialization
2660ccea Poul Sander 2023-09-22 19:25 21613
    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21614
        related CBOR format
2660ccea Poul Sander 2023-09-22 19:25 21615
    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
2660ccea Poul Sander 2023-09-22 19:25 21616
        the related UBJSON format
2660ccea Poul Sander 2023-09-22 19:25 21617
    @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
2660ccea Poul Sander 2023-09-22 19:25 21618
        the related BSON format
2660ccea Poul Sander 2023-09-22 19:25 21619
2660ccea Poul Sander 2023-09-22 19:25 21620
    @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
2660ccea Poul Sander 2023-09-22 19:25 21621
           consume input adapters, removed start_index parameter, and added
2660ccea Poul Sander 2023-09-22 19:25 21622
           @a strict parameter since 3.0.0; added @a allow_exceptions parameter
2660ccea Poul Sander 2023-09-22 19:25 21623
           since 3.2.0
2660ccea Poul Sander 2023-09-22 19:25 21624
    */
2660ccea Poul Sander 2023-09-22 19:25 21625
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 21626
    static basic_json from_msgpack(detail::input_adapter&& i,
2660ccea Poul Sander 2023-09-22 19:25 21627
                                   const bool strict = true,
2660ccea Poul Sander 2023-09-22 19:25 21628
                                   const bool allow_exceptions = true)
2660ccea Poul Sander 2023-09-22 19:25 21629
    {
2660ccea Poul Sander 2023-09-22 19:25 21630
        basic_json result;
2660ccea Poul Sander 2023-09-22 19:25 21631
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2660ccea Poul Sander 2023-09-22 19:25 21632
        const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
2660ccea Poul Sander 2023-09-22 19:25 21633
        return res ? result : basic_json(value_t::discarded);
2660ccea Poul Sander 2023-09-22 19:25 21634
    }
2660ccea Poul Sander 2023-09-22 19:25 21635
2660ccea Poul Sander 2023-09-22 19:25 21636
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21637
    @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
2660ccea Poul Sander 2023-09-22 19:25 21638
    */
2660ccea Poul Sander 2023-09-22 19:25 21639
    template<typename A1, typename A2,
2660ccea Poul Sander 2023-09-22 19:25 21640
             detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 21641
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 21642
    static basic_json from_msgpack(A1 && a1, A2 && a2,
2660ccea Poul Sander 2023-09-22 19:25 21643
                                   const bool strict = true,
2660ccea Poul Sander 2023-09-22 19:25 21644
                                   const bool allow_exceptions = true)
2660ccea Poul Sander 2023-09-22 19:25 21645
    {
2660ccea Poul Sander 2023-09-22 19:25 21646
        basic_json result;
2660ccea Poul Sander 2023-09-22 19:25 21647
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2660ccea Poul Sander 2023-09-22 19:25 21648
        const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
2660ccea Poul Sander 2023-09-22 19:25 21649
        return res ? result : basic_json(value_t::discarded);
2660ccea Poul Sander 2023-09-22 19:25 21650
    }
2660ccea Poul Sander 2023-09-22 19:25 21651
2660ccea Poul Sander 2023-09-22 19:25 21652
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21653
    @brief create a JSON value from an input in UBJSON format
2660ccea Poul Sander 2023-09-22 19:25 21654
2660ccea Poul Sander 2023-09-22 19:25 21655
    Deserializes a given input @a i to a JSON value using the UBJSON (Universal
2660ccea Poul Sander 2023-09-22 19:25 21656
    Binary JSON) serialization format.
2660ccea Poul Sander 2023-09-22 19:25 21657
2660ccea Poul Sander 2023-09-22 19:25 21658
    The library maps UBJSON types to JSON value types as follows:
2660ccea Poul Sander 2023-09-22 19:25 21659
2660ccea Poul Sander 2023-09-22 19:25 21660
    UBJSON type | JSON value type                         | marker
2660ccea Poul Sander 2023-09-22 19:25 21661
    ----------- | --------------------------------------- | ------
2660ccea Poul Sander 2023-09-22 19:25 21662
    no-op       | *no value, next value is read*          | `N`
2660ccea Poul Sander 2023-09-22 19:25 21663
    null        | `null`                                  | `Z`
2660ccea Poul Sander 2023-09-22 19:25 21664
    false       | `false`                                 | `F`
2660ccea Poul Sander 2023-09-22 19:25 21665
    true        | `true`                                  | `T`
2660ccea Poul Sander 2023-09-22 19:25 21666
    float32     | number_float                            | `d`
2660ccea Poul Sander 2023-09-22 19:25 21667
    float64     | number_float                            | `D`
2660ccea Poul Sander 2023-09-22 19:25 21668
    uint8       | number_unsigned                         | `U`
2660ccea Poul Sander 2023-09-22 19:25 21669
    int8        | number_integer                          | `i`
2660ccea Poul Sander 2023-09-22 19:25 21670
    int16       | number_integer                          | `I`
2660ccea Poul Sander 2023-09-22 19:25 21671
    int32       | number_integer                          | `l`
2660ccea Poul Sander 2023-09-22 19:25 21672
    int64       | number_integer                          | `L`
2660ccea Poul Sander 2023-09-22 19:25 21673
    string      | string                                  | `S`
2660ccea Poul Sander 2023-09-22 19:25 21674
    char        | string                                  | `C`
2660ccea Poul Sander 2023-09-22 19:25 21675
    array       | array (optimized values are supported)  | `[`
2660ccea Poul Sander 2023-09-22 19:25 21676
    object      | object (optimized values are supported) | `{`
2660ccea Poul Sander 2023-09-22 19:25 21677
2660ccea Poul Sander 2023-09-22 19:25 21678
    @note The mapping is **complete** in the sense that any UBJSON value can
2660ccea Poul Sander 2023-09-22 19:25 21679
          be converted to a JSON value.
2660ccea Poul Sander 2023-09-22 19:25 21680
2660ccea Poul Sander 2023-09-22 19:25 21681
    @param[in] i  an input in UBJSON format convertible to an input adapter
2660ccea Poul Sander 2023-09-22 19:25 21682
    @param[in] strict  whether to expect the input to be consumed until EOF
2660ccea Poul Sander 2023-09-22 19:25 21683
                       (true by default)
2660ccea Poul Sander 2023-09-22 19:25 21684
    @param[in] allow_exceptions  whether to throw exceptions in case of a
2660ccea Poul Sander 2023-09-22 19:25 21685
    parse error (optional, true by default)
2660ccea Poul Sander 2023-09-22 19:25 21686
2660ccea Poul Sander 2023-09-22 19:25 21687
    @return deserialized JSON value; in case of a parse error and
2660ccea Poul Sander 2023-09-22 19:25 21688
            @a allow_exceptions set to `false`, the return value will be
2660ccea Poul Sander 2023-09-22 19:25 21689
            value_t::discarded.
2660ccea Poul Sander 2023-09-22 19:25 21690
2660ccea Poul Sander 2023-09-22 19:25 21691
    @throw parse_error.110 if the given input ends prematurely or the end of
2660ccea Poul Sander 2023-09-22 19:25 21692
    file was not reached when @a strict was set to true
2660ccea Poul Sander 2023-09-22 19:25 21693
    @throw parse_error.112 if a parse error occurs
2660ccea Poul Sander 2023-09-22 19:25 21694
    @throw parse_error.113 if a string could not be parsed successfully
2660ccea Poul Sander 2023-09-22 19:25 21695
2660ccea Poul Sander 2023-09-22 19:25 21696
    @complexity Linear in the size of the input @a i.
2660ccea Poul Sander 2023-09-22 19:25 21697
2660ccea Poul Sander 2023-09-22 19:25 21698
    @liveexample{The example shows the deserialization of a byte vector in
2660ccea Poul Sander 2023-09-22 19:25 21699
    UBJSON format to a JSON value.,from_ubjson}
2660ccea Poul Sander 2023-09-22 19:25 21700
2660ccea Poul Sander 2023-09-22 19:25 21701
    @sa http://ubjson.org
2660ccea Poul Sander 2023-09-22 19:25 21702
    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21703
             analogous serialization
2660ccea Poul Sander 2023-09-22 19:25 21704
    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21705
        related CBOR format
2660ccea Poul Sander 2023-09-22 19:25 21706
    @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
2660ccea Poul Sander 2023-09-22 19:25 21707
        the related MessagePack format
2660ccea Poul Sander 2023-09-22 19:25 21708
    @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
2660ccea Poul Sander 2023-09-22 19:25 21709
        the related BSON format
2660ccea Poul Sander 2023-09-22 19:25 21710
2660ccea Poul Sander 2023-09-22 19:25 21711
    @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
2660ccea Poul Sander 2023-09-22 19:25 21712
    */
2660ccea Poul Sander 2023-09-22 19:25 21713
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 21714
    static basic_json from_ubjson(detail::input_adapter&& i,
2660ccea Poul Sander 2023-09-22 19:25 21715
                                  const bool strict = true,
2660ccea Poul Sander 2023-09-22 19:25 21716
                                  const bool allow_exceptions = true)
2660ccea Poul Sander 2023-09-22 19:25 21717
    {
2660ccea Poul Sander 2023-09-22 19:25 21718
        basic_json result;
2660ccea Poul Sander 2023-09-22 19:25 21719
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2660ccea Poul Sander 2023-09-22 19:25 21720
        const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
2660ccea Poul Sander 2023-09-22 19:25 21721
        return res ? result : basic_json(value_t::discarded);
2660ccea Poul Sander 2023-09-22 19:25 21722
    }
2660ccea Poul Sander 2023-09-22 19:25 21723
2660ccea Poul Sander 2023-09-22 19:25 21724
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21725
    @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
2660ccea Poul Sander 2023-09-22 19:25 21726
    */
2660ccea Poul Sander 2023-09-22 19:25 21727
    template<typename A1, typename A2,
2660ccea Poul Sander 2023-09-22 19:25 21728
             detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 21729
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 21730
    static basic_json from_ubjson(A1 && a1, A2 && a2,
2660ccea Poul Sander 2023-09-22 19:25 21731
                                  const bool strict = true,
2660ccea Poul Sander 2023-09-22 19:25 21732
                                  const bool allow_exceptions = true)
2660ccea Poul Sander 2023-09-22 19:25 21733
    {
2660ccea Poul Sander 2023-09-22 19:25 21734
        basic_json result;
2660ccea Poul Sander 2023-09-22 19:25 21735
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2660ccea Poul Sander 2023-09-22 19:25 21736
        const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
2660ccea Poul Sander 2023-09-22 19:25 21737
        return res ? result : basic_json(value_t::discarded);
2660ccea Poul Sander 2023-09-22 19:25 21738
    }
2660ccea Poul Sander 2023-09-22 19:25 21739
2660ccea Poul Sander 2023-09-22 19:25 21740
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21741
    @brief Create a JSON value from an input in BSON format
2660ccea Poul Sander 2023-09-22 19:25 21742
2660ccea Poul Sander 2023-09-22 19:25 21743
    Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
2660ccea Poul Sander 2023-09-22 19:25 21744
    serialization format.
2660ccea Poul Sander 2023-09-22 19:25 21745
2660ccea Poul Sander 2023-09-22 19:25 21746
    The library maps BSON record types to JSON value types as follows:
2660ccea Poul Sander 2023-09-22 19:25 21747
2660ccea Poul Sander 2023-09-22 19:25 21748
    BSON type       | BSON marker byte | JSON value type
2660ccea Poul Sander 2023-09-22 19:25 21749
    --------------- | ---------------- | ---------------------------
2660ccea Poul Sander 2023-09-22 19:25 21750
    double          | 0x01             | number_float
2660ccea Poul Sander 2023-09-22 19:25 21751
    string          | 0x02             | string
2660ccea Poul Sander 2023-09-22 19:25 21752
    document        | 0x03             | object
2660ccea Poul Sander 2023-09-22 19:25 21753
    array           | 0x04             | array
2660ccea Poul Sander 2023-09-22 19:25 21754
    binary          | 0x05             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21755
    undefined       | 0x06             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21756
    ObjectId        | 0x07             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21757
    boolean         | 0x08             | boolean
2660ccea Poul Sander 2023-09-22 19:25 21758
    UTC Date-Time   | 0x09             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21759
    null            | 0x0A             | null
2660ccea Poul Sander 2023-09-22 19:25 21760
    Regular Expr.   | 0x0B             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21761
    DB Pointer      | 0x0C             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21762
    JavaScript Code | 0x0D             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21763
    Symbol          | 0x0E             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21764
    JavaScript Code | 0x0F             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21765
    int32           | 0x10             | number_integer
2660ccea Poul Sander 2023-09-22 19:25 21766
    Timestamp       | 0x11             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21767
    128-bit decimal float | 0x13       | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21768
    Max Key         | 0x7F             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21769
    Min Key         | 0xFF             | still unsupported
2660ccea Poul Sander 2023-09-22 19:25 21770
2660ccea Poul Sander 2023-09-22 19:25 21771
    @warning The mapping is **incomplete**. The unsupported mappings
2660ccea Poul Sander 2023-09-22 19:25 21772
             are indicated in the table above.
2660ccea Poul Sander 2023-09-22 19:25 21773
2660ccea Poul Sander 2023-09-22 19:25 21774
    @param[in] i  an input in BSON format convertible to an input adapter
2660ccea Poul Sander 2023-09-22 19:25 21775
    @param[in] strict  whether to expect the input to be consumed until EOF
2660ccea Poul Sander 2023-09-22 19:25 21776
                       (true by default)
2660ccea Poul Sander 2023-09-22 19:25 21777
    @param[in] allow_exceptions  whether to throw exceptions in case of a
2660ccea Poul Sander 2023-09-22 19:25 21778
    parse error (optional, true by default)
2660ccea Poul Sander 2023-09-22 19:25 21779
2660ccea Poul Sander 2023-09-22 19:25 21780
    @return deserialized JSON value; in case of a parse error and
2660ccea Poul Sander 2023-09-22 19:25 21781
            @a allow_exceptions set to `false`, the return value will be
2660ccea Poul Sander 2023-09-22 19:25 21782
            value_t::discarded.
2660ccea Poul Sander 2023-09-22 19:25 21783
2660ccea Poul Sander 2023-09-22 19:25 21784
    @throw parse_error.114 if an unsupported BSON record type is encountered
2660ccea Poul Sander 2023-09-22 19:25 21785
2660ccea Poul Sander 2023-09-22 19:25 21786
    @complexity Linear in the size of the input @a i.
2660ccea Poul Sander 2023-09-22 19:25 21787
2660ccea Poul Sander 2023-09-22 19:25 21788
    @liveexample{The example shows the deserialization of a byte vector in
2660ccea Poul Sander 2023-09-22 19:25 21789
    BSON format to a JSON value.,from_bson}
2660ccea Poul Sander 2023-09-22 19:25 21790
2660ccea Poul Sander 2023-09-22 19:25 21791
    @sa http://bsonspec.org/spec.html
2660ccea Poul Sander 2023-09-22 19:25 21792
    @sa @ref to_bson(const basic_json&) for the analogous serialization
2660ccea Poul Sander 2023-09-22 19:25 21793
    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21794
        related CBOR format
2660ccea Poul Sander 2023-09-22 19:25 21795
    @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
2660ccea Poul Sander 2023-09-22 19:25 21796
        the related MessagePack format
2660ccea Poul Sander 2023-09-22 19:25 21797
    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
2660ccea Poul Sander 2023-09-22 19:25 21798
        related UBJSON format
2660ccea Poul Sander 2023-09-22 19:25 21799
    */
2660ccea Poul Sander 2023-09-22 19:25 21800
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 21801
    static basic_json from_bson(detail::input_adapter&& i,
2660ccea Poul Sander 2023-09-22 19:25 21802
                                const bool strict = true,
2660ccea Poul Sander 2023-09-22 19:25 21803
                                const bool allow_exceptions = true)
2660ccea Poul Sander 2023-09-22 19:25 21804
    {
2660ccea Poul Sander 2023-09-22 19:25 21805
        basic_json result;
2660ccea Poul Sander 2023-09-22 19:25 21806
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2660ccea Poul Sander 2023-09-22 19:25 21807
        const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
2660ccea Poul Sander 2023-09-22 19:25 21808
        return res ? result : basic_json(value_t::discarded);
2660ccea Poul Sander 2023-09-22 19:25 21809
    }
2660ccea Poul Sander 2023-09-22 19:25 21810
2660ccea Poul Sander 2023-09-22 19:25 21811
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21812
    @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
2660ccea Poul Sander 2023-09-22 19:25 21813
    */
2660ccea Poul Sander 2023-09-22 19:25 21814
    template<typename A1, typename A2,
2660ccea Poul Sander 2023-09-22 19:25 21815
             detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
2660ccea Poul Sander 2023-09-22 19:25 21816
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 21817
    static basic_json from_bson(A1 && a1, A2 && a2,
2660ccea Poul Sander 2023-09-22 19:25 21818
                                const bool strict = true,
2660ccea Poul Sander 2023-09-22 19:25 21819
                                const bool allow_exceptions = true)
2660ccea Poul Sander 2023-09-22 19:25 21820
    {
2660ccea Poul Sander 2023-09-22 19:25 21821
        basic_json result;
2660ccea Poul Sander 2023-09-22 19:25 21822
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2660ccea Poul Sander 2023-09-22 19:25 21823
        const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
2660ccea Poul Sander 2023-09-22 19:25 21824
        return res ? result : basic_json(value_t::discarded);
2660ccea Poul Sander 2023-09-22 19:25 21825
    }
2660ccea Poul Sander 2023-09-22 19:25 21826
2660ccea Poul Sander 2023-09-22 19:25 21827
2660ccea Poul Sander 2023-09-22 19:25 21828
2660ccea Poul Sander 2023-09-22 19:25 21829
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 21830
2660ccea Poul Sander 2023-09-22 19:25 21831
    //////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 21832
    // JSON Pointer support //
2660ccea Poul Sander 2023-09-22 19:25 21833
    //////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 21834
2660ccea Poul Sander 2023-09-22 19:25 21835
    /// @name JSON Pointer functions
2660ccea Poul Sander 2023-09-22 19:25 21836
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 21837
2660ccea Poul Sander 2023-09-22 19:25 21838
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21839
    @brief access specified element via JSON Pointer
2660ccea Poul Sander 2023-09-22 19:25 21840
2660ccea Poul Sander 2023-09-22 19:25 21841
    Uses a JSON pointer to retrieve a reference to the respective JSON value.
2660ccea Poul Sander 2023-09-22 19:25 21842
    No bound checking is performed. Similar to @ref operator[](const typename
2660ccea Poul Sander 2023-09-22 19:25 21843
    object_t::key_type&), `null` values are created in arrays and objects if
2660ccea Poul Sander 2023-09-22 19:25 21844
    necessary.
2660ccea Poul Sander 2023-09-22 19:25 21845
2660ccea Poul Sander 2023-09-22 19:25 21846
    In particular:
2660ccea Poul Sander 2023-09-22 19:25 21847
    - If the JSON pointer points to an object key that does not exist, it
2660ccea Poul Sander 2023-09-22 19:25 21848
      is created an filled with a `null` value before a reference to it
2660ccea Poul Sander 2023-09-22 19:25 21849
      is returned.
2660ccea Poul Sander 2023-09-22 19:25 21850
    - If the JSON pointer points to an array index that does not exist, it
2660ccea Poul Sander 2023-09-22 19:25 21851
      is created an filled with a `null` value before a reference to it
2660ccea Poul Sander 2023-09-22 19:25 21852
      is returned. All indices between the current maximum and the given
2660ccea Poul Sander 2023-09-22 19:25 21853
      index are also filled with `null`.
2660ccea Poul Sander 2023-09-22 19:25 21854
    - The special value `-` is treated as a synonym for the index past the
2660ccea Poul Sander 2023-09-22 19:25 21855
      end.
2660ccea Poul Sander 2023-09-22 19:25 21856
2660ccea Poul Sander 2023-09-22 19:25 21857
    @param[in] ptr  a JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 21858
2660ccea Poul Sander 2023-09-22 19:25 21859
    @return reference to the element pointed to by @a ptr
2660ccea Poul Sander 2023-09-22 19:25 21860
2660ccea Poul Sander 2023-09-22 19:25 21861
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 21862
2660ccea Poul Sander 2023-09-22 19:25 21863
    @throw parse_error.106   if an array index begins with '0'
2660ccea Poul Sander 2023-09-22 19:25 21864
    @throw parse_error.109   if an array index was not a number
2660ccea Poul Sander 2023-09-22 19:25 21865
    @throw out_of_range.404  if the JSON pointer can not be resolved
2660ccea Poul Sander 2023-09-22 19:25 21866
2660ccea Poul Sander 2023-09-22 19:25 21867
    @liveexample{The behavior is shown in the example.,operatorjson_pointer}
2660ccea Poul Sander 2023-09-22 19:25 21868
2660ccea Poul Sander 2023-09-22 19:25 21869
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 21870
    */
2660ccea Poul Sander 2023-09-22 19:25 21871
    reference operator[](const json_pointer& ptr)
2660ccea Poul Sander 2023-09-22 19:25 21872
    {
2660ccea Poul Sander 2023-09-22 19:25 21873
        return ptr.get_unchecked(this);
2660ccea Poul Sander 2023-09-22 19:25 21874
    }
2660ccea Poul Sander 2023-09-22 19:25 21875
2660ccea Poul Sander 2023-09-22 19:25 21876
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21877
    @brief access specified element via JSON Pointer
2660ccea Poul Sander 2023-09-22 19:25 21878
2660ccea Poul Sander 2023-09-22 19:25 21879
    Uses a JSON pointer to retrieve a reference to the respective JSON value.
2660ccea Poul Sander 2023-09-22 19:25 21880
    No bound checking is performed. The function does not change the JSON
2660ccea Poul Sander 2023-09-22 19:25 21881
    value; no `null` values are created. In particular, the the special value
2660ccea Poul Sander 2023-09-22 19:25 21882
    `-` yields an exception.
2660ccea Poul Sander 2023-09-22 19:25 21883
2660ccea Poul Sander 2023-09-22 19:25 21884
    @param[in] ptr  JSON pointer to the desired element
2660ccea Poul Sander 2023-09-22 19:25 21885
2660ccea Poul Sander 2023-09-22 19:25 21886
    @return const reference to the element pointed to by @a ptr
2660ccea Poul Sander 2023-09-22 19:25 21887
2660ccea Poul Sander 2023-09-22 19:25 21888
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 21889
2660ccea Poul Sander 2023-09-22 19:25 21890
    @throw parse_error.106   if an array index begins with '0'
2660ccea Poul Sander 2023-09-22 19:25 21891
    @throw parse_error.109   if an array index was not a number
2660ccea Poul Sander 2023-09-22 19:25 21892
    @throw out_of_range.402  if the array index '-' is used
2660ccea Poul Sander 2023-09-22 19:25 21893
    @throw out_of_range.404  if the JSON pointer can not be resolved
2660ccea Poul Sander 2023-09-22 19:25 21894
2660ccea Poul Sander 2023-09-22 19:25 21895
    @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
2660ccea Poul Sander 2023-09-22 19:25 21896
2660ccea Poul Sander 2023-09-22 19:25 21897
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 21898
    */
2660ccea Poul Sander 2023-09-22 19:25 21899
    const_reference operator[](const json_pointer& ptr) const
2660ccea Poul Sander 2023-09-22 19:25 21900
    {
2660ccea Poul Sander 2023-09-22 19:25 21901
        return ptr.get_unchecked(this);
2660ccea Poul Sander 2023-09-22 19:25 21902
    }
2660ccea Poul Sander 2023-09-22 19:25 21903
2660ccea Poul Sander 2023-09-22 19:25 21904
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21905
    @brief access specified element via JSON Pointer
2660ccea Poul Sander 2023-09-22 19:25 21906
2660ccea Poul Sander 2023-09-22 19:25 21907
    Returns a reference to the element at with specified JSON pointer @a ptr,
2660ccea Poul Sander 2023-09-22 19:25 21908
    with bounds checking.
2660ccea Poul Sander 2023-09-22 19:25 21909
2660ccea Poul Sander 2023-09-22 19:25 21910
    @param[in] ptr  JSON pointer to the desired element
2660ccea Poul Sander 2023-09-22 19:25 21911
2660ccea Poul Sander 2023-09-22 19:25 21912
    @return reference to the element pointed to by @a ptr
2660ccea Poul Sander 2023-09-22 19:25 21913
2660ccea Poul Sander 2023-09-22 19:25 21914
    @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
2660ccea Poul Sander 2023-09-22 19:25 21915
    begins with '0'. See example below.
2660ccea Poul Sander 2023-09-22 19:25 21916
2660ccea Poul Sander 2023-09-22 19:25 21917
    @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
2660ccea Poul Sander 2023-09-22 19:25 21918
    is not a number. See example below.
2660ccea Poul Sander 2023-09-22 19:25 21919
2660ccea Poul Sander 2023-09-22 19:25 21920
    @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
2660ccea Poul Sander 2023-09-22 19:25 21921
    is out of range. See example below.
2660ccea Poul Sander 2023-09-22 19:25 21922
2660ccea Poul Sander 2023-09-22 19:25 21923
    @throw out_of_range.402 if the array index '-' is used in the passed JSON
2660ccea Poul Sander 2023-09-22 19:25 21924
    pointer @a ptr. As `at` provides checked access (and no elements are
2660ccea Poul Sander 2023-09-22 19:25 21925
    implicitly inserted), the index '-' is always invalid. See example below.
2660ccea Poul Sander 2023-09-22 19:25 21926
2660ccea Poul Sander 2023-09-22 19:25 21927
    @throw out_of_range.403 if the JSON pointer describes a key of an object
2660ccea Poul Sander 2023-09-22 19:25 21928
    which cannot be found. See example below.
2660ccea Poul Sander 2023-09-22 19:25 21929
2660ccea Poul Sander 2023-09-22 19:25 21930
    @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
2660ccea Poul Sander 2023-09-22 19:25 21931
    See example below.
2660ccea Poul Sander 2023-09-22 19:25 21932
2660ccea Poul Sander 2023-09-22 19:25 21933
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 21934
    changes in the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 21935
2660ccea Poul Sander 2023-09-22 19:25 21936
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 21937
2660ccea Poul Sander 2023-09-22 19:25 21938
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 21939
2660ccea Poul Sander 2023-09-22 19:25 21940
    @liveexample{The behavior is shown in the example.,at_json_pointer}
2660ccea Poul Sander 2023-09-22 19:25 21941
    */
2660ccea Poul Sander 2023-09-22 19:25 21942
    reference at(const json_pointer& ptr)
2660ccea Poul Sander 2023-09-22 19:25 21943
    {
2660ccea Poul Sander 2023-09-22 19:25 21944
        return ptr.get_checked(this);
2660ccea Poul Sander 2023-09-22 19:25 21945
    }
2660ccea Poul Sander 2023-09-22 19:25 21946
2660ccea Poul Sander 2023-09-22 19:25 21947
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21948
    @brief access specified element via JSON Pointer
2660ccea Poul Sander 2023-09-22 19:25 21949
2660ccea Poul Sander 2023-09-22 19:25 21950
    Returns a const reference to the element at with specified JSON pointer @a
2660ccea Poul Sander 2023-09-22 19:25 21951
    ptr, with bounds checking.
2660ccea Poul Sander 2023-09-22 19:25 21952
2660ccea Poul Sander 2023-09-22 19:25 21953
    @param[in] ptr  JSON pointer to the desired element
2660ccea Poul Sander 2023-09-22 19:25 21954
2660ccea Poul Sander 2023-09-22 19:25 21955
    @return reference to the element pointed to by @a ptr
2660ccea Poul Sander 2023-09-22 19:25 21956
2660ccea Poul Sander 2023-09-22 19:25 21957
    @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
2660ccea Poul Sander 2023-09-22 19:25 21958
    begins with '0'. See example below.
2660ccea Poul Sander 2023-09-22 19:25 21959
2660ccea Poul Sander 2023-09-22 19:25 21960
    @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
2660ccea Poul Sander 2023-09-22 19:25 21961
    is not a number. See example below.
2660ccea Poul Sander 2023-09-22 19:25 21962
2660ccea Poul Sander 2023-09-22 19:25 21963
    @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
2660ccea Poul Sander 2023-09-22 19:25 21964
    is out of range. See example below.
2660ccea Poul Sander 2023-09-22 19:25 21965
2660ccea Poul Sander 2023-09-22 19:25 21966
    @throw out_of_range.402 if the array index '-' is used in the passed JSON
2660ccea Poul Sander 2023-09-22 19:25 21967
    pointer @a ptr. As `at` provides checked access (and no elements are
2660ccea Poul Sander 2023-09-22 19:25 21968
    implicitly inserted), the index '-' is always invalid. See example below.
2660ccea Poul Sander 2023-09-22 19:25 21969
2660ccea Poul Sander 2023-09-22 19:25 21970
    @throw out_of_range.403 if the JSON pointer describes a key of an object
2660ccea Poul Sander 2023-09-22 19:25 21971
    which cannot be found. See example below.
2660ccea Poul Sander 2023-09-22 19:25 21972
2660ccea Poul Sander 2023-09-22 19:25 21973
    @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
2660ccea Poul Sander 2023-09-22 19:25 21974
    See example below.
2660ccea Poul Sander 2023-09-22 19:25 21975
2660ccea Poul Sander 2023-09-22 19:25 21976
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2660ccea Poul Sander 2023-09-22 19:25 21977
    changes in the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 21978
2660ccea Poul Sander 2023-09-22 19:25 21979
    @complexity Constant.
2660ccea Poul Sander 2023-09-22 19:25 21980
2660ccea Poul Sander 2023-09-22 19:25 21981
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 21982
2660ccea Poul Sander 2023-09-22 19:25 21983
    @liveexample{The behavior is shown in the example.,at_json_pointer_const}
2660ccea Poul Sander 2023-09-22 19:25 21984
    */
2660ccea Poul Sander 2023-09-22 19:25 21985
    const_reference at(const json_pointer& ptr) const
2660ccea Poul Sander 2023-09-22 19:25 21986
    {
2660ccea Poul Sander 2023-09-22 19:25 21987
        return ptr.get_checked(this);
2660ccea Poul Sander 2023-09-22 19:25 21988
    }
2660ccea Poul Sander 2023-09-22 19:25 21989
2660ccea Poul Sander 2023-09-22 19:25 21990
    /*!
2660ccea Poul Sander 2023-09-22 19:25 21991
    @brief return flattened JSON value
2660ccea Poul Sander 2023-09-22 19:25 21992
2660ccea Poul Sander 2023-09-22 19:25 21993
    The function creates a JSON object whose keys are JSON pointers (see [RFC
2660ccea Poul Sander 2023-09-22 19:25 21994
    6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
2660ccea Poul Sander 2023-09-22 19:25 21995
    primitive. The original JSON value can be restored using the @ref
2660ccea Poul Sander 2023-09-22 19:25 21996
    unflatten() function.
2660ccea Poul Sander 2023-09-22 19:25 21997
2660ccea Poul Sander 2023-09-22 19:25 21998
    @return an object that maps JSON pointers to primitive values
2660ccea Poul Sander 2023-09-22 19:25 21999
2660ccea Poul Sander 2023-09-22 19:25 22000
    @note Empty objects and arrays are flattened to `null` and will not be
2660ccea Poul Sander 2023-09-22 19:25 22001
          reconstructed correctly by the @ref unflatten() function.
2660ccea Poul Sander 2023-09-22 19:25 22002
2660ccea Poul Sander 2023-09-22 19:25 22003
    @complexity Linear in the size the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 22004
2660ccea Poul Sander 2023-09-22 19:25 22005
    @liveexample{The following code shows how a JSON object is flattened to an
2660ccea Poul Sander 2023-09-22 19:25 22006
    object whose keys consist of JSON pointers.,flatten}
2660ccea Poul Sander 2023-09-22 19:25 22007
2660ccea Poul Sander 2023-09-22 19:25 22008
    @sa @ref unflatten() for the reverse function
2660ccea Poul Sander 2023-09-22 19:25 22009
2660ccea Poul Sander 2023-09-22 19:25 22010
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 22011
    */
2660ccea Poul Sander 2023-09-22 19:25 22012
    basic_json flatten() const
2660ccea Poul Sander 2023-09-22 19:25 22013
    {
2660ccea Poul Sander 2023-09-22 19:25 22014
        basic_json result(value_t::object);
2660ccea Poul Sander 2023-09-22 19:25 22015
        json_pointer::flatten("", *this, result);
2660ccea Poul Sander 2023-09-22 19:25 22016
        return result;
2660ccea Poul Sander 2023-09-22 19:25 22017
    }
2660ccea Poul Sander 2023-09-22 19:25 22018
2660ccea Poul Sander 2023-09-22 19:25 22019
    /*!
2660ccea Poul Sander 2023-09-22 19:25 22020
    @brief unflatten a previously flattened JSON value
2660ccea Poul Sander 2023-09-22 19:25 22021
2660ccea Poul Sander 2023-09-22 19:25 22022
    The function restores the arbitrary nesting of a JSON value that has been
2660ccea Poul Sander 2023-09-22 19:25 22023
    flattened before using the @ref flatten() function. The JSON value must
2660ccea Poul Sander 2023-09-22 19:25 22024
    meet certain constraints:
2660ccea Poul Sander 2023-09-22 19:25 22025
    1. The value must be an object.
2660ccea Poul Sander 2023-09-22 19:25 22026
    2. The keys must be JSON pointers (see
2660ccea Poul Sander 2023-09-22 19:25 22027
       [RFC 6901](https://tools.ietf.org/html/rfc6901))
2660ccea Poul Sander 2023-09-22 19:25 22028
    3. The mapped values must be primitive JSON types.
2660ccea Poul Sander 2023-09-22 19:25 22029
2660ccea Poul Sander 2023-09-22 19:25 22030
    @return the original JSON from a flattened version
2660ccea Poul Sander 2023-09-22 19:25 22031
2660ccea Poul Sander 2023-09-22 19:25 22032
    @note Empty objects and arrays are flattened by @ref flatten() to `null`
2660ccea Poul Sander 2023-09-22 19:25 22033
          values and can not unflattened to their original type. Apart from
2660ccea Poul Sander 2023-09-22 19:25 22034
          this example, for a JSON value `j`, the following is always true:
2660ccea Poul Sander 2023-09-22 19:25 22035
          `j == j.flatten().unflatten()`.
2660ccea Poul Sander 2023-09-22 19:25 22036
2660ccea Poul Sander 2023-09-22 19:25 22037
    @complexity Linear in the size the JSON value.
2660ccea Poul Sander 2023-09-22 19:25 22038
2660ccea Poul Sander 2023-09-22 19:25 22039
    @throw type_error.314  if value is not an object
2660ccea Poul Sander 2023-09-22 19:25 22040
    @throw type_error.315  if object values are not primitive
2660ccea Poul Sander 2023-09-22 19:25 22041
2660ccea Poul Sander 2023-09-22 19:25 22042
    @liveexample{The following code shows how a flattened JSON object is
2660ccea Poul Sander 2023-09-22 19:25 22043
    unflattened into the original nested JSON object.,unflatten}
2660ccea Poul Sander 2023-09-22 19:25 22044
2660ccea Poul Sander 2023-09-22 19:25 22045
    @sa @ref flatten() for the reverse function
2660ccea Poul Sander 2023-09-22 19:25 22046
2660ccea Poul Sander 2023-09-22 19:25 22047
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 22048
    */
2660ccea Poul Sander 2023-09-22 19:25 22049
    basic_json unflatten() const
2660ccea Poul Sander 2023-09-22 19:25 22050
    {
2660ccea Poul Sander 2023-09-22 19:25 22051
        return json_pointer::unflatten(*this);
2660ccea Poul Sander 2023-09-22 19:25 22052
    }
2660ccea Poul Sander 2023-09-22 19:25 22053
2660ccea Poul Sander 2023-09-22 19:25 22054
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 22055
2660ccea Poul Sander 2023-09-22 19:25 22056
    //////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 22057
    // JSON Patch functions //
2660ccea Poul Sander 2023-09-22 19:25 22058
    //////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 22059
2660ccea Poul Sander 2023-09-22 19:25 22060
    /// @name JSON Patch functions
2660ccea Poul Sander 2023-09-22 19:25 22061
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 22062
2660ccea Poul Sander 2023-09-22 19:25 22063
    /*!
2660ccea Poul Sander 2023-09-22 19:25 22064
    @brief applies a JSON patch
2660ccea Poul Sander 2023-09-22 19:25 22065
2660ccea Poul Sander 2023-09-22 19:25 22066
    [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
2660ccea Poul Sander 2023-09-22 19:25 22067
    expressing a sequence of operations to apply to a JSON) document. With
2660ccea Poul Sander 2023-09-22 19:25 22068
    this function, a JSON Patch is applied to the current JSON value by
2660ccea Poul Sander 2023-09-22 19:25 22069
    executing all operations from the patch.
2660ccea Poul Sander 2023-09-22 19:25 22070
2660ccea Poul Sander 2023-09-22 19:25 22071
    @param[in] json_patch  JSON patch document
2660ccea Poul Sander 2023-09-22 19:25 22072
    @return patched document
2660ccea Poul Sander 2023-09-22 19:25 22073
2660ccea Poul Sander 2023-09-22 19:25 22074
    @note The application of a patch is atomic: Either all operations succeed
2660ccea Poul Sander 2023-09-22 19:25 22075
          and the patched document is returned or an exception is thrown. In
2660ccea Poul Sander 2023-09-22 19:25 22076
          any case, the original value is not changed: the patch is applied
2660ccea Poul Sander 2023-09-22 19:25 22077
          to a copy of the value.
2660ccea Poul Sander 2023-09-22 19:25 22078
2660ccea Poul Sander 2023-09-22 19:25 22079
    @throw parse_error.104 if the JSON patch does not consist of an array of
2660ccea Poul Sander 2023-09-22 19:25 22080
    objects
2660ccea Poul Sander 2023-09-22 19:25 22081
2660ccea Poul Sander 2023-09-22 19:25 22082
    @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
2660ccea Poul Sander 2023-09-22 19:25 22083
    attributes are missing); example: `"operation add must have member path"`
2660ccea Poul Sander 2023-09-22 19:25 22084
2660ccea Poul Sander 2023-09-22 19:25 22085
    @throw out_of_range.401 if an array index is out of range.
2660ccea Poul Sander 2023-09-22 19:25 22086
2660ccea Poul Sander 2023-09-22 19:25 22087
    @throw out_of_range.403 if a JSON pointer inside the patch could not be
2660ccea Poul Sander 2023-09-22 19:25 22088
    resolved successfully in the current JSON value; example: `"key baz not
2660ccea Poul Sander 2023-09-22 19:25 22089
    found"`
2660ccea Poul Sander 2023-09-22 19:25 22090
2660ccea Poul Sander 2023-09-22 19:25 22091
    @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
2660ccea Poul Sander 2023-09-22 19:25 22092
    "move")
2660ccea Poul Sander 2023-09-22 19:25 22093
2660ccea Poul Sander 2023-09-22 19:25 22094
    @throw other_error.501 if "test" operation was unsuccessful
2660ccea Poul Sander 2023-09-22 19:25 22095
2660ccea Poul Sander 2023-09-22 19:25 22096
    @complexity Linear in the size of the JSON value and the length of the
2660ccea Poul Sander 2023-09-22 19:25 22097
    JSON patch. As usually only a fraction of the JSON value is affected by
2660ccea Poul Sander 2023-09-22 19:25 22098
    the patch, the complexity can usually be neglected.
2660ccea Poul Sander 2023-09-22 19:25 22099
2660ccea Poul Sander 2023-09-22 19:25 22100
    @liveexample{The following code shows how a JSON patch is applied to a
2660ccea Poul Sander 2023-09-22 19:25 22101
    value.,patch}
2660ccea Poul Sander 2023-09-22 19:25 22102
2660ccea Poul Sander 2023-09-22 19:25 22103
    @sa @ref diff -- create a JSON patch by comparing two JSON values
2660ccea Poul Sander 2023-09-22 19:25 22104
2660ccea Poul Sander 2023-09-22 19:25 22105
    @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
2660ccea Poul Sander 2023-09-22 19:25 22106
    @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
2660ccea Poul Sander 2023-09-22 19:25 22107
2660ccea Poul Sander 2023-09-22 19:25 22108
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 22109
    */
2660ccea Poul Sander 2023-09-22 19:25 22110
    basic_json patch(const basic_json& json_patch) const
2660ccea Poul Sander 2023-09-22 19:25 22111
    {
2660ccea Poul Sander 2023-09-22 19:25 22112
        // make a working copy to apply the patch to
2660ccea Poul Sander 2023-09-22 19:25 22113
        basic_json result = *this;
2660ccea Poul Sander 2023-09-22 19:25 22114
2660ccea Poul Sander 2023-09-22 19:25 22115
        // the valid JSON Patch operations
2660ccea Poul Sander 2023-09-22 19:25 22116
        enum class patch_operations {add, remove, replace, move, copy, test, invalid};
2660ccea Poul Sander 2023-09-22 19:25 22117
2660ccea Poul Sander 2023-09-22 19:25 22118
        const auto get_op = [](const std::string & op)
2660ccea Poul Sander 2023-09-22 19:25 22119
        {
2660ccea Poul Sander 2023-09-22 19:25 22120
            if (op == "add")
2660ccea Poul Sander 2023-09-22 19:25 22121
            {
2660ccea Poul Sander 2023-09-22 19:25 22122
                return patch_operations::add;
2660ccea Poul Sander 2023-09-22 19:25 22123
            }
2660ccea Poul Sander 2023-09-22 19:25 22124
            if (op == "remove")
2660ccea Poul Sander 2023-09-22 19:25 22125
            {
2660ccea Poul Sander 2023-09-22 19:25 22126
                return patch_operations::remove;
2660ccea Poul Sander 2023-09-22 19:25 22127
            }
2660ccea Poul Sander 2023-09-22 19:25 22128
            if (op == "replace")
2660ccea Poul Sander 2023-09-22 19:25 22129
            {
2660ccea Poul Sander 2023-09-22 19:25 22130
                return patch_operations::replace;
2660ccea Poul Sander 2023-09-22 19:25 22131
            }
2660ccea Poul Sander 2023-09-22 19:25 22132
            if (op == "move")
2660ccea Poul Sander 2023-09-22 19:25 22133
            {
2660ccea Poul Sander 2023-09-22 19:25 22134
                return patch_operations::move;
2660ccea Poul Sander 2023-09-22 19:25 22135
            }
2660ccea Poul Sander 2023-09-22 19:25 22136
            if (op == "copy")
2660ccea Poul Sander 2023-09-22 19:25 22137
            {
2660ccea Poul Sander 2023-09-22 19:25 22138
                return patch_operations::copy;
2660ccea Poul Sander 2023-09-22 19:25 22139
            }
2660ccea Poul Sander 2023-09-22 19:25 22140
            if (op == "test")
2660ccea Poul Sander 2023-09-22 19:25 22141
            {
2660ccea Poul Sander 2023-09-22 19:25 22142
                return patch_operations::test;
2660ccea Poul Sander 2023-09-22 19:25 22143
            }
2660ccea Poul Sander 2023-09-22 19:25 22144
2660ccea Poul Sander 2023-09-22 19:25 22145
            return patch_operations::invalid;
2660ccea Poul Sander 2023-09-22 19:25 22146
        };
2660ccea Poul Sander 2023-09-22 19:25 22147
2660ccea Poul Sander 2023-09-22 19:25 22148
        // wrapper for "add" operation; add value at ptr
2660ccea Poul Sander 2023-09-22 19:25 22149
        const auto operation_add = [&result](json_pointer & ptr, basic_json val)
2660ccea Poul Sander 2023-09-22 19:25 22150
        {
2660ccea Poul Sander 2023-09-22 19:25 22151
            // adding to the root of the target document means replacing it
2660ccea Poul Sander 2023-09-22 19:25 22152
            if (ptr.empty())
2660ccea Poul Sander 2023-09-22 19:25 22153
            {
2660ccea Poul Sander 2023-09-22 19:25 22154
                result = val;
2660ccea Poul Sander 2023-09-22 19:25 22155
                return;
2660ccea Poul Sander 2023-09-22 19:25 22156
            }
2660ccea Poul Sander 2023-09-22 19:25 22157
2660ccea Poul Sander 2023-09-22 19:25 22158
            // make sure the top element of the pointer exists
2660ccea Poul Sander 2023-09-22 19:25 22159
            json_pointer top_pointer = ptr.top();
2660ccea Poul Sander 2023-09-22 19:25 22160
            if (top_pointer != ptr)
2660ccea Poul Sander 2023-09-22 19:25 22161
            {
2660ccea Poul Sander 2023-09-22 19:25 22162
                result.at(top_pointer);
2660ccea Poul Sander 2023-09-22 19:25 22163
            }
2660ccea Poul Sander 2023-09-22 19:25 22164
2660ccea Poul Sander 2023-09-22 19:25 22165
            // get reference to parent of JSON pointer ptr
2660ccea Poul Sander 2023-09-22 19:25 22166
            const auto last_path = ptr.back();
2660ccea Poul Sander 2023-09-22 19:25 22167
            ptr.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 22168
            basic_json& parent = result[ptr];
2660ccea Poul Sander 2023-09-22 19:25 22169
2660ccea Poul Sander 2023-09-22 19:25 22170
            switch (parent.m_type)
2660ccea Poul Sander 2023-09-22 19:25 22171
            {
2660ccea Poul Sander 2023-09-22 19:25 22172
                case value_t::null:
2660ccea Poul Sander 2023-09-22 19:25 22173
                case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 22174
                {
2660ccea Poul Sander 2023-09-22 19:25 22175
                    // use operator[] to add value
2660ccea Poul Sander 2023-09-22 19:25 22176
                    parent[last_path] = val;
2660ccea Poul Sander 2023-09-22 19:25 22177
                    break;
2660ccea Poul Sander 2023-09-22 19:25 22178
                }
2660ccea Poul Sander 2023-09-22 19:25 22179
2660ccea Poul Sander 2023-09-22 19:25 22180
                case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 22181
                {
2660ccea Poul Sander 2023-09-22 19:25 22182
                    if (last_path == "-")
2660ccea Poul Sander 2023-09-22 19:25 22183
                    {
2660ccea Poul Sander 2023-09-22 19:25 22184
                        // special case: append to back
2660ccea Poul Sander 2023-09-22 19:25 22185
                        parent.push_back(val);
2660ccea Poul Sander 2023-09-22 19:25 22186
                    }
2660ccea Poul Sander 2023-09-22 19:25 22187
                    else
2660ccea Poul Sander 2023-09-22 19:25 22188
                    {
2660ccea Poul Sander 2023-09-22 19:25 22189
                        const auto idx = json_pointer::array_index(last_path);
2660ccea Poul Sander 2023-09-22 19:25 22190
                        if (JSON_HEDLEY_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
2660ccea Poul Sander 2023-09-22 19:25 22191
                        {
2660ccea Poul Sander 2023-09-22 19:25 22192
                            // avoid undefined behavior
2660ccea Poul Sander 2023-09-22 19:25 22193
                            JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
2660ccea Poul Sander 2023-09-22 19:25 22194
                        }
2660ccea Poul Sander 2023-09-22 19:25 22195
2660ccea Poul Sander 2023-09-22 19:25 22196
                        // default case: insert add offset
2660ccea Poul Sander 2023-09-22 19:25 22197
                        parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
2660ccea Poul Sander 2023-09-22 19:25 22198
                    }
2660ccea Poul Sander 2023-09-22 19:25 22199
                    break;
2660ccea Poul Sander 2023-09-22 19:25 22200
                }
2660ccea Poul Sander 2023-09-22 19:25 22201
2660ccea Poul Sander 2023-09-22 19:25 22202
                // if there exists a parent it cannot be primitive
2660ccea Poul Sander 2023-09-22 19:25 22203
                default:            // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 22204
                    assert(false);  // LCOV_EXCL_LINE
2660ccea Poul Sander 2023-09-22 19:25 22205
            }
2660ccea Poul Sander 2023-09-22 19:25 22206
        };
2660ccea Poul Sander 2023-09-22 19:25 22207
2660ccea Poul Sander 2023-09-22 19:25 22208
        // wrapper for "remove" operation; remove value at ptr
2660ccea Poul Sander 2023-09-22 19:25 22209
        const auto operation_remove = [&result](json_pointer & ptr)
2660ccea Poul Sander 2023-09-22 19:25 22210
        {
2660ccea Poul Sander 2023-09-22 19:25 22211
            // get reference to parent of JSON pointer ptr
2660ccea Poul Sander 2023-09-22 19:25 22212
            const auto last_path = ptr.back();
2660ccea Poul Sander 2023-09-22 19:25 22213
            ptr.pop_back();
2660ccea Poul Sander 2023-09-22 19:25 22214
            basic_json& parent = result.at(ptr);
2660ccea Poul Sander 2023-09-22 19:25 22215
2660ccea Poul Sander 2023-09-22 19:25 22216
            // remove child
2660ccea Poul Sander 2023-09-22 19:25 22217
            if (parent.is_object())
2660ccea Poul Sander 2023-09-22 19:25 22218
            {
2660ccea Poul Sander 2023-09-22 19:25 22219
                // perform range check
2660ccea Poul Sander 2023-09-22 19:25 22220
                auto it = parent.find(last_path);
2660ccea Poul Sander 2023-09-22 19:25 22221
                if (JSON_HEDLEY_LIKELY(it != parent.end()))
2660ccea Poul Sander 2023-09-22 19:25 22222
                {
2660ccea Poul Sander 2023-09-22 19:25 22223
                    parent.erase(it);
2660ccea Poul Sander 2023-09-22 19:25 22224
                }
2660ccea Poul Sander 2023-09-22 19:25 22225
                else
2660ccea Poul Sander 2023-09-22 19:25 22226
                {
2660ccea Poul Sander 2023-09-22 19:25 22227
                    JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
2660ccea Poul Sander 2023-09-22 19:25 22228
                }
2660ccea Poul Sander 2023-09-22 19:25 22229
            }
2660ccea Poul Sander 2023-09-22 19:25 22230
            else if (parent.is_array())
2660ccea Poul Sander 2023-09-22 19:25 22231
            {
2660ccea Poul Sander 2023-09-22 19:25 22232
                // note erase performs range check
2660ccea Poul Sander 2023-09-22 19:25 22233
                parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
2660ccea Poul Sander 2023-09-22 19:25 22234
            }
2660ccea Poul Sander 2023-09-22 19:25 22235
        };
2660ccea Poul Sander 2023-09-22 19:25 22236
2660ccea Poul Sander 2023-09-22 19:25 22237
        // type check: top level value must be an array
2660ccea Poul Sander 2023-09-22 19:25 22238
        if (JSON_HEDLEY_UNLIKELY(not json_patch.is_array()))
2660ccea Poul Sander 2023-09-22 19:25 22239
        {
2660ccea Poul Sander 2023-09-22 19:25 22240
            JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
2660ccea Poul Sander 2023-09-22 19:25 22241
        }
2660ccea Poul Sander 2023-09-22 19:25 22242
2660ccea Poul Sander 2023-09-22 19:25 22243
        // iterate and apply the operations
2660ccea Poul Sander 2023-09-22 19:25 22244
        for (const auto& val : json_patch)
2660ccea Poul Sander 2023-09-22 19:25 22245
        {
2660ccea Poul Sander 2023-09-22 19:25 22246
            // wrapper to get a value for an operation
2660ccea Poul Sander 2023-09-22 19:25 22247
            const auto get_value = [&val](const std::string & op,
2660ccea Poul Sander 2023-09-22 19:25 22248
                                          const std::string & member,
2660ccea Poul Sander 2023-09-22 19:25 22249
                                          bool string_type) -> basic_json &
2660ccea Poul Sander 2023-09-22 19:25 22250
            {
2660ccea Poul Sander 2023-09-22 19:25 22251
                // find value
2660ccea Poul Sander 2023-09-22 19:25 22252
                auto it = val.m_value.object->find(member);
2660ccea Poul Sander 2023-09-22 19:25 22253
2660ccea Poul Sander 2023-09-22 19:25 22254
                // context-sensitive error message
2660ccea Poul Sander 2023-09-22 19:25 22255
                const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
2660ccea Poul Sander 2023-09-22 19:25 22256
2660ccea Poul Sander 2023-09-22 19:25 22257
                // check if desired value is present
2660ccea Poul Sander 2023-09-22 19:25 22258
                if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
2660ccea Poul Sander 2023-09-22 19:25 22259
                {
2660ccea Poul Sander 2023-09-22 19:25 22260
                    JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
2660ccea Poul Sander 2023-09-22 19:25 22261
                }
2660ccea Poul Sander 2023-09-22 19:25 22262
2660ccea Poul Sander 2023-09-22 19:25 22263
                // check if result is of type string
2660ccea Poul Sander 2023-09-22 19:25 22264
                if (JSON_HEDLEY_UNLIKELY(string_type and not it->second.is_string()))
2660ccea Poul Sander 2023-09-22 19:25 22265
                {
2660ccea Poul Sander 2023-09-22 19:25 22266
                    JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
2660ccea Poul Sander 2023-09-22 19:25 22267
                }
2660ccea Poul Sander 2023-09-22 19:25 22268
2660ccea Poul Sander 2023-09-22 19:25 22269
                // no error: return value
2660ccea Poul Sander 2023-09-22 19:25 22270
                return it->second;
2660ccea Poul Sander 2023-09-22 19:25 22271
            };
2660ccea Poul Sander 2023-09-22 19:25 22272
2660ccea Poul Sander 2023-09-22 19:25 22273
            // type check: every element of the array must be an object
2660ccea Poul Sander 2023-09-22 19:25 22274
            if (JSON_HEDLEY_UNLIKELY(not val.is_object()))
2660ccea Poul Sander 2023-09-22 19:25 22275
            {
2660ccea Poul Sander 2023-09-22 19:25 22276
                JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
2660ccea Poul Sander 2023-09-22 19:25 22277
            }
2660ccea Poul Sander 2023-09-22 19:25 22278
2660ccea Poul Sander 2023-09-22 19:25 22279
            // collect mandatory members
2660ccea Poul Sander 2023-09-22 19:25 22280
            const std::string op = get_value("op", "op", true);
2660ccea Poul Sander 2023-09-22 19:25 22281
            const std::string path = get_value(op, "path", true);
2660ccea Poul Sander 2023-09-22 19:25 22282
            json_pointer ptr(path);
2660ccea Poul Sander 2023-09-22 19:25 22283
2660ccea Poul Sander 2023-09-22 19:25 22284
            switch (get_op(op))
2660ccea Poul Sander 2023-09-22 19:25 22285
            {
2660ccea Poul Sander 2023-09-22 19:25 22286
                case patch_operations::add:
2660ccea Poul Sander 2023-09-22 19:25 22287
                {
2660ccea Poul Sander 2023-09-22 19:25 22288
                    operation_add(ptr, get_value("add", "value", false));
2660ccea Poul Sander 2023-09-22 19:25 22289
                    break;
2660ccea Poul Sander 2023-09-22 19:25 22290
                }
2660ccea Poul Sander 2023-09-22 19:25 22291
2660ccea Poul Sander 2023-09-22 19:25 22292
                case patch_operations::remove:
2660ccea Poul Sander 2023-09-22 19:25 22293
                {
2660ccea Poul Sander 2023-09-22 19:25 22294
                    operation_remove(ptr);
2660ccea Poul Sander 2023-09-22 19:25 22295
                    break;
2660ccea Poul Sander 2023-09-22 19:25 22296
                }
2660ccea Poul Sander 2023-09-22 19:25 22297
2660ccea Poul Sander 2023-09-22 19:25 22298
                case patch_operations::replace:
2660ccea Poul Sander 2023-09-22 19:25 22299
                {
2660ccea Poul Sander 2023-09-22 19:25 22300
                    // the "path" location must exist - use at()
2660ccea Poul Sander 2023-09-22 19:25 22301
                    result.at(ptr) = get_value("replace", "value", false);
2660ccea Poul Sander 2023-09-22 19:25 22302
                    break;
2660ccea Poul Sander 2023-09-22 19:25 22303
                }
2660ccea Poul Sander 2023-09-22 19:25 22304
2660ccea Poul Sander 2023-09-22 19:25 22305
                case patch_operations::move:
2660ccea Poul Sander 2023-09-22 19:25 22306
                {
2660ccea Poul Sander 2023-09-22 19:25 22307
                    const std::string from_path = get_value("move", "from", true);
2660ccea Poul Sander 2023-09-22 19:25 22308
                    json_pointer from_ptr(from_path);
2660ccea Poul Sander 2023-09-22 19:25 22309
2660ccea Poul Sander 2023-09-22 19:25 22310
                    // the "from" location must exist - use at()
2660ccea Poul Sander 2023-09-22 19:25 22311
                    basic_json v = result.at(from_ptr);
2660ccea Poul Sander 2023-09-22 19:25 22312
2660ccea Poul Sander 2023-09-22 19:25 22313
                    // The move operation is functionally identical to a
2660ccea Poul Sander 2023-09-22 19:25 22314
                    // "remove" operation on the "from" location, followed
2660ccea Poul Sander 2023-09-22 19:25 22315
                    // immediately by an "add" operation at the target
2660ccea Poul Sander 2023-09-22 19:25 22316
                    // location with the value that was just removed.
2660ccea Poul Sander 2023-09-22 19:25 22317
                    operation_remove(from_ptr);
2660ccea Poul Sander 2023-09-22 19:25 22318
                    operation_add(ptr, v);
2660ccea Poul Sander 2023-09-22 19:25 22319
                    break;
2660ccea Poul Sander 2023-09-22 19:25 22320
                }
2660ccea Poul Sander 2023-09-22 19:25 22321
2660ccea Poul Sander 2023-09-22 19:25 22322
                case patch_operations::copy:
2660ccea Poul Sander 2023-09-22 19:25 22323
                {
2660ccea Poul Sander 2023-09-22 19:25 22324
                    const std::string from_path = get_value("copy", "from", true);
2660ccea Poul Sander 2023-09-22 19:25 22325
                    const json_pointer from_ptr(from_path);
2660ccea Poul Sander 2023-09-22 19:25 22326
2660ccea Poul Sander 2023-09-22 19:25 22327
                    // the "from" location must exist - use at()
2660ccea Poul Sander 2023-09-22 19:25 22328
                    basic_json v = result.at(from_ptr);
2660ccea Poul Sander 2023-09-22 19:25 22329
2660ccea Poul Sander 2023-09-22 19:25 22330
                    // The copy is functionally identical to an "add"
2660ccea Poul Sander 2023-09-22 19:25 22331
                    // operation at the target location using the value
2660ccea Poul Sander 2023-09-22 19:25 22332
                    // specified in the "from" member.
2660ccea Poul Sander 2023-09-22 19:25 22333
                    operation_add(ptr, v);
2660ccea Poul Sander 2023-09-22 19:25 22334
                    break;
2660ccea Poul Sander 2023-09-22 19:25 22335
                }
2660ccea Poul Sander 2023-09-22 19:25 22336
2660ccea Poul Sander 2023-09-22 19:25 22337
                case patch_operations::test:
2660ccea Poul Sander 2023-09-22 19:25 22338
                {
2660ccea Poul Sander 2023-09-22 19:25 22339
                    bool success = false;
2660ccea Poul Sander 2023-09-22 19:25 22340
                    JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 22341
                    {
2660ccea Poul Sander 2023-09-22 19:25 22342
                        // check if "value" matches the one at "path"
2660ccea Poul Sander 2023-09-22 19:25 22343
                        // the "path" location must exist - use at()
2660ccea Poul Sander 2023-09-22 19:25 22344
                        success = (result.at(ptr) == get_value("test", "value", false));
2660ccea Poul Sander 2023-09-22 19:25 22345
                    }
2660ccea Poul Sander 2023-09-22 19:25 22346
                    JSON_INTERNAL_CATCH (out_of_range&)
2660ccea Poul Sander 2023-09-22 19:25 22347
                    {
2660ccea Poul Sander 2023-09-22 19:25 22348
                        // ignore out of range errors: success remains false
2660ccea Poul Sander 2023-09-22 19:25 22349
                    }
2660ccea Poul Sander 2023-09-22 19:25 22350
2660ccea Poul Sander 2023-09-22 19:25 22351
                    // throw an exception if test fails
2660ccea Poul Sander 2023-09-22 19:25 22352
                    if (JSON_HEDLEY_UNLIKELY(not success))
2660ccea Poul Sander 2023-09-22 19:25 22353
                    {
2660ccea Poul Sander 2023-09-22 19:25 22354
                        JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
2660ccea Poul Sander 2023-09-22 19:25 22355
                    }
2660ccea Poul Sander 2023-09-22 19:25 22356
2660ccea Poul Sander 2023-09-22 19:25 22357
                    break;
2660ccea Poul Sander 2023-09-22 19:25 22358
                }
2660ccea Poul Sander 2023-09-22 19:25 22359
2660ccea Poul Sander 2023-09-22 19:25 22360
                default:
2660ccea Poul Sander 2023-09-22 19:25 22361
                {
2660ccea Poul Sander 2023-09-22 19:25 22362
                    // op must be "add", "remove", "replace", "move", "copy", or
2660ccea Poul Sander 2023-09-22 19:25 22363
                    // "test"
2660ccea Poul Sander 2023-09-22 19:25 22364
                    JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
2660ccea Poul Sander 2023-09-22 19:25 22365
                }
2660ccea Poul Sander 2023-09-22 19:25 22366
            }
2660ccea Poul Sander 2023-09-22 19:25 22367
        }
2660ccea Poul Sander 2023-09-22 19:25 22368
2660ccea Poul Sander 2023-09-22 19:25 22369
        return result;
2660ccea Poul Sander 2023-09-22 19:25 22370
    }
2660ccea Poul Sander 2023-09-22 19:25 22371
2660ccea Poul Sander 2023-09-22 19:25 22372
    /*!
2660ccea Poul Sander 2023-09-22 19:25 22373
    @brief creates a diff as a JSON patch
2660ccea Poul Sander 2023-09-22 19:25 22374
2660ccea Poul Sander 2023-09-22 19:25 22375
    Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
2660ccea Poul Sander 2023-09-22 19:25 22376
    be changed into the value @a target by calling @ref patch function.
2660ccea Poul Sander 2023-09-22 19:25 22377
2660ccea Poul Sander 2023-09-22 19:25 22378
    @invariant For two JSON values @a source and @a target, the following code
2660ccea Poul Sander 2023-09-22 19:25 22379
    yields always `true`:
2660ccea Poul Sander 2023-09-22 19:25 22380
    @code {.cpp}
2660ccea Poul Sander 2023-09-22 19:25 22381
    source.patch(diff(source, target)) == target;
2660ccea Poul Sander 2023-09-22 19:25 22382
    @endcode
2660ccea Poul Sander 2023-09-22 19:25 22383
2660ccea Poul Sander 2023-09-22 19:25 22384
    @note Currently, only `remove`, `add`, and `replace` operations are
2660ccea Poul Sander 2023-09-22 19:25 22385
          generated.
2660ccea Poul Sander 2023-09-22 19:25 22386
2660ccea Poul Sander 2023-09-22 19:25 22387
    @param[in] source  JSON value to compare from
2660ccea Poul Sander 2023-09-22 19:25 22388
    @param[in] target  JSON value to compare against
2660ccea Poul Sander 2023-09-22 19:25 22389
    @param[in] path    helper value to create JSON pointers
2660ccea Poul Sander 2023-09-22 19:25 22390
2660ccea Poul Sander 2023-09-22 19:25 22391
    @return a JSON patch to convert the @a source to @a target
2660ccea Poul Sander 2023-09-22 19:25 22392
2660ccea Poul Sander 2023-09-22 19:25 22393
    @complexity Linear in the lengths of @a source and @a target.
2660ccea Poul Sander 2023-09-22 19:25 22394
2660ccea Poul Sander 2023-09-22 19:25 22395
    @liveexample{The following code shows how a JSON patch is created as a
2660ccea Poul Sander 2023-09-22 19:25 22396
    diff for two JSON values.,diff}
2660ccea Poul Sander 2023-09-22 19:25 22397
2660ccea Poul Sander 2023-09-22 19:25 22398
    @sa @ref patch -- apply a JSON patch
2660ccea Poul Sander 2023-09-22 19:25 22399
    @sa @ref merge_patch -- apply a JSON Merge Patch
2660ccea Poul Sander 2023-09-22 19:25 22400
2660ccea Poul Sander 2023-09-22 19:25 22401
    @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
2660ccea Poul Sander 2023-09-22 19:25 22402
2660ccea Poul Sander 2023-09-22 19:25 22403
    @since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 22404
    */
2660ccea Poul Sander 2023-09-22 19:25 22405
    JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 22406
    static basic_json diff(const basic_json& source, const basic_json& target,
2660ccea Poul Sander 2023-09-22 19:25 22407
                           const std::string& path = "")
2660ccea Poul Sander 2023-09-22 19:25 22408
    {
2660ccea Poul Sander 2023-09-22 19:25 22409
        // the patch
2660ccea Poul Sander 2023-09-22 19:25 22410
        basic_json result(value_t::array);
2660ccea Poul Sander 2023-09-22 19:25 22411
2660ccea Poul Sander 2023-09-22 19:25 22412
        // if the values are the same, return empty patch
2660ccea Poul Sander 2023-09-22 19:25 22413
        if (source == target)
2660ccea Poul Sander 2023-09-22 19:25 22414
        {
2660ccea Poul Sander 2023-09-22 19:25 22415
            return result;
2660ccea Poul Sander 2023-09-22 19:25 22416
        }
2660ccea Poul Sander 2023-09-22 19:25 22417
2660ccea Poul Sander 2023-09-22 19:25 22418
        if (source.type() != target.type())
2660ccea Poul Sander 2023-09-22 19:25 22419
        {
2660ccea Poul Sander 2023-09-22 19:25 22420
            // different types: replace value
2660ccea Poul Sander 2023-09-22 19:25 22421
            result.push_back(
2660ccea Poul Sander 2023-09-22 19:25 22422
            {
2660ccea Poul Sander 2023-09-22 19:25 22423
                {"op", "replace"}, {"path", path}, {"value", target}
2660ccea Poul Sander 2023-09-22 19:25 22424
            });
2660ccea Poul Sander 2023-09-22 19:25 22425
            return result;
2660ccea Poul Sander 2023-09-22 19:25 22426
        }
2660ccea Poul Sander 2023-09-22 19:25 22427
2660ccea Poul Sander 2023-09-22 19:25 22428
        switch (source.type())
2660ccea Poul Sander 2023-09-22 19:25 22429
        {
2660ccea Poul Sander 2023-09-22 19:25 22430
            case value_t::array:
2660ccea Poul Sander 2023-09-22 19:25 22431
            {
2660ccea Poul Sander 2023-09-22 19:25 22432
                // first pass: traverse common elements
2660ccea Poul Sander 2023-09-22 19:25 22433
                std::size_t i = 0;
2660ccea Poul Sander 2023-09-22 19:25 22434
                while (i < source.size() and i < target.size())
2660ccea Poul Sander 2023-09-22 19:25 22435
                {
2660ccea Poul Sander 2023-09-22 19:25 22436
                    // recursive call to compare array values at index i
2660ccea Poul Sander 2023-09-22 19:25 22437
                    auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
2660ccea Poul Sander 2023-09-22 19:25 22438
                    result.insert(result.end(), temp_diff.begin(), temp_diff.end());
2660ccea Poul Sander 2023-09-22 19:25 22439
                    ++i;
2660ccea Poul Sander 2023-09-22 19:25 22440
                }
2660ccea Poul Sander 2023-09-22 19:25 22441
2660ccea Poul Sander 2023-09-22 19:25 22442
                // i now reached the end of at least one array
2660ccea Poul Sander 2023-09-22 19:25 22443
                // in a second pass, traverse the remaining elements
2660ccea Poul Sander 2023-09-22 19:25 22444
2660ccea Poul Sander 2023-09-22 19:25 22445
                // remove my remaining elements
2660ccea Poul Sander 2023-09-22 19:25 22446
                const auto end_index = static_cast<difference_type>(result.size());
2660ccea Poul Sander 2023-09-22 19:25 22447
                while (i < source.size())
2660ccea Poul Sander 2023-09-22 19:25 22448
                {
2660ccea Poul Sander 2023-09-22 19:25 22449
                    // add operations in reverse order to avoid invalid
2660ccea Poul Sander 2023-09-22 19:25 22450
                    // indices
2660ccea Poul Sander 2023-09-22 19:25 22451
                    result.insert(result.begin() + end_index, object(
2660ccea Poul Sander 2023-09-22 19:25 22452
                    {
2660ccea Poul Sander 2023-09-22 19:25 22453
                        {"op", "remove"},
2660ccea Poul Sander 2023-09-22 19:25 22454
                        {"path", path + "/" + std::to_string(i)}
2660ccea Poul Sander 2023-09-22 19:25 22455
                    }));
2660ccea Poul Sander 2023-09-22 19:25 22456
                    ++i;
2660ccea Poul Sander 2023-09-22 19:25 22457
                }
2660ccea Poul Sander 2023-09-22 19:25 22458
2660ccea Poul Sander 2023-09-22 19:25 22459
                // add other remaining elements
2660ccea Poul Sander 2023-09-22 19:25 22460
                while (i < target.size())
2660ccea Poul Sander 2023-09-22 19:25 22461
                {
2660ccea Poul Sander 2023-09-22 19:25 22462
                    result.push_back(
2660ccea Poul Sander 2023-09-22 19:25 22463
                    {
2660ccea Poul Sander 2023-09-22 19:25 22464
                        {"op", "add"},
2660ccea Poul Sander 2023-09-22 19:25 22465
                        {"path", path + "/" + std::to_string(i)},
2660ccea Poul Sander 2023-09-22 19:25 22466
                        {"value", target[i]}
2660ccea Poul Sander 2023-09-22 19:25 22467
                    });
2660ccea Poul Sander 2023-09-22 19:25 22468
                    ++i;
2660ccea Poul Sander 2023-09-22 19:25 22469
                }
2660ccea Poul Sander 2023-09-22 19:25 22470
2660ccea Poul Sander 2023-09-22 19:25 22471
                break;
2660ccea Poul Sander 2023-09-22 19:25 22472
            }
2660ccea Poul Sander 2023-09-22 19:25 22473
2660ccea Poul Sander 2023-09-22 19:25 22474
            case value_t::object:
2660ccea Poul Sander 2023-09-22 19:25 22475
            {
2660ccea Poul Sander 2023-09-22 19:25 22476
                // first pass: traverse this object's elements
2660ccea Poul Sander 2023-09-22 19:25 22477
                for (auto it = source.cbegin(); it != source.cend(); ++it)
2660ccea Poul Sander 2023-09-22 19:25 22478
                {
2660ccea Poul Sander 2023-09-22 19:25 22479
                    // escape the key name to be used in a JSON patch
2660ccea Poul Sander 2023-09-22 19:25 22480
                    const auto key = json_pointer::escape(it.key());
2660ccea Poul Sander 2023-09-22 19:25 22481
2660ccea Poul Sander 2023-09-22 19:25 22482
                    if (target.find(it.key()) != target.end())
2660ccea Poul Sander 2023-09-22 19:25 22483
                    {
2660ccea Poul Sander 2023-09-22 19:25 22484
                        // recursive call to compare object values at key it
2660ccea Poul Sander 2023-09-22 19:25 22485
                        auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
2660ccea Poul Sander 2023-09-22 19:25 22486
                        result.insert(result.end(), temp_diff.begin(), temp_diff.end());
2660ccea Poul Sander 2023-09-22 19:25 22487
                    }
2660ccea Poul Sander 2023-09-22 19:25 22488
                    else
2660ccea Poul Sander 2023-09-22 19:25 22489
                    {
2660ccea Poul Sander 2023-09-22 19:25 22490
                        // found a key that is not in o -> remove it
2660ccea Poul Sander 2023-09-22 19:25 22491
                        result.push_back(object(
2660ccea Poul Sander 2023-09-22 19:25 22492
                        {
2660ccea Poul Sander 2023-09-22 19:25 22493
                            {"op", "remove"}, {"path", path + "/" + key}
2660ccea Poul Sander 2023-09-22 19:25 22494
                        }));
2660ccea Poul Sander 2023-09-22 19:25 22495
                    }
2660ccea Poul Sander 2023-09-22 19:25 22496
                }
2660ccea Poul Sander 2023-09-22 19:25 22497
2660ccea Poul Sander 2023-09-22 19:25 22498
                // second pass: traverse other object's elements
2660ccea Poul Sander 2023-09-22 19:25 22499
                for (auto it = target.cbegin(); it != target.cend(); ++it)
2660ccea Poul Sander 2023-09-22 19:25 22500
                {
2660ccea Poul Sander 2023-09-22 19:25 22501
                    if (source.find(it.key()) == source.end())
2660ccea Poul Sander 2023-09-22 19:25 22502
                    {
2660ccea Poul Sander 2023-09-22 19:25 22503
                        // found a key that is not in this -> add it
2660ccea Poul Sander 2023-09-22 19:25 22504
                        const auto key = json_pointer::escape(it.key());
2660ccea Poul Sander 2023-09-22 19:25 22505
                        result.push_back(
2660ccea Poul Sander 2023-09-22 19:25 22506
                        {
2660ccea Poul Sander 2023-09-22 19:25 22507
                            {"op", "add"}, {"path", path + "/" + key},
2660ccea Poul Sander 2023-09-22 19:25 22508
                            {"value", it.value()}
2660ccea Poul Sander 2023-09-22 19:25 22509
                        });
2660ccea Poul Sander 2023-09-22 19:25 22510
                    }
2660ccea Poul Sander 2023-09-22 19:25 22511
                }
2660ccea Poul Sander 2023-09-22 19:25 22512
2660ccea Poul Sander 2023-09-22 19:25 22513
                break;
2660ccea Poul Sander 2023-09-22 19:25 22514
            }
2660ccea Poul Sander 2023-09-22 19:25 22515
2660ccea Poul Sander 2023-09-22 19:25 22516
            default:
2660ccea Poul Sander 2023-09-22 19:25 22517
            {
2660ccea Poul Sander 2023-09-22 19:25 22518
                // both primitive type: replace value
2660ccea Poul Sander 2023-09-22 19:25 22519
                result.push_back(
2660ccea Poul Sander 2023-09-22 19:25 22520
                {
2660ccea Poul Sander 2023-09-22 19:25 22521
                    {"op", "replace"}, {"path", path}, {"value", target}
2660ccea Poul Sander 2023-09-22 19:25 22522
                });
2660ccea Poul Sander 2023-09-22 19:25 22523
                break;
2660ccea Poul Sander 2023-09-22 19:25 22524
            }
2660ccea Poul Sander 2023-09-22 19:25 22525
        }
2660ccea Poul Sander 2023-09-22 19:25 22526
2660ccea Poul Sander 2023-09-22 19:25 22527
        return result;
2660ccea Poul Sander 2023-09-22 19:25 22528
    }
2660ccea Poul Sander 2023-09-22 19:25 22529
2660ccea Poul Sander 2023-09-22 19:25 22530
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 22531
2660ccea Poul Sander 2023-09-22 19:25 22532
    ////////////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 22533
    // JSON Merge Patch functions //
2660ccea Poul Sander 2023-09-22 19:25 22534
    ////////////////////////////////
2660ccea Poul Sander 2023-09-22 19:25 22535
2660ccea Poul Sander 2023-09-22 19:25 22536
    /// @name JSON Merge Patch functions
2660ccea Poul Sander 2023-09-22 19:25 22537
    /// @{
2660ccea Poul Sander 2023-09-22 19:25 22538
2660ccea Poul Sander 2023-09-22 19:25 22539
    /*!
2660ccea Poul Sander 2023-09-22 19:25 22540
    @brief applies a JSON Merge Patch
2660ccea Poul Sander 2023-09-22 19:25 22541
2660ccea Poul Sander 2023-09-22 19:25 22542
    The merge patch format is primarily intended for use with the HTTP PATCH
2660ccea Poul Sander 2023-09-22 19:25 22543
    method as a means of describing a set of modifications to a target
2660ccea Poul Sander 2023-09-22 19:25 22544
    resource's content. This function applies a merge patch to the current
2660ccea Poul Sander 2023-09-22 19:25 22545
    JSON value.
2660ccea Poul Sander 2023-09-22 19:25 22546
2660ccea Poul Sander 2023-09-22 19:25 22547
    The function implements the following algorithm from Section 2 of
2660ccea Poul Sander 2023-09-22 19:25 22548
    [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
2660ccea Poul Sander 2023-09-22 19:25 22549
2660ccea Poul Sander 2023-09-22 19:25 22550
    ```
2660ccea Poul Sander 2023-09-22 19:25 22551
    define MergePatch(Target, Patch):
2660ccea Poul Sander 2023-09-22 19:25 22552
      if Patch is an Object:
2660ccea Poul Sander 2023-09-22 19:25 22553
        if Target is not an Object:
2660ccea Poul Sander 2023-09-22 19:25 22554
          Target = {} // Ignore the contents and set it to an empty Object
2660ccea Poul Sander 2023-09-22 19:25 22555
        for each Name/Value pair in Patch:
2660ccea Poul Sander 2023-09-22 19:25 22556
          if Value is null:
2660ccea Poul Sander 2023-09-22 19:25 22557
            if Name exists in Target:
2660ccea Poul Sander 2023-09-22 19:25 22558
              remove the Name/Value pair from Target
2660ccea Poul Sander 2023-09-22 19:25 22559
          else:
2660ccea Poul Sander 2023-09-22 19:25 22560
            Target[Name] = MergePatch(Target[Name], Value)
2660ccea Poul Sander 2023-09-22 19:25 22561
        return Target
2660ccea Poul Sander 2023-09-22 19:25 22562
      else:
2660ccea Poul Sander 2023-09-22 19:25 22563
        return Patch
2660ccea Poul Sander 2023-09-22 19:25 22564
    ```
2660ccea Poul Sander 2023-09-22 19:25 22565
2660ccea Poul Sander 2023-09-22 19:25 22566
    Thereby, `Target` is the current object; that is, the patch is applied to
2660ccea Poul Sander 2023-09-22 19:25 22567
    the current value.
2660ccea Poul Sander 2023-09-22 19:25 22568
2660ccea Poul Sander 2023-09-22 19:25 22569
    @param[in] apply_patch  the patch to apply
2660ccea Poul Sander 2023-09-22 19:25 22570
2660ccea Poul Sander 2023-09-22 19:25 22571
    @complexity Linear in the lengths of @a patch.
2660ccea Poul Sander 2023-09-22 19:25 22572
2660ccea Poul Sander 2023-09-22 19:25 22573
    @liveexample{The following code shows how a JSON Merge Patch is applied to
2660ccea Poul Sander 2023-09-22 19:25 22574
    a JSON document.,merge_patch}
2660ccea Poul Sander 2023-09-22 19:25 22575
2660ccea Poul Sander 2023-09-22 19:25 22576
    @sa @ref patch -- apply a JSON patch
2660ccea Poul Sander 2023-09-22 19:25 22577
    @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
2660ccea Poul Sander 2023-09-22 19:25 22578
2660ccea Poul Sander 2023-09-22 19:25 22579
    @since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 22580
    */
2660ccea Poul Sander 2023-09-22 19:25 22581
    void merge_patch(const basic_json& apply_patch)
2660ccea Poul Sander 2023-09-22 19:25 22582
    {
2660ccea Poul Sander 2023-09-22 19:25 22583
        if (apply_patch.is_object())
2660ccea Poul Sander 2023-09-22 19:25 22584
        {
2660ccea Poul Sander 2023-09-22 19:25 22585
            if (not is_object())
2660ccea Poul Sander 2023-09-22 19:25 22586
            {
2660ccea Poul Sander 2023-09-22 19:25 22587
                *this = object();
2660ccea Poul Sander 2023-09-22 19:25 22588
            }
2660ccea Poul Sander 2023-09-22 19:25 22589
            for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
2660ccea Poul Sander 2023-09-22 19:25 22590
            {
2660ccea Poul Sander 2023-09-22 19:25 22591
                if (it.value().is_null())
2660ccea Poul Sander 2023-09-22 19:25 22592
                {
2660ccea Poul Sander 2023-09-22 19:25 22593
                    erase(it.key());
2660ccea Poul Sander 2023-09-22 19:25 22594
                }
2660ccea Poul Sander 2023-09-22 19:25 22595
                else
2660ccea Poul Sander 2023-09-22 19:25 22596
                {
2660ccea Poul Sander 2023-09-22 19:25 22597
                    operator[](it.key()).merge_patch(it.value());
2660ccea Poul Sander 2023-09-22 19:25 22598
                }
2660ccea Poul Sander 2023-09-22 19:25 22599
            }
2660ccea Poul Sander 2023-09-22 19:25 22600
        }
2660ccea Poul Sander 2023-09-22 19:25 22601
        else
2660ccea Poul Sander 2023-09-22 19:25 22602
        {
2660ccea Poul Sander 2023-09-22 19:25 22603
            *this = apply_patch;
2660ccea Poul Sander 2023-09-22 19:25 22604
        }
2660ccea Poul Sander 2023-09-22 19:25 22605
    }
2660ccea Poul Sander 2023-09-22 19:25 22606
2660ccea Poul Sander 2023-09-22 19:25 22607
    /// @}
2660ccea Poul Sander 2023-09-22 19:25 22608
};
2660ccea Poul Sander 2023-09-22 19:25 22609
2660ccea Poul Sander 2023-09-22 19:25 22610
/*!
2660ccea Poul Sander 2023-09-22 19:25 22611
@brief user-defined to_string function for JSON values
2660ccea Poul Sander 2023-09-22 19:25 22612
2660ccea Poul Sander 2023-09-22 19:25 22613
This function implements a user-defined to_string  for JSON objects.
2660ccea Poul Sander 2023-09-22 19:25 22614
2660ccea Poul Sander 2023-09-22 19:25 22615
@param[in] j  a JSON object
2660ccea Poul Sander 2023-09-22 19:25 22616
@return a std::string object
2660ccea Poul Sander 2023-09-22 19:25 22617
*/
2660ccea Poul Sander 2023-09-22 19:25 22618
2660ccea Poul Sander 2023-09-22 19:25 22619
NLOHMANN_BASIC_JSON_TPL_DECLARATION
2660ccea Poul Sander 2023-09-22 19:25 22620
std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
2660ccea Poul Sander 2023-09-22 19:25 22621
{
2660ccea Poul Sander 2023-09-22 19:25 22622
    return j.dump();
2660ccea Poul Sander 2023-09-22 19:25 22623
}
2660ccea Poul Sander 2023-09-22 19:25 22624
} // namespace nlohmann
2660ccea Poul Sander 2023-09-22 19:25 22625
2660ccea Poul Sander 2023-09-22 19:25 22626
///////////////////////
2660ccea Poul Sander 2023-09-22 19:25 22627
// nonmember support //
2660ccea Poul Sander 2023-09-22 19:25 22628
///////////////////////
2660ccea Poul Sander 2023-09-22 19:25 22629
2660ccea Poul Sander 2023-09-22 19:25 22630
// specialization of std::swap, and std::hash
2660ccea Poul Sander 2023-09-22 19:25 22631
namespace std
2660ccea Poul Sander 2023-09-22 19:25 22632
{
2660ccea Poul Sander 2023-09-22 19:25 22633
2660ccea Poul Sander 2023-09-22 19:25 22634
/// hash value for JSON objects
2660ccea Poul Sander 2023-09-22 19:25 22635
template<>
2660ccea Poul Sander 2023-09-22 19:25 22636
struct hash<nlohmann::json>
2660ccea Poul Sander 2023-09-22 19:25 22637
{
2660ccea Poul Sander 2023-09-22 19:25 22638
    /*!
2660ccea Poul Sander 2023-09-22 19:25 22639
    @brief return a hash value for a JSON object
2660ccea Poul Sander 2023-09-22 19:25 22640
2660ccea Poul Sander 2023-09-22 19:25 22641
    @since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 22642
    */
2660ccea Poul Sander 2023-09-22 19:25 22643
    std::size_t operator()(const nlohmann::json& j) const
2660ccea Poul Sander 2023-09-22 19:25 22644
    {
2660ccea Poul Sander 2023-09-22 19:25 22645
        // a naive hashing via the string representation
2660ccea Poul Sander 2023-09-22 19:25 22646
        const auto& h = hash<nlohmann::json::string_t>();
2660ccea Poul Sander 2023-09-22 19:25 22647
        return h(j.dump());
2660ccea Poul Sander 2023-09-22 19:25 22648
    }
2660ccea Poul Sander 2023-09-22 19:25 22649
};
2660ccea Poul Sander 2023-09-22 19:25 22650
2660ccea Poul Sander 2023-09-22 19:25 22651
/// specialization for std::less<value_t>
2660ccea Poul Sander 2023-09-22 19:25 22652
/// @note: do not remove the space after '<',
2660ccea Poul Sander 2023-09-22 19:25 22653
///        see https://github.com/nlohmann/json/pull/679
2660ccea Poul Sander 2023-09-22 19:25 22654
template<>
2660ccea Poul Sander 2023-09-22 19:25 22655
struct less<::nlohmann::detail::value_t>
2660ccea Poul Sander 2023-09-22 19:25 22656
{
2660ccea Poul Sander 2023-09-22 19:25 22657
    /*!
2660ccea Poul Sander 2023-09-22 19:25 22658
    @brief compare two value_t enum values
2660ccea Poul Sander 2023-09-22 19:25 22659
    @since version 3.0.0
2660ccea Poul Sander 2023-09-22 19:25 22660
    */
2660ccea Poul Sander 2023-09-22 19:25 22661
    bool operator()(nlohmann::detail::value_t lhs,
2660ccea Poul Sander 2023-09-22 19:25 22662
                    nlohmann::detail::value_t rhs) const noexcept
2660ccea Poul Sander 2023-09-22 19:25 22663
    {
2660ccea Poul Sander 2023-09-22 19:25 22664
        return nlohmann::detail::operator<(lhs, rhs);
2660ccea Poul Sander 2023-09-22 19:25 22665
    }
2660ccea Poul Sander 2023-09-22 19:25 22666
};
2660ccea Poul Sander 2023-09-22 19:25 22667
2660ccea Poul Sander 2023-09-22 19:25 22668
/*!
2660ccea Poul Sander 2023-09-22 19:25 22669
@brief exchanges the values of two JSON objects
2660ccea Poul Sander 2023-09-22 19:25 22670
2660ccea Poul Sander 2023-09-22 19:25 22671
@since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 22672
*/
2660ccea Poul Sander 2023-09-22 19:25 22673
template<>
2660ccea Poul Sander 2023-09-22 19:25 22674
inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
2660ccea Poul Sander 2023-09-22 19:25 22675
    is_nothrow_move_constructible<nlohmann::json>::value and
2660ccea Poul Sander 2023-09-22 19:25 22676
    is_nothrow_move_assignable<nlohmann::json>::value
2660ccea Poul Sander 2023-09-22 19:25 22677
)
2660ccea Poul Sander 2023-09-22 19:25 22678
{
2660ccea Poul Sander 2023-09-22 19:25 22679
    j1.swap(j2);
2660ccea Poul Sander 2023-09-22 19:25 22680
}
2660ccea Poul Sander 2023-09-22 19:25 22681
2660ccea Poul Sander 2023-09-22 19:25 22682
} // namespace std
2660ccea Poul Sander 2023-09-22 19:25 22683
2660ccea Poul Sander 2023-09-22 19:25 22684
/*!
2660ccea Poul Sander 2023-09-22 19:25 22685
@brief user-defined string literal for JSON values
2660ccea Poul Sander 2023-09-22 19:25 22686
2660ccea Poul Sander 2023-09-22 19:25 22687
This operator implements a user-defined string literal for JSON objects. It
2660ccea Poul Sander 2023-09-22 19:25 22688
can be used by adding `"_json"` to a string literal and returns a JSON object
2660ccea Poul Sander 2023-09-22 19:25 22689
if no parse error occurred.
2660ccea Poul Sander 2023-09-22 19:25 22690
2660ccea Poul Sander 2023-09-22 19:25 22691
@param[in] s  a string representation of a JSON object
2660ccea Poul Sander 2023-09-22 19:25 22692
@param[in] n  the length of string @a s
2660ccea Poul Sander 2023-09-22 19:25 22693
@return a JSON object
2660ccea Poul Sander 2023-09-22 19:25 22694
2660ccea Poul Sander 2023-09-22 19:25 22695
@since version 1.0.0
2660ccea Poul Sander 2023-09-22 19:25 22696
*/
2660ccea Poul Sander 2023-09-22 19:25 22697
JSON_HEDLEY_NON_NULL(1)
2660ccea Poul Sander 2023-09-22 19:25 22698
inline nlohmann::json operator "" _json(const char* s, std::size_t n)
2660ccea Poul Sander 2023-09-22 19:25 22699
{
2660ccea Poul Sander 2023-09-22 19:25 22700
    return nlohmann::json::parse(s, s + n);
2660ccea Poul Sander 2023-09-22 19:25 22701
}
2660ccea Poul Sander 2023-09-22 19:25 22702
2660ccea Poul Sander 2023-09-22 19:25 22703
/*!
2660ccea Poul Sander 2023-09-22 19:25 22704
@brief user-defined string literal for JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 22705
2660ccea Poul Sander 2023-09-22 19:25 22706
This operator implements a user-defined string literal for JSON Pointers. It
2660ccea Poul Sander 2023-09-22 19:25 22707
can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
2660ccea Poul Sander 2023-09-22 19:25 22708
object if no parse error occurred.
2660ccea Poul Sander 2023-09-22 19:25 22709
2660ccea Poul Sander 2023-09-22 19:25 22710
@param[in] s  a string representation of a JSON Pointer
2660ccea Poul Sander 2023-09-22 19:25 22711
@param[in] n  the length of string @a s
2660ccea Poul Sander 2023-09-22 19:25 22712
@return a JSON pointer object
2660ccea Poul Sander 2023-09-22 19:25 22713
2660ccea Poul Sander 2023-09-22 19:25 22714
@since version 2.0.0
2660ccea Poul Sander 2023-09-22 19:25 22715
*/
2660ccea Poul Sander 2023-09-22 19:25 22716
JSON_HEDLEY_NON_NULL(1)
2660ccea Poul Sander 2023-09-22 19:25 22717
inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
2660ccea Poul Sander 2023-09-22 19:25 22718
{
2660ccea Poul Sander 2023-09-22 19:25 22719
    return nlohmann::json::json_pointer(std::string(s, n));
2660ccea Poul Sander 2023-09-22 19:25 22720
}
2660ccea Poul Sander 2023-09-22 19:25 22721
2660ccea Poul Sander 2023-09-22 19:25 22722
// #include <nlohmann/detail/macro_unscope.hpp>
2660ccea Poul Sander 2023-09-22 19:25 22723
2660ccea Poul Sander 2023-09-22 19:25 22724
2660ccea Poul Sander 2023-09-22 19:25 22725
// restore GCC/clang diagnostic settings
2660ccea Poul Sander 2023-09-22 19:25 22726
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2660ccea Poul Sander 2023-09-22 19:25 22727
    #pragma GCC diagnostic pop
2660ccea Poul Sander 2023-09-22 19:25 22728
#endif
2660ccea Poul Sander 2023-09-22 19:25 22729
#if defined(__clang__)
2660ccea Poul Sander 2023-09-22 19:25 22730
    #pragma GCC diagnostic pop
2660ccea Poul Sander 2023-09-22 19:25 22731
#endif
2660ccea Poul Sander 2023-09-22 19:25 22732
2660ccea Poul Sander 2023-09-22 19:25 22733
// clean up
2660ccea Poul Sander 2023-09-22 19:25 22734
#undef JSON_INTERNAL_CATCH
2660ccea Poul Sander 2023-09-22 19:25 22735
#undef JSON_CATCH
2660ccea Poul Sander 2023-09-22 19:25 22736
#undef JSON_THROW
2660ccea Poul Sander 2023-09-22 19:25 22737
#undef JSON_TRY
2660ccea Poul Sander 2023-09-22 19:25 22738
#undef JSON_HAS_CPP_14
2660ccea Poul Sander 2023-09-22 19:25 22739
#undef JSON_HAS_CPP_17
2660ccea Poul Sander 2023-09-22 19:25 22740
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
2660ccea Poul Sander 2023-09-22 19:25 22741
#undef NLOHMANN_BASIC_JSON_TPL
2660ccea Poul Sander 2023-09-22 19:25 22742
2660ccea Poul Sander 2023-09-22 19:25 22743
// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
2660ccea Poul Sander 2023-09-22 19:25 22744
#undef JSON_HEDLEY_ALWAYS_INLINE
2660ccea Poul Sander 2023-09-22 19:25 22745
#undef JSON_HEDLEY_ARM_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22746
#undef JSON_HEDLEY_ARM_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22747
#undef JSON_HEDLEY_ARRAY_PARAM
2660ccea Poul Sander 2023-09-22 19:25 22748
#undef JSON_HEDLEY_ASSUME
2660ccea Poul Sander 2023-09-22 19:25 22749
#undef JSON_HEDLEY_BEGIN_C_DECLS
2660ccea Poul Sander 2023-09-22 19:25 22750
#undef JSON_HEDLEY_C_DECL
2660ccea Poul Sander 2023-09-22 19:25 22751
#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22752
#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2660ccea Poul Sander 2023-09-22 19:25 22753
#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22754
#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22755
#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2660ccea Poul Sander 2023-09-22 19:25 22756
#undef JSON_HEDLEY_CLANG_HAS_FEATURE
2660ccea Poul Sander 2023-09-22 19:25 22757
#undef JSON_HEDLEY_CLANG_HAS_WARNING
2660ccea Poul Sander 2023-09-22 19:25 22758
#undef JSON_HEDLEY_COMPCERT_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22759
#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22760
#undef JSON_HEDLEY_CONCAT
2660ccea Poul Sander 2023-09-22 19:25 22761
#undef JSON_HEDLEY_CONCAT_EX
2660ccea Poul Sander 2023-09-22 19:25 22762
#undef JSON_HEDLEY_CONST
2660ccea Poul Sander 2023-09-22 19:25 22763
#undef JSON_HEDLEY_CONST_CAST
2660ccea Poul Sander 2023-09-22 19:25 22764
#undef JSON_HEDLEY_CONSTEXPR
2660ccea Poul Sander 2023-09-22 19:25 22765
#undef JSON_HEDLEY_CPP_CAST
2660ccea Poul Sander 2023-09-22 19:25 22766
#undef JSON_HEDLEY_CRAY_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22767
#undef JSON_HEDLEY_CRAY_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22768
#undef JSON_HEDLEY_DEPRECATED
2660ccea Poul Sander 2023-09-22 19:25 22769
#undef JSON_HEDLEY_DEPRECATED_FOR
2660ccea Poul Sander 2023-09-22 19:25 22770
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
2660ccea Poul Sander 2023-09-22 19:25 22771
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
2660ccea Poul Sander 2023-09-22 19:25 22772
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
2660ccea Poul Sander 2023-09-22 19:25 22773
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
2660ccea Poul Sander 2023-09-22 19:25 22774
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
2660ccea Poul Sander 2023-09-22 19:25 22775
#undef JSON_HEDLEY_DIAGNOSTIC_POP
2660ccea Poul Sander 2023-09-22 19:25 22776
#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
2660ccea Poul Sander 2023-09-22 19:25 22777
#undef JSON_HEDLEY_DMC_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22778
#undef JSON_HEDLEY_DMC_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22779
#undef JSON_HEDLEY_EMPTY_BASES
2660ccea Poul Sander 2023-09-22 19:25 22780
#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22781
#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22782
#undef JSON_HEDLEY_END_C_DECLS
2660ccea Poul Sander 2023-09-22 19:25 22783
#undef JSON_HEDLEY_FALL_THROUGH
2660ccea Poul Sander 2023-09-22 19:25 22784
#undef JSON_HEDLEY_FLAGS
2660ccea Poul Sander 2023-09-22 19:25 22785
#undef JSON_HEDLEY_FLAGS_CAST
2660ccea Poul Sander 2023-09-22 19:25 22786
#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22787
#undef JSON_HEDLEY_GCC_HAS_BUILTIN
2660ccea Poul Sander 2023-09-22 19:25 22788
#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22789
#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22790
#undef JSON_HEDLEY_GCC_HAS_EXTENSION
2660ccea Poul Sander 2023-09-22 19:25 22791
#undef JSON_HEDLEY_GCC_HAS_FEATURE
2660ccea Poul Sander 2023-09-22 19:25 22792
#undef JSON_HEDLEY_GCC_HAS_WARNING
2660ccea Poul Sander 2023-09-22 19:25 22793
#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22794
#undef JSON_HEDLEY_GCC_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22795
#undef JSON_HEDLEY_GCC_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22796
#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22797
#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
2660ccea Poul Sander 2023-09-22 19:25 22798
#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22799
#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22800
#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
2660ccea Poul Sander 2023-09-22 19:25 22801
#undef JSON_HEDLEY_GNUC_HAS_FEATURE
2660ccea Poul Sander 2023-09-22 19:25 22802
#undef JSON_HEDLEY_GNUC_HAS_WARNING
2660ccea Poul Sander 2023-09-22 19:25 22803
#undef JSON_HEDLEY_GNUC_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22804
#undef JSON_HEDLEY_GNUC_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22805
#undef JSON_HEDLEY_HAS_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22806
#undef JSON_HEDLEY_HAS_BUILTIN
2660ccea Poul Sander 2023-09-22 19:25 22807
#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22808
#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
2660ccea Poul Sander 2023-09-22 19:25 22809
#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
2660ccea Poul Sander 2023-09-22 19:25 22810
#undef JSON_HEDLEY_HAS_EXTENSION
2660ccea Poul Sander 2023-09-22 19:25 22811
#undef JSON_HEDLEY_HAS_FEATURE
2660ccea Poul Sander 2023-09-22 19:25 22812
#undef JSON_HEDLEY_HAS_WARNING
2660ccea Poul Sander 2023-09-22 19:25 22813
#undef JSON_HEDLEY_IAR_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22814
#undef JSON_HEDLEY_IAR_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22815
#undef JSON_HEDLEY_IBM_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22816
#undef JSON_HEDLEY_IBM_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22817
#undef JSON_HEDLEY_IMPORT
2660ccea Poul Sander 2023-09-22 19:25 22818
#undef JSON_HEDLEY_INLINE
2660ccea Poul Sander 2023-09-22 19:25 22819
#undef JSON_HEDLEY_INTEL_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22820
#undef JSON_HEDLEY_INTEL_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22821
#undef JSON_HEDLEY_IS_CONSTANT
2660ccea Poul Sander 2023-09-22 19:25 22822
#undef JSON_HEDLEY_IS_CONSTEXPR_
2660ccea Poul Sander 2023-09-22 19:25 22823
#undef JSON_HEDLEY_LIKELY
2660ccea Poul Sander 2023-09-22 19:25 22824
#undef JSON_HEDLEY_MALLOC
2660ccea Poul Sander 2023-09-22 19:25 22825
#undef JSON_HEDLEY_MESSAGE
2660ccea Poul Sander 2023-09-22 19:25 22826
#undef JSON_HEDLEY_MSVC_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22827
#undef JSON_HEDLEY_MSVC_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22828
#undef JSON_HEDLEY_NEVER_INLINE
2660ccea Poul Sander 2023-09-22 19:25 22829
#undef JSON_HEDLEY_NO_ESCAPE
2660ccea Poul Sander 2023-09-22 19:25 22830
#undef JSON_HEDLEY_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 22831
#undef JSON_HEDLEY_NO_RETURN
2660ccea Poul Sander 2023-09-22 19:25 22832
#undef JSON_HEDLEY_NO_THROW
2660ccea Poul Sander 2023-09-22 19:25 22833
#undef JSON_HEDLEY_NULL
2660ccea Poul Sander 2023-09-22 19:25 22834
#undef JSON_HEDLEY_PELLES_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22835
#undef JSON_HEDLEY_PELLES_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22836
#undef JSON_HEDLEY_PGI_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22837
#undef JSON_HEDLEY_PGI_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22838
#undef JSON_HEDLEY_PREDICT
2660ccea Poul Sander 2023-09-22 19:25 22839
#undef JSON_HEDLEY_PRINTF_FORMAT
2660ccea Poul Sander 2023-09-22 19:25 22840
#undef JSON_HEDLEY_PRIVATE
2660ccea Poul Sander 2023-09-22 19:25 22841
#undef JSON_HEDLEY_PUBLIC
2660ccea Poul Sander 2023-09-22 19:25 22842
#undef JSON_HEDLEY_PURE
2660ccea Poul Sander 2023-09-22 19:25 22843
#undef JSON_HEDLEY_REINTERPRET_CAST
2660ccea Poul Sander 2023-09-22 19:25 22844
#undef JSON_HEDLEY_REQUIRE
2660ccea Poul Sander 2023-09-22 19:25 22845
#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
2660ccea Poul Sander 2023-09-22 19:25 22846
#undef JSON_HEDLEY_REQUIRE_MSG
2660ccea Poul Sander 2023-09-22 19:25 22847
#undef JSON_HEDLEY_RESTRICT
2660ccea Poul Sander 2023-09-22 19:25 22848
#undef JSON_HEDLEY_RETURNS_NON_NULL
2660ccea Poul Sander 2023-09-22 19:25 22849
#undef JSON_HEDLEY_SENTINEL
2660ccea Poul Sander 2023-09-22 19:25 22850
#undef JSON_HEDLEY_STATIC_ASSERT
2660ccea Poul Sander 2023-09-22 19:25 22851
#undef JSON_HEDLEY_STATIC_CAST
2660ccea Poul Sander 2023-09-22 19:25 22852
#undef JSON_HEDLEY_STRINGIFY
2660ccea Poul Sander 2023-09-22 19:25 22853
#undef JSON_HEDLEY_STRINGIFY_EX
2660ccea Poul Sander 2023-09-22 19:25 22854
#undef JSON_HEDLEY_SUNPRO_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22855
#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22856
#undef JSON_HEDLEY_TINYC_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22857
#undef JSON_HEDLEY_TINYC_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22858
#undef JSON_HEDLEY_TI_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22859
#undef JSON_HEDLEY_TI_VERSION_CHECK
2660ccea Poul Sander 2023-09-22 19:25 22860
#undef JSON_HEDLEY_UNAVAILABLE
2660ccea Poul Sander 2023-09-22 19:25 22861
#undef JSON_HEDLEY_UNLIKELY
2660ccea Poul Sander 2023-09-22 19:25 22862
#undef JSON_HEDLEY_UNPREDICTABLE
2660ccea Poul Sander 2023-09-22 19:25 22863
#undef JSON_HEDLEY_UNREACHABLE
2660ccea Poul Sander 2023-09-22 19:25 22864
#undef JSON_HEDLEY_UNREACHABLE_RETURN
2660ccea Poul Sander 2023-09-22 19:25 22865
#undef JSON_HEDLEY_VERSION
2660ccea Poul Sander 2023-09-22 19:25 22866
#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
2660ccea Poul Sander 2023-09-22 19:25 22867
#undef JSON_HEDLEY_VERSION_DECODE_MINOR
2660ccea Poul Sander 2023-09-22 19:25 22868
#undef JSON_HEDLEY_VERSION_DECODE_REVISION
2660ccea Poul Sander 2023-09-22 19:25 22869
#undef JSON_HEDLEY_VERSION_ENCODE
2660ccea Poul Sander 2023-09-22 19:25 22870
#undef JSON_HEDLEY_WARNING
2660ccea Poul Sander 2023-09-22 19:25 22871
#undef JSON_HEDLEY_WARN_UNUSED_RESULT
2660ccea Poul Sander 2023-09-22 19:25 22872
2660ccea Poul Sander 2023-09-22 19:25 22873
2660ccea Poul Sander 2023-09-22 19:25 22874
2660ccea Poul Sander 2023-09-22 19:25 22875
#endif  // INCLUDE_NLOHMANN_JSON_HPP_
1970-01-01 00:00 22876